aprsd-2.2.5-13/0000777000000000000000000000000007665450621006600 5aprsd-2.2.5-13/README0000644000076400007640000001430307660326006007431 # $Id: README,v 1.7 2003/05/14 02:37:58 kg4ijb Exp $ README ------------------------------------------------------------------------ Please at least SKIM this document before asking questions. In fact, READ IT if you've never successfully set up aprsd before. PLEASE! READ IT! If you haven't read this file, and ask for help expect to be told to READ the README file first! or rtfm :) Contents 0 Important notice 1 What is aprsd? 2 How do I get aprsd 2a CVS usage 3 Quick startup 4 Upgrading 5 Boring legal stuff 6 Mailing list 7 Documentation 8 Obtaining help ------------------------------------------------------------------------ (0) NOTICE Please read this file carefully before trying to set up aprsd. This software was developed to be used by licensced amateur radio operators. You are responsible for any information transmitted or propogated on any network. (1) WHAT IS APRSD? APRSd is an APRS server program that uses amateur radio and internet# services to convey GPS mapping, weather, and positional data. It has been developed by and for amateur radio enthusiasts to provide real-time data in an easy to use package. APRSd is an open-source project: Most sources, documentation, and binaries are available under the GPL license, with a few modules available under other open-source or public domain licenses. (2) HOW TO GET APRSD Currently, the 2.2.x tree of aprsd is developed at You can get the latest version of aprsd from there. (2a) CVS USAGE You might obtain the *very latest* version of aprsd that is still under development by using CVS. CVS means 'Concurrent Versions System' and is a tool for developers to always keep source code up to date. Try 'man cvs' on your shell for more information about CVS ;-) This intended only for users that know a fair bit about aprsd. Be aware that the versions of aprsd that you get by CVS are still being developed, and may be buggy. The aprsd devteam will in *NO WAY* take any responsibility for whatever might happen to you or your computer if you use a CVS version of aprsd. To obtain aprsd over CVS, go to the aprsd project page at SourceForge: , Click on CVS, then follow the instructions listed. Notes: (1) you can 'cvs logout', but you don't need to. (2) you don't need to go through this whole process every time; if you want to get a CVS version of aprsd at a later time, you can just 'cd ~/' and type 'cvs update -A'. (3) if you experience errors when using 'export', you might be using tclsh or csh as a shell. If so, try using the command 'setenv' instead of 'export': 'setenv CVSROOT (3) QUICK STARTUP *** ToDo *** (4) UPGRADING *** ToDo *** (5) BORING LEGAL STUFF APRSd is Copyright © by Dale A. Heatherington, WA4DSY. APRSd is distributed according to the GNU General Public License. There should be a copy of this license in the file COPYING. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. As of aprsd 2.2.0 all changes made by the aprsd development team to the aprsd source code and any related files are Copyright © 2002-2003 by The aprsd DevTeam. The source code will still be distributed according to the GNU General Public License as Dale A. Heatherington did in the past. There is no warranty, implied or whatever. You use this software at your own risk, no matter what purpose you put it to. You didn't pay for it, so don't expect magic. (6) MAILING LIST There are currently a couple of mailing lists about aprsd. aprsd-users@lists.sourceforge.net is the one relevant for posts about aprsd 2.2.x and up (and bug fixes, and suggestions, etc). To subscribe to the aprsd mailing list, send email to: aprsd-users-request@lists.sourceforge.net In the body of the message, put "subscribe aprsd-users"; or go to http://lists.sourceforge.net/lists/listinfo/aprsd-users Please, before posting to this list, see what things are like, and when you do post, read over your post for readability, spelling, and grammar mistakes. Obviously, we're all human (or are we?) and we all make mistakes (heck, look at this document! ;). Open discussion and debate is integral to change and progress. Don't flame others over mere form (grammar and spelling), or even substantive issues either for that matter. Please read and follow the mailing list rules. The aprsd-users@lists.sourceforge.net maillist is dedicated to Bug reports, technical questions, your thoughts or suggestions on new features being added to aprsd, things that should be removed or fixed, amazing problems that even stump the guru's, etc... are what we want to see here. (7) DOCUMENTATION We're trying to keep the documentation up to date. If you feel that anything is missing here, or that anything should be added etc, please email aprsd-users@lists.sourceforge.net about it, thank you. (10) OBTAINING HELP Please read the file FAQ, and make sure you've followed any relevant instructions in this document. If the problem still exists, feel free to ask on the aprsd mailing list, as described above. ------------------------------------------------------------------------ (c) 1997 by Dale A. Heatherington, WA4DSY (c) 2002-2003 The APRSd DevTeam aprsd-2.2.5-13/AUTHORS0000664000076400007640000000217107660322524007624 Developers and Contributors _________________________________________________________________ This file attempts to list the majority of the aprsd developers and contributors who have devoted a lot of their time into making aprsd one of the best APRS server available. aprsd was originally written by Dale A. Heatherington, WA4DSY. APRS is trademarked by Bob Bruninga. Developers and Contributors (in alphabetical order): KG4IJB Chuck Byam N2YGK Alan Crosswell (original MIC-E code) N5VFF Brian D Heaton VK3SB Hamish Moffatt Thanks go to all the people who have made individual contributions to the aprsd project by sending bug-reports, patches and otherwise have supported the project. Patch contributors are listed in the UPDATES files. If you think that you are missing from this list contact the aprsd Development Team at http://sourceforge.net/projects/aprsd _________________________________________________________________ Copyright (C) 2000-2003 aprsd Development Team aprsd-2.2.5-13/COPYING0000644000076400007640000004311007615210750007600 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) 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) year 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. aprsd-2.2.5-13/ChangeLog0000664000076400007640000000564707665450554010353 2003-05-29 Chuck Byam, KG4IJB - server.cpp RFalways was evaluating to true when it should have been false (an vice-versa). - Released 2.2.5-13 2003-05-28 Chuck Byam, KG4IJB - ax25 sockets fixed - no really - Released 2.2.5-12 2003-05-18 Chuck Byam, KG4IJB - aprspath invalid string - Released 2.2.5-11 2003-05-17 - aprspath not being properly set - released 2.2.5-10 2003-05-14 Chuck Byam, KG4IJB - Added bootstrap.sh to CVS. Will help generate needed autostuff for CVS builds. - Updated README... well actually it was null bytes. 2003-05-13 Chuck Byam, KG4IJB - Added missing include; ax25socket.cpp - split() now should handle ia64 int more gracefully - Released 2.2.5-9 2003-05-12 Chuck Byam, KG4IJB - AX25 code fixed (needs more testing) - Released 2.2.5-8 2003-05-04 Chuck Byam, KG4IJB - Added aprspass dir and rules to build binary - aprspass.cpp - lame include - admin/ still wasn't populated - Released 2.2.5-7 2003-04-23 Chuck Byam, KG4IJB - Serial I/O support was borked; fixed but in the process I broke ax25 code. I'll release this and work in the ax25 code as time permits. - make dist wasn't pulling in admin and doc - string.cpp/hpp string helper functions/definitions - Logic in html to check for use of tnc - Released 2.2.5-6 2003-04-20 Chuck Byam, KG4IJB - Fixed compile problem with gcc 3.2/automake 1.6 - Fixed minor issue with Exception class - Fixed lock contention in Mutex class - Released 2.2.5-5 2002-12-8 Chuck Byam, KG4IJB - Added constants to pull tocall and program version from config.h in constant.h - More fun with HTML status page - Added functions isAPRSD and isJAVAprsSrv. If true, adds links to the server status page. - Added functions convertRate and convertScale. Displays rates in bits/sec or Kb/sec. - Added function getQRZCall to embed href link to qrz.com for user info. Not very smart, only strips SSID from callsign. 2002-10-27 Chuck Byam, KG4IJB I have taken Dale's latest source (2.1.5x) and made some heavy mods and code clean-ups. - Integrated mutex class. This class eliviates the problem of hung locks as all locks are locally defined and expire when they are out of scope. - Integrated exception class. This is a drop in replacement for the gnu class and is doing little more than the replacing the the current lib version... for now anyway. - Reconfigured package to use AutoTools for configuration and make. - Removed references to STLport. Using gnu gcc >= 3.1 should preclude the use of this library as it is supposed to be "thread-safe". I may re-enable this as a configure option at a later time. - Minor mods to the httpserver pages - mostly cosmetic. - Added ConvertUpTime() to servers.cpp which takes the server uptime, in seconds, and converts it into a more meaningful value. This is used in console status output and html status pages. aprsd-2.2.5-13/INSTALL0000644000076400007640000002202407615210750007577 Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. Basic Installation ================== 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, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. (Caching is disabled by default to prevent problems with accidental use of stale cache files.) 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 you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You only need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and 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. 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. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix *Note Defining Variables::, for more details. 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 support 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' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS 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 machine type. If you are _building_ compiler tools for cross-compiling, you should use the `--target=TYPE' option to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. 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. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc will cause the specified gcc to be used as the C compiler (unless it is overridden in the site shell script). `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of the options to `configure', and exit. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--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. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. aprsd-2.2.5-13/Makefile.am0000664000076400007640000000017507655346517010626 ## Process this file with automake to produce Makefile.in AUTOMAKE_OPTIONS = gnu SUBDIRS = src support doc admin aprspass aprsd-2.2.5-13/Makefile.in0000644000000000000000000003141507665450603010565 # Makefile.in generated by automake 1.6.3 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 # 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. @SET_MAKE@ 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 pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = . ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_HEADER = $(INSTALL_DATA) transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : EXEEXT = @EXEEXT@ OBJEXT = @OBJEXT@ PATH_SEPARATOR = @PATH_SEPARATOR@ AMTAR = @AMTAR@ AWK = @AWK@ CC = @CC@ CXX = @CXX@ DEPDIR = @DEPDIR@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ PACKAGE = @PACKAGE@ STRIP = @STRIP@ VERSION = @VERSION@ am__include = @am__include@ am__quote = @am__quote@ install_sh = @install_sh@ AUTOMAKE_OPTIONS = gnu SUBDIRS = src support doc admin aprspass subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/support/mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = DIST_SOURCES = RECURSIVE_TARGETS = info-recursive dvi-recursive install-info-recursive \ uninstall-info-recursive all-recursive install-data-recursive \ install-exec-recursive installdirs-recursive install-recursive \ uninstall-recursive check-recursive installcheck-recursive DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \ Makefile.in NEWS aclocal.m4 config.h.in configure configure.ac DIST_SUBDIRS = $(SUBDIRS) all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe) $(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(srcdir)/configure: $(srcdir)/configure.ac $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) cd $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): configure.ac cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) config.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ $(MAKE) stamp-h1; \ else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(top_srcdir)/configure.ac $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOHEADER) touch $(srcdir)/config.h.in distclean-hdr: -rm -f config.h stamp-h1 uninstall-info-am: # 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. $(RECURSIVE_TARGETS): @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; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ 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 ETAGS = etags ETAGSFLAGS = tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(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) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = . distdir = $(PACKAGE)-$(VERSION) am__remove_distdir = \ { test ! -d $(distdir) \ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr $(distdir); }; } GZIP_ENV = --best distcleancheck_listfiles = find . -type f -print distdir: $(DISTFILES) $(am__remove_distdir) mkdir $(distdir) @list='$(DISTFILES)'; for file in $$list; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d $(distdir)/$$subdir \ || mkdir $(distdir)/$$subdir \ || exit 1; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" \ distdir=../$(distdir)/$$subdir \ distdir) \ || exit 1; \ fi; \ done -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r $(distdir) dist-gzip: distdir $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist dist-all: distdir $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_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 $(am__remove_distdir) GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf - chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/=build mkdir $(distdir)/=inst chmod a-w $(distdir) dc_install_base=`$(am__cd) $(distdir)/=inst && pwd` \ && cd $(distdir)/=build \ && ../configure --srcdir=.. --prefix=$$dc_install_base \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && (test `find $$dc_install_base -type f -print | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ find $$dc_install_base -type f -print ; \ exit 1; } >&2 ) \ && $(MAKE) $(AM_MAKEFLAGS) dist-gzip \ && rm -f $(distdir).tar.gz \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck $(am__remove_distdir) @echo "$(distdir).tar.gz is ready for distribution" | \ sed 'h;s/./=/g;p;x;p;x' distcleancheck: distclean if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile config.h installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) distclean-am: clean-am distclean-generic distclean-hdr distclean-tags dvi: dvi-recursive dvi-am: info: info-recursive info-am: install-data-am: install-exec-am: install-info: install-info-recursive install-man: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf autom4te.cache maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic uninstall-am: uninstall-info-am uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) GTAGS all all-am check check-am clean \ clean-generic clean-recursive dist dist-all dist-gzip distcheck \ distclean distclean-generic distclean-hdr distclean-recursive \ distclean-tags distcleancheck distdir dvi dvi-am dvi-recursive \ info info-am info-recursive install install-am install-data \ install-data-am install-data-recursive install-exec \ install-exec-am install-exec-recursive install-info \ install-info-am install-info-recursive install-man \ install-recursive install-strip installcheck installcheck-am \ installdirs installdirs-am installdirs-recursive \ maintainer-clean maintainer-clean-generic \ maintainer-clean-recursive mostlyclean mostlyclean-generic \ mostlyclean-recursive tags tags-recursive uninstall \ uninstall-am uninstall-info-am uninstall-info-recursive \ uninstall-recursive # 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: aprsd-2.2.5-13/NEWS0000664000076400007640000000000007637157036007250 aprsd-2.2.5-13/aclocal.m40000664000076400007640000007420707665450577010444 # aclocal.m4 generated automatically by aclocal 1.6.3 -*- Autoconf -*- # Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 # Free Software Foundation, Inc. # This file 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. # Like AC_CONFIG_HEADER, but automatically create stamp file. -*- Autoconf -*- # Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc. # 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. AC_PREREQ([2.52]) # serial 6 # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. We must strip everything past the first ":", # and everything past the last "/". # _AM_DIRNAME(PATH) # ----------------- # Like AS_DIRNAME, only do it during macro expansion AC_DEFUN([_AM_DIRNAME], [m4_if(regexp([$1], [^.*[^/]//*[^/][^/]*/*$]), -1, m4_if(regexp([$1], [^//\([^/]\|$\)]), -1, m4_if(regexp([$1], [^/.*]), -1, [.], patsubst([$1], [^\(/\).*], [\1])), patsubst([$1], [^\(//\)\([^/].*\|$\)], [\1])), patsubst([$1], [^\(.*[^/]\)//*[^/][^/]*/*$], [\1]))[]dnl ])# _AM_DIRNAME # The stamp files are numbered to have different names. # We could number them on a directory basis, but that's additional # complications, let's have a unique counter. m4_define([_AM_STAMP_Count], [0]) # _AM_STAMP(HEADER) # ----------------- # The name of the stamp file for HEADER. AC_DEFUN([_AM_STAMP], [m4_define([_AM_STAMP_Count], m4_incr(_AM_STAMP_Count))dnl AS_ESCAPE(_AM_DIRNAME(patsubst([$1], [:.*])))/stamp-h[]_AM_STAMP_Count]) # _AM_CONFIG_HEADER(HEADER[:SOURCES], COMMANDS, INIT-COMMANDS) # ------------------------------------------------------------ # We used to try to get a real timestamp in stamp-h. But the fear is that # that will cause unnecessary cvs conflicts. AC_DEFUN([_AM_CONFIG_HEADER], [# Add the stamp file to the list of files AC keeps track of, # along with our hook. AC_CONFIG_HEADERS([$1], [# update the timestamp echo 'timestamp for $1' >"_AM_STAMP([$1])" $2], [$3]) ])# _AM_CONFIG_HEADER # AM_CONFIG_HEADER(HEADER[:SOURCES]..., COMMANDS, INIT-COMMANDS) # -------------------------------------------------------------- AC_DEFUN([AM_CONFIG_HEADER], [AC_FOREACH([_AM_File], [$1], [_AM_CONFIG_HEADER(_AM_File, [$2], [$3])]) ])# AM_CONFIG_HEADER # Do all the work for Automake. -*- Autoconf -*- # 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. # Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 # Free Software Foundation, Inc. # 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. # serial 8 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... AC_PREREQ([2.52]) # Autoconf 2.50 wants to disallow AM_ names. We explicitly allow # the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])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 # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl AC_SUBST([PACKAGE], [AC_PACKAGE_TARNAME])dnl AC_SUBST([VERSION], [AC_PACKAGE_VERSION])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AM_MISSING_PROG(AMTAR, tar) AM_PROG_INSTALL_SH AM_PROG_INSTALL_STRIP # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_][CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_][CC], defn([AC_PROG_][CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_][CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_][CXX], defn([AC_PROG_][CXX])[_AM_DEPENDENCIES(CXX)])])dnl ]) ]) # Copyright 2002 Free Software Foundation, Inc. # 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 # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.6"]) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION so it can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.6.3])]) # Helper functions for option handling. -*- Autoconf -*- # Copyright 2001, 2002 Free Software Foundation, Inc. # 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. # serial 2 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # ------------------------------ # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ---------------------------------- # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # # Check to make sure that the build environment is sane. # # Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc. # 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. # serial 3 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # 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 conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $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]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # -*- Autoconf -*- # Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc. # 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. # serial 3 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # AM_AUX_DIR_EXPAND # Copyright 2001 Free Software Foundation, Inc. # 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. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. # Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50]) AC_DEFUN([AM_AUX_DIR_EXPAND], [ # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. # Copyright 2001 Free Software Foundation, Inc. # 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. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl install_sh=${install_sh-"$am_aux_dir/install-sh"} AC_SUBST(install_sh)]) # AM_PROG_INSTALL_STRIP # Copyright 2001 Free Software Foundation, Inc. # 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. # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # serial 4 -*- Autoconf -*- # Copyright 1999, 2000, 2001 Free Software Foundation, Inc. # 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. # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi for depmode in $am_compiler_list; do # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. echo '#include "conftest.h"' > conftest.c echo 'int i;' > conftest.h echo "${am__include} ${am__quote}conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=conftest.c object=conftest.o \ depfile=conftest.Po tmpdepfile=conftest.TPo \ $SHELL ./depcomp $depcc -c conftest.c -o conftest.o >/dev/null 2>&1 && grep conftest.h conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then am_cv_$1_dependencies_compiler_type=$depmode break fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [rm -f .deps 2>/dev/null mkdir .deps 2>/dev/null if test -d .deps; then DEPDIR=.deps else # MS-DOS does not allow filenames that begin with a dot. DEPDIR=_deps fi rmdir .deps 2>/dev/null AC_SUBST([DEPDIR]) ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking Speeds up one-time builds --enable-dependency-tracking Do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH]) ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. # 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. #serial 2 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # So let's grep whole file. if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue # Extract the definition of DEP_FILES from the Makefile without # running `make'. DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` test -z "$DEPDIR" && continue # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n -e '/^U = / s///p' < "$mf"` test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" # We invoke sed twice because it is the simplest approach to # changing $(DEPDIR) to its actual value in the expansion. for file in `sed -n -e ' /^DEP_FILES = .*\\\\$/ { s/^DEP_FILES = // :loop s/\\\\$// p n /\\\\$/ b loop p } /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Copyright 2001 Free Software Foundation, Inc. -*- Autoconf -*- # 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. # serial 2 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' doit: @echo done END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | fgrep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi AC_SUBST(am__include) AC_SUBST(am__quote) AC_MSG_RESULT($_am_result) rm -f confinc confmf ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright 1997, 2000, 2001 Free Software Foundation, Inc. # 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. # serial 5 AC_PREREQ(2.52) # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE]) AC_SUBST([$1_FALSE]) if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([conditional \"$1\" was never defined. Usually this means the macro was only invoked conditionally.]) fi])]) aprsd-2.2.5-13/config.h.in0000664000076400007640000001413307665450620010604 /* config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the header file. */ #undef HAVE_ARPA_INET_H /* Define to 1 if you have the declaration of `strerror_r', and to 0 if you don't. */ #undef HAVE_DECL_STRERROR_R /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if you have the `fork' function. */ #undef HAVE_FORK /* Define to 1 if you have the `gethostbyname' function. */ #undef HAVE_GETHOSTBYNAME /* Define to 1 if you have the `gethostname' function. */ #undef HAVE_GETHOSTNAME /* Define to 1 if you have the `getspnam' function. */ #undef HAVE_GETSPNAM /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY /* Define to 1 if you have the `inet_ntoa' function. */ #undef HAVE_INET_NTOA /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `ax25' library (-lax25). */ #undef HAVE_LIBAX25 /* Define to 1 if you have the `crypt' library (-lcrypt). */ #undef HAVE_LIBCRYPT /* Define to 1 if you have the `pthread' library (-lpthread). */ #undef HAVE_LIBPTHREAD /* Define to 1 if you have the `malloc' function. */ #undef HAVE_MALLOC /* Define to 1 if you have the `memchr' function. */ #undef HAVE_MEMCHR /* Define to 1 if you have the `memmove' function. */ #undef HAVE_MEMMOVE /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `memset' function. */ #undef HAVE_MEMSET /* Define to 1 if you have the header file. */ #undef HAVE_NETAX25_AX25_H /* Define to 1 if you have the header file. */ #undef HAVE_NETDB_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IN_H /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT /* Define to 1 if you have the header file. */ #undef HAVE_SHADOW_H /* Define to 1 if you have the `socket' function. */ #undef HAVE_SOCKET /* Define to 1 if `stat' has the bug that it succeeds when given the zero-length file name argument. */ #undef HAVE_STAT_EMPTY_STRING_BUG /* Define to 1 if stdbool.h conforms to C99. */ #undef HAVE_STDBOOL_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strchr' function. */ #undef HAVE_STRCHR /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP /* Define to 1 if you have the `strerror' function. */ #undef HAVE_STRERROR /* Define to 1 if you have the `strerror_r' function. */ #undef HAVE_STRERROR_R /* Define to 1 if you have the `strftime' function. */ #undef HAVE_STRFTIME /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strpbrk' function. */ #undef HAVE_STRPBRK /* Define to 1 if you have the `strstr' function. */ #undef HAVE_STRSTR /* Define to 1 if you have the `strtol' function. */ #undef HAVE_STRTOL /* Define to 1 if you have the header file. */ #undef HAVE_SYS_IOCTL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SELECT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIMEB_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have that is POSIX.1 compatible. */ #undef HAVE_SYS_WAIT_H /* Define to 1 if you have the header file. */ #undef HAVE_TERMIOS_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `vfork' function. */ #undef HAVE_VFORK /* Define to 1 if you have the header file. */ #undef HAVE_VFORK_H /* Define to 1 if `fork' works. */ #undef HAVE_WORKING_FORK /* Define to 1 if `vfork' works. */ #undef HAVE_WORKING_VFORK /* Define to 1 if the system has the type `_Bool'. */ #undef HAVE__BOOL /* Define to 1 if `lstat' dereferences a symlink specified with a trailing slash. */ #undef LSTAT_FOLLOWS_SLASHED_SYMLINK /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define as the return type of signal handlers (`int' or `void'). */ #undef RETSIGTYPE /* Define to the type of arg 1 for `select'. */ #undef SELECT_TYPE_ARG1 /* Define to the type of args 2, 3 and 4 for `select'. */ #undef SELECT_TYPE_ARG234 /* Define to the type of arg 5 for `select'. */ #undef SELECT_TYPE_ARG5 /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define to 1 if strerror_r returns char *. */ #undef STRERROR_R_CHAR_P /* Define to 1 if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* Define to 1 if your declares `struct tm'. */ #undef TM_IN_SYS_TIME /* Defines the AX25 tocall constant */ #undef TOCALL /* Version number of package */ #undef VERSION /* This is a GNU compliant source, use GNU extensions. */ #undef _GNU_SOURCE /* Use reentrant code if available. */ #undef _REENTRANT /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define as `__inline' if that's what the C compiler calls it, or to nothing if it is not supported. */ #undef inline /* Define to `int' if does not define. */ #undef pid_t /* Define to `unsigned' if does not define. */ #undef size_t /* Define as `fork' if `vfork' does not work. */ #undef vfork aprsd-2.2.5-13/configure0000775000076400007640000071021107665450602010470 #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.57 for aprsd 2.2.5-13. # # Report bugs to . # # Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 # Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi # Support unset when possible. if (FOO=FOO; unset FOO) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" # Sed expression to map a string onto a valid variable name. as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` exec 6>&1 # # Initializations. # ac_default_prefix=/usr/local ac_config_libobj_dir=. cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. # This variable seems obsolete. It should probably be removed, and # only ac_max_sed_lines should be used. : ${ac_max_here_lines=38} # Identity of this package. PACKAGE_NAME='aprsd' PACKAGE_TARNAME='aprsd' PACKAGE_VERSION='2.2.5-13' PACKAGE_STRING='aprsd 2.2.5-13' PACKAGE_BUGREPORT='cbyam@virginia.edu' ac_unique_file="src/aprsd.cpp" # Factoring default headers for most tests. ac_includes_default="\ #include #if HAVE_SYS_TYPES_H # include #endif #if HAVE_SYS_STAT_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif #if HAVE_STRINGS_H # include #endif #if HAVE_INTTYPES_H # include #else # if HAVE_STDINT_H # include # endif #endif #if HAVE_UNISTD_H # include #endif" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE CXX CXXFLAGS LDFLAGS CPPFLAGS ac_ct_CXX EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CXXDEPMODE CC CFLAGS ac_ct_CC CCDEPMODE CPP EGREP LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. 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' 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 ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` # 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_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$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 ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval "enable_$ac_feature=no" ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) 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 | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$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 | -n) 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_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package| sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "with_$ac_package='$ac_optarg'" ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } 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 "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` eval "$ac_envvar='$ac_optarg'" export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute paths. for ac_var in exec_prefix prefix do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* | NONE | '' ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # Be sure to have absolute paths. for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ localstatedir libdir includedir oldincludedir infodir mandir do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null # 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_confdir=`(dirname "$0") 2>/dev/null || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` 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 "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 { (exit 1); exit 1; }; } else { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi fi (cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 { (exit 1); exit 1; }; } srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` ac_env_build_alias_set=${build_alias+set} ac_env_build_alias_value=$build_alias ac_cv_env_build_alias_set=${build_alias+set} ac_cv_env_build_alias_value=$build_alias ac_env_host_alias_set=${host_alias+set} ac_env_host_alias_value=$host_alias ac_cv_env_host_alias_set=${host_alias+set} ac_cv_env_host_alias_value=$host_alias ac_env_target_alias_set=${target_alias+set} ac_env_target_alias_value=$target_alias ac_cv_env_target_alias_set=${target_alias+set} ac_cv_env_target_alias_value=$target_alias ac_env_CXX_set=${CXX+set} ac_env_CXX_value=$CXX ac_cv_env_CXX_set=${CXX+set} ac_cv_env_CXX_value=$CXX ac_env_CXXFLAGS_set=${CXXFLAGS+set} ac_env_CXXFLAGS_value=$CXXFLAGS ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set} ac_cv_env_CXXFLAGS_value=$CXXFLAGS ac_env_LDFLAGS_set=${LDFLAGS+set} ac_env_LDFLAGS_value=$LDFLAGS ac_cv_env_LDFLAGS_set=${LDFLAGS+set} ac_cv_env_LDFLAGS_value=$LDFLAGS ac_env_CPPFLAGS_set=${CPPFLAGS+set} ac_env_CPPFLAGS_value=$CPPFLAGS ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} ac_cv_env_CPPFLAGS_value=$CPPFLAGS ac_env_CC_set=${CC+set} ac_env_CC_value=$CC ac_cv_env_CC_set=${CC+set} ac_cv_env_CC_value=$CC ac_env_CFLAGS_set=${CFLAGS+set} ac_env_CFLAGS_value=$CFLAGS ac_cv_env_CFLAGS_set=${CFLAGS+set} ac_cv_env_CFLAGS_value=$CFLAGS ac_env_CPP_set=${CPP+set} ac_env_CPP_value=$CPP ac_cv_env_CPP_set=${CPP+set} ac_cv_env_CPP_value=$CPP # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures aprsd 2.2.5-13 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] _ACEOF cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data [PREFIX/share] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --infodir=DIR info documentation [PREFIX/info] --mandir=DIR man documentation [PREFIX/man] _ACEOF cat <<\_ACEOF Program names: --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 _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of aprsd 2.2.5-13:";; esac cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-dependency-tracking Speeds up one-time builds --enable-dependency-tracking Do not reject slow dependency extractors Some influential environment variables: CXX C++ compiler command CXXFLAGS C++ compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CC C compiler command CFLAGS C compiler flags CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. ac_popdir=`pwd` for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d $ac_dir || continue ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be # absolute. ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` cd $ac_dir # Check for guested configure; otherwise get Cygnus style configure. if test -f $ac_srcdir/configure.gnu; then echo $SHELL $ac_srcdir/configure.gnu --help=recursive elif test -f $ac_srcdir/configure; then echo $SHELL $ac_srcdir/configure --help=recursive elif test -f $ac_srcdir/configure.ac || test -f $ac_srcdir/configure.in; then echo $ac_configure --help else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi cd $ac_popdir done fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF aprsd configure 2.2.5-13 generated by GNU Autoconf 2.57 Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit 0 fi exec 5>config.log cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by aprsd $as_me 2.2.5-13, which was generated by GNU Autoconf 2.57. Invocation command line was $ $0 $@ _ACEOF { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` hostinfo = `(hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_sep= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" # Get rid of the leading space. ac_sep=" " ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Be sure not to use single quotes in there, as some shells, # such as our DU 5.0 friend, will then `close' the trap. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, { (set) 2>&1 | case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in *ac_space=\ *) sed -n \ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" ;; *) sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------- ## ## Output files. ## ## ------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo sed "/^$/d" confdefs.h | sort echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core core.* *.core && rm -rf conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # 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 # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # 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 "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . $cache_file;; *) . ./$cache_file;; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in `(set) 2>&1 | sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val="\$ac_cv_env_${ac_var}_value" eval ac_new_val="\$ac_env_${ac_var}_value" case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in support $srcdir/support; 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 elif test -f $ac_dir/shtool; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in support $srcdir/support" >&5 echo "$as_me: error: cannot find install-sh or install.sh in support $srcdir/support" >&2;} { (exit 1); exit 1; }; } fi ac_config_guess="$SHELL $ac_aux_dir/config.guess" ac_config_sub="$SHELL $ac_aux_dir/config.sub" ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. # Add the stamp file to the list of files AC keeps track of, # along with our hook. ac_config_headers="$ac_config_headers config.h" am__api_version="1.6" # 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 # AmigaOS /C/install, which installs bootblocks on floppy discs # 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 "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /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 for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done 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 "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&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}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo "$as_me:$LINENO: checking whether build environment is sane" >&5 echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 # Just in case sleep 1 echo timestamp > conftest.file # 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 conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $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 "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&5 echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&2;} { (exit 1); exit 1; }; } fi test "$2" = conftest.file ) then # Ok. : else { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! Check your system clock" >&5 echo "$as_me: error: newly created file is older than distributed files! Check your system clock" >&2;} { (exit 1); exit 1; }; } fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 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" # Double any \ or $. echo might interpret backslashes. # By default was `s,x,x', remove it if useless. cat <<\_ACEOF >conftest.sed s/[\\$]/&&/g;s/;s,x,x,$// _ACEOF program_transform_name=`echo $program_transform_name | sed -f conftest.sed` rm conftest.sed # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_AWK+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then echo "$as_me:$LINENO: result: $AWK" >&5 echo "${ECHO_T}$AWK" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$AWK" && break done echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'` if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.make <<\_ACEOF all: @echo 'ac_maketemp="$(MAKE)"' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} -f conftest.make 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 conftest.make fi if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 SET_MAKE= else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 SET_MAKE="MAKE=${MAKE-make}" fi # test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} { (exit 1); exit 1; }; } fi # Define the identity of the package. PACKAGE=aprsd VERSION=2.2.5-13 cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} AMTAR=${AMTAR-"${am_missing_run}tar"} install_sh=${install_sh-"$am_aux_dir/install-sh"} # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then echo "$as_me:$LINENO: result: $STRIP" >&5 echo "${ECHO_T}$STRIP" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 echo "${ECHO_T}$ac_ct_STRIP" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi STRIP=$ac_ct_STRIP else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" # We need awk for the "check" target. The system "awk" is bad on # some platforms. cat >>confdefs.h <<\_ACEOF #define TOCALL "APD225" _ACEOF cat >>confdefs.h <<\_ACEOF #define _GNU_SOURCE 1 _ACEOF # Checks for programs. ac_ext=cc ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -n "$ac_tool_prefix"; then for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then echo "$as_me:$LINENO: result: $CXX" >&5 echo "${ECHO_T}$CXX" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 echo "${ECHO_T}$ac_ct_CXX" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CXX" && break done test -n "$ac_ct_CXX" || ac_ct_CXX="g++" CXX=$ac_ct_CXX fi # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C++ compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. echo "$as_me:$LINENO: checking for C++ compiler default output" >&5 echo $ECHO_N "checking for C++ compiler default output... $ECHO_C" >&6 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 (eval $ac_link_default) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Find the output, starting from the most likely. This scheme is # not robust to junk in `.', hence go to wildcards (a.*) only as a last # resort. # Be careful to initialize this variable, since it used to be cached. # Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. ac_cv_exeext= # b.out is created by i960 compilers. for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; conftest.$ac_ext ) # This is the source file. ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` # FIXME: I believe we export ac_cv_exeext for Libtool, # but it would be cool to find out if it's true. Does anybody # maintain Libtool? --akim. export ac_cv_exeext break;; * ) break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C++ compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C++ compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6 # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether the C++ compiler works" >&5 echo $ECHO_N "checking whether the C++ compiler works... $ECHO_C" >&6 # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6 echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` export ac_cv_exeext break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6 rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6 OBJEXT=$ac_cv_objext ac_objext=$OBJEXT echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6 if test "${ac_cv_cxx_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6 GXX=`test $ac_compiler_gnu = yes && echo yes` ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS CXXFLAGS="-g" echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cxx_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cxx_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cxx_g=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6 if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi for ac_declaration in \ ''\ '#include ' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 continue fi rm -f conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then echo '#ifdef __cplusplus' >>confdefs.h echo $ac_declaration >>confdefs.h echo '#endif' >>confdefs.h fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu rm -f .deps 2>/dev/null mkdir .deps 2>/dev/null if test -d .deps; then DEPDIR=.deps else # MS-DOS does not allow filenames that begin with a dot. DEPDIR=_deps fi rmdir .deps 2>/dev/null ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' doit: @echo done END # If we don't find an include directive, just comment out the code. echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6 am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | fgrep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi echo "$as_me:$LINENO: result: $_am_result" >&5 echo "${ECHO_T}$_am_result" >&6 rm -f confinc confmf # Check whether --enable-dependency-tracking or --disable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then enableval="$enable_dependency_tracking" fi; if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CXX" am_compiler_list= echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi for depmode in $am_compiler_list; do # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. echo '#include "conftest.h"' > conftest.c echo 'int i;' > conftest.h echo "${am__include} ${am__quote}conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=conftest.c object=conftest.o \ depfile=conftest.Po tmpdepfile=conftest.TPo \ $SHELL ./depcomp $depcc -c conftest.c -o conftest.o >/dev/null 2>&1 && grep conftest.h conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then am_cv_CXX_dependencies_compiler_type=$depmode break fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6 CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done 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 $# != 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 ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CC" && break done CC=$ac_ct_CC fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS CFLAGS="-g" echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cc_g=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then 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 "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 if test "${ac_cv_prog_cc_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_stdc=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF # Don't try gcc -ansi; that turns off useful extensions and # breaks some systems' header files. # AIX -qlanglvl=ansi # Ultrix and OSF/1 -std1 # HP-UX 10.20 and later -Ae # HP-UX older versions -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_stdc=$ac_arg break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext done rm -f conftest.$ac_ext conftest.$ac_objext CC=$ac_save_CC fi case "x$ac_cv_prog_cc_stdc" in x|xno) echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6 ;; *) echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 CC="$CC $ac_cv_prog_cc_stdc" ;; esac # Some people use a C++ compiler to compile C. Since we use `exit', # in C++ we need to declare it. In case someone uses the same compiler # for both compiling C and C++ we need to have the C++ compiler decide # the declaration of exit, since it's the most demanding environment. cat >conftest.$ac_ext <<_ACEOF #ifndef __cplusplus choke me #endif _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then for ac_declaration in \ ''\ '#include ' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 continue fi rm -f conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then echo '#ifdef __cplusplus' >>confdefs.h echo $ac_declaration >>confdefs.h echo '#endif' >>confdefs.h fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi for depmode in $am_compiler_list; do # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. echo '#include "conftest.h"' > conftest.c echo 'int i;' > conftest.h echo "${am__include} ${am__quote}conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=conftest.c object=conftest.o \ depfile=conftest.Po tmpdepfile=conftest.TPo \ $SHELL ./depcomp $depcc -c conftest.c -o conftest.o >/dev/null 2>&1 && grep conftest.h conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then am_cv_CC_dependencies_compiler_type=$depmode break fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6 CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "$GCC" = "yes"; then CXXFLAGS="$CXXFLAGS -Wall -pipe -pthread" fi # Checks for libraries. echo "$as_me:$LINENO: checking for pthread_mutexattr_init in -lpthread" >&5 echo $ECHO_N "checking for pthread_mutexattr_init in -lpthread... $ECHO_C" >&6 if test "${ac_cv_lib_pthread_pthread_mutexattr_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pthread_mutexattr_init (); int main () { pthread_mutexattr_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_pthread_pthread_mutexattr_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthread_pthread_mutexattr_init=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_mutexattr_init" >&5 echo "${ECHO_T}$ac_cv_lib_pthread_pthread_mutexattr_init" >&6 if test $ac_cv_lib_pthread_pthread_mutexattr_init = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBPTHREAD 1 _ACEOF LIBS="-lpthread $LIBS" fi echo "$as_me:$LINENO: checking for crypt in -lcrypt" >&5 echo $ECHO_N "checking for crypt in -lcrypt... $ECHO_C" >&6 if test "${ac_cv_lib_crypt_crypt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char crypt (); int main () { crypt (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_crypt_crypt=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_crypt_crypt=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_crypt_crypt" >&5 echo "${ECHO_T}$ac_cv_lib_crypt_crypt" >&6 if test $ac_cv_lib_crypt_crypt = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBCRYPT 1 _ACEOF LIBS="-lcrypt $LIBS" fi # Check for AX.25 library has_axlib=no ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6 ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6 if test "${ac_cv_prog_egrep+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | (grep -E '(a|b)') >/dev/null 2>&1 then ac_cv_prog_egrep='grep -E' else ac_cv_prog_egrep='egrep' fi fi echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 echo "${ECHO_T}$ac_cv_prog_egrep" >&6 EGREP=$ac_cv_prog_egrep echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else 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 <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else 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 <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #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); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6 if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in netax25/ax25.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc in yes:no ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; no:yes ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF echo "$as_me:$LINENO: checking for ax25_config_load_ports in -lax25" >&5 echo $ECHO_N "checking for ax25_config_load_ports in -lax25... $ECHO_C" >&6 if test "${ac_cv_lib_ax25_ax25_config_load_ports+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lax25 $LIBS" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char ax25_config_load_ports (); int main () { ax25_config_load_ports (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_ax25_ax25_config_load_ports=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ax25_ax25_config_load_ports=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_ax25_ax25_config_load_ports" >&5 echo "${ECHO_T}$ac_cv_lib_ax25_ax25_config_load_ports" >&6 if test $ac_cv_lib_ax25_ax25_config_load_ports = yes; then has_axlib=yes LIBS="$LIBS -lax25" cat >>confdefs.h <<\_ACEOF #define HAVE_LIBAX25 _ACEOF break fi fi done # Checks for header files. echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else 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 <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else 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 <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #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); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6 if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5 echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6 if test "${ac_cv_header_sys_wait_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #ifndef WEXITSTATUS # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) #endif #ifndef WIFEXITED # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif int main () { int s; wait (&s); s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_sys_wait_h=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_sys_wait_h=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6 if test $ac_cv_header_sys_wait_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_SYS_WAIT_H 1 _ACEOF fi for ac_header in arpa/inet.h fcntl.h netdb.h netinet/in.h shadow.h stdlib.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc in yes:no ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; no:yes ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in string.h sys/ioctl.h sys/socket.h sys/time.h sys/timeb.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc in yes:no ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; no:yes ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in termios.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc in yes:no ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; no:yes ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Checks for typedefs, structures, and compiler characteristics. echo "$as_me:$LINENO: checking for stdbool.h that conforms to C99" >&5 echo $ECHO_N "checking for stdbool.h that conforms to C99... $ECHO_C" >&6 if test "${ac_cv_header_stdbool_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #ifndef bool # error bool is not defined #endif #ifndef false # error false is not defined #endif #if false # error false is not 0 #endif #ifndef true # error true is not defined #endif #if true != 1 # error true is not 1 #endif #ifndef __bool_true_false_are_defined # error __bool_true_false_are_defined is not defined #endif struct s { _Bool s: 1; _Bool t; } s; char a[true == 1 ? 1 : -1]; char b[false == 0 ? 1 : -1]; char c[__bool_true_false_are_defined == 1 ? 1 : -1]; char d[(bool) -0.5 == true ? 1 : -1]; bool e = &s; char f[(_Bool) -0.0 == false ? 1 : -1]; char g[true]; char h[sizeof (_Bool)]; char i[sizeof s.t]; int main () { return !a + !b + !c + !d + !e + !f + !g + !h + !i; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdbool_h=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdbool_h=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_header_stdbool_h" >&5 echo "${ECHO_T}$ac_cv_header_stdbool_h" >&6 echo "$as_me:$LINENO: checking for _Bool" >&5 echo $ECHO_N "checking for _Bool... $ECHO_C" >&6 if test "${ac_cv_type__Bool+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if ((_Bool *) 0) return 0; if (sizeof (_Bool)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type__Bool=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type__Bool=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type__Bool" >&5 echo "${ECHO_T}$ac_cv_type__Bool" >&6 if test $ac_cv_type__Bool = yes; then cat >>confdefs.h <<_ACEOF #define HAVE__BOOL 1 _ACEOF fi if test $ac_cv_header_stdbool_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_STDBOOL_H 1 _ACEOF fi echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 if test "${ac_cv_c_const+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { /* FIXME: Include the comments suggested by Paul. */ #ifndef __cplusplus /* Ultrix mips cc rejects this. */ typedef int charset[2]; const charset x; /* SunOS 4.1.1 cc rejects this. */ char const *const *ccp; char **p; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; ccp = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++ccp; p = (char**) ccp; ccp = (char const *const *) p; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; }; struct s *b; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; } #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_const=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_const=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 echo "${ECHO_T}$ac_cv_c_const" >&6 if test $ac_cv_c_const = no; then cat >>confdefs.h <<\_ACEOF #define const _ACEOF fi echo "$as_me:$LINENO: checking for inline" >&5 echo $ECHO_N "checking for inline... $ECHO_C" >&6 if test "${ac_cv_c_inline+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_inline=$ac_kw; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext done fi echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 echo "${ECHO_T}$ac_cv_c_inline" >&6 case $ac_cv_c_inline in inline | yes) ;; no) cat >>confdefs.h <<\_ACEOF #define inline _ACEOF ;; *) cat >>confdefs.h <<_ACEOF #define inline $ac_cv_c_inline _ACEOF ;; esac echo "$as_me:$LINENO: checking for pid_t" >&5 echo $ECHO_N "checking for pid_t... $ECHO_C" >&6 if test "${ac_cv_type_pid_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if ((pid_t *) 0) return 0; if (sizeof (pid_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_pid_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_pid_t=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 echo "${ECHO_T}$ac_cv_type_pid_t" >&6 if test $ac_cv_type_pid_t = yes; then : else cat >>confdefs.h <<_ACEOF #define pid_t int _ACEOF fi echo "$as_me:$LINENO: checking for size_t" >&5 echo $ECHO_N "checking for size_t... $ECHO_C" >&6 if test "${ac_cv_type_size_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if ((size_t *) 0) return 0; if (sizeof (size_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_size_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_size_t=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 echo "${ECHO_T}$ac_cv_type_size_t" >&6 if test $ac_cv_type_size_t = yes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned _ACEOF fi echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6 if test "${ac_cv_header_time+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include int main () { if ((struct tm *) 0) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_time=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_time=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 echo "${ECHO_T}$ac_cv_header_time" >&6 if test $ac_cv_header_time = yes; then cat >>confdefs.h <<\_ACEOF #define TIME_WITH_SYS_TIME 1 _ACEOF fi echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5 echo $ECHO_N "checking whether struct tm is in sys/time.h or time.h... $ECHO_C" >&6 if test "${ac_cv_struct_tm+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { struct tm *tp; tp->tm_sec; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_struct_tm=time.h else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_struct_tm=sys/time.h fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_struct_tm" >&5 echo "${ECHO_T}$ac_cv_struct_tm" >&6 if test $ac_cv_struct_tm = sys/time.h; then cat >>confdefs.h <<\_ACEOF #define TM_IN_SYS_TIME 1 _ACEOF fi cat >>confdefs.h <<\_ACEOF #define _GNU_SOURCE 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _REENTRANT 1 _ACEOF # Checks for library functions. for ac_header in unistd.h vfork.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc in yes:no ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; no:yes ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in fork vfork do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done if test "x$ac_cv_func_fork" = xyes; then echo "$as_me:$LINENO: checking for working fork" >&5 echo $ECHO_N "checking for working fork... $ECHO_C" >&6 if test "${ac_cv_func_fork_works+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then ac_cv_func_fork_works=cross else cat >conftest.$ac_ext <<_ACEOF /* By Ruediger Kuhlmann. */ #include #if HAVE_UNISTD_H # include #endif /* Some systems only have a dummy stub for fork() */ int main () { if (fork() < 0) exit (1); exit (0); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_fork_works=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_func_fork_works=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_func_fork_works" >&5 echo "${ECHO_T}$ac_cv_func_fork_works" >&6 else ac_cv_func_fork_works=$ac_cv_func_fork fi if test "x$ac_cv_func_fork_works" = xcross; then case $host in *-*-amigaos* | *-*-msdosdjgpp*) # Override, as these systems have only a dummy fork() stub ac_cv_func_fork_works=no ;; *) ac_cv_func_fork_works=yes ;; esac { echo "$as_me:$LINENO: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5 echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;} fi ac_cv_func_vfork_works=$ac_cv_func_vfork if test "x$ac_cv_func_vfork" = xyes; then echo "$as_me:$LINENO: checking for working vfork" >&5 echo $ECHO_N "checking for working vfork... $ECHO_C" >&6 if test "${ac_cv_func_vfork_works+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then ac_cv_func_vfork_works=cross else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Thanks to Paul Eggert for this test. */ #include #include #include #include #include #if HAVE_UNISTD_H # include #endif #if HAVE_VFORK_H # include #endif /* On some sparc systems, changes by the child to local and incoming argument registers are propagated back to the parent. The compiler is told about this with #include , but some compilers (e.g. gcc -O) don't grok . Test for this by using a static variable whose address is put into a register that is clobbered by the vfork. */ static void #ifdef __cplusplus sparc_address_test (int arg) # else sparc_address_test (arg) int arg; #endif { static pid_t child; if (!child) { child = vfork (); if (child < 0) { perror ("vfork"); _exit(2); } if (!child) { arg = getpid(); write(-1, "", 0); _exit (arg); } } } int main () { pid_t parent = getpid (); pid_t child; sparc_address_test (0); child = vfork (); if (child == 0) { /* Here is another test for sparc vfork register problems. This test uses lots of local variables, at least as many local variables as main has allocated so far including compiler temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should reuse the register of parent for one of the local variables, since it will think that parent can't possibly be used any more in this routine. Assigning to the local variable will thus munge parent in the parent process. */ pid_t p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(), p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid(); /* Convince the compiler that p..p7 are live; otherwise, it might use the same hardware register for all 8 local variables. */ if (p != p1 || p != p2 || p != p3 || p != p4 || p != p5 || p != p6 || p != p7) _exit(1); /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent from child file descriptors. If the child closes a descriptor before it execs or exits, this munges the parent's descriptor as well. Test for this by closing stdout in the child. */ _exit(close(fileno(stdout)) != 0); } else { int status; struct stat st; while (wait(&status) != child) ; exit( /* Was there some problem with vforking? */ child < 0 /* Did the child fail? (This shouldn't happen.) */ || status /* Did the vfork/compiler bug occur? */ || parent != getpid() /* Did the file descriptor bug occur? */ || fstat(fileno(stdout), &st) != 0 ); } } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_vfork_works=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_func_vfork_works=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_func_vfork_works" >&5 echo "${ECHO_T}$ac_cv_func_vfork_works" >&6 fi; if test "x$ac_cv_func_fork_works" = xcross; then ac_cv_func_vfork_works=ac_cv_func_vfork { echo "$as_me:$LINENO: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5 echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;} fi if test "x$ac_cv_func_vfork_works" = xyes; then cat >>confdefs.h <<\_ACEOF #define HAVE_WORKING_VFORK 1 _ACEOF else cat >>confdefs.h <<\_ACEOF #define vfork fork _ACEOF fi if test "x$ac_cv_func_fork_works" = xyes; then cat >>confdefs.h <<\_ACEOF #define HAVE_WORKING_FORK 1 _ACEOF fi if test $ac_cv_c_compiler_gnu = yes; then echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5 echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6 if test "${ac_cv_prog_gcc_traditional+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_pattern="Autoconf.*'x'" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include Autoconf TIOCGETP _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "$ac_pattern" >/dev/null 2>&1; then ac_cv_prog_gcc_traditional=yes else ac_cv_prog_gcc_traditional=no fi rm -f conftest* if test $ac_cv_prog_gcc_traditional = no; then cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include Autoconf TCGETA _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "$ac_pattern" >/dev/null 2>&1; then ac_cv_prog_gcc_traditional=yes fi rm -f conftest* fi fi echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5 echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6 if test $ac_cv_prog_gcc_traditional = yes; then CC="$CC -traditional" fi fi #AC_FUNC_MALLOC echo "$as_me:$LINENO: checking for working memcmp" >&5 echo $ECHO_N "checking for working memcmp... $ECHO_C" >&6 if test "${ac_cv_func_memcmp_working+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then ac_cv_func_memcmp_working=no else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { /* Some versions of memcmp are not 8-bit clean. */ char c0 = 0x40, c1 = 0x80, c2 = 0x81; if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0) exit (1); /* The Next x86 OpenStep bug shows up only when comparing 16 bytes or more and with at least one buffer not starting on a 4-byte boundary. William Lewis provided this test program. */ { char foo[21]; char bar[21]; int i; for (i = 0; i < 4; i++) { char *a = foo + i; char *b = bar + i; strcpy (a, "--------01111111"); strcpy (b, "--------10000000"); if (memcmp (a, b, 16) >= 0) exit (1); } exit (0); } ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_memcmp_working=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_func_memcmp_working=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_func_memcmp_working" >&5 echo "${ECHO_T}$ac_cv_func_memcmp_working" >&6 test $ac_cv_func_memcmp_working = no && LIBOBJS="$LIBOBJS memcmp.$ac_objext" for ac_header in sys/select.h sys/socket.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc in yes:no ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; no:yes ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done echo "$as_me:$LINENO: checking types of arguments for select" >&5 echo $ECHO_N "checking types of arguments for select... $ECHO_C" >&6 if test "${ac_cv_func_select_args+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else for ac_arg234 in 'fd_set *' 'int *' 'void *'; do for ac_arg1 in 'int' 'size_t' 'unsigned long' 'unsigned'; do for ac_arg5 in 'struct timeval *' 'const struct timeval *'; do cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #if HAVE_SYS_SELECT_H # include #endif #if HAVE_SYS_SOCKET_H # include #endif int main () { extern int select ($ac_arg1, $ac_arg234, $ac_arg234, $ac_arg234, $ac_arg5); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_select_args="$ac_arg1,$ac_arg234,$ac_arg5"; break 3 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext done done done # Provide a safe default value. : ${ac_cv_func_select_args='int,int *,struct timeval *'} fi echo "$as_me:$LINENO: result: $ac_cv_func_select_args" >&5 echo "${ECHO_T}$ac_cv_func_select_args" >&6 ac_save_IFS=$IFS; IFS=',' set dummy `echo "$ac_cv_func_select_args" | sed 's/\*/\*/g'` IFS=$ac_save_IFS shift cat >>confdefs.h <<_ACEOF #define SELECT_TYPE_ARG1 $1 _ACEOF cat >>confdefs.h <<_ACEOF #define SELECT_TYPE_ARG234 ($2) _ACEOF cat >>confdefs.h <<_ACEOF #define SELECT_TYPE_ARG5 ($3) _ACEOF rm -f conftest* echo "$as_me:$LINENO: checking return type of signal handlers" >&5 echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6 if test "${ac_cv_type_signal+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #ifdef signal # undef signal #endif #ifdef __cplusplus extern "C" void (*signal (int, void (*)(int)))(int); #else void (*signal ()) (); #endif int main () { int i; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_signal=void else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_signal=int fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 echo "${ECHO_T}$ac_cv_type_signal" >&6 cat >>confdefs.h <<_ACEOF #define RETSIGTYPE $ac_cv_type_signal _ACEOF echo "$as_me:$LINENO: checking whether lstat dereferences a symlink specified with a trailing slash" >&5 echo $ECHO_N "checking whether lstat dereferences a symlink specified with a trailing slash... $ECHO_C" >&6 if test "${ac_cv_func_lstat_dereferences_slashed_symlink+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else rm -f conftest.sym conftest.file echo >conftest.file if test "$as_ln_s" = "ln -s" && ln -s conftest.file conftest.sym; then if test "$cross_compiling" = yes; then ac_cv_func_lstat_dereferences_slashed_symlink=no else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { struct stat sbuf; /* Linux will dereference the symlink and fail. That is better in the sense that it means we will not have to compile and use the lstat wrapper. */ exit (lstat ("conftest.sym/", &sbuf) ? 0 : 1); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_lstat_dereferences_slashed_symlink=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_func_lstat_dereferences_slashed_symlink=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi else # If the `ln -s' command failed, then we probably don't even # have an lstat function. ac_cv_func_lstat_dereferences_slashed_symlink=no fi rm -f conftest.sym conftest.file fi echo "$as_me:$LINENO: result: $ac_cv_func_lstat_dereferences_slashed_symlink" >&5 echo "${ECHO_T}$ac_cv_func_lstat_dereferences_slashed_symlink" >&6 test $ac_cv_func_lstat_dereferences_slashed_symlink = yes && cat >>confdefs.h <<_ACEOF #define LSTAT_FOLLOWS_SLASHED_SYMLINK 1 _ACEOF if test $ac_cv_func_lstat_dereferences_slashed_symlink = no; then LIBOBJS="$LIBOBJS lstat.$ac_objext" fi echo "$as_me:$LINENO: checking whether stat accepts an empty string" >&5 echo $ECHO_N "checking whether stat accepts an empty string... $ECHO_C" >&6 if test "${ac_cv_func_stat_empty_string_bug+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then ac_cv_func_stat_empty_string_bug=yes else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { struct stat sbuf; exit (stat ("", &sbuf) ? 1 : 0); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_stat_empty_string_bug=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_func_stat_empty_string_bug=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_func_stat_empty_string_bug" >&5 echo "${ECHO_T}$ac_cv_func_stat_empty_string_bug" >&6 if test $ac_cv_func_stat_empty_string_bug = yes; then LIBOBJS="$LIBOBJS stat.$ac_objext" cat >>confdefs.h <<_ACEOF #define HAVE_STAT_EMPTY_STRING_BUG 1 _ACEOF fi echo "$as_me:$LINENO: checking whether strerror_r is declared" >&5 echo $ECHO_N "checking whether strerror_r is declared... $ECHO_C" >&6 if test "${ac_cv_have_decl_strerror_r+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { #ifndef strerror_r char *p = (char *) strerror_r; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_have_decl_strerror_r=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_strerror_r=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_have_decl_strerror_r" >&5 echo "${ECHO_T}$ac_cv_have_decl_strerror_r" >&6 if test $ac_cv_have_decl_strerror_r = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRERROR_R 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRERROR_R 0 _ACEOF fi for ac_func in strerror_r do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done echo "$as_me:$LINENO: checking whether strerror_r returns char *" >&5 echo $ECHO_N "checking whether strerror_r returns char *... $ECHO_C" >&6 if test "${ac_cv_func_strerror_r_char_p+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_func_strerror_r_char_p=no if test $ac_cv_have_decl_strerror_r = yes; then cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { char buf[100]; char x = *strerror_r (0, buf, sizeof buf); char *p = strerror_r (0, buf, sizeof buf); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_strerror_r_char_p=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext else # strerror_r is not declared. Choose between # systems that have relatively inaccessible declarations for the # function. BeOS and DEC UNIX 4.0 fall in this category, but the # former has a strerror_r that returns char*, while the latter # has a strerror_r that returns `int'. # This test should segfault on the DEC system. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default extern char *strerror_r (); int main () { char buf[100]; char x = *strerror_r (0, buf, sizeof buf); exit (!isalpha (x)); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_strerror_r_char_p=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi echo "$as_me:$LINENO: result: $ac_cv_func_strerror_r_char_p" >&5 echo "${ECHO_T}$ac_cv_func_strerror_r_char_p" >&6 if test $ac_cv_func_strerror_r_char_p = yes; then cat >>confdefs.h <<\_ACEOF #define STRERROR_R_CHAR_P 1 _ACEOF fi for ac_func in strftime do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else # strftime is in -lintl on SCO UNIX. echo "$as_me:$LINENO: checking for strftime in -lintl" >&5 echo $ECHO_N "checking for strftime in -lintl... $ECHO_C" >&6 if test "${ac_cv_lib_intl_strftime+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lintl $LIBS" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char strftime (); int main () { strftime (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_intl_strftime=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_intl_strftime=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_intl_strftime" >&5 echo "${ECHO_T}$ac_cv_lib_intl_strftime" >&6 if test $ac_cv_lib_intl_strftime = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_STRFTIME 1 _ACEOF LIBS="-lintl $LIBS" fi fi done for ac_func in gethostbyname gethostname getspnam gettimeofday inet_ntoa do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in malloc memchr memmove memset select socket strchr strdup strerror do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in strpbrk strstr strtol do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done ac_config_files="$ac_config_files Makefile src/Makefile support/Makefile doc/Makefile admin/Makefile aprspass/Makefile" cat >confcache <<\_ACEOF # 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, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # 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 \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } | sed ' t clear : clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ : end' >>confcache if diff $cache_file confcache >/dev/null 2>&1; then :; else if test -w $cache_file; then test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" cat confcache >$cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/; s/:*\${srcdir}:*/:/; s/:*@srcdir@:*/:/; s/^\([^=]*=[ ]*\):*/\1/; s/:*$//; s/^[^=]*=[ ]*$//; }' fi DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_i=`echo "$ac_i" | sed 's/\$U\././;s/\.o$//;s/\.obj$//'` # 2. Add them. ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi # Support unset when possible. if (FOO=FOO; unset FOO) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" # Sed expression to map a string onto a valid variable name. as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH exec 6>&1 # Open the log real soon, to keep \$[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. Logging --version etc. is OK. exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX } >&5 cat >&5 <<_CSEOF This file was extended by aprsd $as_me 2.2.5-13, which was generated by GNU Autoconf 2.57. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ _CSEOF echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 echo >&5 _ACEOF # Files that config.status was made for. if test -n "$ac_config_files"; then echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS fi if test -n "$ac_config_headers"; then echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS fi if test -n "$ac_config_links"; then echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS fi if test -n "$ac_config_commands"; then echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS fi cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ aprsd config.status 2.2.5-13 configured by $0, generated by GNU Autoconf 2.57, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." srcdir=$srcdir INSTALL="$INSTALL" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "x$1" : 'x\([^=]*\)='` ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` ac_shift=: ;; -*) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; *) # This is not an option, so the user has probably given explicit # arguments. ac_option=$1 ac_need_defaults=false;; esac case $ac_option in # Handling of the options. _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --vers* | -V ) echo "$ac_cs_version"; exit 0 ;; --he | --h) # Conflict between --help and --header { { echo "$as_me:$LINENO: error: ambiguous option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # INIT-COMMANDS section. # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_config_target in $ac_config_targets do case "$ac_config_target" in # Handling of arguments. "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "support/Makefile" ) CONFIG_FILES="$CONFIG_FILES support/Makefile" ;; "doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "admin/Makefile" ) CONFIG_FILES="$CONFIG_FILES admin/Makefile" ;; "aprspass/Makefile" ) CONFIG_FILES="$CONFIG_FILES aprspass/Makefile" ;; "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason to put it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Create a temporary directory, and hook for its removal unless debugging. $debug || { trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./confstat$$-$RANDOM (umask 077 && mkdir $tmp) } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "\$CONFIG_FILES"; then # Protect against being on the right side of a sed subst in config.status. sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF s,@SHELL@,$SHELL,;t t s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t s,@exec_prefix@,$exec_prefix,;t t s,@prefix@,$prefix,;t t s,@program_transform_name@,$program_transform_name,;t t s,@bindir@,$bindir,;t t s,@sbindir@,$sbindir,;t t s,@libexecdir@,$libexecdir,;t t s,@datadir@,$datadir,;t t s,@sysconfdir@,$sysconfdir,;t t s,@sharedstatedir@,$sharedstatedir,;t t s,@localstatedir@,$localstatedir,;t t s,@libdir@,$libdir,;t t s,@includedir@,$includedir,;t t s,@oldincludedir@,$oldincludedir,;t t s,@infodir@,$infodir,;t t s,@mandir@,$mandir,;t t s,@build_alias@,$build_alias,;t t s,@host_alias@,$host_alias,;t t s,@target_alias@,$target_alias,;t t s,@DEFS@,$DEFS,;t t s,@ECHO_C@,$ECHO_C,;t t s,@ECHO_N@,$ECHO_N,;t t s,@ECHO_T@,$ECHO_T,;t t s,@LIBS@,$LIBS,;t t s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t s,@INSTALL_DATA@,$INSTALL_DATA,;t t s,@PACKAGE@,$PACKAGE,;t t s,@VERSION@,$VERSION,;t t s,@ACLOCAL@,$ACLOCAL,;t t s,@AUTOCONF@,$AUTOCONF,;t t s,@AUTOMAKE@,$AUTOMAKE,;t t s,@AUTOHEADER@,$AUTOHEADER,;t t s,@MAKEINFO@,$MAKEINFO,;t t s,@AMTAR@,$AMTAR,;t t s,@install_sh@,$install_sh,;t t s,@STRIP@,$STRIP,;t t s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t s,@AWK@,$AWK,;t t s,@SET_MAKE@,$SET_MAKE,;t t s,@CXX@,$CXX,;t t s,@CXXFLAGS@,$CXXFLAGS,;t t s,@LDFLAGS@,$LDFLAGS,;t t s,@CPPFLAGS@,$CPPFLAGS,;t t s,@ac_ct_CXX@,$ac_ct_CXX,;t t s,@EXEEXT@,$EXEEXT,;t t s,@OBJEXT@,$OBJEXT,;t t s,@DEPDIR@,$DEPDIR,;t t s,@am__include@,$am__include,;t t s,@am__quote@,$am__quote,;t t s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t s,@CXXDEPMODE@,$CXXDEPMODE,;t t s,@CC@,$CC,;t t s,@CFLAGS@,$CFLAGS,;t t s,@ac_ct_CC@,$ac_ct_CC,;t t s,@CCDEPMODE@,$CCDEPMODE,;t t s,@CPP@,$CPP,;t t s,@EGREP@,$EGREP,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t CEOF _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # 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_lines=48 ac_sed_frag=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_lines # 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" $tmp/subs.sed >$tmp/subs.frag else sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag fi if test ! -s $tmp/subs.frag; then ac_more_lines=false else # The purpose of the label and of the branching condition is to # speed up the sed processing (if there are no `@' at all, there # is no need to browse any of the substitutions). # These are the two extra sed commands mentioned above. (echo ':t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" else ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" fi ac_sed_frag=`expr $ac_sed_frag + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_lines` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi fi # test -n "$CONFIG_FILES" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be # absolute. ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_builddir$INSTALL ;; esac if test x"$ac_file" != x-; then { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} rm -f "$ac_file" fi # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then configure_input= else configure_input="$ac_file. " fi configure_input=$configure_input"Generated from `echo $ac_file_in | sed 's,.*/,,'` by configure." # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } echo $f;; *) # Relative if test -f "$f"; then # Build tree echo $f elif test -f "$srcdir/$f"; then # Source tree echo $srcdir/$f else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s,@configure_input@,$configure_input,;t t s,@srcdir@,$ac_srcdir,;t t s,@abs_srcdir@,$ac_abs_srcdir,;t t s,@top_srcdir@,$ac_top_srcdir,;t t s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t s,@builddir@,$ac_builddir,;t t s,@abs_builddir@,$ac_abs_builddir,;t t s,@top_builddir@,$ac_top_builddir,;t t s,@abs_top_builddir@,$ac_abs_top_builddir,;t t s,@INSTALL@,$ac_INSTALL,;t t " $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out rm -f $tmp/stdin if test x"$ac_file" != x-; then mv $tmp/out $ac_file else cat $tmp/out rm -f $tmp/out fi done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # # CONFIG_HEADER section. # # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' ac_dB='[ ].*$,\1#\2' ac_dC=' ' ac_dD=',;t' # ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='$,\1#\2define\3' ac_uC=' ' ac_uD=',;t' for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } echo $f;; *) # Relative if test -f "$f"; then # Build tree echo $f elif test -f "$srcdir/$f"; then # Source tree echo $srcdir/$f else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } # Remove the trailing spaces. sed 's/[ ]*$//' $ac_file_inputs >$tmp/in _ACEOF # Transform confdefs.h into two sed scripts, `conftest.defines' and # `conftest.undefs', that substitutes the proper values into # config.h.in to produce config.h. The first handles `#define' # templates, and the second `#undef' templates. # And first: Protect against being on the right side of a sed subst in # config.status. Protect against being in an unquoted here document # in config.status. rm -f conftest.defines conftest.undefs # Using a here document instead of a string reduces the quoting nightmare. # Putting comments in sed scripts is not portable. # # `end' is used to avoid that the second main sed command (meant for # 0-ary CPP macros) applies to n-ary macro definitions. # See the Autoconf documentation for `clear'. cat >confdef2sed.sed <<\_ACEOF s/[\\&,]/\\&/g s,[\\$`],\\&,g t clear : clear s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp t end s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp : end _ACEOF # If some macros were called several times there might be several times # the same #defines, which is useless. Nevertheless, we may not want to # sort them, since we want the *last* AC-DEFINE to be honored. uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs rm -f confdef2sed.sed # This sed command replaces #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. cat >>conftest.undefs <<\_ACEOF s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, _ACEOF # Break up conftest.defines because some shells have a limit on the size # of here documents, and old seds have small limits too (100 cmds). echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS echo ' :' >>$CONFIG_STATUS rm -f conftest.tail while grep . conftest.defines >/dev/null do # Write a limited-size here document to $tmp/defines.sed. echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS # Speed up: don't consider the non `#define' lines. echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS # Work around the forget-to-reset-the-flag bug. echo 't clr' >>$CONFIG_STATUS echo ': clr' >>$CONFIG_STATUS sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS echo 'CEOF sed -f $tmp/defines.sed $tmp/in >$tmp/out rm -f $tmp/in mv $tmp/out $tmp/in ' >>$CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail rm -f conftest.defines mv conftest.tail conftest.defines done rm -f conftest.defines echo ' fi # grep' >>$CONFIG_STATUS echo >>$CONFIG_STATUS # Break up conftest.undefs because some shells have a limit on the size # of here documents, and old seds have small limits too (100 cmds). echo ' # Handle all the #undef templates' >>$CONFIG_STATUS rm -f conftest.tail while grep . conftest.undefs >/dev/null do # Write a limited-size here document to $tmp/undefs.sed. echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS # Speed up: don't consider the non `#undef' echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS # Work around the forget-to-reset-the-flag bug. echo 't clr' >>$CONFIG_STATUS echo ': clr' >>$CONFIG_STATUS sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS echo 'CEOF sed -f $tmp/undefs.sed $tmp/in >$tmp/out rm -f $tmp/in mv $tmp/out $tmp/in ' >>$CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail rm -f conftest.undefs mv conftest.tail conftest.undefs done rm -f conftest.undefs cat >>$CONFIG_STATUS <<\_ACEOF # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then echo "/* Generated by configure. */" >$tmp/config.h else echo "/* $ac_file. Generated by configure. */" >$tmp/config.h fi cat $tmp/in >>$tmp/config.h rm -f $tmp/in if test x"$ac_file" != x-; then if diff $ac_file $tmp/config.h >/dev/null 2>&1; then { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 echo "$as_me: $ac_file is unchanged" >&6;} else ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } rm -f $ac_file mv $tmp/config.h $ac_file fi else cat $tmp/config.h rm -f $tmp/config.h fi # Run the commands associated with the file. case $ac_file in config.h ) # update the timestamp echo 'timestamp for config.h' >"./stamp-h1" ;; esac done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # # CONFIG_COMMANDS section. # for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue ac_dest=`echo "$ac_file" | sed 's,:.*,,'` ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_dir=`(dirname "$ac_dest") 2>/dev/null || $as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_dest" : 'X\(//\)[^/]' \| \ X"$ac_dest" : 'X\(//\)$' \| \ X"$ac_dest" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_dest" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be # absolute. ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 echo "$as_me: executing $ac_dest commands" >&6;} case $ac_dest in depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # So let's grep whole file. if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then dirpart=`(dirname "$mf") 2>/dev/null || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` else continue fi grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue # Extract the definition of DEP_FILES from the Makefile without # running `make'. DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` test -z "$DEPDIR" && continue # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n -e '/^U = / s///p' < "$mf"` test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" # We invoke sed twice because it is the simplest approach to # changing $(DEPDIR) to its actual value in the expansion. for file in `sed -n -e ' /^DEP_FILES = .*\\\\$/ { s/^DEP_FILES = // :loop s/\\\\$// p n /\\\\$/ b loop p } /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`(dirname "$file") 2>/dev/null || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p $dirpart/$fdir else as_dir=$dirpart/$fdir as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5 echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;} { (exit 1); exit 1; }; }; } # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ;; esac done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi aprsd-2.2.5-13/configure.ac0000664000076400007640000000351407665450571011055 # Process this file with autoconf to produce a configure script. AC_PREREQ(2.57) AC_INIT(aprsd, 2.2.5-13, cbyam@virginia.edu) AC_CONFIG_AUX_DIR(support) AC_CONFIG_SRCDIR([src/aprsd.cpp]) AM_CONFIG_HEADER([config.h]) AM_INIT_AUTOMAKE AC_DEFINE(TOCALL, "APD225", [Defines the AX25 tocall constant]) AC_GNU_SOURCE # Checks for programs. AC_PROG_CXX AC_PROG_CC if test "$GCC" = "yes"; then CXXFLAGS="$CXXFLAGS -Wall -pipe -pthread" fi # Checks for libraries. AC_CHECK_LIB([pthread], [pthread_mutexattr_init]) AC_CHECK_LIB([crypt], [crypt]) # Check for AX.25 library has_axlib=no AC_CHECK_HEADERS(netax25/ax25.h, [AC_CHECK_LIB(ax25, ax25_config_load_ports, has_axlib=yes LIBS="$LIBS -lax25" AC_DEFINE(HAVE_LIBAX25, , Define to 1 if you have the `ax25' library (-lax25). ) break)]) # Checks for header files. AC_HEADER_STDC AC_HEADER_SYS_WAIT AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h shadow.h stdlib.h]) AC_CHECK_HEADERS([string.h sys/ioctl.h sys/socket.h sys/time.h sys/timeb.h]) AC_CHECK_HEADERS([termios.h unistd.h]) # Checks for typedefs, structures, and compiler characteristics. AC_HEADER_STDBOOL AC_C_CONST AC_C_INLINE AC_TYPE_PID_T AC_TYPE_SIZE_T AC_HEADER_TIME AC_STRUCT_TM AC_DEFINE(_GNU_SOURCE, 1, [This is a GNU compliant source, use GNU extensions.]) AC_DEFINE(_REENTRANT, 1, Use reentrant code if available.) # Checks for library functions. AC_FUNC_FORK AC_PROG_GCC_TRADITIONAL #AC_FUNC_MALLOC AC_FUNC_MEMCMP AC_FUNC_SELECT_ARGTYPES AC_TYPE_SIGNAL AC_FUNC_STAT AC_FUNC_STRERROR_R AC_FUNC_STRFTIME AC_CHECK_FUNCS([gethostbyname gethostname getspnam gettimeofday inet_ntoa]) AC_CHECK_FUNCS([malloc memchr memmove memset select socket strchr strdup strerror]) AC_CHECK_FUNCS([strpbrk strstr strtol]) AC_CONFIG_FILES([Makefile \ src/Makefile \ support/Makefile \ doc/Makefile \ admin/Makefile \ aprspass/Makefile]) AC_OUTPUT aprsd-2.2.5-13/src/0000777000000000000000000000000007665450620007366 5aprsd-2.2.5-13/src/Makefile.am0000664000076400007640000000121007657576172011410 bin_PROGRAMS = aprsd aprsd_SOURCES = aprsd.cpp aprsd.h \ aprsString.cpp aprsString.h \ aprsdassert.h \ ax25socket.cpp ax25socket.h \ constant.h \ cpqueue.cpp cpqueue.h \ crc32.c crc.h \ dupCheck.cpp dupCheck.h \ aprsdexception.cpp aprsdexception.h \ exceptionguard.cpp exceptionguard.h \ history.cpp history.h \ httpserver.cpp httppage.h \ mic_e.cpp mic_e.h \ mutex.cpp mutex.h \ osdep.cpp osdep.h \ queryResp.cpp queryResp.h \ rf.cpp rf.h \ serial.cpp serial.h \ servers.cpp servers.h \ sniptype.h \ string.cpp string.hpp \ utils.cpp utils.h \ validate.cpp validate.h INCLUDES = -I$(top_srcdir)/src aprsd-2.2.5-13/src/Makefile.in0000644000000000000000000003065107665450603011355 # Makefile.in generated by automake 1.6.3 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 # 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. @SET_MAKE@ 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 pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_HEADER = $(INSTALL_DATA) transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : EXEEXT = @EXEEXT@ OBJEXT = @OBJEXT@ PATH_SEPARATOR = @PATH_SEPARATOR@ AMTAR = @AMTAR@ AWK = @AWK@ CC = @CC@ CXX = @CXX@ DEPDIR = @DEPDIR@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ PACKAGE = @PACKAGE@ STRIP = @STRIP@ VERSION = @VERSION@ am__include = @am__include@ am__quote = @am__quote@ install_sh = @install_sh@ bin_PROGRAMS = aprsd aprsd_SOURCES = aprsd.cpp aprsd.h \ aprsString.cpp aprsString.h \ aprsdassert.h \ ax25socket.cpp ax25socket.h \ constant.h \ cpqueue.cpp cpqueue.h \ crc32.c crc.h \ dupCheck.cpp dupCheck.h \ aprsdexception.cpp aprsdexception.h \ exceptionguard.cpp exceptionguard.h \ history.cpp history.h \ httpserver.cpp httppage.h \ mic_e.cpp mic_e.h \ mutex.cpp mutex.h \ osdep.cpp osdep.h \ queryResp.cpp queryResp.h \ rf.cpp rf.h \ serial.cpp serial.h \ servers.cpp servers.h \ sniptype.h \ string.cpp string.hpp \ utils.cpp utils.h \ validate.cpp validate.h INCLUDES = -I$(top_srcdir)/src subdir = src mkinstalldirs = $(SHELL) $(top_srcdir)/support/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = bin_PROGRAMS = aprsd$(EXEEXT) PROGRAMS = $(bin_PROGRAMS) am_aprsd_OBJECTS = aprsd.$(OBJEXT) aprsString.$(OBJEXT) \ ax25socket.$(OBJEXT) cpqueue.$(OBJEXT) crc32.$(OBJEXT) \ dupCheck.$(OBJEXT) aprsdexception.$(OBJEXT) \ exceptionguard.$(OBJEXT) history.$(OBJEXT) httpserver.$(OBJEXT) \ mic_e.$(OBJEXT) mutex.$(OBJEXT) osdep.$(OBJEXT) \ queryResp.$(OBJEXT) rf.$(OBJEXT) serial.$(OBJEXT) \ servers.$(OBJEXT) string.$(OBJEXT) utils.$(OBJEXT) \ validate.$(OBJEXT) aprsd_OBJECTS = $(am_aprsd_OBJECTS) aprsd_LDADD = $(LDADD) aprsd_DEPENDENCIES = aprsd_LDFLAGS = DEFS = @DEFS@ DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ depcomp = $(SHELL) $(top_srcdir)/support/depcomp am__depfiles_maybe = depfiles @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/aprsString.Po ./$(DEPDIR)/aprsd.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/aprsdexception.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/ax25socket.Po ./$(DEPDIR)/cpqueue.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/crc32.Po ./$(DEPDIR)/dupCheck.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/exceptionguard.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/history.Po ./$(DEPDIR)/httpserver.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/mic_e.Po ./$(DEPDIR)/mutex.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/osdep.Po ./$(DEPDIR)/queryResp.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/rf.Po ./$(DEPDIR)/serial.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/servers.Po ./$(DEPDIR)/string.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/utils.Po ./$(DEPDIR)/validate.Po COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ CFLAGS = @CFLAGS@ CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ CXXFLAGS = @CXXFLAGS@ DIST_SOURCES = $(aprsd_SOURCES) DIST_COMMON = Makefile.am Makefile.in SOURCES = $(aprsd_SOURCES) all: all-am .SUFFIXES: .SUFFIXES: .c .cpp .o .obj $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(bindir) @list='$(bin_PROGRAMS)'; for p in $$list; do \ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ if test -f $$p \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \ $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f; \ else :; fi; \ done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; for p in $$list; do \ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ echo " rm -f $(DESTDIR)$(bindir)/$$f"; \ rm -f $(DESTDIR)$(bindir)/$$f; \ done clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) aprsd$(EXEEXT): $(aprsd_OBJECTS) $(aprsd_DEPENDENCIES) @rm -f aprsd$(EXEEXT) $(CXXLINK) $(aprsd_LDFLAGS) $(aprsd_OBJECTS) $(aprsd_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) core *.core distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aprsString.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aprsd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aprsdexception.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ax25socket.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpqueue.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc32.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dupCheck.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exceptionguard.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/history.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpserver.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mic_e.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mutex.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/osdep.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/queryResp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/serial.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/servers.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/validate.Po@am__quote@ distclean-depend: -rm -rf ./$(DEPDIR) .c.o: @AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< .c.obj: @AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ $(COMPILE) -c `cygpath -w $<` CCDEPMODE = @CCDEPMODE@ .cpp.o: @AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< .cpp.obj: @AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ $(CXXCOMPILE) -c -o $@ `cygpath -w $<` CXXDEPMODE = @CXXDEPMODE@ uninstall-info-am: ETAGS = etags ETAGSFLAGS = tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = .. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) @list='$(DISTFILES)'; for file in $$list; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: $(mkinstalldirs) $(DESTDIR)$(bindir) install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-compile distclean-depend \ distclean-generic distclean-tags dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-exec-am: install-binPROGRAMS install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic uninstall-am: uninstall-binPROGRAMS uninstall-info-am .PHONY: GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic distclean distclean-compile distclean-depend \ distclean-generic distclean-tags distdir dvi dvi-am info \ info-am install install-am install-binPROGRAMS install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic tags uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-info-am # 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: aprsd-2.2.5-13/src/aprsd.cpp0000644000076400007640000012340007665274763011175 /* * $Id: aprsd.cpp,v 1.72 2003/05/29 03:09:39 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #include #include #include #include #if TIME_WITH_SYS_TIME # include # include #else # if HAVE_SYS_TIME_H # include # else # include # endif #endif #include #include #include #include #include #include #include #include #include #include #include #include #ifdef linux #include #include #endif #include //tcpip header files #include #include #include #include #include #include #include #include "dupCheck.h" #include "cpqueue.h" #include "utils.h" #include "constant.h" #include "history.h" #include "serial.h" #include "aprsString.h" #include "validate.h" #include "queryResp.h" #include "rf.h" #include "aprsd.h" #include "servers.h" #include "exceptionguard.h" using namespace aprsd; using namespace std; struct termios initial_settings, new_settings; //char *szComPort; string szComPort; string szAprsPath; int msgsn; const string HOMEDIR("/home/aprsd2"); const string CONFPATH(""); const string CONFFILE("aprsd.conf"); const string MAINLOG("aprsd.log"); const string STSMLOG("thirdparty.log"); const string RFLOG("rf.log"); const string UDPLOG("udp.log"); const string ERRORLOG("error.log"); const string DEBUGLOG("debug.log"); const string REJECTLOG("reject.log"); const string LOOPLOG("loop.log"); const string WELCOME("welcome.txt"); const string TNC_INIT("INIT.TNC"); const string TNC_RESTORE("RESTORE.TNC"); const string APRSD_INIT("INIT.APRSD"); const string SAVE_HISTORY("history.txt"); const string USER_DENY("user.deny"); //---------------------------------------------------------------------- void serverQuit(void) /* Invoked by console 'q' quit or SIGINT (killall -INT aprsd) */ { timespec ts; cout << "\nBeginning shutdown..." << endl; WriteLog(string("Server Shutdown"), MAINLOG); tcsetattr(fileno(stdin),TCSANOW,&initial_settings); //restore terminal mode string outFile = CONFPATH; outFile += SAVE_HISTORY; int n = SaveHistory(outFile); cout << "Saved " << n << " history items in " << outFile << endl; string ShutDown = szServerCall; ShutDown += szJAVAMSG; ShutDown += MyLocation; ShutDown += " "; ShutDown += szServerID; ShutDown += " shutting down... Bye.\r\n"; aprsString* abuff = new aprsString(ShutDown.c_str(), SRC_INTERNAL, srcSYSTEM); sendQueue.write(abuff); ts.tv_sec = 1; ts.tv_nsec = 0; nanosleep(&ts,NULL); if (tncPresent) { //char *pRestore = new char[CONFPATH.length() + TNC_RESTORE.length() + 1]; //strcpy(pRestore, CONFPATH.c_str()); //strcat(pRestore, TNC_RESTORE.c_str()); string pRestore = CONFPATH; pRestore += TNC_RESTORE; rfSendFiletoTNC(pRestore); AsyncClose() ; //delete pRestore; } ShutDownServer = true; kill(pidlist.main, SIGTERM); //Kill main thread } //--------------------------------------------------------------------- /* Signal handler. Note: Signals are received by ALL threads at once. To ensure the handler only reacts once, the PID is checked and only signals to the main thread are accepted. */ void sig_handler(int sig) { if (getpid() != pidlist.main) return; //Only allow signals from main thread. if (sig == SIGINT) serverQuit(); //Shut ourself down. } //------------------------------------------------------------------------ //Server configuration parser. //Non-comment lines from aprsd.conf pass through this. //Action is taken based on the command and args. int serverConfig(const string& cf) { const int maxToken=32; int nTokens ; char Line[256]; string cmd, errmsg; int n, m = 0; rfcall_idx = 0; posit_rfcall_idx = 0; stsmDest_rfcall_idx = 0; for (int i = 0; i < MAXRFCALL; i++) { rfcall[i] = NULL; //clear the rfcall arrays posit_rfcall[i] = NULL; stsmDest_rfcall[i] = NULL; } cout << "Reading " << cf << endl; ifstream file(cf.c_str()); //delete pSaveHistory; if (!file) { cerr << "Can't open " << cf << endl; return -1; } do { errmsg = ""; file.getline(Line,256); //Read each line in file if (!file.good()) break; n = 0; int i; if (strlen(Line) > 0) { if (Line[0] != '#') { //Ignore comments string sLine(Line); string token[maxToken]; nTokens = split(sLine, token, maxToken, RXwhite); //Parse into tokens for (i = 0 ; i < nTokens; i++) cout << token[i] << " " ; upcase(token[0]); cmd = token[0]; if ((cmd.compare("USER") == 0) && (nTokens >= 2)) { //upcase(token[1]); logon.user = strdup(token[1].c_str()); n = 1; } if ((cmd.compare("PASS") == 0) && (nTokens >= 2)) { logon.pass = strdup(token[1].c_str()); n = 1; } if ((cmd.compare("TNCPORT") == 0) && (nTokens >= 2)) { szComPort = token[1]; n = 1; } if ((cmd.compare("UDPPORT") == 0) && (nTokens >= 2)) { upUdpServer.ServerPort = atoi(token[1].c_str()); n = 1; } if ((cmd.compare("TRUST") == 0) && (nTokens >= 2) && (nTrusted < maxTRUSTED)) { int rc = inet_aton(token[1].c_str(), &Trusted[nTrusted].sin_addr); if (nTokens >= 3) inet_aton(token[2].c_str(), &Trusted[nTrusted].sin_mask); else Trusted[nTrusted].sin_mask.s_addr = 0xffffffff; if (rc ) nTrusted++; else Trusted[nTrusted].sin_addr.s_addr = 0; n = 1; } if ((cmd.compare("SERVER") == 0) //New server command in vers 2.1.5 && (nTokens >= 2)) { cpIGATE[m].EchoMask = 0; //default is to not send any data to other igates cpIGATE[m].user = MyCall; cpIGATE[m].pass = passDefault; cpIGATE[m].RemoteSocket = 1313; //Default remote port is 1313 cpIGATE[m].starttime = -1; cpIGATE[m].lastActive = -1; cpIGATE[m].pid = 0; cpIGATE[m].remoteIgateInfo = string(""); cpIGATE[m].hub = false; cpIGATE[m].mode = MODE_RECV_ONLY; cpIGATE[m].serverCmd[0] = NULL; cpIGATE[m].serverCmd[1] = NULL; cpIGATE[m].serverCmd[2] = NULL; cpIGATE[m].nCmds = 0; cpIGATE[m].alias = string("*"); cpIGATE[m].RemoteName = "UNDEFINED"; if (nTokens >= 2) cpIGATE[m].RemoteName = strdup(token[1].c_str()); //remote domain name if (nTokens >= 3) cpIGATE[m].RemoteSocket = atoi(token[2].c_str()); //remote port number if (nTokens >= 4) { upcase(token[3]); //parse RO-HUB or SR-HUB or RO or SR if(token[3].find("HUB") != string::npos) cpIGATE[m].hub = true; if(token[3].find("SR") != string::npos) cpIGATE[m].mode = MODE_RECV_SEND; } if (logon.user) cpIGATE[m].user = logon.user; else { cpIGATE[m].user = MyCall; cpIGATE[m].pass = passDefault; } if (logon.pass) cpIGATE[m].pass = logon.pass; else cpIGATE[m].pass = passDefault; //The following strings are sent to remote server as messages after logon if (nTokens >= 5) { cpIGATE[m].serverCmd[0] = strdup(token[4].c_str()); cpIGATE[m].nCmds++; } if (nTokens >= 6) { cpIGATE[m].serverCmd[1] = strdup(token[5].c_str()); cpIGATE[m].nCmds++; } if (nTokens >= 7) { cpIGATE[m].serverCmd[2] = strdup(token[6].c_str()); cpIGATE[m].nCmds++; } //Locally validate the passcode to see if we are allowed to send data if ((validate(cpIGATE[m].user, cpIGATE[m].pass,APRSGROUP, APRS_PASS_ALLOW) == 0) && (cpIGATE[m].mode == MODE_RECV_SEND)){ cpIGATE[m].EchoMask = srcUSERVALID //If valid passcode present then we send out data + srcUSER //Same data as igate port 1313 + srcTNC + srcBEACON + srcUDP; //Changed in 2.1.5: Internal status packets NOT sent } else { if (cpIGATE[m].mode == MODE_RECV_SEND) errmsg = " <--Invalid APRS passcode"; cpIGATE[m].mode = MODE_RECV_ONLY; cpIGATE[m].EchoMask = 0; } if (m < maxIGATES) m++; nIGATES = m; n = 1; } if ((cmd.compare("IGATE") == 0) //IGATE still recognized so not to break old .conf files. || (cmd.compare("HUB") == 0)) { //HUB is assumed to have all APRS data cpIGATE[m].hub = (cmd.compare("HUB") == 0) ? true : false ; cpIGATE[m].EchoMask = 0; //default is to not send any data to other igates cpIGATE[m].user = MyCall; cpIGATE[m].pass = passDefault; cpIGATE[m].RemoteSocket = 1313; //Default remote port is 1313 cpIGATE[m].starttime = -1; cpIGATE[m].lastActive = -1; cpIGATE[m].pid = 0; cpIGATE[m].remoteIgateInfo = string(""); cpIGATE[m].mode = MODE_RECV_ONLY; cpIGATE[m].serverCmd[0] = NULL; cpIGATE[m].serverCmd[1] = NULL; cpIGATE[m].serverCmd[2] = NULL; cpIGATE[m].nCmds = 0; cpIGATE[m].alias = string(""); if (nTokens >= 2) cpIGATE[m].RemoteName = strdup(token[1].c_str()); //remote domain name if (nTokens >= 3) cpIGATE[m].RemoteSocket = atoi(token[2].c_str()); //remote port number if (nTokens >= 4) cpIGATE[m].user = strdup(token[3].c_str()); //User name (call) if (nTokens >= 5) cpIGATE[m].pass = strdup(token[4].c_str()); //Get Passcode /* If passcode is valid allow the this server to send data up stream */ if ((validate(cpIGATE[m].user, cpIGATE[m].pass,APRSGROUP, APRS_PASS_ALLOW) == 0)){ cpIGATE[m].mode = MODE_RECV_SEND; cpIGATE[m].EchoMask = srcUSERVALID //If valid passcode present then we send out data + srcUSER //Same data as igate port 1313 + srcTNC + srcBEACON + srcUDP; //Changed in 2.1.5: Internal status packets NOT sent } else { if(cpIGATE[m].pass[0] != '-') errmsg = " <--Invalid APRS passcode"; cpIGATE[m].EchoMask = 0; cpIGATE[m].mode = MODE_RECV_ONLY; } if (m < maxIGATES) m++; nIGATES = m; n = 1; } if (cmd.compare("LOCALPORT") == 0) { //provides local TNC data only spLocalServer.ServerPort = atoi(token[1].c_str()); //set server port number spLocalServer.EchoMask = srcUDP + srcTNC /*Set data sources to echo*/ + srcSYSTEM + srcBEACON + sendHISTORY; n = 1; } if(cmd.compare("RAWTNCPORT") == 0) { //provides local TNC data only spRawTNCServer.ServerPort = atoi(token[1].c_str()); //set server port number spRawTNCServer.EchoMask = srcTNC /*Set data sources to echo*/ + wantRAW; //RAW data spRawTNCServer.FilterMask = false; spRawTNCServer.omni = false; n = 1; } if (cmd.compare("SYSOPPORT") == 0) { // provides no igated data // This is for telnetting directly to the TNC spSysopServer.ServerPort = atoi(token[1].c_str()); //set server port number spSysopServer.EchoMask = 0; spSysopServer.FilterMask = 0; spSysopServer.omni = false; n = 1; } if (cmd.compare("ERRORPORT") == 0) { // provides only rejected packets // This is for telneting directly to the TNC spErrorServer.ServerPort = atoi(token[1].c_str()); //set server port number spErrorServer.EchoMask = wantREJECTED ; spErrorServer.FilterMask = 0; spErrorServer.omni = false; n = 1; } if (cmd.compare("HTTPPORT") == 0) { //provides server status in HTML format spHTTPServer.ServerPort = atoi(token[1].c_str()); //set server port number spHTTPServer.EchoMask = wantHTML; spHTTPServer.FilterMask = 0; spHTTPServer.omni = false; n = 1; } if(cmd.compare("OMNIPORT") == 0) { //provides any data stream the user requests spOmniServer.ServerPort = atoi(token[1].c_str()); //set server port number spOmniServer.EchoMask = omniPortBit; spOmniServer.FilterMask = 0; spOmniServer.omni = true; n = 1; } if (cmd.compare("MAINPORT") == 0) { //provides all data spMainServer.ServerPort = atoi(token[1].c_str()); //set server port number spMainServer.EchoMask = srcUSERVALID + srcUSER + srcIGATE + srcUDP + srcTNC + srcSYSTEM + srcBEACON + sendHISTORY; spMainServer.FilterMask = 0; spMainServer.omni = false; n = 1; } if (cmd.compare("MAINPORT-NH") == 0) { //provides all data but no history dump spMainServer_NH.ServerPort = atoi(token[1].c_str()); //set server port number spMainServer_NH.EchoMask = srcUSERVALID + srcUSER + srcIGATE + srcUDP + srcTNC + srcBEACON + srcSYSTEM; spMainServer_NH.FilterMask = 0; spMainServer.omni = false; n = 1; } if (cmd.compare("LINKPORT") == 0) { //provides local TNC data + logged on users spLinkServer.ServerPort = atoi(token[1].c_str()); spLinkServer.EchoMask = srcUSERVALID + srcUSER + srcTNC + srcUDP + srcBEACON ; //System messages removed from link port v.215 spLinkServer.FilterMask = 0; spLinkServer.omni = false; n = 1; } if(cmd.compare("MSGPORT") == 0) { //System messages removed from msgport port v.215 spMsgServer.ServerPort = atoi(token[1].c_str()); spMsgServer.EchoMask = src3RDPARTY ; spMsgServer.FilterMask = 0; spMsgServer.omni = false; n = 1; } if (cmd.compare("IPWATCHPORT") == 0){ spIPWatchServer.ServerPort = atoi(token[1].c_str()); spIPWatchServer.EchoMask = srcUSERVALID + srcUSER + srcIGATE + srcTNC + srcUDP + srcBEACON + wantSRCHEADER; spIPWatchServer.FilterMask = 0; spIPWatchServer.omni = false; n = 1; } if (cmd.compare("TNCBAUD") == 0) { // Set TNC baud rate 1200,2400,4800,9600,19200 TncBaud = strdup(token[1].c_str()); n = 1; } if (cmd.compare("MYCALL") == 0) { // This will be over-written by the MYCALL in INIT.TNC... // ...if a TNC is being used. MyCall = token[1]; if (MyCall.length() > 9) MyCall.resize(9); //Truncate to 9 chars. n = 1; } if (cmd.compare("MYEMAIL") == 0) { MyEmail = token[1]; n = 1; } if (cmd.compare("SERVERCALL") == 0) { szServerCall = token[1]; if (szServerCall.length() > 9) //szServerCall[9] = '\0'; //Truncate to 9 chars. szServerCall.resize(9); // truncate to 9 chars //cout << "Config server call: " << szServerCall << endl; n = 1; } if (cmd.compare("APRSPATH") == 0) { for (n = 1; n < nTokens; n++) { //cout << "Token["< 0) MaxClients = mc; n = 1; } if (cmd.compare("MAXLOAD") == 0) { //Set max server output load in bytes/sec. int ml = atoi(token[1].c_str()); if (ml > 0) MaxLoad = ml ; n = 1; } if (cmd.compare("EXPIRE") == 0) { //Set time to live for history items (minutes) int ttl = atoi(token[1].c_str()); if (ttl > 0) ttlDefault = ttl; n = 1; } /* if (cmd.compare("TIMETOLIVE") == 0) //Set time to live for packets on Internet (Hops) { int t = atoi(token[1].c_str()); if (t > 0) defaultPktTTL = t; n = 1; ] */ if (cmd.compare("FILTERNOGATE") == 0) { //Set YES to enable reject filtering of NOGATE and RFONLY upcase(token[1]); if (token[1].compare("YES") == 0) NOGATE_FILTER = true; else NOGATE_FILTER = false; n = 1; } if (cmd.compare("HISTORY-ALLOW") == 0) { //Allow history list dumps. upcase(token[1]); if (token[1].compare("YES") == 0 ) History_ALLOW = true; else History_ALLOW = false; n = 1; } if (cmd.compare("RF-ALLOW") == 0) { //Allow internet to RF message passing. upcase(token[1]); if (token[1].compare("YES") == 0 ) RF_ALLOW = true; else RF_ALLOW = false; n = 1; } if (cmd.compare("TRACE") == 0) { //Enable full internet path tracing. upcase(token[1]); if (token[1].compare("YES") == 0 ) traceMode = true; else traceMode = false; n = 1; } if (cmd.compare("IGATEMYCALL") == 0) {//Allow igating packets from "MyCall" upcase(token[1]); if (token[1].compare("YES") == 0 ) igateMyCall = true; else igateMyCall = false; n = 1; } if (cmd.compare("LOGALLRF") == 0) { //If "YES" then all packets heard are logged to rf.log" upcase(token[1]); if (token[1].compare("YES") == 0 ) logAllRF = true; else logAllRF = false; n = 1; } if (cmd.compare("CONVERTMICE") == 0) { //If "YES" then all MIC-E packets converted to classic APRS" upcase(token[1]); //Note that compile time option CONVERT_MIC_E in constant.h // must also be set true. if ((token[1].compare("YES") == 0 ) && (CONVERT_MIC_E == true)) ConvertMicE = true; else ConvertMicE = false; n = 1; } if (cmd.compare("GATE2RF") == 0) { //Call signs of users always gated to RF for (int i = 1; i < nTokens; i++) { string* s = new string(token[i]); if (rfcall_idx < MAXRFCALL) rfcall[rfcall_idx++] = s; //add it to the list } n = 1; } if (cmd.compare("POSIT2RF") == 0) { //Call sign posits gated to RF every 16 minutes for (int i = 1; i < nTokens; i++) { string* s = new string(token[i]); if (posit_rfcall_idx < MAXRFCALL) posit_rfcall[posit_rfcall_idx++] = s; //add it to the list } n = 1; } if (cmd.compare("MSGDEST2RF") == 0) { //Destination call signs // of station to station messages for (int i = 1; i < nTokens; i++) { //always gated to RF string* s = new string(token[i]); if (stsmDest_rfcall_idx < MAXRFCALL) stsmDest_rfcall[stsmDest_rfcall_idx++] = s; //add it to the list } n = 1; } if (cmd.compare("ACKREPEATS") == 0) { //How many extra ACKs to send to tnc int mc = atoi(token[1].c_str()); if (mc < 0) { mc = 0; cout << "ACKREPEATS set to ZERO" << endl; } if (mc > 9) { mc = 9; cout << "ACKREPEATS set to 9" << endl; } ackRepeats = mc; n = 1; } if (cmd.compare("ACKREPEATTIME") == 0) { //Time in secs between extra ACKs int mc = atoi(token[1].c_str()); if (mc < 1) { mc = 1; cout << "ACKREPEATTIME set to 1 sec." << endl; } if (mc > 30) { mc = 30; cout << "ACKREPEATTIME set to 30 sec." << endl; } ackRepeatTime = mc; n = 1; } if (cmd.compare("NETBEACON") == 0) { //Internet Beacon text if (nTokens > 1) { NetBeaconInterval = atoi(token[1].c_str());//Set Beacon Interval in minutes if (nTokens > 2) { string s = token[2]; for (int i = 3 ; i < nTokens; i++) s = s + " " + token[i]; NetBeacon = s; //strdup(s); } } n = 1; } if (cmd.compare("TNCBEACON") == 0) { //TNC Beacon text if (nTokens > 1){ TncBeaconInterval = atoi(token[1].c_str()); //Set Beacon Interval in minutes if (nTokens > 2){ string s = token[2]; for (int i = 3 ; i < nTokens; i++) s = s + " " + token[i] ; TncBeacon = strdup(s.c_str()); } } n = 1; } if (cmd.compare("TNCPKTSPACING") == 0) { //Set tnc packet spacing in ms if (nTokens > 1) tncPktSpacing = 1000 * atoi(token[1].c_str());// ms to microsecond conversion n = 1; } if (cmd.compare("APRSPASS") == 0) { //Allow aprs style user passcodes for validation? upcase(token[1]); if (token[1].compare("YES") == 0 ) APRS_PASS_ALLOW = true; else APRS_PASS_ALLOW = false; n = 1; } cout << errmsg << endl; if (n == 0) cout << "Unknown command: " << Line << endl; } } } while(file.good()); file.close(); return 0; } //--------------------------------------------------------------------- /* FOR DEBUGGING ONLY */ /* void segvHandler(int signum) //For debugging seg. faults { pid_t pid,ppid; char* err; pid = getpid(); if(pid == pidlist.main) err = "aprsd main"; if(pid == spMainServer.pid) err = "spMainServer"; if(pid == spMainServer_NH.pid) err = "spMainServer_NH"; if(pid == spLocalServer.pid) err = "spLocalServer"; if(pid == spLinkServer.pid) err = "spLinkServer" ; if(pid == spMsgServer.pid) err = "spMsgServer"; if(pid == upUdpServer.pid) err = "upUdpServer"; if(pid == pidlist.SerialInp) err = "Serial input thread"; if(pid == pidlist.TncQueue) err = "TNC Dequeue"; if(pid == pidlist.InetQueue) err = "Internet Dequeue"; char buf[256]; memset(buf,0,256); ostrstream sout(buf,255); sout << "A segment violation has occured in process id " << pid << " Thread: " << err << endl ; char buf2[256]; memset(buf2,0,256); ostrstream sout2(buf2,255); sout2 << "Died in " << DBstring << " Last packet: " << lastPacket->c_str() << " Packet length = " << lastPacket->length() << endl << ends; cout << buf << buf2; WriteLog(buf,"segfault.log"); WriteLog(buf2,"segfault.log"); exit(-1); } */ //---------------------------------------------------------------------- //If aprsd is invoked with the -d option... int daemonInit(void) { pid_t pid; pid_t xx; string pid_file = "/var/run/aprsd.pid"; char s[25]; // Check for pre-existing aprsd fstream f(pid_file.c_str(), ios::in); if (f.is_open()) { f.read(s, 10); xx = atoi(s); kill(xx, SIGCHLD); // Meaningless kill to determine if pid is used if (errno != ESRCH) { cout << "aprsd already running" << endl; cout << "PID: " << pid_file << endl; exit(1); } } if ((pid = fork()) < 0) return -1 ; else if (pid != 0) exit(0); // Parent goes away // child continues unlink(pid_file.c_str()); xx = getpid(); fstream fp(pid_file.c_str(), ios::out); cout << "pid " << xx << endl; if (fp.is_open()) { fp << xx; fp.flush(); if (fp.fail()) { // Let aprsd live since this doesn't appear to be a chkaprsd cout << "Warning: Could not write " << pid_file << " file!" << endl; fp.close(); unlink(pid_file.c_str()); } else fp.close(); } setpgid(0, 0); freopen("/dev/null", "r", stdin); // redirect output freopen("/dev/null", "w", stdout); freopen("/dev/null", "w", stderr); setsid(); // Become session leader chdir(HOMEDIR.c_str()); // change to the aprsd2 directory umask(0); // Clear our file mode selection mask return(0); } //---------------------------------------------------------------------- int main(int argc, char *argv[]) { int rc, di; string sConfFile; timespec ts; string stats; time_t lastSec,tNow,tLast,tLastDel, tPstats; time_t LastNetBeacon , LastTncBeacon; time_t Time = time(NULL); time_t tCalcLoad = Time; serverStartTime = Time; ExceptionGuard exceptionguard; try { msgsn = 0; //Clear message serial number initDefaults(); //Initialize some variables if (argc > 1) if (strcmp("-d",argv[1]) == 0) daemonInit(); //option -d means run as daemon pidlist.main = getpid(); //Save our own PID for future use signal(SIGPIPE, SIG_IGN); signal(SIGXCPU, SIG_IGN); signal(SIGTSTP, SIG_IGN); signal(SIGSTOP, SIG_IGN); signal(SIGINT, sig_handler); //SIGINT is handled by sig_handler() . LastNetBeacon = 0; LastTncBeacon = 0; /* memset(&sa,0,sizeof(sa)); sa.sa_handler = segvHandler; if(sigaction(SIGSEGV,&sa,NULL)) perror("sigaction"); */ configComplete = false; szComPort = string(""); //null string for TNC com port CreateHistoryList(); //Make the history linked list structure cout << SIGNON << endl; /* //DEBUG & TEST CODE //aprsString mic_e("K4HG-9>RU4U9T,WIDE,WIDE,WIDE:`l'q#R>/\r\n"); aprsString mic_e("K4HG-9>RU4W5S,WIDE,WIDE,WIDE:`l(XnUU>/Steve's RX-7/Mic-E\r\n"); aprsString* posit = NULL; aprsString* telemetry = NULL; if(mic_e.aprsType == APRSMIC_E) mic_e.mic_e_Reformat(&posit,&telemetry); if(posit){ posit->print(cout); delete posit;} if(telemetry) { telemetry->print(cout); delete telemetry;} sleep(5); */ //fdump = fopen("dump.txt","w+"); //debug string histFile = CONFPATH; histFile += SAVE_HISTORY; ReadHistory(histFile); string sConfFile = CONFPATH; sConfFile += CONFFILE; //default server configuration file if (argc > 1) { if (strcmp("-d",argv[argc-1]) != 0){ //szConfFile = new char[CONFPATH.length() + CONFFILE.length() + 1]; //szConfFile = new char[MAX]; sConfFile = ""; sConfFile = argv[argc-1]; //szConfFile = argv[argc-1]; //get optional 1st or 2nd arg which is configuration file name } } if (serverConfig(sConfFile) != 0) exit(-1); //Read configuration file (aprsd.conf) //Now add a ax25 path to the Internet beacon text string ostringstream osnetbc; osnetbc << szServerCall << szAPRSDPATH << NetBeacon << "\r\n"; NetBeacon = osnetbc.str(); //Internet beacon complete with ax25 path cout << "NetBeacon is: " << osnetbc.str() << endl; if (TncBeacon.length() > 0){ ostringstream ostncbc; ostncbc << TncBeacon << "\r\n"; TncBeacon = ostncbc.str(); //TNC beacon (no ax25 path) } if (szAprsPath.length() > 0) { cout << "APRS packet path = " << szAprsPath << endl; rfSetPath(szAprsPath); } /*Initialize TNC Com port if specified in config file */ if (szComPort.size() > 0) { cout << "Opening serial port device " << szComPort << endl; if ((rc = rfOpen(szComPort, TncBaud)) != 0) { ts.tv_sec = 2; ts.tv_nsec = 0; nanosleep(&ts,NULL); return -1; } cout << "Setting up TNC" << endl; string pInitTNC = CONFPATH; pInitTNC += TNC_INIT; //cerr << "AsyncSendFiletoTNC..." << "filename: " << pInitTNC << endl; rfSendFiletoTNC(pInitTNC); //Setup TNC from initialization file tncPresent = true; } else cout << "TNC com port not defined." << endl; if (RF_ALLOW) cout << "Internet to RF data flow is ENABLED" << endl; else cout << "Internet to RF data flow is DISABLED" << endl; serverInit(); //Initialize Server - start threads WriteLog(string("Server Start"), MAINLOG); cout << "Server Started" << endl; Time = time(NULL); tNow = Time; tLast = Time; tLastDel = Time ; tPstats = Time; configComplete = true; if (TncBeacon.length() > 0) cout << "TncBeacon every " << TncBeaconInterval << " minutes : " << TncBeacon << endl; if (NetBeacon.length() > 0) cout << "NetBeacon every " << NetBeaconInterval << " minutes : " << NetBeacon << endl; cout << "MYCALL set to: " << MyCall << endl; tcgetattr(fileno(stdin), &initial_settings); new_settings = initial_settings; new_settings.c_lflag &= ~ICANON; new_settings.c_lflag &= ~ISIG; new_settings.c_cc[VMIN] = 0; new_settings.c_cc[VTIME] = 1; //.1 second timeout for input chars tcsetattr(fileno(stdin), TCSANOW, &new_settings); /* char *xx = "WA4DSY-2>APRS,WIDE:}WA4DSY-5>APX,WIDE2-1,TCPIP,WIDE7-7:TESTING 12345\n"; aprsString* testpkt = new aprsString(xx,SRC_TNC,srcTNC,"192.168.0.1","WA4DSY-15"); testpkt->sourceSock = 333; testpkt->EchoMask = 4; testpkt->print(cerr); testpkt->thirdPartyToNormal(); testpkt->print(cerr); testpkt->addPath(MyCall); testpkt->print(cerr); string ssss = "MOREPATH"; testpkt->addPath(ssss); testpkt->print(cerr); testpkt->cutUnusedPath(); testpkt->print(cerr); exit(0); */ /* sigAct.sa_handler = sig_handler; //Allow shutdown by SIGINT sigemptyset(&sigAct.sa_mask); sigAct.sa_flags = 0; sigaction(SIGINT,&sigAct,0); */ do { ts.tv_sec = 0; ts.tv_nsec = 1000000; nanosleep(&ts, NULL); //Sleep 1ms if (msgsn > 9999) msgsn = 0; while (conQueue.ready()) { //Data for Console? char *cp = (char*)conQueue.read(NULL); //Yes, read and print it. if (cp) { printf("%s",cp); strcat(cp, "\r"); aprsString* monStats = new aprsString(cp, SRC_INTERNAL, srcSTATS); sendQueue.write(monStats); delete cp; } } char ch = fgetc(stdin); //stalls for 0.1 sec. switch (ch) { case 'r': resetCounters(); break; case 0x03: case 'q' : serverQuit(); raise(SIGTERM);; } lastSec = Time; Time = time(NULL); if (difftime(Time,lastSec) > 0) schedule_posit2RF(Time); //Once per second if (difftime(Time, LastNetBeacon) >= NetBeaconInterval * 60) { //Send Internet Beacon text LastNetBeacon = Time; if ((NetBeacon.length() > 0) && (NetBeaconInterval > 0)){ aprsString* netbc = new aprsString(NetBeacon.c_str(), SRC_INTERNAL, srcBEACON); netbc->addIIPPE() ; //qAI netbc->addPath(szServerCall); //qAI,servercall sendQueue.write(netbc); } } if (difftime(Time, LastTncBeacon) >= TncBeaconInterval * 60){ //Send TNC Beacon text LastTncBeacon = Time; if ((TncBeacon.length() > 0) && (TncBeaconInterval > 0)){ aprsString* tncbc = new aprsString(TncBeacon.c_str(), SRC_INTERNAL, srcBEACON); tncQueue.write(tncbc); } } if ((Time - tCalcLoad) >= 15){ // Every 15 Seconds, Compute short term server load computeShortTermLoad(15); tCalcLoad = Time; } if ((Time - tPstats) > 60) { // 1 minute if (WatchDog < 2) cerr << "** No data from TNC during previous 2 minutes **" << endl; tPstats = Time; WatchDog = 0; //Serial port reader increments this with each rx line. stats = getStats(); cout << stats; aprsString* monStats = new aprsString(stats.c_str(), SRC_INTERNAL, srcSTATS); sendQueue.write(monStats); enforceMaxLoad(); //Check server load and shed users if required } if ((Time - tLastDel) > 300 ) { //do this every 5 minutes. //Remove old entrys from history list if ((di = DeleteOldItems(5)) > 0) cout << " Deleted " << di << " expired items from history list" << endl; tLastDel = Time; } /* if ((Time - tLast) > 900) //Save history list every 15 minutes { SaveHistory(pSaveHistory); tLast = Time; } */ } while (1==1); // ctrl-C to quit } catch (Exception& e) { cerr << e.toString() << endl; return 1; } catch (exception& e) { cerr << e.what() << endl; return 1; } return 0; } aprsd-2.2.5-13/src/aprsd.h0000664000076400007640000000207707655343017010636 #ifndef APRSD_H #define APRSD_H #include #include "constant.h" #include "cpqueue.h" /* update the next 3 lines with each version change */ #define SIGNON "# " PACKAGE_STRING " Oct 2002 aprsd group\r\n" #define VERS PACKAGE_STRING //The next char string is put into the AX25 "TO" field. Keep length at 6 chars. #define PGVERS TOCALL /*--------------------------------------------------*/ // To run aprsd from another directory change the next line extern const std::string HOMEDIR; extern const std::string CONFPATH; extern const std::string CONFFILE; extern const std::string MAINLOG; extern const std::string STSMLOG; extern const std::string RFLOG; extern const std::string UDPLOG; extern const std::string ERRORLOG; extern const std::string DEBUGLOG; extern const std::string REJECTLOG; extern const std::string LOOPLOG; extern const std::string WELCOME; extern const std::string TNC_INIT; extern const std::string TNC_RESTORE; extern const std::string APRSD_INIT; extern const std::string SAVE_HISTORY; extern const std::string USER_DENY; #endif // APRSD_H aprsd-2.2.5-13/src/aprsString.cpp0000644000000000000000000012237307665450331012151 /* * $Id: aprsString.cpp,v 1.41 2003/05/29 18:26:33 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #include #include #include #include #include #include #include #include #include #include "aprsString.h" #include "aprsd.h" #include "constant.h" #include "utils.h" #include "mic_e.h" #include "crc.h" #include "aprsdexception.h" using namespace std; using namespace aprsd; pthread_mutex_t* aprsString::mutex = NULL; // mutex semaphore pointer common to all instances of aprsString pthread_mutexattr_t* aprsString::mutexAttr = NULL; //unsigned int* aprsString::NN = new unsigned int(1); //unsigned long* aprsString::objCount = new unsigned long(1); unsigned int aprsString::NN = 0; unsigned long aprsString::objCount = 0; int ttlDefault = 35; #define pathDelm ",>:\r\n" #define cmdDelim ",)\r\n" aprsString::aprsString(const char* cp, int s, int e, const char* szPeer, const char* userCall) : string(cp) { constructorSetUp(cp,s,e); peer = szPeer; call = userCall; srcHeader = "!" + peer + ":" + call + "!"; //Build the source ip header } aprsString::aprsString(const char* cp, int s, int e) : string(cp) { peer = ""; user = ""; call = ""; srcHeader = "!:!"; constructorSetUp(cp,s,e); } aprsString::aprsString(const char* cp) : string(cp) { peer = ""; user = ""; call = ""; srcHeader = "!:!"; constructorSetUp(cp,0,0); } aprsString::aprsString(string& cp) : string(cp) { peer = ""; user = ""; call = ""; srcHeader = "!:!"; constructorSetUp(cp.c_str(),0,0); } //Copy constructor aprsString::aprsString(aprsString& as) { *this = as; ax25Source = as.ax25Source; ax25Dest = as.ax25Dest; stsmDest = as.stsmDest; query = as.query; acknum = as.acknum; dest = as.dest; path = as.path; data = as.data; user = as.user; pass = as.pass; call = as.call; icall = as.icall; pgmName = as.pgmName; pgmVers = as.pgmVers; peer = as.peer; raw = as.raw; srcHeader = as.srcHeader; for (int i = 0; i < MAXPATH; i++) ax25Path[i] = as.ax25Path[i]; ttl = as.ttl; next = NULL; last = NULL; aprsType = as.aprsType; msgType = as.msgType; allowdup = as.allowdup; sourceSock = as.sourceSock; pathSize = as.pathSize; EchoMask = as.EchoMask; nogate = as.nogate; reformatted = as.reformatted; normalized = as.normalized; cci = as.cci; valid_ax25 = as.valid_ax25; IjpIdx = as.IjpIdx; pthread_mutex_lock(mutex); // Lock the counters ! //++(*NN); // Increment counters //++(*objCount); NN++; objCount++; ID = objCount; //new serial number pthread_mutex_unlock(mutex); // Unlock counters timestamp = time(NULL); //User current time instead of time in original instances = 0; } aprsString::~aprsString(void) throw() { pthread_mutex_lock(mutex); /* //if (--(*refCount) == 0) { if (--(*NN) <= 0) { pthread_mutex_unlock(mutex); pthread_mutex_destroy(mutex); pthread_mutexattr_destroy(mutexAttr); try { delete mutex; mutex = NULL; delete mutexAttr; mutexAttr = NULL; //delete refCount; refCount = NULL; //delete object; object = NULL; } catch (...) { cerr << "Error in aprsString destructor; nn = " << (*NN) << endl; } } else { --(*NN); pthread_mutex_unlock(mutex); } */ //pthread_mutex_lock(pmtxCounters); //Lock countLock(pmtxCounters); NN--; pthread_mutex_unlock(mutex); } void aprsString::constructorSetUp(const char* cp, int s, int e) { try{ //refCount = new unsigned int(1); aprsType = APRSUNKNOWN; //Default to unknown aprs packet type cmdType = CMDNULL; dest = 0; instances = 0; reformatted = false; normalized = false; allowdup = false; msgType = 0; sourceSock = s; EchoMask = e; nogate = false; last = NULL; next = NULL; ttl = ttlDefault; timeRF = 0; AEA = false; acknum = ""; query = ""; icall = ""; valid_ax25 = false; cci = false; pIdx = 0; gtIdx = 0; dataIdx = 0; IjpIdx = 0; //if(pmtxCounters == NULL){ //Create mutex semaphore to protect counters if it doesn't exist... // pmtxCounters = new pthread_mutex_t; //...This semaphore is common to all instances of aprsString. // pthread_mutex_init(pmtxCounters,NULL); //} if (mutex == NULL) { mutexAttr = new pthread_mutexattr_t; mutex = new pthread_mutex_t; pthread_mutexattr_init(mutexAttr); pthread_mutex_init(mutex, mutexAttr); } pthread_mutex_lock(mutex); objCount++; ID = objCount; //set unique ID number for this new object NN++; pthread_mutex_unlock(mutex); timestamp = time(NULL); ax25Source = ""; ax25Dest = ""; stsmDest = ""; raw = string(cp); pathSize = 0; if ((length() <= 0) || (find("cmd:",0,4) == 0) || (find("EH?",0,3) == 0)) { //new in 2.1.5, reject EH? and cmd: aprsType = APRSREJECT; return; } if (cp[0] == '#') { aprsType = COMMENT; // print(); return; } gtIdx = find(">"); //Find the first ">" pIdx = find(":", gtIdx); //Find the first ":" after the ">" if ((gtIdx != npos) // ">" exists && (pIdx != npos) // ":" exists after the ">" &&(gtIdx > 0) // ">" is not the first character && (gtIdx <= 10) // ">" is not at character position 10 or lower && (pIdx > (gtIdx + 1))){ // there is at least 1 char between ">" and ":" //This could be a valid ax25 packet parseAPRS(); // process further return; } data = substr(0,MAXPKT); //Default the data and path to be the whole packet. path = data; if ((find("user ",0,5) == 0 || find("USER ",0,5) == 0)){ //Must be a logon string parseLogon(); //Process it. return; } opIdx = find("("); cpIdx = find(")"); if ((opIdx != npos) && (cpIdx != npos)) { //Command string of the form " command(arg1,arg2...) " parseCommand(); } return; } catch(exception& e) { char *errormsg; errormsg = new char[501]; memset(errormsg,0,501); std::ostrstream msg(errormsg,500); msg << "Caught exception in aprsString: " << e.what() << endl << " [" << peer << "] " << raw.c_str() << endl << ends ; WriteLog(errormsg,ERRORLOG); cerr << errormsg; delete errormsg; aprsType = APRSREJECT; return; } } //------------------------------------------------------------- void aprsString::parseAPRS(void) { valid_ax25 = true; tcpxx = false; path = substr(0,pIdx); //extract all chars up to the ":" into path dataIdx = pIdx+1; //remember where data starts size_type gt2Idx = path.find_last_of(">"); // find last ">" in path /* Filter out packets from misconfigured TNCs that put and [time] in the path */ if((path.find("<") != npos) || (path.find("[") != npos) || (path.find(" ") != npos)){ aprsType = APRSREJECT; valid_ax25 = false; return; //Bad things found in path - REJECT } if ((gtIdx != gt2Idx)&&(gtIdx != npos)) { //This is in AEA TNC format because it has more than 1 ">" //cout << "AEA " << *this << endl << flush; size_type savepIdx = pIdx; string rs; bool rv = AEAtoTAPR(*this,rs); //Replace AEA path with TAPR path if (rv == false) { //New in 2.1.5 aprsType = APRSREJECT; valid_ax25 = false; return; //Conversion failed } pIdx = rs.find(":"); string rsPath = rs.substr(0,pIdx); replace(0,savepIdx,rsPath); path = rsPath; AEA = true; } if ((pIdx+1) < length()) data = substr(pIdx+1,MAXPKT); //The data portion of the packet for (int i = 0; i < MAXPATH; i++) ax25Path[i] = ""; pathSize = split(path ,ax25Path,MAXPATH,pathDelm); if (pathSize >= 2) ax25Dest = ax25Path[1]; //AX25 destination if (pathSize >= 1) ax25Source = ax25Path[0]; //AX25 Source findInjectionPoint(); //Set IjpIdx and IjpOffset (Points to IIPPE ) //Also sets tcpxx if reqired if (data.length() == 0) return; size_type idx,qidx,aidx; if(ax25Dest.compare("ID") == 0){ //ax25 ID packet aprsType = APRSID; return; } switch (data[0]) { case ':' : /* station to station message, new 1998 format*/ /* example of string in "data" :N0CLU :ack1 */ stsmDest = data.substr(1,MAXPKT); idx = stsmDest.find(":"); if (idx == npos) break; stsmDest = stsmDest.substr(0,idx); if (stsmDest.length() != 9) break; idx = stsmDest.find_first_of(RXwhite); if (idx != npos) stsmDest = stsmDest.substr(0,idx); aprsType = APRSMSG; EchoMask |= src3RDPARTY; msgType = APRSMSGTEXT; if (stsmDest.compare("SERVER") == 0) msgType = APRSMSGSERVER; aidx = data.find_last_of('{'); if (aidx != npos) acknum = data.substr(aidx+1); if (data.length() >= 15) if (data.substr(10,4) == string(":ack")) msgType = APRSMSGACK ; if (data.substr(10,2) == string(":?")){ qidx = data.find('?',12); if (qidx != string::npos) { query = data.substr(12,qidx-12); msgType = APRSMSGQUERY; qidx = data.find('{',qidx); if (qidx != string::npos) { acknum = data.substr(qidx); } //cout << "Query=" << query << " qidx=" << qidx << endl; } } break; case '_' : aprsType = APRSWX; break;/* weather */ case '@' : /* APRS mobile station */ case '=' : /* APRS fixed station */ case '!' : /* APRS not runing, fixed short format */ case '/' : aprsType = APRSPOS; /* APRS not running, fade to gray in 2 hrs */ break; case '>' : aprsType = APRSSTATUS; break; case '?' : qidx = data.find('?',1); if (qidx != string::npos) { query = data.substr(1,qidx-1); aprsType = APRSQUERY; } break; case ';' : aprsType = APRSOBJECT; break; case 0x60: //These indicate it's a Mic-E packet case 0x27: case 0x1c: case 0x1d: aprsType = APRSMIC_E; break; case '}' : { aprsType = APRS3RDPARTY; //Extract the 3rd party path data string tp_path = data.substr(1,data.find(":",1)); thirdPartyPathSize = split(tp_path , thirdPartyPath,MAXPATH,pathDelm); //reformatted = true; //string temp = data.substr(1,MAXPKT); // aprsString reparse(temp); // aprsType = reparse.aprsType; //print(cout); break; } case '$' : aprsType = NMEA; break; /* check for messages in the old format */ default: if (data.length() >= 10) { if ((data.at(9) == ':') && isalnum(data.at(0))) { idx = data.find(":"); stsmDest = data.substr(0,idx); //Old format aprsType = APRSMSG; EchoMask |= src3RDPARTY; idx = stsmDest.find_first_of(RXwhite); if (idx != npos) stsmDest = stsmDest.substr(0,idx); if (data.substr(9,4) == string(":ack")) msgType = APRSMSGACK ; if (data.substr(9,2) == string(":?")) { qidx = data.find('?',11); if (qidx != string::npos) { query = data.substr(11,qidx-11); msgType = APRSMSGQUERY; qidx = data.find('{',qidx); if (qidx != string::npos) { acknum = data.substr(qidx); } //cout << "Query=" << query << " qidx=" << qidx << endl; } } } if ((data.at(9) == '*') && isalnum(data.at(0))) { aprsType = APRSOBJECT; } } break; }; /* end switch */ /* mark packets for certain path elements (TCPXX, RFONLY, NOGATE) between the destination call and the Internet Injection Point (q string). */ int stop,start; start = 2; if (IjpIdx > 0) stop = IjpIdx-1; else stop = pathSize-1; if (queryPath("TCPXX",start,stop,5) != npos) tcpxx = true; //If TCPXX or TCPXX* don't allow Inet->RF gating // qAX is checked elsewhere in findInjectionPoint() nogate = false; if (queryPath("NOGATE",start,stop) != npos) nogate = true; //If NOGATE or RFONLY don't allow RF->Inet gating if (queryPath("RFONLY",start,stop) != npos) nogate = true; } //------------------------------------------------------------- void aprsString::parseLogon(void) { for (int i = 0; i < MAXWORDS; i++) words[i] = ""; int n = split(*this,words,MAXWORDS,RXwhite); if (n > 1) user = words[1]; else user = "Telnet"; if (n > 3) pass = words[3]; else pass = "-1"; if (n > 5) pgmName = words[5]; else pgmName = "Telnet"; if (n > 6) pgmVers = words[6]; EchoMask = 0; //Don't echo any logon strings aprsType = APRSLOGON; } //------------------------------------------------------------- //Puts the message text into msg. void aprsString::getMsgText(string& msg) { if (aprsType == APRSMSG) { msg = data.substr(11); size_type ackidx = msg.find_last_of('{'); if(ackidx != npos) msg.erase(ackidx); //Remove {001 ack number } else msg = "*"; } //------------------------------------------------------------- // Packets of the form "command(arg1,arg2,arg3,...)" are processed here. bool aprsString::parseCommand(void) { bool rv = false; string cmd = substr(0,opIdx); //cmd is everything up to first "(" upcase(cmd); if ((cmd.compare("PORTFILTER") == 0 ) || cmd.compare("PF") == 0) rv = parsePortFilter(); if (cmd.compare("LOCK") == 0 ){ rv = true; cmdType = CMDLOCK; } aprsType = CONTROL; return rv; } //------------------------------------------------------------ //User selects his port filter parameters here. bool aprsString::parsePortFilter(void) { int i,n; bool rv = false; string arg; string args = substr(opIdx+1) ; int nw = split(args,words,MAXWORDS,cmdDelim); cmdType = CMDPORTFILTER; n = 0; EchoMask = 0; for (i = 0; i < nw; i++) { //Go through the arg list arg = words[i]; //Grab an argument from the list upcase(arg); //Convert to uppercase //See if it's anything we recognize below... if ((arg.compare("ALL") == 0) || (arg.compare("FULL") == 0) || (arg.compare("23") == 0) || (arg.compare("10152") == 0)){ EchoMask |= srcTNC | srcIGATE | srcUDP | srcUSER | srcUSERVALID | srcSYSTEM | srcBEACON; n++; continue; } if ((arg.compare("1313") == 0) || (arg.compare("LINK") == 0)) { EchoMask |= srcTNC | srcUSER | srcUSERVALID | srcUDP | srcBEACON; n++; continue; } if ((arg.compare("14579") == 0) || (arg.compare("LOCAL") == 0)) { EchoMask |= srcTNC | srcUDP | srcSYSTEM | srcBEACON; n++; continue; } if ((arg.compare("1314") == 0) || (arg.compare("MSG") == 0)) { EchoMask |= src3RDPARTY; n++; continue; } if ((arg.compare("-HUB") == 0) || (arg.compare("-SERVER") == 0) || (arg.compare("-IGATE") == 0)) { EchoMask &= ~srcIGATE; n++; continue; } if (arg.compare("-TNC") == 0) { EchoMask &= ~srcTNC; n++; continue; } if (arg.compare("-USER") == 0) { EchoMask &= ~(srcUSER | srcUSERVALID); n++ ; continue; } if (arg.compare("-SYSTEM") == 0) { EchoMask &= ~srcSYSTEM; n++ ; continue; } if (arg.compare("-BEACON") == 0) { EchoMask &= ~srcBEACON; n++; continue; } if (arg.compare("ECHO") == 0) { EchoMask |= wantECHO; n++; continue; } if ((arg.compare("REJECT") == 0) || (arg.compare("14503") == 0)) { EchoMask |= wantREJECTED; n++ ; continue; } if ((arg.compare("HEADER") == 0) || (arg.compare("14502") == 0)) { EchoMask |= wantSRCHEADER | srcUSER | srcUSERVALID | srcTNC | srcUDP | srcIGATE; n++ ; continue; } if (arg.compare("RAW") == 0) { EchoMask |= wantRAW | srcTNC ; n++ ; continue; } if (arg.compare("DUP") == 0) { EchoMask |= sendDUPS ; n++ ; continue; } if (arg.compare("TNC") == 0) { EchoMask |= srcTNC; n++; continue; } if (arg.compare("UDP") == 0) { EchoMask |= srcUDP; n++; continue; } if (arg.compare("USER") == 0){ EchoMask |= srcUSERVALID | srcUSER ; n++; continue; } if (arg.compare("SERVER") == 0){ EchoMask |= srcIGATE; n++; continue; } if (arg.compare("HUB") == 0){ EchoMask |= srcIGATE; n++; continue; } if (arg.compare("IGATE") == 0){ EchoMask |= srcIGATE; n++; continue; } if (arg.compare("SYSTEM")== 0){ EchoMask |= srcSYSTEM | srcBEACON; n++; continue; } if (arg.compare("STATS") == 0){ EchoMask |= srcSTATS; n++; continue; } if (arg.compare("HISTORY") == 0){ EchoMask |= sendHISTORY; n++; continue; } if (arg.compare("CLEAR") == 0){ EchoMask = 0; n++; } } rv = (n == nw); //Check for error if (!rv) EchoMask = 0; //if error then clear echomask. return rv; } //------------------------------------------------------------- bool aprsString::AEAtoTAPR(string& s, string& rs) { bool rv; string pathElem[MAXPATH+2]; string pathPart, dataPart; try { size_type pIdx = find(":"); dataPart = s.substr(pIdx+1,MAXPKT); pathPart = s.substr(0,pIdx+1); int n = split(pathPart,pathElem,MAXPATH+2,pathDelm); rs = pathElem[0] + '>' + pathElem[n-1]; for (int i = 1; i < n-1; ++i) rs = rs + ',' + pathElem[i]; rs = rs + ':' + dataPart; rv = true; }catch(exception& error) { rv = false; WriteLog("AEA to TAPR conversion error",ERRORLOG); WriteLog(s.c_str(),ERRORLOG); } return rv; } //-------------------------------------------------------------- /* This is for debugging only. It dumps important variables to the console */ void aprsString::print(ostream& os) { string s_ref = "FALSE"; string s_igated = "FALSE"; string s_digipeated = "FALSE"; if (reformatted) s_ref = "TRUE"; if (hasBeenIgated()) s_igated = "TRUE"; os << *this << endl << "Serial No. = " << ID << endl << "TCPIP source socket = " << sourceSock << endl << "Packet type = " << aprsType << endl << "Reformatted = " << s_ref << endl << "Has Been Igated = " << s_igated << endl << "EchoMask = " << EchoMask << endl << "Peer= " << peer << endl << "User Call= " << call << endl; if (aprsType == APRSLOGON) { os << "User: " << user << endl << "Pass: " << pass << endl << "Program: " << pgmName << endl << "Vers: " << pgmVers << endl; } else { os << "Source =" << getAX25Source() << endl << "Destination = " << getAX25Dest() << endl; for (int i = 0; i< pathSize; i++) { os << "Path " << i << " " << ax25Path[i] << endl; } } os << endl << ends; } //---------------------------------------------------------------- /*returns the string as a char* */ const char* aprsString::getChar(void) { return c_str(); } echomask_t aprsString::getEchoMask(void) { return EchoMask; } void aprsString::setEchoMask(echomask_t m) { EchoMask = m; } string aprsString::getAX25Source(void) { return ax25Path[0]; } string aprsString::getAX25Dest(void) { return ax25Path[1]; } //--------------------------------------------------------------------------- bool aprsString::queryLocal(void) { bool localSource = false; if (!valid_ax25) return localSource; // false if ((EchoMask & srcTNC) && (path.find("GATE*") == npos ) && (freq(path,'*') < 3)) localSource = true; return localSource; // true } //------------------------------------------------------------------------------- //Search 1st n chars of ax25path elements for match with string s // starting at path element "start" and ending at "stop" //If n not present compare complete string. //Returns index of path element if match found // or npos is not found. unsigned aprsString::queryPath(const string& s, int start, int stop , unsigned n) { unsigned rc = npos; if (valid_ax25 == false) return rc; if (stop == -1) stop = pathSize-1; if (start >= pathSize) return rc; if (stop < start) return rc; for (int i = start; i <= stop; i++){ #if (__GNUC__ >= 3) || (STLport) if (s.compare(0,n,ax25Path[i]) == 0){ rc = i; break; } #else if (s.compare(ax25Path[i],0,n) == 0){ rc = i; break; } #endif } return rc; } //------------------------------------------------------- //Add character string "s" + "c" to the ax25 path bool aprsString::addPath(string s, char c) { if (aprsType == APRSREJECT) return false; if (pathSize == MAXPATH) return false; if (valid_ax25 == false) return false; try { if (c != ' ') s = s + c; path = path + "," + s; //Add string to path part replace(0,dataIdx-1,path); //Replace path portion of complete packet dataIdx = path.length() + 1; //adjust dataIdx to point to moved data beginning ax25Path[pathSize++] = s ; //Update path array and pathSize } catch(exception& error){ return false; } return true; } //----------------------------------------------------- bool aprsString::addPath(const char *cp, char c) { string s = cp; return addPath(s,c); } //----------------------------------------------------- //Return max hops int aprsString::getMaxHops(void) { return MAXISHOPS; } //------------------------------------------------------ //Return 0 if packet does not have any injection point //or else return the path index where it's located. //Injection point is indicated by a path element with "q" as first char. int aprsString::findInjectionPoint(void) { if ((aprsType == APRSREJECT) || (pathSize == MAXPATH) || (valid_ax25 == false)) return -1; bool done = false; int i = 2; while(( i < pathSize) && !done) { if (ax25Path[i][0] == 'q') done = true; if (!done) i++; } if ((i < pathSize) && (i >= 2)){ IjpIdx = i; IjpOffset = find(ax25Path[i],0); if ((ax25Path[IjpIdx][2] == 'X') //qAX - unvalidated user || (ax25Path[IjpIdx][2] == 'Z')) //qAZ - Zero hops allowed tcpxx = true; //Mark for NO RF gating return i; } else return 0; } //------------------------------------------------------ /* If IIPPE (q string) is present change it to new string in qs */ int aprsString::changeIIPPE(const char* qs) { if (IjpIdx == 0) return 0; //No q string to change cerr << "qs=" << qs << " at IjpIdx=" << ax25Path[IjpIdx] << endl; string oldq = ax25Path[IjpIdx]; return changePath(qs, oldq.c_str()); } //------------------------------------------------------- //Convert a packet to 3rd party format if it's not // already in 3rd party format. Return true on success. bool aprsString::thirdPartyReformat(const char *mycall) { char *co; char out[BUFSIZE+1]; if (valid_ax25 == false) return false; //If it isn't AX25 do not attempt conversion if (aprsType == APRS3RDPARTY) return false; //Refuse to convert existing 3rd party packets memset(out, 0, BUFSIZE+1); std::ostrstream os(out,BUFSIZE); co = ":"; if ((aprsType == APRSMSG) && (data.at(0) != ':')) co = "::"; //convert to new msg format if old os << "}" << ax25Source << ">" << ax25Dest << ",TCPIP*," << mycall << "*" << co << data << ends; data = out; reformatted = true; normalized = false; aprsType = APRS3RDPARTY; return true; } //---------------------------------------------------------- //Convert 3rd party format packet to normal format (inverse of thirdPartyReformat above) bool aprsString::thirdPartyToNormal(void) { if (valid_ax25 == false) return false; if (aprsType != APRS3RDPARTY) return false; string Icall = removeI(); //If there was a CALLSIGN,I in path remove it an keep CALLSIGN in Icall string d = data.substr(1,data.length()); //Keep only the data after ":}" //Use data to create a new aprsString aprsString* temp = new aprsString(d.c_str(),sourceSock,EchoMask,peer.c_str(),call.c_str()); if (temp->aprsType == APRSREJECT){ //Check for validity aprsType = APRSREJECT; //Flag as error if defective return false; //Do not copy if defective } temp->reformatted = false; //Indicate it's not a 3rd party packet temp->normalized = true; //Indicate it's been converted to normal format *this = *temp; //Copy data into this aprsString object delete temp; //Delete the local temporary object if (Icall.length() > 0){ //Re-insert the CALLSIGN,I construct if (Icall[Icall.length()-1] == '*') addPath(Icall); else addPath(Icall,'*'); //Reinsert CALLSIGN and * if not present addPath("I"); //Add the "I" path element } return true; } //--------------------------------------------------------- //checks for string s = any of: TCPIP*, TCPXX*, I* , I. bool aprsString::igated(const string& s) { if (s.compare("TCPIP*") == 0) return true; if (s.compare("TCPIP") == 0) return true; if (s.compare("I") == 0) return true; if (s.compare("I*") == 0) return true; if (s.compare("TCPXX*") == 0) return true; if (s.compare("TCPXX") == 0) return true; if (s[0] == 'q') return true; return false; } //--------------------------------------------------------- //Returns true if 3rd party path indicates this has been igated to RF from Internet. bool aprsString::hasBeenIgated(void) { int i; bool rv = false; if (valid_ax25 == false) return false; if (aprsType == APRS3RDPARTY){ //Scan the 3rd party header for igated flags i = thirdPartyPathSize - 1; while ((i > 0) && (rv == false)){ rv = igated(thirdPartyPath[i--]); } } return rv; } //-------------------------------------------------------- //Returns true if string s is a path element that's been used. bool aprsString::pathUsed(const string& s) { int sz = s.size(); if (s[sz-1] == '*') return true; //Last char is an '*' ? if(sz == 7){ //Is it WIDEn-n format? #if (__GNUC__ >= 3) || (STLport) if ((s.compare(0,4,"WIDE")) //1st 4 chars are "WIDE" && (s[5] == '-') // 6th char is "-" && (s[4] >= '0') // 5th char is'0' or higher && (s[4] <= '7')){ // 5th char is 7 or lower if (s[4] > s[6]) return true; //if 5th char greater than 7th char ret true } #else if((s.compare("WIDE",0,4)) //1st 4 chars are "WIDE" && (s[5] == '-') // 6th char is "-" && (s[4] >= '0') // 5th char is'0' or higher && (s[4] <= '7')){ // 5th char is 7 or lower if (s[4] > s[6]) return true; //if 5th char greater than 7th char ret true } #endif } return false; } //-------------------------------------------------------- //Starting at the last ax25 path element work backward //removing elements until a used element is found. void aprsString::cutUnusedPath(void) { int i = pathSize -1; if (valid_ax25 == false) return; while ((i > 1) && (pathUsed(ax25Path[i]) == false)) i--; pathSize = i + 1; //New path size path = ax25Path[0] + ">"; for (i = 1; i < pathSize; i++){ //Now rebuild the path path = path + ax25Path[i]; if (i < (pathSize-1)) path = path + ','; } replace(0,dataIdx-1,path); //Replace path portion of complete packet dataIdx = path.length() + 1; //adjust dataIdx to point to moved data beginning } //----------------------------------------------------------- //Remove the last n path elements void aprsString::trimPath(int n) { int i; pathSize = pathSize - n; //Reduce path size by n if (pathSize < 2) pathSize = 2; // Do not trim the destination field! path = ax25Path[0] + ">"; //Start path rebuild for (i = 1; i < pathSize; i++){ //Now rebuild the rest of the path path = path + ax25Path[i]; if (i < (pathSize-1)) path = path + ','; } replace(0,dataIdx-1,path); //Replace path portion of complete packet dataIdx = path.length() + 1; //adjust dataIdx to point to moved data beginning } //------------------------------------------------------------ //If the last path element it "I" or "I*" remove it and the preceeding path element. //Return the callsign preceeding the "I". string aprsString::removeI(void) { if (pathSize < 4) return ""; string sI = ax25Path[pathSize-1]; //sI is last path element if (sI.size() <= 2){ if ((sI.compare("I") == 0) || (sI.compare("I*") == 0)){ icall = ax25Path[pathSize-2]; //Get the callsign before th "I" trimPath(2); cci = true; //Set "Converted Callsign I" flag true } } return icall; //Return the callsign or empty string } //---------------------------------------------------------- char aprsString::getPktSource(void) { if(EchoMask & srcUSERVALID) { if (cci){ //Converted from callsign,I construct if(call.compare(icall) == 0) return 'R'; //call preceeding I == login so return R else return 'r'; //Else return r } //No callsign,i in packet if (ax25Source.compare(call) == 0) return 'C'; //return C if login call matches ax25 FROM call else return 'S'; //Else return S for all others } if (EchoMask & srcIGATE){ //From an aprs Server or Hub if (cci) return 'r'; //I conversion to qAr else return 'S'; //No I so return S } if (EchoMask & srcTNC) return 'R' ; //From RF (TNC) if (EchoMask & srcUSER) return 'X'; //From non-validated client if (EchoMask & srcUDP) return 'U'; //From UDP port if (EchoMask & srcBEACON) return 'I'; //From system Internal beacon if (EchoMask & srcSYSTEM) return 'Z'; //Zero hop for system status messages return 'Z'; //Zero hop DEFAULT } //----------------------------------------------------------- //Create Internet Injection Point Path Element //If c parameter present it replaces char from getPktSource(). void aprsString::createIIPPE(char* out, int size, char c ) { if (c == ' ') c = getPktSource(); ostrstream os(out,size); os << "qA" << c << ends; //Create IIPPE } //------------------------------------------------------------ //Add IIPPE to ax25 path. If the c parameter //is present it replaces the character from getPacketSource(). void aprsString::addIIPPE(char c ) { char IIPPE[12]; //Where IIPPE string will be createIIPPE(IIPPE,11,c); //Create IIPPE string addPath(IIPPE); //Add it to end of path findInjectionPoint(); //Update indexs and offsets } //----------------------------------------------------------- //Converts mic-e packets to 1 or 2 normal APRS packets //Returns pointers to newly allocated aprsStrings //Pointers remain NULL if conversion fails. void aprsString::mic_e_Reformat(aprsString** posit, aprsString** telemetry) { unsigned char mic1[512], mic2[512]; int l1, l2; time_t now = time(NULL); //cout << data; //printhex((char*)ax25Dest.c_str(),strlen(ax25Dest.c_str())); //printhex((char*)data.c_str(),strlen(data.c_str())); //cout << "data len=" << data.find("\r") << endl; int i = fmt_mic_e((unsigned char*)ax25Dest.c_str(), (unsigned char*)data.c_str(), data.find("\r"), mic1,&l1, mic2,&l2, now); if (i) { mic1[l1] = mic2[l2] = '\0'; if (l1) { char *buf1 = new char[512]; memset(buf1,0,512); std::ostrstream pbuf(buf1,511); pbuf << path << ':' << mic1 << "\r\n" << ends; aprsString* Posit = new aprsString(buf1,sourceSock,EchoMask,peer.c_str(),call.c_str()); Posit->raw = string(raw); // Save a copy of the raw mic_e packet Posit->changePath(PGVERS,ax25Dest.c_str()); delete buf1; *posit = Posit; } if (l2){ char *buf2 = new char[512]; memset(buf2,0,512); ostrstream tbuf(buf2,511); tbuf << path << ':' << mic2 << "\r\n" << ends; aprsString* Telemetry = new aprsString(buf2,sourceSock,EchoMask,peer.c_str(),call.c_str()); Telemetry->raw = string(raw); // Save a copy of the raw mic_e packet Telemetry->changePath(PGVERS,ax25Dest.c_str()); delete buf2; *telemetry = Telemetry; } } } //--------------------------------------------------------- //Find path element oldPath and replace with newPath //Returns true if success. bool aprsString::changePath(const char* newPath, const char* oldPath) { bool rc = false; int i; if (valid_ax25 == false) return false; try { for (i = 0; i < pathSize; i++) if (ax25Path[i].compare(oldPath) == 0 ) { ax25Path[i] = newPath; size_type idx = find(oldPath); replace(idx,strlen(oldPath),newPath); path.replace(idx,strlen(oldPath),newPath); dataIdx = find(":") + 1; //Update offset to data part rc = true; if (i==1) ax25Dest = newPath; if (i==0) ax25Source = newPath; break; } } catch(exception& error) { rc = false; WriteLog("aprsString changePath error",ERRORLOG); WriteLog(oldPath,ERRORLOG); } return rc; } //----------------------------------------------------------- void aprsString::printN(void) { cout << "N=" << NN << endl; } //----------------------------------------------------------------- //This is a hash function used for duplicate packet detection INT32 aprsString::gethash(INT32 seed) { int i; INT32 crc32 = seed; int datalen = data.length(); //Length of ax25 information field if (datalen >= 2) datalen -= 2; //Don't include CR-LF in length if (datalen > 0){ while ((data[datalen-1] == ' ') && (datalen > 0)) datalen--; //Strip off trailing spaces } int len = length(); int slen = ax25Source.length(); int destlen = ax25Dest.length(); if ((aprsType == COMMENT) || (valid_ax25 == false)){ //hash the whole packet, else... for (i = 0; i < len; i++) crc32 = updateCRC32(c_str()[i],crc32); } else { //hash only ax25Source and data. Ignore path. if (slen > 0) for (i = 0; i < slen; i++) crc32 = updateCRC32(ax25Source.c_str()[i],crc32); //If it's a Mic-E also hash the ax25 Destination (really Longitude). if ((aprsType == APRSMIC_E) && (ConvertMicE == false)) for (i = 0; i < destlen; i++) crc32 = updateCRC32(ax25Dest.c_str()[i],crc32); if (datalen > 0) { for(i = 0; i < datalen; i++){ char c = data.c_str()[i]; if ((c == 0) || (c == 0x0d) || (c == 0x0a)){ i = datalen; //Ignore NULLs, Cr,LF in data } else { crc32 = updateCRC32(c , crc32); } } //end for() } crc32 ^= dest ; // "dest" value is 1 or 2 depending on if destTNC or destINET. } // This is done so the same packet can be sent to both the TNC and Internet // queues and be dup checked without a false positive. hash = crc32; return crc32 ; //Return 32 bit hash value } //------------------------------------------- //Returns the number of aprsString objects that currently exist. int aprsString::getObjCount() { int n = 0; //Lock countCount(pmtxCounters); pthread_mutex_lock(mutex); n = NN; pthread_mutex_unlock(mutex); //cerr << "getObjCount: n = " << n << endl; //cerr << "getObjCount: nn = " << NN << endl; return n; } //---------------- aprsd-2.2.5-13/src/aprsString.h0000644000000000000000000002467407665450331011623 /* * $Id: aprsString.h,v 1.14 2003/05/29 18:26:33 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #ifndef APRSSTRING_H #define APRSSTRING_H #include #include #include "constant.h" #define MAXPKT 256 #define MAXPATH 22 /* longest path we can parse */ #define MAXISPATH 18 /* Largest Internet System path allowed (CALL + DEST + 8 digi + qAc + N other things :) */ #define MAXRFPATH 10 #define MAXISHOPS (MAXISPATH-MAXRFPATH-1) //----------------------------------- //Constants for EchoMask. Each aprsSting object has this variable. //These allow each Internet listen port to filter //data it needs to send. static const echomask_t srcTNC = 1; //data from TNC static const echomask_t srcUSER = 2; //data from any logged on internet user static const echomask_t srcUSERVALID = 4; //data from validated internet user static const echomask_t srcIGATE = 8; //data from another IGATE static const echomask_t srcSYSTEM = 16; //data from this server program static const echomask_t srcUDP = 32; //data from UDP port static const echomask_t srcHISTORY = 64; //data fetched from history list static const echomask_t src3RDPARTY = 128; //data is a 3rd party station to station message static const echomask_t srcSTATS = 0x100; //data is server statistics static const echomask_t srcBEACON = 0x200; //data is from internal beacon for ID // static const echomask_t wantREJECTED = 0x400; //user wants rejected packets static const echomask_t wantSRCHEADER = 0x0800;//User wants Source info header prepended to data static const echomask_t wantHTML = 0x1000; //User wants html server statistics (added in version 2.1.2) static const echomask_t wantRAW = 0x2000; //User wants raw data only static const echomask_t sendDUPS = 0x4000; //if set then don't filter duplicates static const echomask_t sendHISTORY = 0x8000; //if set then history list is sent on connect static const echomask_t wantECHO = 0x10000; //Echo users data back to him static const echomask_t omniPortBit = 0x80000000; //User defines his own echo mask // static const int APRSMSGACK = 31; //These three are for the msgType variable static const int APRSMSGTEXT = 32; // and indicate what kind of message it is. static const int APRSMSGQUERY = 33; static const int APRSMSGSERVER = 34; //SERVER command embedded in a message //------------------------------------- //Packet types static const int APRSMIC_E = 20; static const int APRSOBJECT = 9; static const int COMMENT = 10; static const int APRSID = 11; //Station ID packet eg: WA4DSY>ID...... static const int CONTROL = 12; //User control command to configure his port static const int NMEA = 100; static const int APRS3RDPARTY = 8; static const int APRSREFORMATTED = 8; static const int APRSQUERY = 7; static const int APRSSTATUS = 6; static const int APRSTCPXX = 5; static const int APRSLOGON = 4; static const int APRSMSG = 3; static const int APRSWX = 2; static const int APRSPOS = 1; static const int APRSUNKNOWN = 0; static const int APRSREJECT = -1; //Command Types static const int CMDNULL = 0; static const int CMDPORTFILTER = 1; static const int CMDLOCK = 2; static const int MAXWORDS = 8; static const unsigned int ttlSize = 5; //String length of a TTL path element //Return codes from decrementTTL() static const int ttlExpired = -1; static const int ttlNotPresent = 1; static const int ttlSuccess = 0; static const int TTLSIZE = 5; //Length of TTL or Internet Injection point string extern int ttlDefault; //Make ttlDefault available to other modules namespace aprsd { using namespace std; class aprsString: public string { public: static unsigned int NN; //Tells how many objects exist static unsigned long objCount; //Total of objects created (used as ID) //static unsigned int* refCount; static pthread_mutexattr_t* mutexAttr; static pthread_mutex_t* mutex; unsigned long ID; //Unique ID number for this object int instances ; //Number of pointers to this object that exist in user queues bool tcpxx; //true = TCPXX or TCPXX* was in the path bool reformatted; //true = packet has been reformatted into 3rd party format bool normalized; //true = packet has been converted to normal from 3rd party bool cci; //true = converted from CallSign,I to qAR. time_t timestamp; // time it was created int ttl; // time to live (minutes) in history list INT32 hash; // 32 bit hash code of this packet time_t timeRF; // time this was sent on RF (0 = never) aprsString* next; //Only used if this is part of a linked list aprsString* last; // ditto.. bool localSource; //true = source station is local bool nogate; //true = do not igate this packet int aprsType; //Type of packet (comment, 3rdparty etc.) int cmdType; //User command code bool valid_ax25; //Validated as a good ax25 packet with PATH and DATA parts int sourceSock; //tcpip socket this came from int pathSize; //Length of the path part in bytes int thirdPartyPathSize; //Length of the 3rd party path in bytes echomask_t EchoMask; //Set a bit to indicate where this object came from long FilterMask; //Mask for USER selected regional data streams int dest; //Where it's going, destTNC or destINET string::size_type gtIdx; //character position of the ">" symbol string::size_type pIdx; //Character position of the ":" symbol string::size_type opIdx; //Character position of the "(" symbol string::size_type cpIdx; //Character position of the ")" symbol string::size_type dataIdx; //index of data part of this packet, usually pIdx + 1 int IjpIdx; //index to path element that has IS Injection point ( qAc ) int IjpOffset; //Offset in characters from start of packet of the Injection point bool allowdup; //true or false, object is a duplicate (for redundent ACKs) int msgType; //Indicates if message is an ACK or just text //bool Expired; //True indicates this packet has expired (time-to-Live is zero) bool AEA; string ax25Source; //ax25 source string ax25Dest ; //ax25 destination string stsmDest; //Station to Station Message destination string path; //Raw ax25 path (up to but not including the colon) string data; //Raw ax25 data (all following first colon) string ax25Path[MAXPATH]; string thirdPartyPath[MAXPATH]; string words[MAXWORDS]; string user; string pass; string pgmName; string pgmVers; string peer; string call; string icall; //Callsign precceding the "I" in old uiview packets string query; //APRS Query string string acknum; //The "{nnn" at the end of messages string raw; //copy of complete raw packet preserved here string srcHeader; //Source IP and user call header. format example: !192.168.1.1:N0CALL! aprsString(const char *cp, int s,int e); aprsString(const char *cp, int s,int e, const char* szPeer, const char *userCall); aprsString(const char *cp); aprsString(string& as); aprsString(aprsString& as); ~aprsString(void) throw(); void parseAPRS(void); void parseLogon(void); bool parseCommand(void); bool parsePortFilter(void); void aprsString::getMsgText(string& msg); void print(ostream& os); string getAX25Source(void); string getAX25Dest(void); const char* getChar(void); echomask_t getEchoMask(void); void setEchoMask(echomask_t m); //Tells if char string cp is in the ax25 path unsigned queryPath(const string& s, int start = 0, int stop = -1, unsigned n = npos); bool changePath(const char* newPath, const char* oldPath); //Change one path element bool addPath(const char* cp, char c = ' '); bool addPath(string s, char c = ' '); void trimPath(int n); //Remove last n path elements bool queryLocal(void); //returns true if source call is local bool igated(void); //Returns true if packet has been igated to RF bool thirdPartyReformat(const char *call); //Convert to 3rd party format bool thirdPartyToNormal(void); //Convert 3rd party to normal void mic_e_Reformat(aprsString** posit, aprsString** telemetry); void printN(void); void addInstance(void); void removeInstance(void); INT32 gethash(INT32 seed = 0); bool hasBeenDigipeated(const string& s); bool hasBeenIgated(void); bool igated(const string& s) ; bool pathUsed(const string& s); void cutUnusedPath(void) ; int decrementTTL(void); char getPktSource(void); //get char code for packet source ( C I R U X Z ) void addIIPPE( char c = ' '); //add IIPPE to path string removeI(void); void createIIPPE(char* out, int size, char c = ' ') ; // Create Internet Injection Point Path Element int getIsHops(void); int getMaxHops(void) ; int changeIIPPE(const char* qs); int findInjectionPoint(void); bool loopCheck(const string& ucall); //true if ucall is in IS path. * is ignored static int getObjCount(void); private: void constructorSetUp(const char *cp, int s, int e); bool AEAtoTAPR(string& s, string& rs); } ; } #endif // APESSTRING_H aprsd-2.2.5-13/src/aprsdassert.h0000664000076400007640000000342007655343015012047 /* * $Id: aprsdassert.h,v 1.3 2003/04/20 18:34:47 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #ifndef ASSERT_H #define ASSERT_H #include "osdep.h" #include #ifndef DEBUG #ifdef NDEBUG #define DEBUG(x) /* Debug assertion */ #else #define DEBUG(x) x #endif #endif /** * \def DEBUG(x) * * Removes x from the source code if NDEBUG is defined. */ /** * Throws an object as an exception if an assertion is not met. Can be used with the * DEBUG macro to selectively remove assertions from production code. For example: * *
 * Assert(foo == bar, AssertException("failed!"));
 *
 * DEBUG(Assert(foo == bar, AssertException("failed!")));
 * 
* * The second assertion will be removed if NDEBUG is defined. */ namespace aprsd { template inline void Assert(bool assertion, E e) { if (!assertion) throw e; } } #endif // ASSERT_H aprsd-2.2.5-13/src/ax25socket.cpp0000644000000000000000000002230007665450331011772 /* * $Id: ax25socket.cpp,v 1.8 2003/05/29 18:26:33 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2001 Dale A. Heatherington, WA4DSY * Copyright (C) 2001 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ /* Based on serial.cpp Implements the same interface as serial.cpp (as specified in serial.h), but uses Linux network sockets. */ #include "config.h" #ifdef HAVE_LIBAX25 // if no AX25, do nothing #include #include #include // poll, et el #include #include #include #include #include // isprint #include #include #include #include #include "osdep.h" #include "ax25socket.h" #include "constant.h" #include "rf.h" #include "servers.h" using std::cerr; using std::endl; using std::cout; //--------------------------------------------------------------------- // AX.25 constants #define ALEN 6 #define AXLEN 7 /* SSID mask and various flags that are stuffed into the SSID byte */ #define SSID 0x1E #define HDLCAEB 0x01 #define REPEATED 0x80 #define UI 0x03 // unnumbered information (unproto) #define PID_NO_L3 0xF0 // no level-3 (text) //--------------------------------------------------------------------- // AX.25 variables char* ax25port; // Name of port to use char* ax25dev; // Associated device name int rx_socket, tx_socket; // RX and TX socket descriptors int proto = ETH_P_ALL; // Protocol to use for receive struct full_sockaddr_ax25 tx_dest; // TX destination address struct full_sockaddr_ax25 tx_src; // TX source address int tx_src_len, tx_dest_len; // Length of addresses //--------------------------------------------------------------------- // AX.25 function prototypes void fmt (const unsigned char*, int, unsigned char**); char* pax25 (char*, const unsigned char*); //--------------------------------------------------------------------- // Open the AX.25 sockets int SocketOpen(const string& rfport, const string& destcall) { char* portcall; if (destcall.size() == 0) { cerr << "aprsd: no APRSPATH specified, required for sockets" << endl; return 1; } // Open network sockets here ax25port = strdup(rfport.c_str()); if (ax25_config_load_ports() == 0) cerr << "aprsd: no AX.25 port data configured" << endl; if ((ax25dev = ax25_config_get_dev(ax25port)) == NULL) { cerr << "aprsd: invalid port name - " << ax25port << endl; return 1; } // Create the receive socket if ((rx_socket = socket(PF_PACKET, SOCK_PACKET, htons(proto))) == -1) { perror("socket"); return 1; } // Create the transmit socket if ((tx_socket = socket(PF_AX25, SOCK_DGRAM, 0)) == -1) { perror("socket"); return 1; } // Get the port's callsign if ((portcall = ax25_config_get_addr(ax25port)) == NULL) { cerr << "invalid AX.25 port setting - " << ax25port << endl; return 1; } // Convert to AX.25 addresses if ((tx_src_len = ax25_aton(portcall, &tx_src)) == -1) { cerr << "unable to convert callsign '" << portcall << "'" << endl; return 1; } if ((tx_dest_len = ax25_aton(destcall.c_str(), &tx_dest)) == -1) { cerr << "unable to convert callsign '" << destcall << "'" << endl; return 1; } // Bind the socket if (bind(tx_socket, (struct sockaddr *)&tx_src, tx_src_len) == -1) { perror("bind"); return 1; } return 0; } //-------------------------------------------------------------------- int SocketClose (void) { // nothing to do here return 0; } //-------------------------------------------------------------------- // This is the socket read thread. // It polls the socket, and returns any data received // (after reformatting it to raw TNC format). bool SocketReadWrite(char buf[]) { bool lineTimeout; struct pollfd pfd; struct sockaddr sa; struct ifreq ifr; int asize; int result; int size = 0; unsigned char rxbuf[1500]; unsigned char *textbuf; int rc; lineTimeout = false; do { if (txrdy) { //Check for data to Transmit //cerr << "DEBUG: SocketReadWrite: Sending " << buf << " to Socket" << endl; if ((rc = sendto(tx_socket, tx_buffer, strlen(tx_buffer), 0, (struct sockaddr *)&tx_dest, tx_dest_len)) < 0) cerr << "DEBUG: SocketReadWrite: Error sending to TNC" << endl; txrdy = false; //Indicate we sent it. } pfd.fd = rx_socket; pfd.events = 0x040; // Read normal data -- should be POLLRDNORM result = poll(&pfd, 1, 100); // Time-out after 100ms if (result == 1) { asize = sizeof(sa); if ((size = recvfrom(rx_socket, rxbuf, sizeof(rxbuf), 0, &sa, (socklen_t*)&asize)) == -1) { perror("AX25 Socket recvfrom error"); result = -1; } else { if (ax25dev != NULL && strcmp(ax25dev, sa.sa_data) != 0) result = 0; if (proto == ETH_P_ALL) { // promiscuous mode? strcpy(ifr.ifr_name, sa.sa_data); if (ioctl(rx_socket, SIOCGIFHWADDR, &ifr) < 0 || ifr.ifr_hwaddr.sa_family != AF_AX25) result = 0; // not AX25 so ignore this packet } if (result == 1) { fmt(rxbuf, size, &textbuf); // convert to text strncpy(buf, (char*)textbuf, BUFSIZE); TotalTncChars += BUFSIZE; } } } if (result < 0) // input error lineTimeout = true; // Error has occurred } while (result == 0); //cout << "DEBUG: AX25SockReadWrite: " << buf << endl; return lineTimeout; } //--------------------------------------------------------------------- // fmt converts a received packet into a TNC message string void fmt(const unsigned char *buf, int len, unsigned char **outbuf) { static unsigned char buf1[1000]; char from[10], to[10], digis[100]; int i, hadlast, l; char tmp[15]; *buf1 = '\0'; *outbuf = buf1; if ((buf[0] & 0xf) != 0) // not a kiss data frame return; ++buf; --len; if (len < (AXLEN + ALEN + 1)) // too short return; pax25 (to, buf); // to call pax25 (from, &buf[AXLEN]); // from call buf += AXLEN; // skip over the from call now... len -= AXLEN; *digis = '\0'; if (!(buf[ALEN] & HDLCAEB)) { // is there a digipeater path? for (l = 0, buf += AXLEN, len -= AXLEN, i = 0; i < 6 && len >= 0; i++, len -= AXLEN, buf += AXLEN) { int nextrept = buf[AXLEN + ALEN] & REPEATED; if (buf[ALEN] & HDLCAEB) nextrept = 0; pax25 (tmp, buf); if (*tmp) { sprintf (&digis[l], ",%s%s", tmp, (buf[ALEN] & REPEATED && !nextrept) ? "*" : ""); ++hadlast; l += strlen (&digis[l]); } if (buf[ALEN] & HDLCAEB) break; } } buf += AXLEN; len -= AXLEN; if (len <= 0) return; // no data after callsigns if (*buf++ == UI && *buf++ == PID_NO_L3) { len -= 2; } else { return; // must have UI text to be useful } // No rewriting for mic-e frames because aprsd does this later sprintf ((char*)buf1, "%s>%s%s:", from, to, digis); l = strlen ((char*)buf1); for (i = 0; i < len; i++, l++) { buf1[l] = (isprint (buf[i])) ? buf[i] : ' '; // keep it clean } buf1[l++] = 0x0d; buf1[l++] = 0x0a; buf1[l] = '\0'; return; } //--------------------------------------------------------------------- // pax25 formats an AX.25 callsign. char * pax25 (char *buf, const unsigned char *data) { int i, ssid; char *s; char c; s = buf; for (i = 0; i < ALEN; i++) { c = (data[i] >> 1) & 0x7F; if (c != ' ') *s++ = c; } if ((ssid = (data[ALEN] & SSID) >> 1) != 0) sprintf (s, "-%d", ssid); else *s = '\0'; return (buf); } #endif // HAVE_LIBAX25 aprsd-2.2.5-13/src/ax25socket.h0000644000076400007640000000254207661563341011511 /* * $Id: ax25socket.h,v 1.5 2003/05/18 01:50:25 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2001 Dale A. Heatherington, WA4DSY * Copyright (C) 2001 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #ifndef AX25SOCKETS_H #define AX25SOCKETS_H #include "constant.h" using namespace aprsd; // TCP Wrappers int inet_ptons(int family, const char *strptr, void *addrptr); int SocketOpen (const string& rfport, const string& destcall); int SocketClose (void); int SocketWrite (const char *cp); int SocketWrite (void); bool SocketReadWrite (char buf[]); #endif // AX25SOCKETS_H aprsd-2.2.5-13/src/constant.h0000664000076400007640000000601307655343020011342 /* * $Id: constant.h,v 1.12 2003/03/31 04:47:54 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #ifndef CONSTANT_H #define CONSTANT_H #include #include "config.h" //If you really must convert Mic-E packets to traditional APRS //change this to TRUE and add "ConvertMicE yes" to your aprsd.conf file. //#define CONVERT_MIC_E FALSE const bool CONVERT_MIC_E = false; /* Define this to write 3rd party pkts to debug.log */ // #define DEBUGTHIRDPARTY //If this is defined the qAc,CallSign construct is added to path #define INET_TRACE #define ULONG unsigned long #define LONG long #define USHORT unsigned short int #define INT16 unsigned short int #define APIRET int #define INT32 int #define echomask_t unsigned long #define LF 0x0a #define CR 0x0d #define RXwhite " \t\n\r" //#define LINK_SERVER_PORT 1313 #define CMD_END_THREAD -1L #define SRC_TNC -2L #define SRC_USER -3L #define SRC_INTERNAL -4L #define SRC_UDP -5L #define SRC_IGATE -6L #define MAXCLIENTS 30 #define MAXLOAD 200000 //This sets the Internet line input buffer size. //Lines longer than this, including CR,LF,NULL, will be truncated. //Actually, the data will be truncated but a CR,LF,NULL will always be on the end. #define BUFSIZE 255 //Defines duplicate detection window time in seconds #define DUPWINDOW 20 #define RUNTSIZE 0 #define MAXRETRYS 7 #define HOSTIPSIZE 33 #define destINET 1 #define destTNC 2 /* These are for Linux user/pass logons. They define the group used by /etc/group . You must have these groups and users defined in /etc/group. The "tnc" group defines which users are allowed direct access to control the TNC. The "aprs" group defines users which log on with a Linux user/password instead of the Mac/WinAPRS automatic password. These users are allowed to insert data into the data stream. To add a group logon as root and edit the /etc/group file by adding a line such as: tnc::102:root,wa4dsy,bozo */ #define APRSGROUP "aprs" #define TNCGROUP "tnc" /* this is not used in production code*/ //#define TEST "WA4DSY>APRS,WIDE:!3405.31N/08422.46WyWA4DSY APRS Internet Server running on Linux.\r\n" #endif // CONSTANT_H aprsd-2.2.5-13/src/cpqueue.cpp0000664000076400007640000001175607655343021011526 /* * $Id: cpqueue.cpp,v 1.19 2003/03/31 04:47:54 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #include #include #include #include #include #include #include #include "constant.h" #include "cpqueue.h" #include "aprsString.h" using namespace std; using namespace aprsd; /*-------------------------------------------------------*/ //Build a Queue object cpQueue::cpQueue(int n, bool d) { overrun = 0; size = n; dyn = d; base_p = new queueData[size]; write_p = 0; read_p = 0; itemsQueued = 0; lock = 0; inRead = 0; inWrite = 0; for (int i = 0; i < size; i++) { base_p[i].qcp = NULL; // NULL all the pointers base_p[i].qcmd = 0; base_p[i].rdy = false; // Clear the ready flags } } //Destroy Queue object cpQueue::~cpQueue(void) { lock = 1; while(inRead); while(inWrite); if (dyn) { while (read_p != write_p) if (base_p[read_p].qcp != NULL) delete (aprsString*)base_p[read_p++].qcp ; } delete base_p; } //Place a pointer and an Integer in the queue //returns 0 on success; int cpQueue::write(char *cp, int n) { int rc = 0; Lock qlock(Q_mutex, false); if (lock) return -2; //Lock is only set true in the destructor inWrite = 1; qlock.get(); int idx = write_p; if (base_p[idx].rdy == false) { // Be sure not to overwrite old stuff base_p[idx].qcp = (void*)cp; // put char* on queue base_p[idx].qcmd = n; // put int (cmd) on queue base_p[idx].rdy = true; // Set the ready flag idx++; itemsQueued++; if (idx >= size) idx = 0; write_p = idx; } else { overrun++ ; if (dyn) { delete[] cp; //Added [] brackets 14-July-2001 wa4dsy cp = NULL; //Added set to NULL 14-July-2001 wa4dsy } rc = -1; } qlock.release(); inWrite = 0; return rc; } int cpQueue::write(unsigned char *cp, int n) { return write((char*)cp, n); } int cpQueue::write(const char* cp, int n) { return write((char*)cp, n); } int cpQueue::write(aprsString* cs, int n) { int rc = 0; Lock qlock(Q_mutex, false); if (lock) return -2; inWrite = 1; qlock.get(); int idx = write_p; if (base_p[idx].rdy == false) { // Be sure not to overwrite old stuff base_p[idx].qcp = (void*)cs; // put String on queue base_p[idx].qcmd = n; // put int (cmd) on queue base_p[idx].rdy = true; // Set the ready flag itemsQueued++; idx++; if (idx >= size) idx = 0; write_p = idx; }else { overrun++ ; if (dyn){ delete cs; // Delete the object that couldn't be put in the queue cs = NULL; } rc = -1; } qlock.release(); inWrite = 0; return rc; } int cpQueue::write(aprsString* cs) { return write(cs, cs->sourceSock); } //Read a pointer and Integer from the Queue void* cpQueue::read(int *ip) { Lock qlock(Q_mutex, false); inRead = 1; qlock.get(); void* cp = base_p[read_p].qcp ; // Read the aprsString* if (ip) *ip = base_p[read_p].qcmd ; // read the optional integer command base_p[read_p].qcp = NULL; // Set the data pointer to NULL base_p[read_p].rdy = false; // Clear ready flag read_p++; itemsQueued--; if(read_p >= size) read_p = 0; inRead = 0; qlock.release(); return cp; } int cpQueue::ready(void) //returns true if data available { int rc=false; Lock qlock(Q_mutex); //if ((read_p != write_p) || wrap) rc = true ; if(base_p[read_p].rdy) rc = true; //pthread_mutex_unlock(Q_mutex); return rc; } int cpQueue::getWritePtr(void) { return write_p; } int cpQueue::getReadPtr(void) { return read_p; } int cpQueue::getItemsQueued(void) { return itemsQueued; } aprsd-2.2.5-13/src/cpqueue.h0000664000076400007640000000375007655343021011166 /* * $Id: cpqueue.h,v 1.10 2003/03/31 04:47:55 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #ifndef CPQUEUE_H #define CPQUEUE_H #include "aprsString.h" #include "mutex.h" using namespace aprsd; class queueData { public: void* qcp; //Pointer to dynamically allocated aprsString or char string. int qcmd; //Optional interger data command or info bool rdy; }; class cpQueue { private: queueData *base_p; int write_p; int read_p; int size, lock, inRead, inWrite; Mutex Q_mutex; bool dyn; public: int overrun; int itemsQueued; cpQueue(int n, bool d); // fifo Queue constructor ~cpQueue(void); // destructor int write(aprsString* cs, int cmd); int write(aprsString* cs); int write(char* cs, int cmd); int write(unsigned char* cs, int cmd); int write(const char* cs, int cmd); void* read(int *cmd); int ready(void); //return non-zero when queue data is available int getWritePtr(void); //For debugging int getReadPtr(void); int getItemsQueued(void); }; #endif // CPQUEUE_H aprsd-2.2.5-13/src/crc32.c0000664000076400007640000002054307655343021010425 /* +++Date last modified: 05-Jul-1997 */ /* Crc - 32 BIT ANSI X3.66 CRC checksum files */ #include #include "crc.h" /**********************************************************************\ |* Demonstration program to compute the 32-bit CRC used as the frame *| |* check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71 *| |* and FED-STD-1003, the U.S. versions of CCITT's X.25 link-level *| |* protocol). The 32-bit FCS was added via the Federal Register, *| |* 1 June 1982, p.23798. I presume but don't know for certain that *| |* this polynomial is or will be included in CCITT V.41, which *| |* defines the 16-bit CRC (often called CRC-CCITT) polynomial. FIPS *| |* PUB 78 says that the 32-bit FCS reduces otherwise undetected *| |* errors by a factor of 10^-5 over 16-bit FCS. *| \**********************************************************************/ /* Need an unsigned type capable of holding 32 bits; */ typedef DWORD UNS_32_BITS; /* Copyright (C) 1986 Gary S. Brown. You may use this program, or code or tables extracted from it, as desired without restriction.*/ /* First, the polynomial itself and its table of feedback terms. The */ /* polynomial is */ /* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ /* Note that we take it "backwards" and put the highest-order term in */ /* the lowest-order bit. The X^32 term is "implied"; the LSB is the */ /* X^31 term, etc. The X^0 term (usually shown as "+1") results in */ /* the MSB being 1. */ /* Note that the usual hardware shift register implementation, which */ /* is what we're using (we're merely optimizing it by doing eight-bit */ /* chunks at a time) shifts bits into the lowest-order term. In our */ /* implementation, that means shifting towards the right. Why do we */ /* do it this way? Because the calculated CRC must be transmitted in */ /* order from highest-order term to lowest-order term. UARTs transmit */ /* characters in order from LSB to MSB. By storing the CRC this way, */ /* we hand it to the UART in the order low-byte to high-byte; the UART */ /* sends each low-bit to hight-bit; and the result is transmission bit */ /* by bit from highest- to lowest-order term without requiring any bit */ /* shuffling on our part. Reception works similarly. */ /* The feedback terms table consists of 256, 32-bit entries. Notes: */ /* */ /* 1. The table can be generated at runtime if desired; code to do so */ /* is shown later. It might not be obvious, but the feedback */ /* terms simply represent the results of eight shift/xor opera- */ /* tions for all combinations of data and CRC register values. */ /* */ /* 2. The CRC accumulation logic is the same for all CRC polynomials, */ /* be they sixteen or thirty-two bits wide. You simply choose the */ /* appropriate table. Alternatively, because the table can be */ /* generated at runtime, you can start by generating the table for */ /* the polynomial in question and use exactly the same "updcrc", */ /* if your application needn't simultaneously handle two CRC */ /* polynomials. (Note, however, that XMODEM is strange.) */ /* */ /* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */ /* of course, 32-bit entries work OK if the high 16 bits are zero. */ /* */ /* 4. The values must be right-shifted by eight bits by the "updcrc" */ /* logic; the shift must be unsigned (bring in zeroes). On some */ /* hardware you could probably optimize the shift in assembler by */ /* using byte-swap instructions. */ static UNS_32_BITS crc_32_tab[] = { /* CRC polynomial 0xedb88320 */ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; DWORD updateCRC32(unsigned char ch, DWORD crc) { return UPDC32(ch, crc); } Boolean_T crc32file(char *name, DWORD *crc, long *charcnt) { register FILE *fin; register DWORD oldcrc32; register int c; oldcrc32 = 0xFFFFFFFF; *charcnt = 0; #ifdef MSDOS if ((fin=fopen(name, "rb"))==NULL) #else if ((fin=fopen(name, "r"))==NULL) #endif { perror(name); return Error_; } while ((c=getc(fin))!=EOF) { ++*charcnt; oldcrc32 = UPDC32(c, oldcrc32); } if (ferror(fin)) { perror(name); *charcnt = -1; } fclose(fin); *crc = oldcrc32 = ~oldcrc32; return Success_; } DWORD crc32buf(char *buf, size_t len) { register DWORD oldcrc32; oldcrc32 = 0xFFFFFFFF; for ( ; len; --len, ++buf) { oldcrc32 = UPDC32(*buf, oldcrc32); } return ~oldcrc32; } #ifdef TEST main(int argc, char *argv[]) { DWORD crc; long charcnt; register errors = 0; while(--argc > 0) { errors |= crc32file(*++argv, &crc, &charcnt); printf("%08lX %7ld %s\n", crc, charcnt, *argv); } return(errors != 0); } #endif /* TEST */ aprsd-2.2.5-13/src/crc.h0000664000076400007640000000203507655343022010262 /* +++Date last modified: 05-Jul-1997 */ /* ** CRC.H - header file for SNIPPETS CRC and checksum functions */ #ifndef CRC__H #define CRC__H #include /* For size_t */ #include "sniptype.h" /* For BYTE, WORD, DWORD */ #ifdef __cplusplus extern "C" { #endif /* ** File: ARCCRC16.C */ void init_crc_table(void); WORD crc_calc(WORD crc, char *buf, unsigned nbytes); void do_file(char *fn); /* ** File: CRC-16.C */ WORD crc16(char *data_p, WORD length); /* ** File: CRC-16F.C */ WORD updcrc(WORD icrc, BYTE *icp, size_t icnt); /* ** File: CRC_32.C */ #define UPDC32(octet,crc) (crc_32_tab[((crc)\ ^ ((BYTE)octet)) & 0xff] ^ ((crc) >> 8)) DWORD updateCRC32(unsigned char ch, DWORD crc); Boolean_T crc32file(char *name, DWORD *crc, long *charcnt); DWORD crc32buf(char *buf, size_t len); /* ** File: CHECKSUM.C */ unsigned checksum(void *buffer, size_t len, unsigned int seed); /* ** File: CHECKEXE.C */ void checkexe(char *fname); #ifdef __cplusplus } #endif #endif /* CRC__H */ aprsd-2.2.5-13/src/dupCheck.cpp0000664000076400007640000000613207655343022011576 /* * $Id: dupCheck.cpp,v 1.10 2003/03/31 04:48:18 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #include #include #include #include #include #include #include #include #include #include #include #include #include "constant.h" #include "dupCheck.h" #include "mutex.h" #define TABLESIZE 0x10000 /* 64K hash table containing time_t values */ using namespace std; using namespace aprsd; dupCheck::dupCheck() { hashtime = new time_t[TABLESIZE]; hashhash = new INT16[TABLESIZE]; clear(); time_t t = time(NULL); //Make sure no two aprsd servers user the same seed in the hash function seed = (unsigned long)t; if ((hashtime == NULL) || (hashhash == NULL)) cerr << "Dup Filter failed to initialize" << endl; } dupCheck::~dupCheck() { try { if (hashtime != NULL) { delete hashtime; hashtime = NULL; } if (hashhash != NULL) { delete hashhash; hashhash = NULL; } } catch (...) { } } bool dupCheck::check(aprsString* s, int t) { bool dup = false; time_t dt = 0; static int processed = 0; static int dupcount = 0; Lock locker(mutex); if ((hashtime == NULL) || (hashhash == NULL) || s->allowdup) return false; INT32 hash = s->gethash(seed); //Generate hash value from initial seed based on pgm start time. INT16 hash_lo = hash & 0xffff; //be sure we stay inside the table! INT16 hash_hi = hash >> 16; //upper 16 bits of hash hash_hi &= 0xffff; dt = s->timestamp - hashtime[hash_lo]; if (( dt <= t ) // See if time difference is less than t seconds && (hash_hi == hashhash[hash_lo])) { // and hash_hi value is identical dup = true; } hashtime[hash_lo] = s->timestamp; // put this new data in the tables hashhash[hash_lo] = hash_hi; if (dup) dupcount++; processed++; return dup; } void dupCheck::clear() { for (int i = 0; i < TABLESIZE; i++){ if (hashtime) hashtime[i] = 0; //Initialize tables if (hashhash) hashhash[i] = 0; } } aprsd-2.2.5-13/src/dupCheck.h0000664000076400007640000000261207655343022011242 /* * $Id: dupCheck.h,v 1.6 2003/03/31 04:48:18 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #ifndef DUPCHECK_H #define DUPCHECK_H #include #include "constant.h" #include "aprsString.h" #include "mutex.h" using namespace std; using namespace aprsd; class dupCheck { public: dupCheck(); ~dupCheck(); bool check(aprsString* s, int t); void clear(void); private: Mutex mutex; time_t* hashtime; INT16* hashhash; unsigned long seed; } ; #endif // DUPCHECK__H aprsd-2.2.5-13/src/aprsdexception.cpp0000664000076400007640000001102107655343016013074 /* * $Id: aprsdexception.cpp,v 1.3 2003/04/20 18:34:47 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #include "aprsdexception.h" namespace aprsd { Exception::Exception(const string& arg_message) : m_message(arg_message) { } Exception::~Exception() throw() { } string Exception::getMessage() const { return m_message; } string Exception::toString() const { if (getMessage().empty()) return getName(); else return getName() + ": " + getMessage(); } const char *Exception::what( void ) const throw() { return m_message.c_str(); } string Exception::getName() const { return "aprsd::Exception"; } AssertException::AssertException(const string& message) : Exception(message) { } string AssertException::getName() const { return "aprsd::AssertException"; } UnexpectedException::UnexpectedException(const string& message) : AssertException(message) { } string UnexpectedException::getName() const { return "aprsd::UnexpectedException"; } IOException::IOException(const string& message) throw() : Exception(message) { m_errno = 0; } IOException::IOException( int ERRNUM ) throw() { m_message = strerror_r(ERRNUM); m_errno = ERRNUM; } string IOException::getName() const { return "aprsd::IOException"; } UnknownHostException::UnknownHostException(const string& message) : IOException(message) { } string UnknownHostException::getName() const { return "aprsd::UnknownHostException"; } TimeoutException::TimeoutException(const string& message) : IOException(message) { } string TimeoutException::getName() const { return "aprsd::TimeoutException"; } SocketException::SocketException(const string& message) : IOException(message) { } string SocketException::getName() const { return "aprsd::SocketException"; } BindException::BindException(const string& message) : SocketException(message) { } string BindException::getName() const { return "aprsd::BindException"; } ConnectException::ConnectException(const string& message) : SocketException(message) { } string ConnectException::getName() const { return "aprsd::ConnectException"; } RegexException::RegexException(const string& message) : Exception(message) { } string RegexException::getName() const { return "aprsd::RegexException"; } NoSuchElementException::NoSuchElementException(const string& message) : Exception(message) { } string NoSuchElementException::getName() const { return "aprsd::NoSuchElementException"; } UnsupportedOperationException::UnsupportedOperationException(const string& message) : Exception(message) { } string UnsupportedOperationException::getName() const { return "aprsd::UnsupportedOperationException"; } ParseException::ParseException(const string& message) : Exception(message) { } string ParseException::getName() const { return "aprsd::ParseException"; } ThreadControlException::ThreadControlException( const string& message ) : Exception(message) { } string ThreadControlException::getName() const { return "aprsd::ThreadControlException"; } RefCountException::RefCountException( const string& message ) : Exception( message ) {} string RefCountException::getName() const { return "aprsd::RefCountException"; } } aprsd-2.2.5-13/src/aprsdexception.h0000664000076400007640000001506307655343017012554 /* * $Id: aprsdexception.h,v 1.3 2003/04/20 18:34:47 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #ifndef APRSD_EXCEPTION_H #define APRSD_EXCEPTION_H #include "osdep.h" #include #include namespace aprsd { using std::string; using std::exception; /** * A base class for exceptions. */ class Exception : public std::exception { public: /** * Constructs an Exception with an optional detail message. * * param message a detail message indicating the reason for the * exception. */ explicit Exception(const string& message = ""); /** * Destructor. */ virtual ~Exception() throw(); /** * return the exception's class name. */ virtual string getName() const; /** * @return a detail message indicating the reason for the * exception. */ virtual string getMessage() const; /** * A concatenation of the exception's class name and its detail * message, if available. */ string toString(void) const; /** Return only the message, but following the normal C++ notation ! @return a ziro terminated const char string */ const char *what( void ) const throw(); protected: string m_message; }; /** * Indicates that an assertion failed. */ class AssertException : public Exception { public: explicit AssertException(const string& message = ""); virtual string getName() const; }; /** * Indicates that an unexpected exception was thrown. * * see ExceptionGuard */ class UnexpectedException : public AssertException { public: explicit UnexpectedException(const string& message = ""); virtual string getName() const; }; /** * Indicates that an I/O error has occurred. */ class IOException : public Exception { public: explicit IOException( const string& message = "" ) throw(); explicit IOException( int ERRNUM ) throw(); ~IOException() throw(){} virtual string getName() const; int getErrno( void ) const { return m_errno;} private: int m_errno; }; /** * Indicates that the IP address of a host could not be resolved. */ class UnknownHostException : public IOException { public: explicit UnknownHostException( const string& message = "" ); explicit UnknownHostException( int ERRNUM ) throw() : IOException( ERRNUM ) {} virtual string getName() const; }; /** * Indicates that an operation has timed out. */ class TimeoutException : public IOException { public: explicit TimeoutException( const string& message = "" ); explicit TimeoutException( int ERRNUM ) throw() : IOException( ERRNUM ) {} virtual string getName() const; }; /** * Indicates that an error occurred while performing an operation * on a socket. */ class SocketException : public IOException { public: explicit SocketException( const string& message = "" ); explicit SocketException( int ERRNUM ) throw() : IOException( ERRNUM ) {} virtual string getName() const; }; /** * Indicates that an error occurred while attempting to bind a * socket to a local address and port. */ class BindException : public SocketException { public: explicit BindException( const string& message = "" ); explicit BindException( int ERRNUM ) throw() : SocketException( ERRNUM ) {} virtual string getName() const; }; /** * Indicates that an error occurred while attempting to connect a * socket to a remote address and port. */ class ConnectException : public SocketException { public: explicit ConnectException(const string& message = ""); explicit ConnectException( int ERRNUM ) throw() : SocketException( ERRNUM ) {} virtual string getName() const; }; /** * Indicates that the regular expression engine returned an error. */ class RegexException : public Exception { public: explicit RegexException(const string& message = ""); virtual string getName() const; }; /** * Indicates that the element does not exist. */ class NoSuchElementException : public Exception { public: explicit NoSuchElementException(const string& message = ""); virtual string getName() const; }; /** * Indicates that the operation is not supported by the library/OS. */ class UnsupportedOperationException : public Exception { public: explicit UnsupportedOperationException(const string& message = ""); virtual string getName() const; }; /** * Indicates that an error was found while parsing text. */ class ParseException : public Exception { public: explicit ParseException(const string& message = ""); virtual string getName() const; }; /** * Indicates that an error occurred while trying to control * a thread or process. */ class ThreadControlException : public Exception { public: explicit ThreadControlException(const string& message = ""); virtual string getName() const; }; /** This indicate an error occurred while using refcounting. */ class RefCountException : public Exception { public: explicit RefCountException(const string& message = ""); virtual string getName() const; }; } #endif // APRSD_EXCEPTION_H aprsd-2.2.5-13/src/exceptionguard.cpp0000664000076400007640000000325007655343022013067 /* * $Id: exceptionguard.cpp,v 1.3 2003/03/31 04:48:33 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #include "exceptionguard.h" namespace aprsd { void assertUnexpected() throw(UnexpectedException) { try { throw; } catch (Exception& e) { throw UnexpectedException(e.toString()); } catch (exception& e) { throw UnexpectedException(string("Unexpected system exception: ") + e.what()); } catch (...) { throw UnexpectedException("Exception thrown of unknown type"); } } ExceptionGuard::ExceptionGuard() throw() { old = std::set_unexpected(&assertUnexpected); } ExceptionGuard::~ExceptionGuard() throw() { std::set_unexpected(old); } } aprsd-2.2.5-13/src/exceptionguard.h0000664000076400007640000000421607655343023012540 /* * $Id: exceptionguard.h,v 1.3 2003/03/31 04:48:33 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #ifndef EXCEPTIONGUARD_H #define EXCEPTIONGUARD_H #include "aprsdexception.h" namespace aprsd { using std::unexpected_handler; extern void assertUnexpected() throw(UnexpectedException); /** * Catches unexpected exceptions in a program, and rethrows them as * UnexpectedException objects. UnexpectedException is derived from AssertException, * which passes to user code. If the unexpected exception is derived from * Exception or std::exception, the UnexpectedException object's detail * message will contain a description of it. * * To use this feature, just instantiate an ExceptionGuard as a local variable at the * beginning of your program's main() method. * * This class is not reference-counted. * */ class ExceptionGuard { std::unexpected_handler old; public: /** * Sets an unexpected_handler that rethrows exceptions as UnexpectedException * objects. */ ExceptionGuard() throw(); /** * Restores the original unexpected_handler. */ ~ExceptionGuard() throw(); }; } #endif // EXCEPTIONGUARD_H aprsd-2.2.5-13/src/history.cpp0000644000000000000000000004420707665450331011515 /* * $Id: history.cpp,v 1.28 2003/05/29 18:26:33 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ /*This code maintains a linked list of aprsString objects called the "History List". It is used to detect and remove duplicate packets from the APRS stream, provide a 30 minute history of activity to new users when they log on and determine if the destination of a 3rd party station to station message is "local". */ #include //#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "history.h" #include "aprsd.h" #include "utils.h" #include "aprsString.h" #include "servers.h" #include "mutex.h" #include "constant.h" using namespace std; using namespace aprsd; struct histRec { //This is for the History Array int count; time_t timestamp; echomask_t EchoMask; int type; bool reformatted; char *data; }; class HistoryRecord { public: HistoryRecord() throw(); ~HistoryRecord() throw(); int count; time_t timestamp; echomask_t EchoMask; int type; bool reformatted; char* data; }; aprsString *pHead, *pTail; int ItemCount; Mutex histMutex; Mutex dupMutex; int dumpAborts = 0; //--------------------------------------------------------------------- void CreateHistoryList() { pHead = NULL; pTail = NULL; ItemCount = 0; } //--------------------------------------------------------------------- //Adds aprs packet to history list //Returns true on success, false on failure bool AddHistoryItem(aprsString *hp) { Lock histLock(histMutex); if (hp == NULL) return false; if (pTail == NULL) { // Starting from empty list pTail = hp; pHead = hp; hp->next = NULL; hp->last = NULL; ItemCount++; } else { // List has at least one item in it. DeleteItem(hp); // Delete any previously stored items with same call and type if (ItemCount == 0) { // List is empty, put in first item pTail = hp; pHead = hp; hp->next = NULL; hp->last = NULL; } else { // list not empty... pTail->next = hp; // link the last item to us hp->last = pTail; // link us to last item hp->next = NULL; // link us to next item which is NULL pTail = hp; // link pTail to us } ItemCount++; } return true; } //--------------------------------------------------------------------- //Don't call this from anywhere except DeleteOldItems(). void DeleteHistoryItem(aprsString *hp) { if (hp == NULL) return; aprsString *li = hp->last; aprsString *ni = hp->next; if (hp != NULL) { if (li != NULL) li->next = ni; if (ni != NULL) ni->last = li; if (hp == pHead) pHead = ni; if (hp == pTail) pTail = li; delete hp; // Delete the aprsString object ItemCount--; // Reduce ItemCount by 1 } return; } //----------------------------------------------------------------------- //Call this once per 5 minutes //This reduces the ttl field by x then deletes items when the ttl field is zero or less. int DeleteOldItems(int x) { int delCount = 0; Lock histLock(histMutex); if ((pHead == NULL) || (pHead == pTail)) return 0; //empty list aprsString *hp = pHead; aprsString *pNext; while (hp) { hp->ttl = hp->ttl - x; //update time to live pNext = hp->next; if (hp->ttl <= 0 ) { DeleteHistoryItem(hp); delCount++; } hp = pNext; } return delCount; } //------------------------------------------------------------------------- //Deletes an aprsString object matching the ax25Source call sign and packet type // of the "ref" aprsString. The destination (destTNC or destINET) must also match. // pmtxHistory mutex must be locked when calling this. int DeleteItem(aprsString* ref) { int delCount = 0; if ((pHead == NULL) || (pHead == pTail) || (ref == NULL)) return 0; aprsString *hp = pHead; aprsString *pNext; while (hp != NULL) { pNext = hp->next; if ((hp->aprsType == ref->aprsType ) && (hp->dest == ref->dest)) { if (hp->ax25Source.compare(ref->ax25Source) == 0) { //cerr << "deleteing " << hp->getChar() << flush; DeleteHistoryItem(hp); delCount++ ; } } hp = pNext; } return delCount; } //------------------------------------------------------------------------- /* Check history list for a packet whose data matches that of "*ref" that was transmitted less or equal to "t" seconds ago. Returns true if duplicate exists. Scanning stops when a packet older than "t" seconds is found. */ /* bool DupCheck(aprsString* ref, time_t t) // Now obsolete and not used in version 2.1.2, June 2000 { int x = -1; bool z; time_t tNow,age; if (ref->allowdup) return false; if ((pTail == NULL) || (pHead == NULL)) return false; //Empty list pthread_mutex_lock(pmtxDupCheck); //Grab semaphore time(&tNow); //get current time aprsString *hp = pTail; //Point hp to last item in list age = tNow - hp->timestamp; while((hp != NULL) && (x != 0) && (age <= t)) { age = tNow - hp->timestamp; if((ref->ax25Source.compare(hp->ax25Source) == 0) && (ref->dest == hp->dest)) //check for matching call signs and destination (TNC or Internet) { if(ref->data.compare(hp->data) == 0) x = 0; //and matching data } hp = hp->last; //Go back in time through list //Usually less than 10 entrys need checking for 30 sec. } if (x == 0) z = true; else z = false; pthread_mutex_unlock(pmtxDupCheck); return z; } */ //-------------------------------------------------------------------------- //Scan history list for source callsign which exactly matches *cp . //If callsign is present and GATE* is not in the path and hops are 3 or less then return true //The code to scan for "GATE* and hops have been moved to aprsString.queryLocal() . bool StationLocal(const string& sp, int em) { bool retval = false; Lock histLock(histMutex); if ((pTail == NULL) || (pHead == NULL)) return retval; // Empty list if (ItemCount == 0) // if no data then... return retval; // ...return false aprsString *hp = pTail; // point to end of history list while ((!retval) && (hp != NULL)) { // Loop while no match and not at beginning of list if (hp->EchoMask & em) { if (hp->ax25Source.compare(sp) == 0) // Find the source call sign retval = hp->queryLocal(); // then see if it's local } hp = hp->last; } return retval; // return true or false } //------------------------------------------------------------------------ /* Returns number of stations in history list defined as "Local" */ int localCount() { int localCounter = 0; Lock histLock(histMutex); if ((pTail == NULL) || (pHead == NULL)) return 0; //Empty list if (ItemCount == 0) // if no data then... return 0; // ...return zero aprsString *hp = pTail; // point to end of history list while (hp != NULL) { // Go through the whole list if ( hp->queryLocal()) localCounter++; // Increment conter if local hp = hp->last; } return localCounter; // return number of local staitons } //------------------------------------------------------------------------ //Returns a new aprsString of the posit packet whose ax25 source call //matches the "call" arg and echomask bit matches a bit in "em". //Memory allocated for the returned aprsString must be deleted by the caller. aprsString* getPosit(const string& call, int em) { Lock histLock(histMutex); // create a semaphore object if ((pTail == NULL) || (pHead == NULL)) return NULL ; // Empty list aprsString* posit = NULL; if (ItemCount == 0) // if no data then... return NULL; // ...return NULL aprsString *hp = pTail; // point to end of history list while ((posit == NULL) && (hp != NULL)) { // Loop while no match and not at beginning of list if (hp->EchoMask & em) { if ((hp->ax25Source.compare(call) == 0) // Find the source call sign && ((hp->aprsType == APRSPOS) || hp->aprsType == NMEA)) { // of a posit packet posit = new aprsString(*hp); // make a copy of the packet } } hp = hp->last; } return posit; } //------------------------------------------------------------------------- /* timestamp the timeRF variable in an aprsString object in the history list given the objects serial number. Return true if object exists. */ bool timestamp(unsigned long sn, time_t t) { bool x = false; Lock histLock(histMutex); if ((pTail == NULL) || (pHead == NULL)) return false ; //Empty list if (ItemCount == 0) //if no data then... return false; // ...return false aprsString *hp = pTail; //point to end of history list while ((x == false) && (hp != NULL)) { //Loop while no match and not at beginning of list if (hp->ID == sn) { hp->timeRF = t; //time stamp it. x = true; //indicate we did it. } hp = hp->last; } return x; } //-------------------------------------------------------------------------- /* Deletes the history array and it's data created above */ void deleteHistoryArray(histRec* hr) { int i; if (hr) { int arraySize = hr[0].count; for (i = 0;itimestamp; hr[i].EchoMask = hp->EchoMask; hr[i].type = hp->aprsType; hr[i].reformatted = hp->reformatted; hr[i].data = strdup(hp->getChar()); //Allocate memory and copy data if (hr[i].data == NULL) { deleteHistoryArray(hr); //Abort if malloc fails return NULL; } if (hp->next == NULL) break; hp = hp->next; } return hr; } //-------------------------------------------------------------------------- //Send the history items to the user when he connects //returns number of history items sent or -1 if an error in sending occured int SendHistory(int session, int em) { int rc,count, i=0; int retrys; timespec ts; Lock histLock(histMutex, false); if (pHead == NULL) return 0; //Nothing to send histLock.get(); aprsString *hp = pHead; //Start at the beginning of list histRec* hr = createHistoryArray(hp); //copy it to an array histLock.release(); if (hr == NULL) return 0; int n = hr[0].count; // n has total number of items count = 0; //float throttle = 32; //Initial rate about 250kbaud (1/baud * 8 * 1e6) /* New smart rate throttle for history dump */ float maxspeed = 1e6/(MaxLoad - serverLoad); //This much BW remaining... if (maxspeed > 833) maxspeed = 833; // No slower than 9600 baud if (maxspeed < 32) maxspeed = 32; // No faster than 250k baud. float throttle = maxspeed; //Initial rate is MaxLoad - serverLoad bytes/sec for (i = 0; i < n; i++) { if ((hr[i].EchoMask & em) && (hr[i].reformatted == false)) { //filter data intended for this users port count++; //Count how many items we actually send size_t dlen = strlen(hr[i].data); retrys = 0; do { rc = send(session, (const void*)hr[i].data, dlen, 0); //Send history list item to client ts.tv_sec = 0; ts.tv_nsec = (int)throttle * dlen * 1000; //Delay time in nano seconds nanosleep(&ts, NULL); //pace ourself if (rc < 0) { ts.tv_sec = 1; ts.tv_nsec = 0; nanosleep(&ts, NULL); //Pause output 1 second if resource unavailable if (retrys == 0) { throttle = throttle * 2; } //cut our speed in half if (throttle > 833) throttle = 833; //Don't go slower than 9600 baud retrys++; } else if (throttle > maxspeed) throttle = throttle * 0.98; //Speed up 2% } while ((errno == EAGAIN) && (rc < 0) && ( retrys <= 180)); //Keep trying for 3 minutes if (rc < 0) { cerr << "send() error in SendHistory() errno= " << errno << " retrys= " << retrys << " \n[" << strerror(errno) << "]" << endl; deleteHistoryArray(hr); histLock.get(); dumpAborts++; histLock.release(); return -1; } } } deleteHistoryArray(hr); return count; } //--------------------------------------------------------------------- //Save history list to disk int SaveHistory(const string& name) { int icount = 0; Lock histLock(histMutex); if (pHead == NULL) return icount; ofstream hf(name.c_str()); // Open the output file if (hf.good()) { //if no open errors go ahead and write data aprsString *hp = pHead; for (;;) { if (hp->EchoMask){ //Save only items which have a bit set in EchoMask hf << hp->ttl << " " << hp->timestamp << " " << hp->EchoMask << " " << hp->aprsType << " " << hp->getChar() ; //write to file if (!hf.good()) { cerr << "Error writing " << SAVE_HISTORY << endl; break; } icount++; } if (hp->next == NULL) break; hp = hp->next; //go to next item in list } hf.close(); } return icount; } //--------------------------------------------------------------------- int ReadHistory(const string& name) { int icount = 0; int expiredCount = 0; int ttl,EchoMask,aprsType; char *data = new char[256]; time_t now,timestamp; ifstream hf(name.c_str()); // Create ifstream instance "hf" and open the input file if (hf.good()) { //if no open errors go ahead and read data now = time(NULL); while (hf.good() ) { hf >> ttl >> timestamp >> EchoMask >> aprsType; hf.get(); // skip 1 space hf.get(data, 252, '\r'); // read the rest of the line as a char string int i = strlen(data); data[i++] = '\r'; data[i++] = '\n'; data[i++] = '\0'; aprsString *hist = new aprsString(data); hist->EchoMask = EchoMask; hist->timestamp = timestamp; ttl = ttl - ((now - timestamp) / 60); //Adjust timep-to-live field if (ttl < 0) ttl = 0; hist->ttl = ttl; hist->aprsType = aprsType; //Now add to list only items which have NOT expired if (ttl > 0) { AddHistoryItem(hist); icount++; } else { delete hist; expiredCount++; } } hf.close(); } delete data; cout << "Read " << icount+expiredCount << " items from " << name << endl; if (expiredCount) cout << "Ignored " << expiredCount << " expired items in " << name << endl; return icount; } //------------------------------------------------------------------------------------- aprsd-2.2.5-13/src/history.h0000664000076400007640000000330607655343023011217 /* * $Id: history.h,v 1.6 2003/03/31 04:49:40 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #ifndef HISTORY_H #define HISTORY_H #include "aprsString.h" extern int dumpAborts; //Number of history dumps aborted extern int ItemCount; //number of items in History list void CreateHistoryList(); bool AddHistoryItem(aprsd::aprsString *hp); void DeleteHistoryItem(aprsd::aprsString *hp); int DeleteOldItems(int x); int DeleteItem(aprsd::aprsString* ref); bool DupCheck(aprsd::aprsString* ref, time_t t); int SendHistory(int session,int em); int SaveHistory(const std::string& name); int ReadHistory(const std::string& name); bool StationLocal(const std::string& sp, int em); aprsd::aprsString* getPosit(const std::string& call, int em); bool timestamp(unsigned long sn, time_t t); int localCount(); #endif // HISTORY_H aprsd-2.2.5-13/src/httpserver.cpp0000644000076400007640000006065207657351712012272 /* * $Id: httpserver.cpp,v 1.5 2003/05/11 04:38:34 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #include #include // send() #include // send() #include // close() #include #include #include #include #include "osdep.h" #include "servers.h" #include "mutex.h" #include "dupCheck.h" #include "cpqueue.h" #include "utils.h" #include "constant.h" #include "history.h" #include "serial.h" #include "aprsString.h" #include "validate.h" #include "queryResp.h" #include "aprsdexception.h" using namespace aprsd; typedef std::list StringList; void buildPage(StringList& htmlpage); string getCall(const string& sp) { string retval; int i; if ((i = sp.find("-")) < (int)sp.length()) retval = sp.substr(0, i); else retval = sp; retval += "*"; return retval; } string fixEmail(const string& sp) { string retval; int i; if ((i = sp.find("@")) < (int)sp.length()) { retval = sp.substr(0, i); retval += " at "; retval += sp.substr(i+1, sp.length()); } else retval = sp; return retval; } bool isAPRSD(const string& sp) { if ((unsigned)sp.compare("aprsd") < sp.length()) return true; else return false; } bool isJAVAAprsSrv(const string& sp) { if ((unsigned)sp.compare("javAPRS") < sp.length()) return true; else return false; } double convertRate(int rate) { double retval = 0; if (rate < 1000) retval = (double)rate; if (rate > 1000) retval = (((double)rate / 1000)); // Kb if (retval > 1000) retval = (retval / 1000); // Mb, is this possible? return retval; } string convertScale(int rate) { string retval; double value = 0; if (rate < 1000) { retval = " bits/sec"; return retval; } if (rate > 1000) { value = (((double)rate / 1000)); retval = " Kb/sec"; if (value > 1000) retval = " Mb/sec"; // is this possible? } return retval; } void buildPage(StringList& htmlpage) { //StringList htmlpage; time_t localtime; int i; char szTime[64]; struct tm *gmt = NULL; string xmode ; Lock countLock(pmtxCount, false); Lock addDelSessLock(pmtxAddDelSess, false); ostringstream stats; ostringstream igateheader; ostringstream userheader; ostringstream endpage; // streams to build page countLock.get(); webCounter++; gmt = new tm; time(&localtime); gmt = gmtime_r(&localtime,gmt); strftime(szTime,64,"%a, %d %b %Y %H:%M:%S GMT",gmt); // Date in RFC 1123 format delete gmt; char *szHdumps, *szMicE, *szTrace; if(History_ALLOW) szHdumps = "YES"; else szHdumps = "NO"; if(ConvertMicE) szMicE = "YES"; else szMicE = "NO"; if(traceMode) szTrace = "YES"; else szTrace = "NO"; stats << setiosflags(ios::showpoint | ios::fixed) << setprecision(1) << "HTTP/1.0 200 OK\n" << "Date: " << szTime << "\n" << "Server: aprsd\n" << "MIME-version: 1.0\n" << "Content-type: text/html\n" << "Expires: " << szTime << "\n" << "Refresh: 300\n" //uncomment to activate 5 minute refresh time << "\n" // Blank line terminates headers << "\n" << "\n" << "\n" << "" << szServerCall << " Server Status Report\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "" << "\n" << "" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" //<< "\n" << "\n"; if (tncPresent) { stats << "\n" << "\n"; } //<< "\n" stats << "\n" //<< "\n" //<< "\n" //<< "\n" << "\n" << "\n" << "\n"; if (tncPresent) { stats << "\n"; } stats << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" //<< "\n" //<< "\n" //<< "\n" //<< "\n" //<< "\n" << "\n" //<< "\n" //<< "\n" //<< "\n" //<< "\n" << "\n" << "\n" << "\n" << "\n" << "
" << "Server: " << szServerCall << " " << MyLocation //<< "
" << "Igate: " << MyCall << "
" << szTime << "
Server Up-Time" << convertUpTime(upTime) << "
Users" << getConnectedClients() << "
Peak Users" << MaxConnects << "
Max User Limit" << MaxClients << "
Max Server Load (Bps)" << MaxLoad << "
Connect Count" << TotalConnects << "
TNC Packets" << TotalLines << "
Pkts gated to RF" << msg_cnt << "
Local Count" << localCount() << "
Internet Packet Count" << countIGATED << "
NOGATE Pkts" << countNOGATE << "
LOOPED Pkts" << countLOOP << "
OVERSIZE Pkts" << countOVERSIZE << "
Dropped Packets" << countREJECTED << "
UDP Stream Rate" << convertRate(getStreamRate(STREAM_UDP)) << convertScale(getStreamRate(STREAM_UDP)) << "
Message Stream Rate" << convertRate(getStreamRate(STREAM_MSG)) << convertScale(getStreamRate(STREAM_MSG)) << "
TNC stream Rate" << getStreamRate(STREAM_TNC) << convertScale(getStreamRate(STREAM_TNC)) << "
User Stream Rate" << convertRate(getStreamRate(STREAM_USER)) << convertScale(getStreamRate(STREAM_USER)) << "
Server Stream Rate" << convertRate(getStreamRate(STREAM_SERVER)) << convertScale(getStreamRate(STREAM_SERVER)) << "
Full Stream Rate -dups" << convertRate(getStreamRate(STREAM_FULL)) << convertScale(getStreamRate(STREAM_FULL)) << "
Server Load" << convertRate(serverLoad) << convertScale(serverLoad) << "
AprsString Objects" << aprsString::getObjCount() << "
History Items" << ItemCount << "
History Time Limit" << ttlDefault << " min.
History dump aborts" << dumpAborts << "
History dumps allowed" << szHdumps << "
Mic-E conversions " << szMicE << "
Trace Internet Path " << szTrace << "
Items in Queue" << sendQueue.getItemsQueued() << "
Queue Overflows" << sendQueue.overrun << "
TncQ overflows" << tncQueue.overrun << "
ConQ overflows" << conQueue.overrun << "
charQ overflows" << charQueue.overrun << "
HTTP Access Counter" << webCounter << "
IGATE Queries" << queryCounter << "
Server Version" << VERS << "
Sysop email" << fixEmail(MyEmail) << "

\n"; countLock.release(); htmlpage.push_back(stats.str()); igateheader << "" << "\n" << "\n" << "\n" << "\n"; htmlpage.push_back(igateheader.str()); countLock.get(); for (i = 0; i < nIGATES; i++) { if (cpIGATE[i].RemoteSocket != -1) { char timeStr[32]; strElapsedTime(cpIGATE[i].starttime,timeStr); // Compute elapsed time of connection char lastActiveTime[32]; strElapsedTime(cpIGATE[i].lastActive,lastActiveTime); // Compute time since last input char ostringstream igateinfo; //char *status, *bgcolor, *conType; string status, bgcolor, conType; if (cpIGATE[i].hub) { if (cpIGATE[i].connected) { status = "UP"; bgcolor = "\"#C0C0C0\""; } else { status = "N/C" ; bgcolor = "\"#909090\""; } conType = "HUB"; } else { if (cpIGATE[i].connected) { status = "UP"; bgcolor = "\"#C0C0C0\""; } else { status = "DOWN" ; bgcolor = "\"#909090\""; } conType = "SERVER"; } xmode = ""; if (cpIGATE[i].mode == MODE_RECV_ONLY) xmode = "-RO"; if (cpIGATE[i].mode == MODE_RECV_SEND) xmode = "-SR"; string infoTokens[3]; infoTokens[1] = "*"; infoTokens[2] = ""; int ntok = 0; if (cpIGATE[i].remoteIgateInfo.length() > 0) { string rii(cpIGATE[i].remoteIgateInfo); if (rii[0] == '#') { ntok = split(rii, infoTokens, 3, RXwhite); // Parse into tokens if first char was "#". } // Token 1 is remote igate program name and token 2 is the version number. } igateinfo << ""; else igateinfo << cpIGATE[i].RemoteName << ""; igateinfo << "" << "" << "" << "" << "" << "" << "" << "" << "" //<< "" << "\n"; htmlpage.push_back(igateinfo.str()); } } countLock.release(); userheader << "
Server Connections
Domain NameHex IP
Alias
PortTypeStatusIgate PgmLast active
H:M:S
Bytes
In
Bytes
Out
Time
H:M:S
"; // See if this client/server supports a status page if (isAPRSD(infoTokens[1]) || isJAVAAprsSrv(infoTokens[1])) igateinfo << "" << cpIGATE[i].RemoteName << "" << cpIGATE[i].alias << "" << cpIGATE[i].RemoteSocket << "" << conType << xmode << "" << status << "" << infoTokens[1] << " " << infoTokens[2] << "" << lastActiveTime << "" << cpIGATE[i].bytesIn / 1024 << " K" << cpIGATE[i].bytesOut / 1024 << " K" << timeStr << "" << cpIGATE[i].pid << "

\n" << "" // Start of user list table << "\n" << "\n" << "" << "\n"; htmlpage.push_back(userheader.str()); addDelSessLock.get(); countLock.get(); string TszPeer; string TserverPort; string TuserCall; string TpgmVers; string TlastActive; string TtimeStr; int bytesout = 0; int bytesin = 0; int npid = -1; for (i = 0; i < MaxClients; i++) { // Create html table with user information if ((sessions[i].Socket != -1) && (sessions[i].ServerPort != -1)){ char timeStr[32]; strElapsedTime(sessions[i].starttime, timeStr); // Compute elapsed time char lastActiveTime[32]; strElapsedTime(sessions[i].lastActive, lastActiveTime); // Compute elapsed time from last input char string szVrfy; TszPeer = sessions[i].szPeer; TuserCall = sessions[i].userCall; TpgmVers = sessions[i].pgmVers; TlastActive = lastActiveTime; TtimeStr = timeStr; removeHTML(TszPeer); removeHTML(TuserCall); removeHTML(TpgmVers); removeHTML(TlastActive); removeHTML(TtimeStr); if (sessions[i].vrfy) szVrfy = "YES"; else szVrfy = "NO"; if (sessions[i].bytesOut > 0) bytesout = (sessions[i].bytesOut / 1024); if (sessions[i].bytesIn > 0) bytesin = (sessions[i].bytesIn / 1024); if (sessions[i].pid > 0) npid = sessions[i].pid; ostringstream userinfo; userinfo << ""; else userinfo << TszPeer << ""; //<< "" userinfo << "" << "" << "" << "" << "" << "" << "" << "" //<< "" << "" << endl; htmlpage.push_back(userinfo.str()); } //End of if() } //End of for() countLock.release(); addDelSessLock.release(); endpage << "
Client Connections
IP AddressPortCallVrfyProgram VersLast Active
H:M:S
Bytes
In
Bytes
Out
Time
H:M:S
"; if (isAPRSD(TpgmVers) || isJAVAAprsSrv(TpgmVers)) userinfo << "" << TszPeer << "" << sessions[i].ServerPort << "" << sessions[i].ServerPort << "" << "" << TuserCall << "" << "" << szVrfy << "" << TpgmVers << "" << TlastActive << "" << bytesin << " K" << bytesout << " K" << TtimeStr << "" << npid << "
\n\n"; htmlpage.push_back(endpage.str()); //return htmlpage; } //---------------------------------------------------------------------- void buildPortInfoPage(list& htmlpage, const string& arg) { time_t localtime; unsigned idx,i; char szTime[64]; struct tm *gmt = NULL; long sNum = 0; char *endptr; gmt = new tm; Lock addDelSessLock(pmtxAddDelSess, false); ostringstream stats, endpage; time(&localtime); gmt = gmtime_r(&localtime,gmt); strftime(szTime,64,"%a, %d %b %Y %H:%M:%S GMT",gmt); // Date in RFC 1123 format delete gmt; idx = arg.find_last_of("."); if (idx != string::npos){ string snum = arg.substr(idx+1); //Get session number in ascii form. sNum = strtol(snum.c_str(),&endptr,10); if((sNum == 0) && (endptr == snum.c_str())) return; if((sNum >= MaxClients) || (sNum < 0)) return; } addDelSessLock.get(); if ((sessions[sNum].Socket == -1) || (sessions[sNum].ServerPort == -1)) {//No such session? addDelSessLock.release(); return; } unsigned nBits = (sizeof(echomask_t) * 8); //Number of bits in the EchoMask char emb[nBits + 1]; for (i = 0; i < nBits; i++) { if (sessions[sNum].EchoMask & (1 << i)) emb[i] = '1'; else emb[i] = '0'; } emb[i] = '\0'; char* name[nBits]; name[0] = "Local TNC"; name[1] = "User"; name[2] = "Validated User"; name[3] = "Server/Hub"; name[4] = "System Msgs"; name[5] = "UDP Port"; name[6] = "History List"; name[7] = "All Messages"; name[8] = "Server Stats"; name[9] = "Server Beacon"; name[10]= "Rejected Pkts"; name[11]= "Source Header"; name[12]= "HTML"; name[13]= "Raw"; name[14]= "Duplicates"; name[15]= "History"; name[16]= "Echo"; name[17]= NULL; string TszServerCall = szServerCall; removeHTML(TszServerCall); string TuserCall = sessions[sNum].userCall; removeHTML(TuserCall); i = 0; string emStr = ""; string color; while (name[i]) { if (emb[i] == '1') color = ""; else color = ""; emStr = emStr + color + "" + name[i] + "" + emb[i] + "\n"; i++; } stats << setiosflags(ios::showpoint | ios::fixed) << setprecision(1) << "HTTP/1.0 200 OK\n" << "Date: " << szTime << "\n" << "Server: aprsd\n" << "MIME-version: 1.0\n" << "Content-type: text/html\n" << "Expires: " << szTime << "\n" << "\n" //Blank line terminates headers << "\n" << "" << "" << TszServerCall << " User Stream Filter Info\n" << "\n" << "\n" << "
" << "

" << "" << "\n" << "" << "\n" //<< "" << emStr; addDelSessLock.release(); htmlpage.push_back(stats.str()); endpage << "
Port Filter
User: " << TuserCall << "
Port: " << sessions[sNum].ServerPort << "
" << emb << "

"; htmlpage.push_back(endpage.str()); return; } /* Thread to process http request for server status data */ void *HTTPServerThread(void *p) { unsigned idx, i; char buf[BUFSIZE]; SessionParams *psp = (SessionParams*)p; int sock = psp->Socket; delete psp; int page_select; char szError[MAX]; int n, rc,data; int err,nTokens; if (sock < 0) pthread_exit(0); data = 1; // Set socket for non-blocking ioctl(sock,FIONBIO, (char*)&data, sizeof(int)); rc = recvline(sock, buf, BUFSIZE, &err, 10); //10 sec timeout value if (rc<=0) { close(sock); pthread_exit(0); } string sLine(buf); string token[4]; nTokens = split(sLine, token, 4, RXwhite); // Parse http request into tokens char buf2[127]; do { n = recvline(sock,buf2,126,&err, 1); // Discard everything else } while (n > 0); if (n == -2) { close(sock); pthread_exit(0); } page_select = 0; idx = 0; if ((token[0].compare("GET") == 0) && (token[1].find("/portinfo.") != string::npos)) page_select = 2; if ((token[0].compare("GET") == 0) && (token[1].compare("/") == 0)) page_select = 1; list html2send; /* Assemble page based on value of page_select variable */ switch (page_select) { case 1: buildPage(html2send); idx = html2send.size(); break; case 2: buildPortInfoPage(html2send, token[1]); idx = html2send.size(); break; } //Now read fully assembled web page from html2send and send to the tcpip socket. if (idx > 0) { data = 0; // Set socket for blocking ioctl(sock, FIONBIO, (char*)&data, sizeof(int)); rc = 1; i = 0; list::iterator it = html2send.begin(); while ((rc > 0) && (it != html2send.end())) { //cout << *it << endl; string as = *it; rc = send(sock, as.c_str(), as.size(), 0); it++; } } else { //Error if page failed to assemble strcpy(szError,"HTTP/1.0 404 Not Found\nContent-Type: text/html\n\nUnable to process request\n"); send(sock, szError, strlen(szError), 0); } close(sock); pthread_exit(0); return NULL; //To keep g++ and RH-7.x happy. } aprsd-2.2.5-13/src/httppage.h0000664000076400007640000000003407655343023011325 class httpPage { }; aprsd-2.2.5-13/src/mic_e.cpp0000664000076400007640000003205007655343024011124 /* * $Id: mic_e.cpp,v 1.11 2003/03/31 04:49:40 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #include #include #include #include #include #include "constant.h" #include "mic_e.h" using namespace std; static char *msgname[] = { "EMERGENCY.", "PRIORITY..", "Special...", "Committed.", "Returning.", "In Service", "Enroute...", "Off duty..", " ", "Custom-6..", "Custom-5..", "Custom-4..", "Custom-3..", "Custom-2..", "Custom-1..", "Custom-0.." }; bool ConvertMicE = false; //Set TRUE causes Mic-E pkts to be converted // to classic APRS pkts. /* Latitude digit lookup table based on APRS Protocol Spec 1.0, page 42 */ static char lattb[] = "0123456789 0123456789 0123456789 " ; /* if this function fails to convert the packet it returns ZERO and the user supplied length variables, l1 and l2 are zero. Otherwise it returns non-zero values. */ int fmt_mic_e(const u_char *t, /* tocall */ const u_char *i, /* info */ const int l, /* length of info */ u_char *buf1, /* output buffer */ int *l1, /* length of output buffer */ u_char *buf2, /* 2nd output buffer */ int *l2, /* length of 2nd output buffer */ time_t tick) /* received timestamp of the packet */ { u_int msg,sp,dc,se,spd,cse; char north, west,c; int lon1,lonDD,lonMM,lonHH; char *bp; enum {none=0, BETA, REV1} rev = none; /* mic_e revision level */ int gps_valid = 0; char symtbl = '/', symbol = '$', adti = '!'; int buf2_n = 0; char lat[6]; int x; unsigned lx; char msgclass; int trash = 0; /* Try to avoid conversion of bogus packets */ if ( l > 255) return 0; /* info field must be less than 256 bytes long */ if (strlen((char*)t) != 6) return 0; /* AX25 dest addr must be 6 bytes long. */ for (x = 0; x < 6; x++) { c = t[x]; /* search for invalid characters in the ax25 destination */ if ((c < '0') /* Nothing below zero */ || (c > 'Z') /* Nothing above 'Z' */ || (c == 'M') /* M,N,O not allowed */ || (c == 'N') || (c == 'O')) trash |= 1 ; if ((c > '9') && (c < 'A')) trash |= 2; /* symbols :;<>?@ are invalid */ if ((x >= 3) && (c >= 'A') && (c <= 'K')) trash |= 4; /* A-K not allowed in last 3 bytes */ } for (x = 1; x < 7; x++) { if ((i[x] < 0x1c) || (i[x] > 0x7f)) trash |= 8; // Range check the longitude and speed/course } //printf("Trash=%d %s %s \n",trash, t, i); //Debug if (trash) return 0; /* exit without converting packet if it's malformed */ *l1 = *l2 = 0; /* This switch statement processes the 1st information field byte, byte 0 */ switch (i[0]) { /* possible valid MIC-E flags */ case 0x60: /* ` Current GPS data (not used in Kenwood TM-D700) */ gps_valid = 1; rev = REV1; if (l < 9) return 0; /* reject packet if less than 9 bytes */ break; case 0x27: /* ' Old GPS data or Current data in Kenwood TM-D700 */ gps_valid = 0; rev = REV1; if (l < 9) return 0; /* reject packet if less than 9 bytes */ break; case 0x1c: /* Rev 0 beta units current GPS data */ gps_valid = 1; rev = BETA; if (l < 8) return 0; /* reject packet if less than 8 bytes */ break; case 0x1d: /* Rev 0 beta units old GPS data */ gps_valid = 0; rev = BETA; if (l < 8) return 0; /* reject packet if less than 8 bytes */ break; default: return 0; /* Don't attempt to process a packet that's not a Mic-E type */ } if ((i[9] == ']') || (i[9] == '>')) adti = '='; /* Kenwood with messaging detected */ if (l >= 7 ) { /* <-- old beta units could have only 7 bytes, new units should have 9 or more bytes */ msg = ((t[0] >= 'P')?4:0) | ((t[1] >= 'P')?2:0) | ((t[2] >= 'P')?1:0); //Standard messages 0..7 if (msg == 0) { msg = (((t[0] >= 'A') && (t[0] < 'L'))?0xC:0) //Custom messages 9..15 | (((t[1] >= 'A') && (t[1] < 'L'))?0xA:0) | (((t[2] >= 'A') && (t[2] < 'L'))?9:0); } msg &= 0xf; /* make absolutly sure we don't exceed the array bounds */ msgclass = (msg > 7) ? 'C':'M'; /* Message class is either standard=M or custom=C */ /* Recover the latitude digits from the ax25 destination field */ for (x=0;x<6;x++) { lx = t[x] - '0'; //subtract offset from raw latitude character if ((lx >= 0 ) && ( lx < strlen(lattb))) { lat[x] = lattb[lx]; /* Latitude output digits into lat[] array */ } else lat[x] = ' '; } if (lat[0] == '9') { if((lat[1] != '0') //reject lat degrees > 90 degrees || (lat[2] != '0') || (lat[3] != '0') || (lat[4] != '0') || (lat[5] != '0')) return 0; } if (lat[2] > '5') return 0; //reject lat minutes >= 60 if ((lat[0] == ' ') || (lat[1] == ' ')) return 0; //Reject ambiguious degrees north = t[3] >= 'P' ? 'N':'S'; west = t[5] >= 'P' ? 'W':'E'; lon1 = t[4] >= 'P' ; /* +100 deg offset */ /* Process info field bytes 1 through 6; the Longitude, speed and course bits */ lonDD = i[1] - 28; lonMM = i[2] - 28; lonHH = i[3] - 28; #ifdef DEBUG fprintf(stderr,"raw lon 0x%02x(%d) 0x%02x(%d) 0x%02x(%d) 0x%02x(%d)\n", i[1],i[1],i[2],i[2],i[3],i[3],i[4],i[4]); fprintf(stderr,"before: lonDD=%d, lonMM=%d, lonHH=%d lon1=0x%0x\n",lonDD,lonMM,lonHH,lon1); #endif if (rev >= REV1) { if (lon1) /* do this first? */ lonDD += 100; if (180 <= lonDD && lonDD <= 189) lonDD -= 80; if (190 <= lonDD && lonDD <= 199) lonDD -= 190; if (lonMM >= 60) lonMM -= 60; } #ifdef DEBUG fprintf(stderr,"after: lonDD=%d, lonMM=%d, lonHH=%d lon1=0x%0x\n",lonDD,lonMM,lonHH,lon1); #endif sp = i[4] - 28; dc = i[5] - 28; se = i[6] - 28; buf2_n = 6; /* keep track of where we are */ #ifdef DEBUG fprintf(stderr,"sp=%02x dc==%02x se=%02x\n",sp,dc,se); #endif spd = sp*10+dc/10; cse = (dc%10)*100+se; if (rev >= REV1) { if (spd >= 800) spd -= 800; if (cse >= 400) cse -= 400; } if (cse > 360) return 0; // Reject invalid course value if (spd > 999) return 0; // reject invalid speed value #ifdef DEBUG fprintf(stderr,"symbol=0x%02x, symtbl=0x%02x\n",i[7],i[8]); #endif /* Process information field bytes 7 and 8 (Symbol Code and Sym Table ID) */ symtbl = (l >= 8 && rev >= REV1)? i[8] : '/'; /* rev1 bug workaround: sends null symbol/table bytes */ symbol = i[7]; if (!isprint(symbol)) return 0; /* Reject packet if invalid symbol code */ if ((symtbl != '/' && symtbl != '\\') && !('0' <= symtbl && symtbl <= '9') && !('a' <= symtbl && symtbl <= 'j') && !('A' <= symtbl && symtbl <= 'Z') && (symtbl != '*' && symtbl != '!')) { //printf("Bad symtbl code = %c\n",symtbl); //Debug return 0; /* Reject packet if invalid symtbl code */ } buf2_n = (rev == BETA)?8:9; if (l >= 10) { buf2_n = (rev == BETA)?8:9; switch (i[buf2_n]) { case 0x60: /* two-channel telemetry (Hex data)*/ sprintf((char*)buf2,"T#MIC,%03d,%03d", hex2i(i[buf2_n+1],i[buf2_n+2]), hex2i(i[buf2_n+3],i[buf2_n+4])); buf2_n += 5; *l2 = strlen((char*)buf2); break; case 0x27: /* five-channel telemetry (Hex data)*/ sprintf((char*)buf2,"T#MIC,%03d,%03d,%03d,%03d,%03d", hex2i(i[buf2_n+1],i[buf2_n+2]), hex2i(i[buf2_n+3],i[buf2_n+4]), hex2i(i[buf2_n+5],i[buf2_n+6]), hex2i(i[buf2_n+7],i[buf2_n+8]), hex2i(i[buf2_n+9],i[buf2_n+10])); buf2_n += 11; *l2 = strlen((char*)buf2); break; case 0x1d: /* five-channel telemetry (This works only if the input device supports raw binary data)*/ sprintf((char*)buf2,"T#MIC,%03d,%03d,%03d,%03d,%03d", i[buf2_n+1],i[buf2_n+2],i[buf2_n+3],i[buf2_n+4],i[buf2_n+5]); buf2_n += 6; *l2 = strlen((char*)buf2); break; default: break; /* no telemetry */ } /* end switch */ } /* This sprintf statement creates the output string */ sprintf((char*)buf1,"%c%c%c%c%c.%c%c%c%c%03d%02d.%02d%c%c%03d/%03d/Mic-E/%c%d/%s", adti, lat[0],lat[1],lat[2],lat[3],lat[4],lat[5], north,symtbl, lonDD,lonMM,lonHH, west, symbol, cse,spd, msgclass, ~msg&0x7, msgname[msg]); bp = (char*)&buf1[(*l1 = strlen((char*)buf1))]; if (buf2_n < l) { /* additional comments/btext */ *bp++ = ' '; /* add a space */ (*l1)++; memcpy(bp,&i[buf2_n],l-buf2_n); *l1 += l-buf2_n; } } // printf("buf2_n = %d l=%d %s\n",buf2_n,l,buf1); return ((*l1>0)+(*l2>0)); } /* The following is not used by aprsd */ /* * here's another APRS device that get's mistreated by some APRS * implementations: A TNC2 running TheNet X1J4. * * 1 2 * 1234567890123456789012 * TheNet X-1J4 (RELAY) */ static u_char x1j4prefix[] = "TheNet X-1J4"; #define MINX1J4LEN 14 /* min length w/TheNet X1J4 prefix */ #define MAXX1J4LEN 22 /* max length w/(alias) */ int fmt_x1j4(const u_char *t, /* tocall */ const u_char *i, /* info */ const int l, /* length of info */ u_char *buf1, /* output buffer */ int *l1, /* length of output buffer */ u_char *buf2, /* 2nd output buffer */ int *l2, /* length of 2nd output buffer */ time_t tick) /* received timestamp of the packet */ { const u_char *cp; *l1 = *l2 = 0; if (l < MINX1J4LEN || memcmp(i,x1j4prefix,sizeof(x1j4prefix)-1) != 0) return 0; /* it's a TheNet beacon: either has ()'s w/alias name or no ()'s and the btext starts after some white space! */ cp = (u_char*)memchr(&i[MINX1J4LEN],')',MAXX1J4LEN-MINX1J4LEN); if (cp == NULL) /* no parens (no alias call) */ cp = &i[MINX1J4LEN]; else cp++; /* skip over the ) */ while (cp <= &i[l-1] && *cp == ' ') cp++; /* skip blanks */ memcpy(buf1,cp,*l1=&i[l-1]-cp); return 1; } /*------------------------------------------------------------------------*/ unsigned int hex2i(u_char a,u_char b) { unsigned int r = 0; if (a >= '0' && a <= '9') { r = (a-'0') << 4; } else if (a >= 'A' && a <= 'F') { r = (a-'A'+10) << 4; } if (b >= '0' && b <= '9') { r += (b-'0'); } else if (b >= 'A' && b <= 'F') { r += (b-'A'+10); } return r; } /*------------------------------END---------------------------------------------*/ aprsd-2.2.5-13/src/mic_e.h0000664000076400007640000000404107655343025010571 /* * $Id: mic_e.h,v 1.5 2003/03/31 04:49:40 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #ifndef MIC_E_H #define MIC_E_H #ifndef u_char #define u_char unsigned char #endif extern bool ConvertMicE; unsigned int hex2i(u_char,u_char); int fmt_mic_e(const u_char *t, // tocall const u_char *i, // info const int l, // length of info u_char *buf1, // output buffer int *l1, // length of output buffer u_char *buf2, // 2nd output buffer int *l2, // length of 2nd output buffer time_t tick); // received timestamp of the packet int fmt_x1j4(const u_char *t, // tocall const u_char *i, // info const int l, // length of info u_char *buf1, // output buffer int *l1, // length of output buffer u_char *buf2, // 2nd output buffer int *l2, // length of 2nd output buffer time_t tick); // received timestamp of the packet #endif // MIC_E_H aprsd-2.2.5-13/src/mutex.cpp0000664000076400007640000001761207655343025011222 /* * $Id: mutex.cpp,v 1.5 2003/04/20 18:34:47 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #include "aprsdassert.h" #include "aprsdexception.h" #include "mutex.h" #include #include #include namespace aprsd { using namespace std; /* This is an internal class that maintail a list of all allocated mutexes to keep track of them, if a fork or popen function will be called to make it possible to lock and unlock all at ones, for the fock process to succed. Im still not sure this is the way to do this, and I really like to eliminate the use of fork anyware in nb++, but just in case :-) */ class MutexManager { typedef list mutexes_t; mutexes_t m_mutexes; pthread_mutex_t m_mutex; pthread_mutexattr_t m_mutexAttr; static MutexManager *m_pManager; MutexManager() { reg_funcs(); pthread_mutexattr_init( &m_mutexAttr ); pthread_mutex_init( &m_mutex, &m_mutexAttr ); } ~MutexManager() { pthread_mutex_destroy( &m_mutex ); pthread_mutexattr_destroy( &m_mutexAttr ); } void reg_funcs( void ); public: static MutexManager &getInst( void ) { if( !m_pManager ) m_pManager = new MutexManager(); return *m_pManager; } void add( pthread_mutex_t &mutex ) { pthread_mutex_lock( &m_mutex ); m_mutexes.push_back( &mutex ); pthread_mutex_unlock( &m_mutex ); } void remove( pthread_mutex_t &mutex ) { pthread_mutex_lock( &m_mutex ); mutexes_t::iterator i = find( m_mutexes.begin(), m_mutexes.end(), &mutex ); if (i != m_mutexes.end()) m_mutexes.erase(i); pthread_mutex_unlock(&m_mutex); } void initAll(void) { pthread_mutex_lock(&m_mutex); // cout << "Init all " << m_mutexes.size() << endl; mutexes_t::iterator i; for (i = m_mutexes.begin(); i != m_mutexes.end(); i++ ) ::pthread_mutex_init(*i, NULL); pthread_mutex_unlock(&m_mutex); } void lockAll(void) { pthread_mutex_lock(&m_mutex); // cout << "Lock all " << m_mutexes.size() << endl; mutexes_t::iterator i; for (i = m_mutexes.begin(); i != m_mutexes.end(); i++) ::pthread_mutex_lock(*i); pthread_mutex_unlock(&m_mutex); } void releaseAll(void) { pthread_mutex_lock(&m_mutex); // cout << "Release all " << m_mutexes.size() << endl; mutexes_t::iterator i; for (i = m_mutexes.begin(); i != m_mutexes.end(); i++) ::pthread_mutex_unlock(*i); pthread_mutex_unlock(&m_mutex); } }; void mutex_init_prepare(void) { } void mutex_init_parent(void) { } void mutex_init_child(void) { MutexManager::getInst().initAll(); } MutexManager *MutexManager::m_pManager = NULL; void MutexManager::reg_funcs(void) { int res = ::pthread_atfork(mutex_init_prepare, mutex_init_parent, mutex_init_child); assert(res == 0); } //////////////////// // Impl. of Mutex Mutex::Mutex() throw(AssertException, exception) { pthread_mutexattr_init(&m_mutexAttr); pthread_mutex_init(&m_mutex, &m_mutexAttr); pthread_condattr_init(&m_condAttr); pthread_cond_init(&m_cond, &m_condAttr); // MutexManager::getInst().add( m_mutex ); } Mutex::~Mutex() throw() { // MutexManager::getInst().remove( m_mutex ); pthread_mutexattr_destroy(&m_mutexAttr); pthread_mutex_destroy(&m_mutex); pthread_condattr_destroy(&m_condAttr); pthread_cond_destroy(&m_cond); } void Mutex::lock() throw(AssertException, exception) { pthread_mutex_lock(&m_mutex); } void Mutex::unlock() throw(AssertException, exception) { pthread_mutex_unlock(&m_mutex); } void Mutex::wait() throw(AssertException, exception) { pthread_cond_wait(&m_cond, &m_mutex); } void Mutex::notify() throw(AssertException, exception) { pthread_cond_signal(&m_cond); } void Mutex::notifyAll() throw(AssertException, exception) { pthread_cond_broadcast(&m_cond); } ///////////////////////////// // Impl. of RecursiveMutex RecursiveMutex::RecursiveMutex() throw(AssertException, exception) : m_lockCount(0) { } RecursiveMutex::~RecursiveMutex() throw() { } void RecursiveMutex::lock() throw(AssertException, exception) { if (!m_lockCount || !pthread_equal(m_owner, pthread_self())) { Mutex::lock(); m_owner = pthread_self(); } ++m_lockCount; } void RecursiveMutex::unlock() throw(AssertException, exception) { DEBUG(Assert(m_lockCount > 0, AssertException("aprsd::RecursiveMutex::unlock(): " "mutex already unlocked"))); DEBUG(Assert(pthread_equal(m_owner, pthread_self()), AssertException("aprsd::RecursiveMutex::unlock(): " "mutex locked by another thread"))); if (--m_lockCount == 0) Mutex::unlock(); } void RecursiveMutex::wait() throw(AssertException, exception) { unsigned int saveCount = m_lockCount; m_lockCount = 0; Mutex::wait(); m_owner = pthread_self(); m_lockCount = saveCount; } Lock::Lock(Mutex& arg_mutex, bool autoLock) throw(AssertException, exception) : m_mutex(arg_mutex), m_locked(false) { if ( autoLock ) get(); } Lock::~Lock() throw() { try { release(); } catch (...) { } } void Lock::get() throw(AssertException, exception) { if (!m_locked) { m_mutex.lock(); m_locked = true; } } void Lock::release() throw(AssertException, exception) { if (m_locked) { m_mutex.unlock(); m_locked = false; } } void Lock::wait() throw(AssertException, exception) { DEBUG(Assert(m_locked, AssertException("aprsd::Lock::wait(): " "wait on unlocked mutex"))); m_mutex.wait(); } void Lock::notify() throw(AssertException, exception) { DEBUG(Assert(m_locked, AssertException("aprsd::Lock::notify(): " "notify on unlocked mutex"))); m_mutex.notify(); } void Lock::notifyAll() throw(AssertException, exception) { DEBUG(Assert(m_locked, AssertException("nbpp::Lock::notifyAll(): " "notifyAll on unlocked mutex"))); m_mutex.notifyAll(); } } aprsd-2.2.5-13/src/mutex.h0000664000076400007640000001430207655343025010660 /* * $Id: mutex.h,v 1.4 2003/04/20 18:34:47 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #ifndef MUTEX_H #define MUTEX_H extern "C" { #include } #include "aprsdexception.h" #include "osdep.h" namespace aprsd { class Lock; /** * A fast mutex for synchronizing non-recursive methods. Use a Lock to lock and * unlock a Mutex. Use a RecursiveMutex if you need to be able to lock a mutex * more than once before unlocking it. * * This class is not reference-counted; each instance is intended to be * encapsulated as a member variable by the object that uses it. * */ class Mutex { public: /** * Constructs a Mutex. */ Mutex() throw(AssertException, exception); /** * Destructor. */ virtual ~Mutex() throw(); protected: virtual void lock() throw(AssertException, exception); virtual void unlock() throw(AssertException, exception); virtual void wait() throw(AssertException, exception); private: Mutex(const Mutex&); Mutex& operator=(const Mutex&); void notify() throw(AssertException, exception); void notifyAll() throw(AssertException, exception); pthread_mutex_t m_mutex; pthread_mutexattr_t m_mutexAttr; pthread_cond_t m_cond; pthread_condattr_t m_condAttr; friend class Lock; }; /** * A mutex for synchronizing recursive methods. Use a Lock to lock and unlock a * RecursiveMutex. * * If a locked RecursiveMutex is locked again by the same thread, * its lock count is incremented. If it unlocked by the same * thread, its lock count is decremented. When its lock count * reaches 0, it is unlocked. * * This class is not reference-counted; each instance is intended to be * encapsulated as a member variable by the object that uses it. * */ class RecursiveMutex : public Mutex { public: /** * Constructs a RecursiveMutex. */ RecursiveMutex() throw(AssertException, exception); /** * Destructor. */ virtual ~RecursiveMutex() throw(); protected: virtual void lock() throw(AssertException, exception); virtual void unlock() throw(AssertException, exception); virtual void wait() throw(AssertException, exception); private: RecursiveMutex(const RecursiveMutex&); RecursiveMutex& operator=(const RecursiveMutex&); unsigned int m_lockCount; pthread_t m_owner; }; /** * When constructed, this object acquires (by default) an * exclusive lock from the Mutex passed to it in its constructor. * When the object goes out of scope, it releases the lock. This * makes it convenient to synchronize whole methods, because the * lock will be released even if an exception is thrown. For * example: * * class Foo * { * public: * void bar() * { * Lock lock(mutex); * // do some stuff that could throw exceptions... * } * * private: * Mutex mutex; * }; * * This class is not reference-counted; each instance is intended to be * encapsulated by one method, as a local variable. * */ class Lock { public: /** * By default, gets the Mutex's lock. */ Lock(Mutex& mutex, bool autoLock = true) throw(AssertException, exception); /** * Releases the Mutex's lock. Does nothing if this Lock is * not holding the lock. */ ~Lock() throw(); /** * Gets the Mutex's lock. Does nothing if this Lock is * already holding the lock. */ void get() throw(AssertException, exception); /** * Releases the Mutex's lock. Does nothing if this Lock is * not holding the lock. */ void release() throw(AssertException, exception); /** * Waits for another thread to call notify() or notifyAll() on * a Lock for the same Mutex. The calling thread must already * have the lock. * * exception AssertException if NDEBUG was not defined when * this class was compiled, and the calling thread does not * have the lock. * */ void wait() throw(AssertException, exception); /** * Notifies one thread waiting for this mutex. The calling * thread must already have the lock. * * exception AssertException AssertException if NDEBUG was not defined when this * class was compiled, and the calling thread does not have the lock. * */ void notify() throw(AssertException, exception); /** * Notifies all threads waiting for this mutex. The calling * thread must already have the lock. * * exception AssertException AssertException if NDEBUG was not defined when this * class was compiled, and the calling thread does not have the lock. * */ void notifyAll() throw(AssertException, exception); private: Lock(); Lock(const Lock&); Lock& operator=(Lock&); Mutex& m_mutex; bool m_locked; }; } #endif // MUTEX_H aprsd-2.2.5-13/src/osdep.cpp0000664000076400007640000000517107655343025011167 /* * $Id: osdep.cpp,v 1.3 2003/03/31 04:49:40 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #include "mutex.h" #include "osdep.h" namespace aprsd { string hstrerror_r(int ERRNUM) { static Mutex mutex; Lock lock (mutex); #ifdef HAVE_HSTRERROR return ::hstrerror (ERRNUM); #else /* !HAVE_HSTRERROR */ switch (ERRNUM) { case 0: return "Success."; case HOST_NOT_FOUND: return "The specified host is unknown."; case NO_ADDRESS: #if NO_ADDRESS != NO_DATA case NO_DATA: #endif // NO_ADDRESS != NO_DATA return "The requested name is valid but does not have an IP address."; case NO_RECOVERY: return "A non-recoverable name server error occurred."; case TRY_AGAIN: return "A temporary error occurred on an authoritative name server. " "Try again later."; } return "Unknown error number at hstrerror_r."; #endif/* !HAVE_HSTRERROR */ } void reliable_usleep (int usecs) { timeval now, end; gettimeofday (&now, NULL); end = now; end.tv_sec += usecs / 1000000; end.tv_usec += usecs % 1000000; while ((now.tv_sec < end.tv_sec) || ((now.tv_sec == end.tv_sec) && (now.tv_usec < end.tv_usec))) { timeval tv; tv.tv_sec = end.tv_sec - now.tv_sec; if (end.tv_usec >= now.tv_usec) tv.tv_usec = end.tv_usec - now.tv_usec; else { tv.tv_sec--; tv.tv_usec = 1000000 + end.tv_usec - now.tv_usec; } select (0, NULL, NULL, NULL, &tv); gettimeofday (&now, NULL); } } } aprsd-2.2.5-13/src/osdep.h0000664000076400007640000001115107655343026010630 /* * $Id: osdep.h,v 1.4 2003/04/20 18:34:47 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #ifndef OSDEP_H #define OSDEP_H #include "config.h" #include extern "C" { #include #if TIME_WITH_SYS_TIME # include # include #else # if HAVE_SYS_TIME_H # include # else # include # endif #endif #if !defined(HAVE_LIBPTHREAD) && defined(HAVE_LIBDCE) && \ defined(HAVE_LIBCMA) #include #endif // !defined(HAVE_LIBPTHREAD) && defined(HAVE_LIBDCE) && // defined(HAVE_LIBCMA) #ifndef __GLIBC__ extern int h_errno; #endif // __GLIBC__ } namespace aprsd { using std::string; static inline int gethostbyname_r(const string& name, struct hostent *result_buf, char *buf, size_t buflen, struct hostent **result, int *h_errnop) { #ifdef __GLIBC__ return ::gethostbyname_r (name.c_str (), result_buf, buf, buflen, result, h_errnop); #else if (buflen < sizeof (hostent_data)) { if (h_errnop != NULL) *h_errnop = NO_RECOVERY; return -1; } int rc = ::gethostbyname_r (name.c_str (), *result = result_buf, reinterpret_cast(buf)); if ((rc < 0) && (h_errnop != NULL)) *h_errnop = h_errno; return rc; #endif } extern string hstrerror_r(int ERRNUM); static inline string strerror_r(int ERRNUM) { char buf [1024]; #ifdef __GLIBC__ return ::strerror_r (ERRNUM, buf, sizeof (buf)); #else // !__GLIBC__ ::strerror_r (ERRNUM, buf, sizeof (buf)); return buf; #endif // !__GLIBC__ } #if !defined(HAVE_LIBPTHREAD) && defined(HAVE_LIBDCE) && \ defined(HAVE_LIBCMA) #ifdef select #undef SELECT_TYPE_ARG234 #define SELECT_TYPE_ARG234 (int*) #endif static inline int pthread_mutexattr_init(pthread_mutexattr_t *mutex_attr) { return ::pthread_mutexattr_create(mutex_attr); } static inline int pthread_mutexattr_destroy(pthread_mutexattr_t *mutex_attr) { return ::pthread_mutexattr_delete(mutex_attr); } static inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutex_attr) { if(mutex_attr == NULL) return -1; return ::pthread_mutex_init(mutex, *mutex_attr); } static inline int pthread_condattr_init(pthread_condattr_t *cond_attr) { return ::pthread_condattr_create(cond_attr); } static inline int pthread_condattr_destroy(pthread_condattr_t *cond_attr) { return ::pthread_condattr_delete(cond_attr); } static inline int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr) { if (cond_attr == NULL) return -1; return ::pthread_cond_init (cond, *cond_attr); } static inline int pthread_attr_init(pthread_attr_t *attr) { return ::pthread_attr_create (attr); } static inline int pthread_attr_destroy(pthread_attr_t *attr) { return ::pthread_attr_delete (attr); } static inline int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { if (attr == NULL) return -1; return ::pthread_create (thread, *attr, start_routine, arg); } static inline int pthread_detach(pthread_t th) { return ::pthread_detach(&th); } #endif // !defined(HAVE_LIBPTHREAD) && defined(HAVE_LIBDCE) && // defined(HAVE_LIBCMA) extern void reliable_usleep(int usecs); } #endif // OSDEP_H aprsd-2.2.5-13/src/queryResp.cpp0000664000076400007640000001211607655343026012052 /* * $Id: queryResp.cpp,v 1.22 2003/03/31 04:49:40 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "constant.h" #include "utils.h" #include "aprsString.h" #include "queryResp.h" #include "history.h" #include "servers.h" #include "mutex.h" using namespace std; using namespace aprsd; char szHostIP[HOSTIPSIZE]; int queryCounter; void queryResp(int source, const aprsString* pkt) { int rc; struct hostent *h = NULL; struct hostent hostinfo_d; char h_buf[512]; int h_err; Lock countLock(pmtxCount, false); aprsString *rfpacket, *inetpkt; char* hostname = new char[80]; unsigned char hip[5]; char* cp = new char[256]; char* cpAck = new char[256]; memset(cp,0,256); memset(cpAck,0,256); ostrstream reply(cp,255); ostrstream ack(cpAck,255); for (int i=0;i<4;i++) hip[i] = 0; /* Get hostname and host IP */ if ((rc = gethostname(hostname,80)) != 0) strcpy(hostname, "Host_Unknown"); else { //Thread-Safe verison of gethostbyname() h = NULL; rc = gethostbyname_r(hostname, &hostinfo_d, h_buf, 512, &h, &h_err); if ((rc == 0) && (h!= NULL)) { strncpy(hostname,h->h_name,80); //Copy Full host name hostname[79] = '\0'; //Be sure it's terminated strncpy((char*)hip,h->h_addr_list[0],4); //Copy Host IP } } /*debug*/ /* cout << "Hostname: " << hostname << endl << "IP: " << (int)hip[0] << "." << (int)hip[1] << "." << (int)hip[2] << "." << (int)hip[3] <query.compare("IGATE") == 0) { //pthread_mutex_lock(pmtxCount) ; countLock.get(); queryCounter++; //Count this query //pthread_mutex_unlock(pmtxCount); countLock.release(); reply << szServerCall << ">" << PGVERS << ",TCPIP*:" << "addIIPPE('I'); //Make it an Internal packet inetpkt->addPath(MyCall,'*'); sendQueue.write(inetpkt); //DeQueue() deletes the *msgbuf break; case SRC_TNC: rfpacket = new aprsString(cp); // Query reply //cout << rfpacket << endl; //debug tncQueue.write(rfpacket); // queue read deletes rfpacket break; default: if (source >= 0) { inetpkt = new aprsString(cp, SRC_INTERNAL, srcBEACON); inetpkt->addIIPPE('I'); //Make it an Internal packet inetpkt->addPath(MyCall,'*'); rc = send(source,(const void*)inetpkt->c_str(),strlen(inetpkt->c_str()),0); //Only to one user delete inetpkt; } } } delete cp; delete cpAck; delete hostname; } aprsd-2.2.5-13/src/queryResp.h0000664000076400007640000000223707655343026011522 /* * $Id: queryResp.h,v 1.5 2003/03/31 04:49:40 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #ifndef QUERYRESP_H #define QUERYRESP_H extern int queryCounter; void queryResp(int session, const aprsString* pkt) ; void getHostIP(char* szHostIP); #endif // QUERYRESP_H aprsd-2.2.5-13/src/rf.cpp0000644000076400007640000002072607665274763010502 /* * $Id: rf.cpp,v 1.25 2003/05/29 03:09:39 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2001 Dale A. Heatherington, WA4DSY * Copyright (C) 2001 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #include "config.h" #include // getpid #include #include "rf.h" #include "aprsd.h" #include "servers.h" #include "serial.h" #include "ax25socket.h" #include "aprsString.h" #include "osdep.h" #include "constant.h" #include "utils.h" #include "cpqueue.h" #include "history.h" #include "queryResp.h" using namespace std; using namespace aprsd; pthread_t tidReadCom; Mutex mtxWriteTNC; char tx_buffer[260]; bool txrdy; int CloseAsync, threadAck; bool TncSysopMode; // Set true when sysop wants direct TNC access //int AsyncPort; bool AsyncPort; string AprsPath; char* ComBaud; //-------------------------------------------------------------------- // Set APRS path (before the port is opened) // void rfSetPath(const string& path) { AprsPath = path; } //-------------------------------------------------------------------- // Set serial port speed (before the port is opened) // void rfSetBaud(const char* baud) { ComBaud = strdup(baud); } //-------------------------------------------------------------------- // Open RF ports (TNC or sockets) int rfOpen(const string& szPort, const string& baudrate) { int result; AsyncPort = (szPort[0] == '/'); TncSysopMode = false; txrdy = false; APIRET rc; //cout << "Debug: szPort == " << szPort << endl; if (AsyncPort) { //cout << "AsyncPort is true" << endl; result = AsyncOpen(szPort, baudrate); } #ifdef HAVE_LIBAX25 else { //cout << "AsyncPort is false, using AX25" << endl; result = SocketOpen(szPort, AprsPath); } #else else { cerr << "AX.25 sockets are not supported by this executable" << endl; result = 1; } #endif if (result != 0) return(result); CloseAsync = false; threadAck = false; // Now start the serial port reader thread if ((rc = pthread_create(&tidReadCom, NULL, rfReadCom, NULL)) < 0) { cerr << "Error: ReadCom thread creation failed. Error code = " << rc << endl; CloseAsync = true; } return(0); } //-------------------------------------------------------------------- // Close the RF ports // int rfClose(void) { CloseAsync = true; // Tell the read thread to quit while (!threadAck) reliable_usleep (1000); // wait till it does if (AsyncPort) return(AsyncClose()); #ifdef HAVE_LIBAX25 else return(SocketClose()); #else else return(0); // quite compiler #endif } //------------------------------------------------------------------- // Write NULL terminated string to serial port */ // int rfWrite(const char *cp) { int rc = 0; Lock writeTNCLock(mtxWriteTNC); strncpy(tx_buffer, cp, 256); txrdy = true; while (txrdy) reliable_usleep(10000); // The rfReadCom thread will clear txrdy when it takes data writeTNCLock.release(); return(rc); } //-------------------------------------------------------------------- // This is the RF port read thread. // It also handles buffered writes to the port. // void* rfReadCom(void *vp) { unsigned short i; // APIRET rc; char buf[BUFSIZE]; // unsigned char c; // FILE *rxc = (FILE *) vp; // size_t BytesRead; bool lineTimeout = false; aprsString *abuff; i = 0; pidlist.SerialInp = getpid (); //cerr << "Async Comm thread started." << endl; //cerr << "Debug: AsyncPort is " << (AsyncPort ? "true":"false") << endl; while (!CloseAsync) { if (AsyncPort) lineTimeout = AsyncReadWrite(buf); #ifdef HAVE_LIBAX25 else { //cout << "DEBUG: Using SocketReadWrite" << endl; lineTimeout = SocketReadWrite(buf); } #endif WatchDog++; tickcount = 0; i = strlen((char*)buf); //cout << "DEBUG: buf length is: " << i << endl; if ((i > 0) && ((buf[0] != 0x0d) && (buf[0] != 0x0a))) { if (!lineTimeout) { TotalLines++; buf[i - 1] = 0x0d; buf[i++] = 0x0a; } buf[i++] = '\0'; if ((i > 0) && (!TncSysopMode) && (configComplete)) { abuff = new aprsString ((char *) buf, SRC_TNC, srcTNC, "TNC", "*"); if (abuff != NULL) { //don't let a null pointer get past here! if (abuff->aprsType == APRSQUERY) { // non-directed query ? queryResp(SRC_TNC, abuff); // yes, send our response } if ((abuff->aprsType == APRSMSG) && (abuff->msgType == APRSMSGQUERY)) { // is this a directed query message? if ((stricmp(szServerCall.c_str(), abuff->stsmDest.c_str()) == 0) || (stricmp("aprsd", abuff->stsmDest.c_str()) == 0) || (stricmp("igate", abuff->stsmDest.c_str()) == 0)) { // Is query for us? queryResp(SRC_TNC, abuff); // Yes, respond. } } if (logAllRF || abuff->ax25Source.compare(MyCall) == 0) WriteLog(abuff->c_str(), RFLOG); //Log our own packets that were digipeated if ((abuff->reformatted) || ((abuff->ax25Source.compare(MyCall) == 0) && (igateMyCall == false))) { delete abuff; //don't igate packets which have been igated to RF... abuff = NULL; // ... and/or originated from our own TNC } else { // Not reformatted and not from our own TNC if (abuff->aprsType == APRSMSG) { //find matching posit for 3rd party msg aprsString *posit = getPosit(abuff->ax25Source, srcIGATE | srcUSERVALID | srcTNC); if (posit != NULL) { posit->EchoMask = src3RDPARTY; sendQueue.write(posit); //send matching posit only to msg port } } if (abuff->aprsType == APRSMIC_E) { //Reformat if it's a Mic-E packet reformatAndSendMicE(abuff, sendQueue); } else { sendQueue.write(abuff, 0); // Now put it in the Internet send queue. // *** abuff must be freed by Queue reader ***. //cout << "DEBUG: sent to Inet " << endl; } } } } } i = 0; //Reset buffer pointer } // Loop until server is shut down cerr << "Exiting Async com thread\n" << endl; threadAck = true; pthread_exit(0); return NULL; } //--------------------------------------------------------------------- // Send a text file to the TNC for configuration int rfSendFiletoTNC(const std::string& szName) { if (AsyncPort) { return(SendFiletoTNC(szName)); #ifdef HAVE_LIBAX25 } else { //cout << "DEBUG: rfSendFiletoTNC(): AsyncPort == " << (AsyncPort ? "true":"false") << " using libAX25" << endl; return(0); // Not applicable for sockets } #else } else { return(0); // quite compiler } #endif } aprsd-2.2.5-13/src/rf.h0000644000076400007640000000301007661563341010117 /* * $Id: rf.h,v 1.7 2003/05/18 01:50:25 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2001 Dale A. Heatherington, WA4DSY * Copyright (C) 2001 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #ifndef RF_H #define RF_H #include #include "constant.h" extern int CloseReader, threadAck; extern bool txrdy; extern char tx_buffer[]; extern bool TncSysopMode; /*--------------------------------------------------------------*/ int rfOpen(const std::string& szPort, const std::string& baudrate); int rfClose(void); int rfSendFiletoTNC(const std::string& szName); void* rfReadCom(void* vp); //Com port read thread int rfWrite(const char* cp); void rfSetPath(const std::string& path); void rfSetBaud(const char *baud); #endif // RF_H aprsd-2.2.5-13/src/serial.cpp0000644000076400007640000002044007657626343011337 /* * $Id: serial.cpp,v 1.20 2003/05/12 05:10:59 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2001 Dale A. Heatherington, WA4DSY * Copyright (C) 2001 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //tcpip header files #include #include #include #include #include #include #include "constant.h" #include "serial.h" #include "utils.h" #include "cpqueue.h" #include "history.h" #include "queryResp.h" #include "servers.h" #include "rf.h" #include "mutex.h" using namespace std; using namespace aprsd; int ttySread ; int ttySwrite; //pthread_t tidReadCom; termios newSettings, originalSettings; speed_t newSpeed, originalOSpeed, originalISpeed; Mutex pmtxWriteTNC; //char tx_buffer[260]; //bool txrdy; //int CloseAsync;//, threadAck; //bool TncSysopMode; /*Set true when sysop wants direct TNC access */ //--------------------------------------------------------------------- // Sets various parameters on a COM port for use with TNC int AsyncSetupPort( int fIn, int fOut, const string& TncBaud) { speed_t baud = B0; if (TncBaud.compare("1200") == 0) baud = B1200; if (TncBaud.compare("2400") == 0) baud = B2400; if (TncBaud.compare("4800") == 0) baud = B4800; if (TncBaud.compare("9600") == 0) baud = B9600; if (TncBaud.compare("19200") == 0) baud = B19200; tcgetattr(fIn,&originalSettings); newSettings = originalSettings; newSettings.c_lflag = 0; newSettings.c_cc[VMIN] = 0; newSettings.c_cc[VTIME] = 1; //.1 second timeout for input chars newSettings.c_cflag = CLOCAL | CREAD | CS8 ; newSettings.c_oflag = 0; newSettings.c_iflag = IGNBRK|IGNPAR ; cfsetispeed(&newSettings, baud); cfsetospeed(&newSettings, baud); if (tcsetattr(fIn, TCSANOW, &newSettings) != 0) { cerr << " Error: Could not set input serial port attrbutes\n"; return -1; } if (tcsetattr(fOut, TCSANOW, &newSettings) != 0) { cerr << " Error: Could not set output serial port attrbutes\n"; return -1; } return 0; } //-------------------------------------------------------------------- // Open and initialise the COM port for the TNC int AsyncOpen(const string& szPort, const string& baudrate) { APIRET rc; ttySwrite = open(szPort.c_str(), O_WRONLY | O_NOCTTY); if (ttySwrite == -1) { cerr << "Error: Could not open serial port in WRITE mode: " << szPort << " [" << strerror_r(errno) << "]" << endl; return -1; } ttySread = open(szPort.c_str(), O_RDONLY | O_NOCTTY); if (ttySread == -1) { cerr << "Error: Could not open serial port in READ mode: " << szPort << " [" << strerror_r(errno) << "]" << endl; return -1; } if ((rc = AsyncSetupPort(ttySread, ttySwrite, string(baudrate))) != 0) { cerr << "Error in setting up COM port rc=" << rc << endl << flush; return -2; } return 0; } //-------------------------------------------------------------------- // Close the COM port int AsyncClose (void) { if (tcsetattr (ttySread, TCSANOW, &originalSettings) != 0) { cerr << " Error: Could not reset input serial port attrbutes\n"; } if (tcsetattr (ttySwrite, TCSANOW, &originalSettings) != 0) { cerr << " Error: Could not reset input serial port attrbutes\n"; } close (ttySwrite); return close (ttySread); //close COM port } //-------------------------------------------------------------------- // Read a line from the COM port. bool AsyncReadWrite(char* buf) { unsigned short i; unsigned char c; size_t BytesRead; bool lineTimeout; lineTimeout = false; i = 0; do { if (txrdy) { //Check for data to Transmit size_t len = strlen (tx_buffer); write (ttySwrite, tx_buffer, len); //Send TX data to TNC txrdy = false; //Indicate we sent it. } BytesRead = read(ttySread, &c, 1); //Non-blocking read. 100ms timeout. if (BytesRead == 0) //Serial input timeout { if (i > 0) lineTimeout = true; // We have some data but none has arrived lately. } TotalTncChars += BytesRead; if (BytesRead > 0) { //Actual serial data from TNC has arrived if (i < (BUFSIZE - 4)) buf[i++] = c; else i = 0; if (TncSysopMode) { i = 1; charQueue.write ((char *)NULL, (int) c); //single char mode... //DL5DI } } else c = 0; } while ((c != 0x0a) && (c != 0x0d) && (lineTimeout == false)); buf[i] = '\0'; return lineTimeout; } //--------------------------------------------------------------------- /* This reads file "szName" into the TNC. When the keyword "MYCALL" is encounterd the next word is loaded into the aprsd MyCall variable. When the keyword "UNPROTO" is encountered the word following it is replaced with "APDxxx" where xxx is the aprsd version number. For example UNPROTO APRS VIA WIDE will become UNPROTO APD213 VIA WIDE. */ int SendFiletoTNC(const string& szName) { int nTokens; char Line[256]; const int maxToken = 15; timespec ts; ts.tv_sec = 0; ifstream file(szName.c_str()); if (file.is_open () == false) { cerr << "Can't open " << szName << endl << flush; return -1; } Line[0] = 0x03; //Control C to get TNC into command mode Line[1] = '\0'; rfWrite(Line); ts.tv_sec = 1; //1s timeout for nanosleep() ts.tv_nsec = 0; nanosleep(&ts,NULL); ts.tv_sec = 0; ts.tv_nsec = 500000000; //500ms timeout for nanosleep() while (file.good ()) { file.getline (Line, 256); //Read each line in file and send to TNC strcat (Line, "\r"); //DL5DI if ((Line[0] != '*') && (Line[0] != '#') && (strlen (Line) >= 2)) { //Reject comments string sLine(Line); string token[maxToken]; nTokens = split(sLine, token, maxToken, RXwhite); //Parse line into tokens upcase(token[0]); upcase(token[1]); if (token[0].compare("MYCALL") == 0) { //Extract MYCALL from TNC.INIT MyCall = strdup(token[1].c_str()); //Put it in MyCall if (MyCall.length() > 9) { string tmpstr; tmpstr = MyCall.substr(0,9); //MyCall[9] = '\0'; //Truncate to 9 chars. MyCall = tmpstr; } } if ((token[0].compare("UNPROTO") == 0) && (nTokens >= 2)) { //Insert APDxxx into ax25 dest addr of UNPROTO size_t idx2 = sLine.find(token[1],6); sLine.replace(idx2, token[1].length(), PGVERS); } cout << sLine.c_str() << endl; //print it to the console int len = sLine.length(); write (ttySwrite, Line, len); nanosleep(&ts,NULL); //sleep for 500ms between lines } } file.close (); return 0; } aprsd-2.2.5-13/src/serial.h0000644000076400007640000000236307660071511010771 /* * $Id: serial.h,v 1.8 2003/05/13 04:23:37 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2001 Dale A. Heatherington, WA4DSY * Copyright (C) 2001 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #ifndef SERIAL_H #define SERIAL_H #include #include "constant.h" bool AsyncReadWrite(char* buf); int AsyncOpen(const std::string& szPort, const std::string& baudrate); int AsyncClose(void); int SendFiletoTNC(const std::string& szName); #endif // SERIAL_H aprsd-2.2.5-13/src/servers.cpp0000644000000000000000000036224207665450331011507 /* * $Id: servers.cpp,v 1.6 2003/05/29 18:26:33 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2003 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef linux #include #include #endif #include //tcpip header files #include #include #include #include #include #include #include #include "aprsd.h" #include "servers.h" #include "dupCheck.h" #include "cpqueue.h" #include "utils.h" #include "history.h" #include "serial.h" #include "aprsString.h" #include "validate.h" #include "queryResp.h" #include "mutex.h" #include "rf.h" using namespace std; using namespace aprsd; int nIGATES; //Actual number of IGATES you have defined SessionParams *sessions; //points to array of active socket descriptors int MaxClients; //Limits how many users can log on at once int MaxLoad; //Limits maximum server load in Kbytes/sec int serverLoad_s, bytesSent_s ; // Used in short term load calculation //ULONG ulNScnt = 0; bool tncPresent; //TRUE if TNC com port has been specified bool tncMute; //TRUE stops messages from going to the TNC bool traceMode; //TRUE causes our Server Call to be appended to all packets in the path ServerParams spMainServer, spMainServer_NH, spLinkServer; ServerParams spLocalServer, spMsgServer, spHTTPServer, spSysopServer; ServerParams spRawTNCServer, spIPWatchServer, spErrorServer,spOmniServer; UdpParams upUdpServer; dupCheck dupFilter; //Create a dupCheck class named dupFilter. This identifies duplicate packets. const int maxIGATES = 100; //Defines max number of IGATES/Servers you can connect to #define BASE 0 #define USER 1 #define PASS 2 #define REMOTE 3 #define MAX 256 #define UMSG_SIZE MAX+BUFSIZE+3 //--------------------------------------------------- cpQueue sendQueue(256, true); // Internet transmit queue cpQueue tncQueue(64, true); // TNC RF transmit queue cpQueue charQueue(256, false); // A queue of single characters cpQueue conQueue(256, true); // data going to the console from various threads struct sLogon logon; char *passDefault = "-1"; string MyCall; string MyLocation; string MyEmail; string NetBeacon; string TncBeacon; char *TncBaud; int TncBeaconInterval, NetBeaconInterval; long tncPktSpacing; bool igateMyCall; //Set TRUE if server will gate packets to inet with "MyCall" in the ax25 source field. bool logAllRF; bool APRS_PASS_ALLOW; //Allow APRS style passcodes: T/F bool History_ALLOW; //Allow history list dumps: T/F int defaultPktTTL; //Holds default packet Time to live (hops) value. int ackRepeats,ackRepeatTime; //Used by the ACK repeat thread bool sendOnRF(aprsString& atemp, string szPeer, char* userCall, const int src); //------------------------------------------------------------------- string szServerCall; // This servers "AX25 Source Call" (user defined) string szAPRSDPATH; // Servers "ax25 dest address + path" eg: >APD213,TCPIP*: string szServerID = string("APRS Server: "); string szJAVAMSG = string(">JAVA::javaMSG :"); const string szUSERLISTMSG = string(":USERLIST :"); const string szUNVERIFIED = string("Unverified "); const string szVERIFIED = string("Verified "); const string szRM1 = string("You are an unverified user, Internet access only.\r\n"); const string szRM2 = string("Send Access Denied. Access is Read-Only.\r\n"); const string szRM3 = string("RF access denied, Internet access only.\r\n"); const string szACCESSDENIED = string("Access Denied"); Mutex pmtxSendFile; Mutex pmtxSend; // socket send Mutex pmtxAddDelSess; // add/del sessions Mutex pmtxCount; // counters Mutex pmtxDNS; // buggy gethostbyname2_r ? bool ShutDownServer, configComplete; int msg_cnt; int posit_cnt; ULONG WatchDog, tickcount, TotalConnects, TotalTncChars, TotalLines; int MaxConnects; ULONG TotalServerChars, TotalUserChars,TotalMsgChars, TotalUdpChars, bytesSent, webCounter; ULONG TotalFullStreamChars; ULONG countREJECTED, countLOOP, countOVERSIZE, countNOGATE, countIGATED; time_t serverStartTime; ULONG TotalTNCtxChars; //------------------------------------------------------------------------------------------ //Array to hold list of stations //allowed to full time gate from //Internet to RF string* rfcall[MAXRFCALL]; //list of stations gated to RF full time (all packets) int rfcall_idx; string* posit_rfcall[MAXRFCALL]; //Stations whose posits are always gated to RF int posit_rfcall_idx; string* stsmDest_rfcall[MAXRFCALL]; //Station to station messages with these // DESTINATION call signs are always gated to RF int stsmDest_rfcall_idx; int fullStreamRate, serverLoad; int serverStreamRate, tncStreamRate, userStreamRate, msgStreamRate, udpStreamRate; //Server statistics //double upTime; int upTime; bool RF_ALLOW = false; //TRUE to allow Internet to RF message passing. bool NOGATE_FILTER = true; //TRUE enables the NOGATE and RFONLY packet reject filter //-------------------------------------------------------------------------------------------- ConnectParams cpIGATE[maxIGATES]; const int maxTRUSTED = 20; //Max number of trusted UDP users sTrusted Trusted[maxTRUSTED]; //Array to store their IP addresses int nTrusted = 0; //Number of trusted UDP users defined //Debug stuff pidList pidlist; char* DBstring; //for debugging aprsString* lastPacket; //for debugging FILE* fdump; //------------------------------------------------------------------------------- int initDefaults(void) { int i; logon.user = NULL; logon.pass = NULL; TotalConnects = TotalLines = MaxConnects = TotalServerChars = 0; TotalTncChars = 0; TotalUserChars = 0; TotalMsgChars = 0; TotalServerChars = 0; TotalFullStreamChars = 0; TotalUdpChars = 0; countNOGATE = 0; countREJECTED = 0; countOVERSIZE = 0; countLOOP = 0; countIGATED = 0; defaultPktTTL = 5; //Set default Time-To-Live bytesSent = 0; serverLoad_s = 0; bytesSent_s = 0; TotalTNCtxChars = 0; msg_cnt = 0; posit_cnt = 0; MyCall = "N0CALL"; MyLocation = "NoWhere"; MyEmail = "nobody@NoWhere.net"; TncBeacon = string(""); TncBaud = "9600"; NetBeacon = string(""); TncBeaconInterval = 0; NetBeaconInterval = 0; tncPktSpacing = 1500000; //1.5 second default igateMyCall = true; //To be compatible with previous versions set it TRUE tncPresent = false; traceMode = false; logAllRF = false; ConvertMicE = false; tncMute = false; MaxClients = MAXCLIENTS; //Set default. aprsd.conf file will override this MaxLoad = MAXLOAD ; //Set default server load limit in bytes/sec ackRepeats = 2; //Default extra acks to TNC ackRepeatTime = 5; //Default time between extra acks to TNC in seconds. APRS_PASS_ALLOW = true; //Default: allow aprs style user passcodes History_ALLOW = true; //Default: allow history dumps. webCounter = 0; queryCounter = 0; for (i = 0; i < maxIGATES; i++) { //Clear the array of outbound server connections cpIGATE[i].RemoteSocket = -1; cpIGATE[i].RemoteName = string(""); } szServerCall = "aprsd"; //default server FROM CALL used in system generated pkts. szAPRSDPATH = string(">"); szAPRSDPATH += PGVERS; szAPRSDPATH += ",TCPIP*:"; if (szAPRSDPATH.size() > 64) // Limit data path to 64 bytes szAPRSDPATH.resize(64); spOmniServer.ServerPort = 0; spLinkServer.ServerPort = 0; //Ports are set in aprsd.conf file spMainServer.ServerPort = 0; spMainServer_NH.ServerPort = 0; spLocalServer.ServerPort = 0; spRawTNCServer.ServerPort = 0; spMsgServer.ServerPort = 0; upUdpServer.ServerPort = 0; spSysopServer.ServerPort = 14500; //Sysop Port for telnetting to the TNC directly spSysopServer.EchoMask = 0; spHTTPServer.ServerPort = 14501; //HTTP monitor port default spHTTPServer.EchoMask = wantHTML; spIPWatchServer.ServerPort = 14502; //IP Watch port default spIPWatchServer.EchoMask = srcUSERVALID + srcUSER + srcIGATE + srcTNC + wantSRCHEADER; spErrorServer.ServerPort = 14503; spErrorServer.EchoMask = wantREJECTED + wantSRCHEADER; ShutDownServer = false; return 0; } //---------------------------------------------------------------- //This runs after the aprsd.conf file is read. void serverInit(void) { int i,rc; sessions = new SessionParams[MaxClients]; if (sessions == NULL) { cerr << "Can't create sessions pointer\n" ; exit(-1); } for (i = 0; i < MaxClients; i++) { sessions[i].Socket = -1; sessions[i].ServerPort = -1; sessions[i].EchoMask = 0; sessions[i].szPeer = new char[SZPEERSIZE]; sessions[i].userCall = new char[USERCALLSIZE]; sessions[i].pgmVers = new char[PGMVERSSIZE]; memset((void*)sessions[i].szPeer, 0, SZPEERSIZE); //Fill strings with nulls memset((void*)sessions[i].userCall, 0, USERCALLSIZE); memset((void*)sessions[i].pgmVers, 0, PGMVERSSIZE); } // Create the server threads //Create Main Server thread. (Provides Local data, Logged on users and IGATE data) if (spMainServer.ServerPort > 0) { if ((rc = pthread_create(&spMainServer.tid, NULL,TCPServerThread,&spMainServer)) != 0) { cerr << "Error: Main TCPServerThread failed to start" << endl; exit(-1); } } //Create another Main Server thread . // (Provides Local data, Logged on users and IGATE data but doesn't dump the 30 min. history) if (spMainServer_NH.ServerPort > 0) { if ((rc = pthread_create(&spMainServer_NH.tid, NULL,TCPServerThread,&spMainServer_NH)) != 0) { cerr << "Error: Main-NH TCPServerThread failed to start" << endl; exit(-1); } } // Create Main Server thread. (Provides Local data, Logged on users and IGATE data) if (spOmniServer.ServerPort > 0) { if ((rc = pthread_create(&spOmniServer.tid, NULL,TCPServerThread,&spOmniServer)) != 0) { cerr << "Error: Omni TCPServerThread failed to start" << endl; exit(-1); } } //Create Link Server thread. (Provides local TNC data plus logged on users data) if (spLinkServer.ServerPort > 0) { if ((rc = pthread_create(&spLinkServer.tid, NULL,TCPServerThread,&spLinkServer)) != 0) { cerr << "Error: Link TCPServerThread failed to start" << endl; exit(-1); } } //Create Local Server thread (Provides only local TNC data). if (spLocalServer.ServerPort > 0) { if ((rc = pthread_create(&spLocalServer.tid, NULL,TCPServerThread,&spLocalServer)) != 0) { cerr << "Error: Local TCPServerThread failed to start" << endl; exit(-1); } } // Create Sysop Port thread (Provides no data, only for talking to the TNC directly). if (spSysopServer.ServerPort > 0) { if ((rc = pthread_create(&spSysopServer.tid, NULL,TCPServerThread,&spSysopServer)) != 0) { cerr << "Error: Sysop Port TCPServerThread failed to start" << endl; exit(-1); } } // Create Local Server thread (Provides only local TNC data). if (spRawTNCServer.ServerPort > 0) { if ((rc = pthread_create(&spRawTNCServer.tid, NULL,TCPServerThread,&spRawTNCServer)) != 0) { cerr << "Error: RAW TNC TCPServerThread failed to start" << endl; exit(-1); } } //Create message Server thread (Provides only 3rd party message data). if (spMsgServer.ServerPort > 0) { if ((rc = pthread_create(&spMsgServer.tid, NULL,TCPServerThread,&spMsgServer)) != 0) { cerr << "Error: 3rd party message TCPServerThread failed to start" << endl; exit(-1); } } if (upUdpServer.ServerPort > 0) { if ((rc = pthread_create(&upUdpServer.tid, NULL,UDPServerThread,&upUdpServer)) != 0) { cerr << "Error: UDP Server thread failed to start" << endl; exit(-1); } } // Create HTTP Server thread. (Provides server status in HTML format) if (spHTTPServer.ServerPort > 0) { if ((rc = pthread_create(&spHTTPServer.tid, NULL,TCPServerThread,&spHTTPServer)) != 0) { cerr << "Error: HTTP server thread failed to start" << endl; exit(-1); } } // Create IPWatch Server thread. (Provides prepended header with IP and User Call // on aprs packets) if (spIPWatchServer.ServerPort > 0) { if ((rc = pthread_create(&spIPWatchServer.tid, NULL,TCPServerThread,&spIPWatchServer)) != 0) { cerr << "Error: IPWatch server thread failed to start" << endl; exit(-1); } } // Create ERROR Server thread. (Provides prepended header with IP and User Call on // REJECTED aprs packets) if (spErrorServer.ServerPort > 0) { if ((rc = pthread_create(&spErrorServer.tid, NULL,TCPServerThread,&spErrorServer)) != 0) { cerr << "Error: Rejected aprs packet server thread failed to start" << endl; exit(-1); } } pthread_t tidDeQueuethread; if ((rc = pthread_create(&tidDeQueuethread, NULL, DeQueue, NULL)) != 0) { cerr << "Error: DeQueue thread failed to start" << endl; exit(-1); } cerr << "nIGATES=" << nIGATES << endl; cerr << "igate0=" << cpIGATE[0].RemoteName << endl; bool firstHub = false; if (nIGATES > 0) cout << "Connecting to IGATEs and Hubs now..." << endl; for (i = 0; i < nIGATES; i++) { if (cpIGATE[i].RemoteSocket == 0) { string warn = string(cpIGATE[i].RemoteName) + ": Error: No socket number specified for Server/Hub\n"; cerr << warn ; WriteLog(warn, string(MAINLOG)); } else { if (!firstHub) { if ((rc = pthread_create(&cpIGATE[i].tid, NULL,TCPConnectThread,&cpIGATE[i])) == 0) pthread_detach(cpIGATE[i].tid); if (cpIGATE[i].hub) firstHub = true; } else { if (!cpIGATE[i].hub) { if ((rc = pthread_create(&cpIGATE[i].tid, NULL,TCPConnectThread,&cpIGATE[i])) == 0) pthread_detach(cpIGATE[i].tid); } } } } } //----------------------------------------------------------------- void initSessionParams(SessionParams* sp, int s, int echo, bool svr) { sp->Socket = s; sp->EchoMask = echo; sp->overruns = 0; sp->bytesIn = 0; sp->bytesOut = 0; sp->vrfy = false; sp->dead = false; sp->svrcon = svr; //outbound server connection, T/F sp->starttime = time(NULL); sp->lastActive = sp->starttime; memset((void*)sp->szPeer, 0, SZPEERSIZE); //Fill strings with nulls memset((void*)sp->userCall, 0, USERCALLSIZE); memset((void*)sp->pgmVers, 0, PGMVERSSIZE); } //-------------------------------------------------------------------- //Returns the number of connected clients including IGATE and HUB connections int getConnectedClients(void) { //int i; int count = 0; Lock addDelLock(pmtxAddDelSess); for (int i = 0; i < MaxClients; i++) if ((sessions[i].Socket > -1)) count++; for (int i = 0; i < nIGATES; i++) if (!cpIGATE[i].connected) count--; return count; } //--------------------------------------------------------------------- //Add a new user to the list of active sessions //Includes outbound Igate connections too! //Returns NULL if it can't find an available session // or server load may exceed MaxLoad with the added connection. SessionParams* AddSession(int s, int echo, bool svr) { SessionParams *rv = NULL; int i, softlimit; Lock addDelLock(pmtxAddDelSess); addDelLock.get(); if (fullStreamRate > 0) softlimit = MaxLoad - fullStreamRate; // MaxLoad less 1 full aprs data stream else softlimit = MaxLoad - (MaxLoad / 10); // MaxLoad less 10% for (i = 0; i < MaxClients; i++) if (sessions[i].Socket == -1) break; //Find available unused session // If less than max clients and short term load is well below maxload... if ((i < MaxClients) && (serverLoad_s <= softlimit)) { rv = &sessions[i]; initSessionParams(rv, s, echo, svr); } else rv = NULL; addDelLock.release(); return rv; } //-------------------------------------------------------------------- //Remove a user bool DeleteSession(int s) { bool rv = false; if (s == -1) return rv; Lock addDelLock(pmtxAddDelSess); for (int i = 0; i < MaxClients; i++) { if (sessions[i].Socket == s ) { sessions[i].Socket = -1; sessions[i].EchoMask = 0; sessions[i].pid = 0; sessions[i].dead = true; rv = true; } } return rv; } //------------------------------------------------- bool AddSessionInfo(int s, const char* userCall, const char* szPeer, int port, const char* pgmVers) { bool retval = false; Lock addDelLock(pmtxAddDelSess); for (int i = 0; i < MaxClients; i++) { if (sessions[i].Socket == s ) { strncpy(sessions[i].szPeer, szPeer, SZPEERSIZE-1); strncpy(sessions[i].userCall, userCall, USERCALLSIZE-1); sessions[i].ServerPort = port; strncpy(sessions[i].pgmVers,pgmVers, PGMVERSSIZE-1); sessions[i].pid = getpid(); retval = true; } } return retval; } //--------------------------------------------------------------------- void CloseAllSessions(void) { for (int i = 0; i < MaxClients; i++) { if (sessions[i].Socket != -1 ) { shutdown(sessions[i].Socket,2); close(sessions[i].Socket); sessions[i].Socket = -1; sessions[i].EchoMask = 0; } } } //--------------------------------------------------------------------- //------------------------------------------------------------------- // Send data at "p" to all logged on clients listed in the sessions array // subject to some packet filtering. void SendToAllClients(aprsString* p) { int rc, n, nraw, nsh; bool dup = false; Lock addDelLock(pmtxAddDelSess, false); // don't get these locks quite yet... Lock sendLock(pmtxSend, false); Lock countLock(pmtxCount, false); if (p == NULL) return; if (p->size() < 3) return; //Silently reject runts if ((p->aprsType == CONTROL) || (p->msgType == APRSMSGSERVER)) return; //Silently reject user control commands if (p->EchoMask & sendDUPS) dup = true; //This packet is a duplicate if (NOGATE_FILTER && p->nogate) { //Don't igate NOGATE and RFONLY packets countNOGATE++; //Count the rejected NOGATE packets p->aprsType = APRSREJECT; //Flag as reject } bool bad_ax25 = ((((p->EchoMask & srcSTATS) == 0) //Don't flag system status text stream && (!p->valid_ax25)) //invalid ax25 || (p->aprsType == APRSREJECT) // reject || (p->EchoMask == 0)); //EchoMask is zero if (bad_ax25) { countREJECTED++; //Count rejected AX25 packets p->EchoMask |= wantREJECTED ; //For those who want to see them } if ((!bad_ax25) && (p->EchoMask & srcSTATS) == 0) { countLock.get(); countIGATED++; //Count good packets if (p->aprsType == APRSMSG) TotalMsgChars += p->length(); //Count message characters countLock.release(); } if ((p->aprsType == APRSREJECT) && (!dup)) WriteLog(p->raw, string(REJECTLOG)); // Log rejected packets sendLock.get(); addDelLock.get(); // save some cpu time by putting these values in integers now. n = p->length(); nraw = p->raw.length(); nsh = p->srcHeader.length(); for (int i = 0; i < MaxClients; i++) { if (sessions[i].Socket != -1) { bool wantdups, wantsrcheader,wantrejected,wantecho,echo,raw,wantrej; wantdups = wantsrcheader = wantrejected = wantecho = echo = raw = wantrej = false ; int tc = 0; int Em; if (sessions[i].EchoMask & sendDUPS) wantdups = true; //User wants duplicates if (sessions[i].EchoMask & wantREJECTED) wantrej = true; if (sessions[i].EchoMask & wantSRCHEADER) wantsrcheader = true; //User wants IP source header if (sessions[i].EchoMask & wantRAW) raw = true; //User wants raw TNC data if (sessions[i].EchoMask & wantECHO) wantecho = true; //User wants to see his own packets if (p->sourceSock == sessions[i].Socket) echo = true; //This packet came from the this user // Mask off non-source determining bits. Em = p->EchoMask & 0x7ff; if ((sessions[i].EchoMask & Em) //Echo inet data if source mask bits match session mask && (!ShutDownServer) && (!sessions[i].dead)) {//Send NO data to a dead socket (added vers. 215a6) rc = tc = 0; // User wants raw tnc data if(raw && !echo && (nraw > 0)) { rc = send(sessions[i].Socket,p->raw.c_str(),nraw,0); goto done; } //Normal dup and error filtered data stream if ((!wantsrcheader) /* No IP source header prepended */ && (!dup) /* No duplicates */ && (!bad_ax25) /* No invalid ax25 packets or rejects */ && (!echo)){ /* No echo of users own data */ rc = send(sessions[i].Socket,p->c_str(),n,0); goto done; } // User wants source header prepended to all aprs packets. if (wantsrcheader && !echo && !bad_ax25){ //Append source header to aprs packets, duplicates ok. // Mostly for debugging the network rc = send(sessions[i].Socket,p->srcHeader.c_str(),nsh,0); tc = rc; if (rc != -1) rc = send(sessions[i].Socket, p->c_str(), n, 0); goto done; } //User wants his own data echoed back, // no dup check or validation on his own data. if (echo && wantecho){ rc = send(sessions[i].Socket, p->c_str(), n, 0); goto done; } // Error Port 14503: User wants source header plus Rejected packets ONLY. if (wantrej && bad_ax25 && (!echo) && (!dup) && ((p->EchoMask & srcSTATS) == 0) ){ rc = send(sessions[i].Socket,p->srcHeader.c_str(),nsh,0); tc = rc; if (rc != -1) rc = send(sessions[i].Socket,p->c_str(),n,0); } if (wantdups && dup && !echo ) { //Send only the dups to this guy rc = send(sessions[i].Socket,p->c_str(),n,0); goto done; } /* Disconnect user if socket error or he failed to accept 10 consecutive packets due to resource temporarally unavailable errors */ done: if (rc == -1) { if (errno == EAGAIN) sessions[i].overruns++; if ((errno != EAGAIN) || (sessions[i].overruns >= 10)){ sessions[i].EchoMask = 0; //No more data for you! sessions[i].dead = true; //Mark connection as dead for later removal... //...by thread that owns it. } } else { sessions[i].overruns = 0; //Clear users overrun counter if he accepted packet sessions[i].bytesOut += (tc + rc); //Add these bytes to his bytesOut total bytesSent += (tc + rc); //Add these to the grand total for server load calc. bytesSent_s += (tc + rc); //Also add to short term load } } } } addDelLock.release(); sendLock.release(); return; } //--------------------------------------------------------------------- // Pushes a character string into the server send queue. void BroadcastString(const char* sp) { aprsString *msgbuf = new aprsString(sp, SRC_INTERNAL, srcSYSTEM); msgbuf->addIIPPE('Z'); //Make it a zero hop packet msgbuf->addPath(szServerCall); sendQueue.write(msgbuf); //DeQueue() deletes the *msgbuf return; } //--------------------------------------------------------------------- // This is a thread. It removes items from the send queue and transmits // them to all the clients. Also handles checking for items in the TNC queue // and calling the tnc dequeue routine. void *DeQueue(void* vp) { bool Hist,dup; aprsString* abuff; int MaxAge,MaxCount; struct timeval tv; struct timezone tz; long usLastTime, usNow; long t0; //string serverCall = szServerCall; //convert out Server call to a string timespec ts; char* dcp; Lock countLock(pmtxCount, false); // don't get this lock quite yet... usLastTime = usNow = 0; pidlist.InetQueue = getpid(); nice(-10); //Increase priority of this thread by 10 (only works if run as root) while (!ShutDownServer) { gettimeofday(&tv,&tz); //Get time of day in microseconds to tv.tv_usec usNow = tv.tv_usec + (tv.tv_sec * 1000000); if (usNow < usLastTime) usLastTime = usNow; t0 = usNow; if ((usNow - usLastTime) >= tncPktSpacing) { //Once every 1.5 second or user defined usLastTime = usNow; if (tncQueue.ready()) dequeueTNC(); //Check the TNC queue } while (!sendQueue.ready()) { //Loop here till somethings in the send queue gettimeofday(&tv,&tz); //Get time of day in microseconds to tv.tv_usec usNow = tv.tv_usec + (tv.tv_sec * 1000000); if (usNow < usLastTime) usLastTime = usNow; t0 = usNow; if ((usNow - usLastTime) >= tncPktSpacing) { //Once every 1.5 second or user defined usLastTime = usNow; if (tncQueue.ready()) dequeueTNC(); //Check the TNC queue } ts.tv_sec = 0; ts.tv_nsec = 1000000; //1 ms timeout for nanosleep() nanosleep(&ts,NULL); //1ms if (ShutDownServer) pthread_exit(0); } abuff = (aprsString*)sendQueue.read(NULL); // <--Read an aprsString pointer from the queue to abuff lastPacket = abuff; //debug thing dcp = " "; // another one if (abuff != NULL) { abuff->dest = destINET; #ifdef DEBUGTHIRDPARTY if (abuff->aprsType == APRS3RDPARTY){ string logEntry = abuff->call + ": " + *abuff; WriteLog(logEntry, DEBUGLOG); // DEBUG CODE } #endif if ((abuff->hasBeenIgated()) && (abuff->aprsType == APRS3RDPARTY)) abuff->aprsType = APRSREJECT; if (abuff->aprsType == APRS3RDPARTY){ // Convert 3rd party packets not previously // igated to normal packets abuff->thirdPartyToNormal(); //cerr << "Converted a 3rd party packet\n" ; } //Debug: Prints hash value, packet and marks duplicates with X to console // char f; // if(dup) f = 'X'; else f = ' '; // printf("%c %08X %s",f,abuff->hash,abuff->c_str()); //if(dup) cerr << "DUP: " << abuff->c_str(); // This option enables the adding of callsign of the sender for // so we can see where it entered the internet system. #ifdef INET_TRACE // Now insert the injecting callsign and IIPPE (q string) info into the path if ((abuff->valid_ax25) && ((abuff->EchoMask & srcSTATS) == 0)){ string src_call = MyCall; //Source call defaults to our own Igate call. if (abuff->IjpIdx == 0) { // If q construct not in packet // we need to convert old packet to new format // and add qAc and source callsign. // Convert UI-View "CALLSIGN,I" style packets string Icall = abuff->removeI(); //If present remove I or I* and preceeding call sign //Also saves callsign in abuff->icall if (abuff->cci) src_call = Icall; //Use preceeding call as source call // Add the q string path elemement abuff->addIIPPE(); // At this point we have a packet with IIPPE (q string) in it. char ps = abuff->getPktSource(); // ps is set to C,X,S,R,r,U,I or Z . // add source callsign after the qAc switch (ps) { //Insert the packet source callsign into path case 'X': //non-validated client or case 'C': //Validated client or Server... case 'S': abuff->addPath(abuff->call); //Add peer ip hex alias or user login call break; case 'U': abuff->addPath(szServerCall); // our UDP port break; case 'r': case 'R': abuff->addPath(src_call); // From a TNC, ours or a users. break; case 'I': abuff->addPath(MyCall); //From Internal use our IGATE call break; case 'Z' : abuff->aprsType = APRSREJECT; // Zero Hops, REJECT. break; } ; //End switch } //End if " no Internet Injection Point Path Element." } //End of valid_ax25 test #endif // DUP CHECK HERE dup = false; if (((abuff->EchoMask) & (srcSTATS | srcSYSTEM)) == 0 ) dup = dupFilter.check(abuff,DUPWINDOW); //Check for duplicates within N second window if (!dup){ //Packet is NOT a duplicate //pthread_mutex_lock(pmtxCount); countLock.get(); TotalFullStreamChars += abuff->length(); //Tally all non-duplicate bytes //pthread_mutex_unlock(pmtxCount); countLock.release(); if (abuff->IjpIdx > 0){ //Packet has q construct in it char ps = abuff->ax25Path[abuff->IjpIdx][2]; //Get packet source character from q string if(abuff->EchoMask & (srcUSER | srcUSERVALID | srcIGATE)){ //Came from server/hub or user igate if (ps =='Z') { if (abuff->ax25Source.compare(szServerCall) != 0) abuff->aprsType = APRSREJECT; // Zero Hops, REJECT. } // end Z test // LOOP DETECTORS. // Loop detector #1, Reject if server call or igate call seen after the qA if ((abuff->queryPath(szServerCall,abuff->IjpIdx + 1) != string::npos) || (abuff->queryPath(MyCall,abuff->IjpIdx) != string::npos)){ abuff->aprsType = APRSREJECT; //Looped packet, REJECT string log_str = abuff->srcHeader + *abuff; WriteLog(log_str, LOOPLOG); //Write offending packet to loop.log countLOOP++; } // End loop detect #1 // Loop detector #2, Reject if user login call seen after qA but not last path element unsigned rc = abuff->queryPath(abuff->call,abuff->IjpIdx + 1); if (( rc != string::npos) && (abuff->aprsType != APRSREJECT)){ if (rc != (unsigned)(abuff->pathSize - 1)){ abuff->aprsType = APRSREJECT; //Looped packet, REJECT string log_str = abuff->srcHeader + *abuff; WriteLog(log_str, LOOPLOG); //Write offending packet to loop.log countLOOP++; } } // End loop detect #2 } // End pkt echomask source check, user/server/hub // Add TRACE path element if required if (((ps == 'I') || traceMode) //Beacon packets always get full trace && (abuff->aprsType != APRSREJECT) && (abuff->sourceSock != SRC_INTERNAL)){ if (abuff->EchoMask & srcUSERVALID){ //From validated connection? unsigned rc = abuff->queryPath(abuff->call,abuff->IjpIdx + 1); if(rc == string::npos) abuff->addPath(abuff->call); //Add user login call if not present in path. } abuff->addPath(szServerCall); //Add our server call } } // end if(abuff->IjpIdx > 0){ // pkt has q construct } // end if(dup == false) // Packet size limiter if (abuff->EchoMask & ~srcSTATS){ //Check all except srcSTATS for size if ((abuff->length() >= BUFSIZE - 5) //Limit total packet length (250 bytes) || (abuff->pathSize > MAXISPATH)){ //Limit path size countOVERSIZE++; abuff->aprsType = APRSREJECT; } } // The following code filters input to the History List if (((abuff->EchoMask & src3RDPARTY) && ((abuff->aprsType == APRSPOS)) /* No Posits fetched from history list */ || (abuff->aprsType == COMMENT) /* No comment packets in the history buffer*/ || (abuff->aprsType == CONTROL) /* No user commands */ || (abuff->msgType == APRSMSGSERVER) /* No user Server control messages */ || (abuff->aprsType == APRSREJECT) /* No rejected packets */ || (abuff->aprsType == APRSUNKNOWN) /* No Unknown packets */ || (abuff->aprsType == APRSID) /* No ID packets */ || (abuff->aprsType == APRSQUERY) /* No Querys */ || (abuff->EchoMask & (srcSTATS | srcSYSTEM)) /* No internally generated packets */ || (dup) /* No duplicates */ || (NOGATE_FILTER && abuff->nogate) /* No NOGATE flagged packets, new in v2.1.5 */ || (!abuff->valid_ax25) /* No invalid ax25 packets */ || (abuff->reformatted))){ /* No 3rd party reformatted pkts */ Hist = false; //None of the above allowed in history list } else { GetMaxAgeAndCount(&MaxAge,&MaxCount); //Set max ttl and count values abuff->ttl = MaxAge; Hist = AddHistoryItem(abuff); //Put item in history list. } // if(abuff->EchoMask & sendDUPS) printf("EchoMask sendDUPS bit is set\n"); if (dup) abuff->EchoMask |= sendDUPS; //If it's a duplicate mark it. if ((abuff->aprsType == APRSQUERY) && (!dup)) { if (abuff->EchoMask & srcUSERVALID) queryResp(abuff->sourceSock,abuff); if (abuff->EchoMask & srcIGATE) queryResp(SRC_IGATE, abuff); if (abuff->EchoMask & srcTNC) { queryResp(SRC_TNC,abuff); abuff->aprsType = APRSREJECT; //Do not pass along any queries from TNC. } } SendToAllClients(abuff); // Send item out on internet subject to additional filtering if (!Hist) { if (abuff) delete abuff; //delete it now if it didn't go to the history list. abuff = NULL; } } else cerr << "Error in DeQueue: abuff is NULL" << endl; } return NULL; //Should never return } //---------------------------------------------------------------------- /* This thread is started by code in dequeueTNC when an ACK packet is detected being sent to the TNC. A pointer to the ack packet is passed to this thread. This thread puts additional identical ack packets into the TNC queue. The allowdup attribute is set so the dup detector won't kill 'em. */ void *ACKrepeaterThread(void *p) { timespec ts; ts.tv_sec = ackRepeatTime; ts.tv_nsec = 0; aprsString *paprs; paprs = (aprsString*)p; aprsString *abuff = new aprsString(*paprs); abuff->allowdup = true; //Bypass the dup filter! paprs->ttl = 0; //Flag tells caller we're done with it. for (int i = 0 ; i < ackRepeats; i++) { nanosleep(&ts,NULL); //Delay ackRepeatTime aprsString *ack = new aprsString(*abuff); tncQueue.write(ack); //ack aprsString will be deleted by TNC queue reader } delete abuff; pthread_exit(0); } //---------------------------------------------------------------------- // Pulls aprsString object pointers off the tncQueue // and sends the data to the TNC. #define RFBUFSIZE 252 void dequeueTNC(void) { bool dup; char *rfbuf = NULL; aprsString* abuff = NULL; char szUserMsg[UMSG_SIZE]; timespec ts; pthread_t tid; abuff = (aprsString*)tncQueue.read(NULL); //Get pointer to a packet off the queue if(abuff == NULL) return; if ((RF_ALLOW == false) //See if sysop allows Internet to RF traffic && ((abuff->EchoMask & srcUDP) == false)){ //UDP packets excepted delete abuff; //No RF permitted, delete it and return. return; } //abuff->print(cout); //debug abuff->ttl = 0; abuff->dest = destTNC; dup = dupFilter.check(abuff, DUPWINDOW); //Check for duplicates during past 20 seconds if (dup) { delete abuff; //kill the duplicate here return; } rfbuf = new char[RFBUFSIZE] ; if (rfbuf != NULL) { if (tncPresent ) { if ((!abuff->allowdup) //Prevent infinite loop! && (abuff->msgType == APRSMSGACK) //Only ack packets && (ackRepeats > 0) ) { //Only if repeats greater than zero abuff->ttl = 1; //Mark it as unprocessed (ttl serves double duty here) int rc = pthread_create(&tid, NULL,ACKrepeaterThread,abuff); //Create ack repeater thread if (rc != 0) { //Make sure it starts cerr << "Error: ACKrepeaterThread failed to start" << endl; abuff->ttl = 0; } else pthread_detach(tid); //Run detached to free resources. } memset(rfbuf, 0, RFBUFSIZE); //Clear the RF buffer if (abuff->valid_ax25) strncpy(rfbuf,abuff->data.c_str(), RFBUFSIZE-2); //copy only data portion to rf buffer //and truncate to 250 bytes else strncpy(rfbuf,abuff->c_str(), RFBUFSIZE-2); //If it had no ax25 header copy the whole thing. RemoveCtlCodes(rfbuf); //remove control codes. strcat(rfbuf,"\r"); //append a CR to the end char* cp = new char[301]; //Will be deleted by conQueue reader. memset(cp, 0, 301); ostrstream msg(cp,300); msg << "Sending to TNC: " << rfbuf << endl << ends; //debug only conQueue.write(cp, 0); TotalTNCtxChars += strlen(rfbuf); if (!tncMute){ if (abuff->reformatted) { msg_cnt++; memset(szUserMsg, 0, UMSG_SIZE); ostrstream umsg(szUserMsg,UMSG_SIZE-1); umsg << abuff->peer << " " << abuff->user << ": " << abuff->getChar() << ends; //ostringstream szUserMsg; //szUserMsg << abuff->peer << " " << abuff->user // << ": " // << abuff->getChar(); // Save the station-to-station message in the log WriteLog(szUserMsg, STSMLOG); } //WriteCom(rfbuf); // <- Send string out on RF via TNC rfWrite(rfbuf); } } } ts.tv_sec = 0; ts.tv_nsec = 10000; // 10 uS timeout for nanosleep() if (abuff){ while (abuff->ttl > 0) nanosleep(&ts, NULL) ; //wait 'till it's safe to delete this... delete abuff; // ...ack repeater thread will set ttl to zero } //...Perhaps the ack repeater should delete this? if (rfbuf) delete rfbuf; return ; } //----------------------------------------------------------------------- int SendSessionStr(int session, const char *s) { int rc, retrys; timespec ts; Lock sendLock(pmtxSend); ts.tv_sec = 0; ts.tv_nsec = 50000000; //50mS timeout for nanosleep() retrys = 0; do { if ((rc = send(session, s, strlen(s), 0)) < 0) { nanosleep(&ts,NULL) ; retrys++; } //try again 50ms later } while ((rc < 0) && (errno == EAGAIN) && (retrys <= MAXRETRYS)); return rc; } //----------------------------------------------------------------------- void endSession(int session, char* szPeer, char* userCall, time_t starttime) { char infomsg[MAX]; Lock sendLock(pmtxSend, false); // don't get this lock quite yet... if (ShutDownServer) pthread_exit(0); sendLock.get(); // Be sure not to close during a send() opteration DeleteSession(session); // remove it from list shutdown(session,2); close(session); // Close socket sendLock.release(); { char* cp = new char[128]; memset(cp, 0, 128); ostrstream msg(cp, 127); msg << szPeer << " " << userCall << " has disconnected" << endl << ends; conQueue.write(cp, 0); } ostringstream sLog; sLog << szPeer << " " << userCall << " disconnected"; time_t endtime = time(NULL); double dConnecttime = difftime(endtime , starttime); int iMinute = (int)(dConnecttime / 60); iMinute = iMinute % 60; int iHour = (int)dConnecttime / 3600; int iSecond = (int)dConnecttime % 60; char timeStr[32]; sprintf(timeStr, "%3d:%02d:%02d", iHour, iMinute, iSecond); sLog << timeStr; // time already adds CFLF WriteLog(sLog.str(), MAINLOG); /*{ memset(infomsg, 0, MAX); ostrstream msg(infomsg,MAX-1); msg << szServerCall << szJAVAMSG << MyLocation << " " << szServerID << szPeer << " " << userCall << " disconnected. " << getConnectedClients() << " users online.\r\n" << ends; } BroadcastString(infomsg); //Say IP address of disconected client */ if (strlen(userCall) > 0) { memset(infomsg, 0, MAX); ostrstream msg(infomsg,MAX-1); msg << szServerCall << szAPRSDPATH << szUSERLISTMSG << MyLocation << ": Disconnected from " << userCall << ". " << getConnectedClients() << " users" << "\r\n" << ends; BroadcastString(infomsg); //Say call sign of disconnected client } pthread_exit(0); } //---------------------------------------------------------------------- //Sends an aprs unnumbered message. No acknowledgement expected. void sendMsg(int session, const string& from, const string& to, const string& text) { string dest; dest = to; ostringstream msg; while (dest.size() < 9) dest += " "; //Pad destination with spaces msg << from << ">" << PGVERS << "::" << dest << ":" << text << "\r\n"; SendSessionStr(session, msg.str().c_str()); //Send ack to user } //----------------------------------------------------------------------- //Sends an aprs ack message void sendAck(int session, const string& from, const string& to, const string& acknum) { string dest; dest = to; ostringstream msg; while (dest.size() < 9) dest += " "; //Pad destination with spaces msg << from << ">" << PGVERS << "::" << dest << ":ack" << acknum << "\r\n"; SendSessionStr(session, msg.str().c_str()); //Send ack to user // cerr << "ACK: " << buff; //DEBUG } //----------------------------------------------------------------------- //An instance of this thread is created for each USER who connects. void *TCPSessionThread(void *p) { char buf[BUFSIZE]; string pgm_vers; bool omniPort = false; SessionParams *psp = (SessionParams*)p; int session = psp->Socket; echomask_t EchoMask = psp->EchoMask; int serverport = psp->ServerPort; timespec ts; bool cmd_lock = true; //When set TRUE user commands locked out. Lock countLock(pmtxCount, false); if(EchoMask & omniPortBit) { omniPort = true; //User defines streams he wants cmd_lock = false; //Allow commands } delete psp; int BytesRead, i; struct sockaddr_in peer_adr; char szPeer[MAX], szErrorUsers[MAX], szErrorLoad[MAX], szLog[MAX], infomsg[MAX], logmsg[MAX]; //const char *szUserStatus; string szUserStatus; unsigned char c; char star = '*'; unsigned adr_size = sizeof(peer_adr); int n, rc,data; bool verified = false, loggedon = false; ULONG State = BASE; char userCall[10]; char tc, checkdeny; string szRestriction; //These deal with Telnet protocol option negotiation suppression int iac,sbEsc; #define IAC 255 #define SB 250 #define SE 240 #define DO 253 #define DONT 254 #define WILL 251 #define WONT 252 #define Echo 1 #define SGA 3 #define OPT_LINEMODE 34 //This string puts a telnet client into character at a time mode unsigned char character_at_a_time[] = {IAC, WILL, SGA, IAC, WILL, Echo, '\0'}; //Puts telnet client in lin-at-a-time mode //unsigned char line_at_a_time[] = {IAC,WONT,SGA,IAC,WONT,Echo,'\0'}; char szUser[16], szPass[16]; if (session < 0) return NULL; memset(szPeer, 0, MAX); memset(szLog, 0, MAX); memset(infomsg, 0, MAX); memset(logmsg, 0, MAX); //pthread_mutex_lock(pmtxCount); countLock.get(); TotalConnects++; //pthread_mutex_unlock(pmtxCount); countLock.release(); time_t starttime = time(NULL); szPeer[0] = '\0'; userCall[0] = '\0'; if (getpeername(session, (struct sockaddr *)&peer_adr, &adr_size) == 0) strncpy(szPeer, inet_ntoa(peer_adr.sin_addr), 32); { memset(szErrorUsers, 0, MAX); memset(szErrorLoad, 0, MAX); ostrstream msg1(szErrorUsers, MAX-1); //Build an error message in szErrorUsers ostrstream msg2(szErrorLoad, MAX-1); //Build an error message in szErrorLoad msg1 << szServerCall << szJAVAMSG << "Limit of " << MaxClients << " users exceeded. Try again later. Disconnecting...\r\n" << ends; msg2 << szServerCall << szJAVAMSG << "Server load limit of " << MaxLoad << " bytes/sec exceeded. Try again later. Disconnecting...\r\n" << ends; } { char* cp = new char[256]; memset(cp, 0, 256); ostrstream msg(cp, 255); msg << szPeer << " has connected to port " << serverport << endl << ends; conQueue.write(cp,0); //queue reader deletes cp } { ostringstream msg; msg << szPeer << " connected on " << serverport; /* << " " << aprsString::getObjCount() << "/" << ItemCount */ //Debug //<< ends; WriteLog(msg.str(), MAINLOG); } data = 1; //Set socket for non-blocking ioctl(session, FIONBIO, (char*)&data, sizeof(int)); if (EchoMask == 0) rc = SendSessionStr(session, (char*)character_at_a_time); //Sysop mode. Put Telnet client in char mode rc = SendSessionStr(session, SIGNON); if (rc < 0) endSession(session, szPeer, userCall, starttime); if (NetBeacon.length() != 0) rc = SendSessionStr(session, NetBeacon.c_str()); if (rc < 0) endSession(session, szPeer, userCall, starttime); if ((EchoMask & sendHISTORY) && (History_ALLOW)){ n = SendHistory(session, (EchoMask & ~(srcSYSTEM | srcSTATS))); //Send out the previous N minutes of APRS activity //except messages generated by this system. if (n < 0) { ostringstream msg; msg << szPeer << " aborted during history dump on " << serverport; WriteLog(msg.str(), MAINLOG); endSession(session, szPeer, userCall, starttime); } { char* cp = new char[256]; memset(cp,0,256); ostrstream msg(cp, 255); msg << "Sent " << n << " history items to " << szPeer << endl << ends; conQueue.write(cp, 0); //queue reader deletes cp } } if (!omniPort){ char *pWelcome = new char[CONFPATH.length() + WELCOME.length() + 1]; strcpy(pWelcome, CONFPATH.c_str()); strcat(pWelcome, WELCOME.c_str()); rc = SendFiletoClient(session, pWelcome); //Read Welcome message from file if (rc < 0) { ostringstream msg; msg << szPeer << " aborted welcome msg on " << serverport; WriteLog(msg.str(), MAINLOG); delete pWelcome; endSession(session, szPeer, userCall, starttime); } delete pWelcome; } SessionParams* sp = AddSession(session,EchoMask,0); if (sp == NULL) { if (serverLoad_s < MaxLoad){ rc = SendSessionStr(session,szErrorUsers); WriteLog(string("Error, too many users "), MAINLOG); } else { rc = SendSessionStr(session,szErrorLoad); WriteLog(string("Error, max server load exceeded"), MAINLOG); } if (rc == -1) perror("AddSession"); endSession(session, szPeer, userCall, starttime); char* cp = new char[256]; memset(cp,0,256); ostrstream msg(cp,255); msg << "Can't add client to session list, too many users or max load exceeded - closing connection.\n" << ends; conQueue.write(cp,0); } AddSessionInfo(session,"*",szPeer,serverport, "*"); if(EchoMask == 0) //Empty echomask means this is a Sysop TNC session rc = SendSessionStr(session,"\r\nHit Esc key to login for TNC access, ctrl D to disconnect.\r\n"); { memset(infomsg, 0, MAX); ostrstream msg(infomsg, MAX-1); msg << szServerCall << szJAVAMSG << MyLocation << " " << szServerID << szPeer << " connected " << getConnectedClients() << " users online.\r\n" << ends; aprsString logon_msg(infomsg, SRC_INTERNAL, srcSYSTEM); BroadcastString(infomsg); if ((EchoMask & srcSYSTEM) == 0) { //If user can't see SYSTEM messages logon_msg.addIIPPE('Z'); logon_msg.addPath(szServerCall); SendSessionStr(session,logon_msg.c_str());//Send a copy directly to him } } int cc = getConnectedClients(); if (cc > MaxConnects) MaxConnects = cc; iac = 0; sbEsc = false; do { /* The logic here is that 1 char is fetched on each loop and tested for a CR or LF before the buffer is processed. If "i" is -1 then any socket error other that "would block" causes BytesRead and i to be set to zero which causes the socket to be closed and the thread terminated. If "i" is greater than 0 the character in "c" is put in the buffer. */ BytesRead = 0; //initialize byte counter do { if ((charQueue.ready()) && (State == REMOTE) ) { int ic; charQueue.read(&ic); //RH7 FIX 11-1-00 tc = (char)ic; send(session,&tc,1,0); //send a tnc character to sysop //printhex(&tc,1); } do { c = 0xff; i = recv(session,&c,1,0); //get 1 byte into c } while (c == 0x00); if ((State == USER) && (i != -1)) send(session,&c,1,0); //Echo chars back to telnet client if TNC USER logon if ((State == PASS) && (i != -1) && (c != 0x0a) && (c != 0x0d)) send(session,&star,1,0); //Echo "*" if TNC password is being entered. if (ShutDownServer) raise(SIGTERM); //Terminate this process //if (State == REMOTE) printhex(&c,1); debug if (i == -1) { if (errno != EWOULDBLOCK) { BytesRead = 0; //exit on errors other than EWOULDBLOCK i = 0; } //cerr << "i=" << i << " chTimer=" << chTimer << " c=" << c << endl; if (State != REMOTE) { ts.tv_sec = 1; ts.tv_nsec = 0; nanosleep(&ts,NULL); // Don't hog cpu while in loop awaiting data } } if (sp->dead) { //force disconnect if connection is dead BytesRead = 0; i = 0; } if (i != -1) { //Got a real character from the net if (!loggedon) { if ((c == IAC) && (!sbEsc)) iac = 3; //This is a Telnet IAC byte. Ignore the next 2 chars if ((c == SB) && (iac == 2)) sbEsc = true; //SB is suboption begin. } //Ignore everything until SE, suboption end. // printhex(&c,1); //debug //if ( !((lastch == 0x0d) && (c == 0x0a)) && (c != 0) && (iac == 0) ) //reject LF after CR and NULL // This logic discards CR or LF if it's the first character on the line. bool cLFCR = (( c == LF) || ( c == CR)); bool rejectCH = (((BytesRead == 0) && cLFCR) || (c == 0)) ; //also discard NULLs if ((!rejectCH) && (iac == 0)) { if (BytesRead < BUFSIZE-3) buf[BytesRead] = c; BytesRead += i; //Only enable control char interpreter if user is NOT logged on in client mode if (!loggedon){ switch (c) { case 0x04: i = 0; //Control-D = disconnect BytesRead = 0; break; case 0x1b: if ((State == BASE) && tncPresent && (EchoMask == 0)) { //ESC = TNC control sp->EchoMask = 0; //Stop echoing the aprs data stream. rc = SendSessionStr(session,"\r\n220 Remote TNC control mode. to quit.\r\n503 User:"); if (rc < 0) endSession(session,szPeer,userCall,starttime); State = USER; // Set for remote control of TNC BytesRead = 0; break; } // = exit TNC control if ((State != BASE) && tncPresent) { if (State == REMOTE){ ostringstream log; log << szPeer << " " << szUser << " " << " Exited TNC remote sysop mode." << endl; WriteLog(log.str(), MAINLOG); } tncMute = false; TncSysopMode = false; State = BASE; // Turn off remote rc = SendSessionStr(session,"\r\n200 Exit remote mode successfull\r\n"); if (rc < 0) endSession(session,szPeer,userCall,starttime); sp->EchoMask = EchoMask; //Restore aprs data stream. BytesRead = 0; //Reset buffer } //i = 0; break; }; }//end if (loggedon==false) if ((State == REMOTE) && (c != 0x1b) && (c != 0x0) && (c != 0x0a)) { char chbuf[2]; chbuf[0] = c; chbuf[1] = '\0'; //WriteCom(chbuf); //Send chars to TNC in real time if REMOTE rfWrite(chbuf); send(session, chbuf, 1, 0); //Echo chars back to telnet client //printhex(chbuf,1); //Debug } } }else c = 0; if (!loggedon){ if (c == SE) { sbEsc = false; iac = 0; } //End of telnet suboption string if (!sbEsc) if(iac-- <= 0) iac = 0; //Count the bytes in the Telnet command string } //Terminate loop when we see a CR or LF if it's not the first char on the line. } while (((i != 0) && (c != 0x0d) && (c != 0x0a))||((BytesRead == 0) && (i != 0))); if ((BytesRead > 0) && ( i > 0)) { // 1 or more bytes needed i = BytesRead - 1; buf[i++] = 0x0d; //Put a CR-LF on the end of the buffer buf[i++] = 0x0a; buf[i++] = 0; //pthread_mutex_lock(pmtxCount); countLock.get(); if (sp) { TotalUserChars += i - 1; //Keep a tally of input bytes on this connection. sp->bytesIn += i - 1; sp->lastActive = time(NULL); } //pthread_mutex_unlock(pmtxCount); countLock.release(); if (State == REMOTE) { buf[i-2] = '\0'; //No line feed required for TNC //printhex(buf,strlen(buf)); //debug code } if (State == BASE) { //Internet to RF messaging handler bool sentOnRF=false; aprsString atemp(buf,session,srcUSER,szPeer,userCall); /* if(atemp.aprsType == APRSQUERY){ // non-directed query ? queryResp(session,&atemp); // yes, send our response } */ /* if(atemp.aprsType == APRSMSG) { //DEBUG cerr << atemp.c_str() << "*" << atemp.ax25Source << "*" << " msgType=" << atemp.msgType << " userCall=*" << userCall << "*" << " omniPort=" << omniPort << " cmd_lock=" << cmd_lock << " acknum=" << atemp.acknum << endl; } */ // User stream filter request commands processed here if((atemp.aprsType == APRSMSG) //Server command in a message && (atemp.msgType == APRSMSGSERVER) && (omniPort) //This only works on omniPort && (!cmd_lock)) { //Commands not locked out if (atemp.ax25Source.compare(userCall) == 0){ // From logged on user ONLY string s; atemp.getMsgText(s); //Extract message text into string s. aprsString cmd(s.c_str(),session,srcUSER,szPeer,userCall); //Make s into aprsString if (cmd.cmdType == CMDPORTFILTER){ EchoMask = cmd.EchoMask; //Set user requested EchoMask sp->EchoMask = cmd.EchoMask; atemp.EchoMask = 0; printf("Stream Filter EchoMask= %08lX\n",EchoMask); //Debug if (atemp.acknum.length() > 0) //If ack number present... sendAck(session,"SERVER",userCall,atemp.acknum); // Then send ACK if (EchoMask & sendHISTORY) SendHistory(session,(EchoMask & ~(srcSYSTEM | srcSTATS))); } } } if((atemp.aprsType == CONTROL) //Naked control command && (omniPort) //To omniport only && (!cmd_lock) //Commands not locked out && (!loggedon)){ //Execute only prior to logon! if(atemp.cmdType == CMDPORTFILTER){ EchoMask = atemp.EchoMask; //Set user requested EchoMask sp->EchoMask = atemp.EchoMask; // printf("Stream Filter EchoMask= %08lX\n",EchoMask); //Debug if (EchoMask & sendHISTORY) SendHistory(session,(EchoMask & ~(srcSYSTEM | srcSTATS))); } if (atemp.cmdType == CMDLOCK) cmd_lock = true; //Prevent future command execution. } string vd; unsigned idxInvalid=0; if (atemp.aprsType == APRSLOGON) { loggedon = true; verified = false; vd = atemp.user + atemp.pass ; /* 2.0.7b Security bug fix - don't allow ;!@#$%~^&*():="\<>[] in user or pass! */ if (((idxInvalid = vd.find_first_of(";!@#$%~^&*():=\"\\<>[]",0,20)) == string::npos) && (atemp.user.length() <= 15) /*Limit length to 15 or less*/ && (atemp.pass.length() <= 15)){ if (validate(atemp.user.c_str(), atemp.pass.c_str(),APRSGROUP, APRS_PASS_ALLOW) == 0) verified = true; } else { if (idxInvalid != string::npos){ char *cp = new char[256]; memset(cp,0,256); ostrstream msg(cp,255); msg << szPeer << " Invalid character \"" << vd[idxInvalid] << "\" in APRS logon" << endl << ends ; conQueue.write(cp,0); //cp deleted by queue reader WriteLog(cp,MAINLOG); } } checkdeny = toupper(checkUserDeny(atemp.user)); // returns + , L or R // + = no restriction // L = No login // R = No RF if (verified) { szUserStatus = szVERIFIED ; if (sp) sp->vrfy = true; } else szUserStatus = szUNVERIFIED; switch (checkdeny){ case 'L': szUserStatus = szACCESSDENIED; //Read only access szRestriction = szRM2; verified = false; break; case 'R': szRestriction = szRM3; //No send on RF access break; default: szRestriction = szRM1; } if (checkdeny != 'L'){ memset(infomsg,0,MAX); ostrstream msg(infomsg,MAX-1); msg << szServerCall << szAPRSDPATH << szUSERLISTMSG << MyLocation << ": " << szUserStatus << "user " << atemp.user << " logged on using " << atemp.pgmName << " " << atemp.pgmVers << "." << "\r\n" /* Don't want acks from this! */ << ends; aprsString logon_msg(infomsg, SRC_INTERNAL, srcSYSTEM); BroadcastString(infomsg); //send users logon status to everyone if ((EchoMask & srcSYSTEM) == 0){ //If user can't see system messages logon_msg.addIIPPE('Z'); logon_msg.addPath(szServerCall); SendSessionStr(session,logon_msg.c_str()); //send him his own private copy } //so he knows the logon worked } { ostringstream msg; msg << szPeer << " " << atemp.user << " " << atemp.pgmName << " " << atemp.pgmVers << " " << szUserStatus; WriteLog(msg.str(), MAINLOG); } strncpy(userCall, atemp.user.c_str(), 9); //save users call sign pgm_vers = atemp.pgmName + " " + atemp.pgmVers; AddSessionInfo(session, userCall, szPeer, serverport, pgm_vers.c_str()); //put it here so HTTP monitor can see it if((!verified) || (checkdeny == 'R')) { char call_pad[] = " "; //9 spaces int len = 0; if ((len = atemp.user.length()) > 9) len = 9; memmove(call_pad, atemp.user.c_str(), len); { memset(infomsg, 0, MAX); ostrstream msg(infomsg, MAX-1); //Message to user... msg << szServerCall << szAPRSDPATH << ':' << call_pad << ":" << szRestriction << ends ; } if ((rc = SendSessionStr(session, infomsg)) < 0) endSession(session, szPeer, userCall, starttime); if (checkdeny == '+'){ memset(infomsg,0,MAX); ostrstream msg(infomsg,MAX-1); //messsage to user msg << szServerCall << szAPRSDPATH << ':' << call_pad << ":Contact program author for registration number.\r\n" << ends ; if ((rc = SendSessionStr(session, infomsg)) < 0) endSession(session, szPeer, userCall, starttime); } } if (verified && (atemp.pgmName.compare("monitor") == 0)) { if (sp){ sp->EchoMask = srcSTATS; char prompt[] = "#Entered Monitor mode\n\r"; aprsString *amsg = new aprsString(prompt, SRC_USER, srcSTATS); sendQueue.write(amsg); AddSessionInfo(session, userCall, szPeer, serverport, "Monitor"); } } } // One of the stations in the gate2rf list? bool RFalways = find_rfcall(atemp.ax25Source,rfcall); if (verified && (!RFalways) && (atemp.aprsType == APRSMSG) && (checkdeny == '+')) { sentOnRF = false; atemp.changePath("TCPIP*","TCPIP"); sentOnRF = sendOnRF(atemp, szPeer, userCall, srcUSERVALID); // Send on RF if dest local if (sentOnRF) { //Now find the posit for this guy in the history list // and send it too. aprsString* posit = getPosit(atemp.ax25Source,srcIGATE | srcUSERVALID); if (posit != NULL) { time_t Time = time(NULL); //get current time if ((Time - posit->timeRF) >= 60*10) { //every 10 minutes only timestamp(posit->ID, Time); //Time stamp the original in hist. list if (posit->thirdPartyReformat(MyCall.c_str())) // Reformat it for RF delivery tncQueue.write(posit); //posit will be deleted elsewhere else delete posit; //Delete if conversion failed } else delete posit; } /*else cout << "Can't find matching posit for " << atemp.ax25Source << endl << flush; //Debug only */ } } // Filter out COMMENT type packets, eg: # Tickle if ( verified && (atemp.aprsType != COMMENT) && (atemp.aprsType != APRSLOGON) //No logon strings && (atemp.msgType != APRSMSGSERVER) //No Server control messages && (atemp.aprsType != CONTROL)) { //No naked control strings aprsString* inetpacket = new aprsString(buf, session, srcUSERVALID, szPeer, userCall); inetpacket->changePath("TCPIP*", "TCPIP") ; if (inetpacket->aprsType == APRSMIC_E) //Reformat Mic-E packets reformatAndSendMicE(inetpacket,sendQueue); else sendQueue.write(inetpacket); //note: inetpacket is deleted in DeQueue } /* Here we allow users who logged on with a CALL but used -1 as a password to send data to the internet but restrict them to there OWN packets and we add TCPXX* to the path */ if (!verified && (atemp.aprsType != COMMENT) //Not a comment && (atemp.aprsType != APRSLOGON) //Not a logon && (atemp.valid_ax25) //Valid AX25 format && (checkdeny != 'L')) { //Not denied aprsString* inetpacket = new aprsString(buf,session,srcUSER,szPeer,userCall); bool fromUser = false; // compare users logon call with packet source call (case sensitive) if (inetpacket->ax25Source.compare(userCall) == 0) fromUser = true; if (fromUser){ //Ok, packet has users call in the FROM field (case sensitive match) inetpacket->changePath("TCPIP*", "TCPIP") ; if (inetpacket->changePath("TCPXX*", "TCPIP*")) //Change to TCPXX* inetpacket->changeIIPPE("qAX"); //Change qA? to qAX if present else inetpacket->aprsType = APRSREJECT; //Reject if no TCPIP in path } else { //Not from user inetpacket->aprsType = APRSREJECT; //Unverified users not allowed to relay from others } sendQueue.write(inetpacket); //note: inetpacket is deleted in DeQueue } if ((atemp.aprsType == APRSMSG) && (!RFalways) ) { aprsString* posit = getPosit(atemp.ax25Source, srcIGATE | srcUSERVALID | srcTNC); if (posit != NULL) { posit->EchoMask = src3RDPARTY; sendQueue.write(posit); //send matching posit only to msg port } } // Here's where the priviledged get their posits sent to RF full time. if (configComplete && verified && RFalways && (!StationLocal(atemp.ax25Source, srcTNC)) && (!atemp.tcpxx) && (checkdeny == '+')) { aprsString* RFpacket = new aprsString(buf, session, srcUSER, szPeer, userCall); RFpacket->changePath("TCPIP*","TCPIP"); if (RFpacket->aprsType == APRSMIC_E) { //Reformat Mic-E packets if (ConvertMicE){ aprsString* posit = NULL; aprsString* telemetry = NULL; RFpacket->mic_e_Reformat(&posit,&telemetry); if (posit){ posit->thirdPartyReformat(MyCall.c_str()); // Reformat it for RF delivery tncQueue.write(posit); //Send reformatted packet on RF } if (telemetry) { telemetry->thirdPartyReformat(MyCall.c_str()); // Reformat it for RF delivery tncQueue.write(telemetry); //Send packet on RF } delete RFpacket; } else { if (RFpacket->thirdPartyReformat(MyCall.c_str())) tncQueue.write(RFpacket); // Raw MIC-E data to RF else delete RFpacket; //Kill it if 3rd party conversion fails. } } else { if (RFpacket->thirdPartyReformat(MyCall.c_str())) tncQueue.write(RFpacket); // send data to RF else delete RFpacket; //Kill it if 3rd party conversion fails. } } } int j = i-3; if ((State == PASS) && (BytesRead > 1)) { strncpy(szPass,buf,15); if (j<16) szPass[j] = '\0'; else szPass[15] = '\0'; bool verified_tnc = false; unsigned idxInvalid=0; int valid = -1; string vd = string(szUser) + string(szPass) ; // 2.0.7b Security bug fix - don't allow ;!@#$%~^&*():="\<>[] in szUser or szPass! //Probably not needed in 2.0.9 because validate is not an external pgm anymore! if (((idxInvalid = vd.find_first_of(";!@#$%~^&*():=\"\\<>[]",0,20)) == string::npos) && (strlen(szUser) <= 16) //Limit length to 16 or less && (strlen(szPass) <= 16)){ valid = validate(szUser,szPass,TNCGROUP,APRS_PASS_ALLOW); //Check user/password } else { if (idxInvalid != string::npos){ char *cp = new char[256]; memset(cp,0,256); ostrstream msg(cp,255); msg << szPeer << " Invalid character \"" << vd[idxInvalid] << "\" in TNC logon" << endl << ends ; conQueue.write(cp,0); //cp deleted by queue reader WriteLog(cp,MAINLOG); } } if (valid == 0) verified_tnc = true; if (verified_tnc) { if (!TncSysopMode) { TncSysopMode = true; State = REMOTE; tncMute = true; if ((rc = SendSessionStr(session,"\r\n230 Login successful. to exit remote mode.\r\n")) < 0) endSession(session,szPeer,userCall,starttime); ostringstream log; log << szPeer << " " << szUser << " Entered TNC remote sysop mode." << endl; WriteLog(log.str(), MAINLOG); } else { if ((rc = SendSessionStr(session,"\r\n550 Login failed, TNC is busy\r\n")) < 0) endSession(session,szPeer,userCall,starttime); ostringstream log; log << szPeer << " " << szUser << " Login failed: TNC busy." << endl; WriteLog(log.str(), MAINLOG); State = BASE; if (sp){ sp->EchoMask = EchoMask; //Restore original echomask AddSessionInfo(session, userCall, szPeer, serverport, pgm_vers.c_str()); } else { /* failed to get a session */ } } } else { if ((rc = SendSessionStr(session,"\r\n550 Login failed, invalid user or password\r\n")) < 0) endSession(session, szPeer, userCall, starttime); ostringstream log; log << szPeer << " " << szUser << " " << szPass << " Login failed: Invalid user or password." << endl; WriteLog(log.str(), MAINLOG); State = BASE; if (sp) { sp->EchoMask = EchoMask; AddSessionInfo(session, userCall, szPeer, serverport, pgm_vers.c_str()); } else { /* failed to get a session */ } } } if ((State == USER) && (BytesRead > 1)) { strncpy(szUser,buf,15); if (j < 16) szUser[j] = '\0'; else szUser[15]='\0'; State = PASS; if ((rc = SendSessionStr(session, "\r\n331 Pass:")) < 0) endSession(session, szPeer, userCall, starttime); } } } while (BytesRead != 0);// Loop back and get another line from remote user. if (State == REMOTE){ tncMute = false; TncSysopMode = false; } endSession(session, szPeer, userCall, starttime); pthread_exit(0); //Actually thread exits from endSession above. } //------------------------------------------------------------------------ // One instance of this thread is created for each port definition in aprsd.conf. // Each instance listens on the a user defined port number for clients // wanting to connect. Each connect request is assigned a // new socket and a new instance of TCPSessionThread() is created. void *TCPServerThread(void *p) { int s = 0, rc = 0; unsigned i; SessionParams* session; pthread_t SessionThread; int backlog = 5; // Backlog of pending connections struct sockaddr_in server,client; timespec ts; int optval; ServerParams *sp = (ServerParams*)p; sp->pid = getpid(); s = socket(PF_INET, SOCK_STREAM, 0); sp->ServerSocket = s; optval = 1; //Allow address reuse setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof(int)); setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char*)&optval, sizeof(int)); if (s == 0) { perror("TCPServerThread socket error"); ShutDownServer = true; return NULL; } memset(&server, 0, sizeof(server)); memset(&client, 0, sizeof(client)); server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons(sp->ServerPort); if (bind(s, (struct sockaddr *)&server, sizeof(server)) < 0) { perror("TCPServerThread bind error"); ShutDownServer = true; return NULL; } ts.tv_sec = 0; ts.tv_nsec = 100000000; //100mS timeout for nanosleep() while (!configComplete) nanosleep(&ts, NULL); //Wait till everything else is running. listen(s, backlog); for(;;) { i = sizeof(client); session = new SessionParams; session->Socket = accept(s, (struct sockaddr *)&client, &i); session->EchoMask = sp->EchoMask; session->ServerPort = sp->ServerPort; if (ShutDownServer) { close(s); if (session->Socket >= 0) close(session->Socket); cerr << "Ending TCP server thread" << endl; delete session; if (ShutDownServer) raise(SIGTERM); //Terminate this process } if (session->Socket < 0) { perror( "Error in accepting a connection"); delete session; } else if (session->EchoMask & wantHTML) { rc = pthread_create(&SessionThread, NULL, HTTPServerThread, session); //Added in 2.1.2 } else rc = pthread_create(&SessionThread, NULL, TCPSessionThread, session); if (rc != 0) { cerr << "Error creating new client thread." << endl; shutdown(session->Socket,2); rc = close(session->Socket); // Close it if thread didn't start delete session; if (rc < 0) perror("Session Thread close()"); } else //session will be deleted in TCPSession Thread pthread_detach(SessionThread); //run session thread DETACHED! memset(&client, 0, sizeof(client)); } return 0; } //---------------------------------------------------------------------- //This thread listens to a UDP port and sends all packets heard to all //logged on clients unless the destination call is "TNC" it sends it //out to RF. void *UDPServerThread(void *p) { #define UDPSIZE 256 int s,i; unsigned client_address_size; struct sockaddr_in client, server; char buf[UDPSIZE+3]; UdpParams* upp = (UdpParams*)p; int UDP_Port = upp->ServerPort; //UDP port set in aprsd.conf char *CRLF = "\r\n"; Lock countLock(pmtxCount, false); upp->pid = getpid(); /* * Create a datagram socket in the internet domain and use the * default protocol (UDP). */ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("Failed to create datagram socket"); ShutDownServer = true; return NULL; } /* * * Bind my name to this socket so that clients on the network can * send me messages. (This allows the operating system to demultiplex * messages and get them to the correct server) * * Set up the server name. The internet address is specified as the * wildcard INADDR_ANY so that the server can get messages from any * of the physical internet connections on this host. (Otherwise we * would limit the server to messages from only one network interface) */ server.sin_family = AF_INET; /* Server is in Internet Domain */ server.sin_port = htons(UDP_Port) ;/* 0 = Use any available port */ server.sin_addr.s_addr = INADDR_ANY; /* Server's Internet Address */ if (bind(s, (struct sockaddr *)&server, sizeof(server)) < 0) { perror("Datagram socket bind error"); ShutDownServer = true; return NULL; } cout << "UDP Server listening on port " << UDP_Port << endl; for (;;) { //Loop forever client_address_size = sizeof(client); i = recvfrom(s, buf, UDPSIZE, 0, (struct sockaddr *) &client, &client_address_size) ; //Get client udp data bool sourceOK = false; int n=0; do { //look for clients IP address in list of trusted addresses. long maskedTrusted = Trusted[n].sin_addr.s_addr & Trusted[n].sin_mask.s_addr; long maskedClient = client.sin_addr.s_addr & Trusted[n].sin_mask.s_addr; if(maskedClient == maskedTrusted) sourceOK = true; n++; } while((n < nTrusted) && (!sourceOK)) ; if (sourceOK && configComplete && (i > 0)){ int j = strlen(buf); if (j < i) i = j; //Remove trailing NULLs if (buf[i-1] != '\n') strcat(buf,CRLF); //Add a CR/LF if not present ostringstream log; log << inet_ntoa(client.sin_addr) << ": " << buf; WriteLog(log.str(), UDPLOG); aprsString* abuff = new aprsString(buf, SRC_UDP, srcUDP, inet_ntoa(client.sin_addr), "UDP"); countLock.get(); TotalUdpChars += abuff->length(); countLock.release(); //printhex(abuff->c_str(),strlen(abuff->c_str())); //debug if (abuff->ax25Dest.compare("TNC") == 0 ) { //See if it's data for the TNC tncQueue.write(abuff,SRC_UDP); //Send remaining data from ourself to the TNC } else { sendQueue.write(abuff,0); //else send data to all users. } //Note that abuff is deleted in History list expire func. } if (ShutDownServer) raise(SIGTERM); //Terminate this process } return NULL; } //---------------------------------------------------------------------- /* Receive a line of ASCII from "sock" . Nulls, line feeds and carrage returns are removed. End of line is determined by CR or LF or CR-LF or LF-CR . CR-LF sequences appended before the string is returned. If no data is received in "timeoutMax" seconds it returns int Zero else it returns the number of characters in the received string. Returns ZERO if timeout and -2 if socket error. */ int recvline(int sock, char *buf, int n, int *err,int timeoutMax) { int c; int i,BytesRead ,timeout; timespec ts; *err = 0; BytesRead = 0; bool abort ; timeout = timeoutMax; abort = false; do { c = -1; i = recv(sock,&c,1,0); //get 1 byte into c if (i == 0) abort = true; //recv returns ZERO when remote host disconnects if (i == -1) { *err = errno; if ((*err != EWOULDBLOCK) || (ShutDownServer == true)) { BytesRead = 0; i = -2; abort = true; //exit on errors other than EWOULDBLOCK } ts.tv_sec = 1; ts.tv_nsec = 0; nanosleep(&ts, NULL); // Wait 1 sec. Don't hog cpu while in loop awaiting data if (timeout-- <= 0) { i = 0; abort = true; //Force exit if timeout } //cout << timeout << " Waiting... abort= " << abort << "\n"; //debug code } if (i == 1) { c &= 0xff ; // <--- Changed to support 8 bit wide character sets in version 2.1.5 bool cLFCR = (( c == LF) || ( c == CR)); //true if c is a LF or CR bool rejectCH = (((BytesRead == 0) && cLFCR ) || (c == 0)) ; if ((BytesRead < (n - 3)) && (rejectCH == false)) { //reject if LF or CR is first on line or it's a NULL buf[BytesRead] = (char)c; //and discard data that runs off the end of the buffer BytesRead++; // We have to allow 3 extra bytes for CR,LF,NULL timeout = timeoutMax; } } } while ((c != CR) && (c != LF) && (abort == false)); /* Loop while c is not CR or LF */ /* And no socket errors or timeouts */ //cerr << "Bytes received=" << BytesRead << " abort=" << abort << endl; //debug code if ((BytesRead > 0) && (!abort) ) { // 1 or more bytes needed i = BytesRead -1 ; buf[i++] = (char)CR; //make end-of-line CR-LF buf[i++] = (char)LF; buf[i++] = 0; //Stick a NULL on the end. return i-1; //Return number of bytes received. } //if(i == -2) cerr << "errorno= " << *err << endl; //debug return i; //Return 0 if timeout or // Return -2 if socket error } //--------------------------------------------------------------------------------------------- ConnectParams* getNextHub(ConnectParams* pcp) { int i = 0; if (!pcp->hub) return pcp; while((i < nIGATES) && (pcp != &cpIGATE[i])) //Find current hub i++; //cerr << "Previous hub = " << cpIGATE[i].RemoteName << endl; //debug i++; while ((i < nIGATES) && (!cpIGATE[i].hub)) i++; //Find next hub if(i == nIGATES){ i = 0; //Wrap around to start again while ((i < nIGATES) && (!cpIGATE[i].hub)) i++; } //cerr << "Next hub = " << cpIGATE[i].RemoteName << endl; //debug if (cpIGATE[i].hub){ cpIGATE[i].pid = getpid(); cpIGATE[i].connected = false; cpIGATE[i].bytesIn = 0; cpIGATE[i].bytesOut = 0; cpIGATE[i].starttime = time(NULL); cpIGATE[i].lastActive = time(NULL); return &cpIGATE[i]; //Return pointer to next hub } return pcp ; } //--------------------------------------------------------------------------------------------- /* ***** TCPConnectThread ***** This thread connects to another aprsd or other APRS Server machine as defined in aprsd.conf with the "server", "igate" and "hub commands. One instance of this thread is created for each and every connection. Only a one hub thread is created regardless of the number of "hub" connectons defined. Each hub will be tried until an active one is found. */ void *TCPConnectThread(void *p) { int rc = 0, length, state; int clientSocket; int data; ConnectParams *pcp; int err; int retryTimer; timespec ts; bool gotID = false; time_t connectTime = 0; bool hubConn; SessionParams *sp = NULL; //char ip_hex_alias[32]; Lock countLock(pmtxCount, false); Lock sendLock(pmtxSend, false); int h_err; char h_buf[1024]; struct hostent hostinfo_d; //struct hostent *hinfo = NULL; struct hostent *hostinfo = NULL; struct sockaddr_in host; char buf[BUFSIZE+1]; char remoteIgateInfo[256]; char szLog[MAX]; buf[BUFSIZE] = 0x55; //Debug buffer overflow pcp = (ConnectParams*)p; pcp->pid = getpid(); pcp->connected = false; pcp->bytesIn = 0; pcp->bytesOut = 0; pcp->starttime = time(NULL); pcp->lastActive = time(NULL); hubConn = pcp->hub; //Mark this as an IGATE or HUB connection retryTimer = 60; //time between connection attempts in seconds memset(remoteIgateInfo, 0, 256); do { state = 0; hostinfo = NULL; ostringstream os_iphex; //Thread-Safe version of gethostbyname() rc = gethostbyname_r(pcp->RemoteName, &hostinfo_d, h_buf, 1024, &hostinfo, &h_err); if (rc || (hostinfo == NULL)){ char* cp = new char[256]; memset(cp, 0, 256); ostrstream msg(cp, 255); msg << "Can't resolve igate host name: " << pcp->RemoteName << endl << ends; WriteLog(cp, MAINLOG); conQueue.write(cp, 0); } else state = 1; if (state == 1) { //cerr << pcp->RemoteName << " " << pcp->RemoteSocket << " Connecting.\n"; clientSocket = socket(AF_INET,SOCK_STREAM, 0); host.sin_family = AF_INET; host.sin_port = htons(pcp->RemoteSocket); host.sin_addr = *(struct in_addr *)*hostinfo->h_addr_list; length = sizeof(host); /* Create HEX format IP address of distant server to use as alias */ os_iphex.flags(ios::hex | ios::uppercase); os_iphex.width(8); os_iphex.fill('0'); os_iphex << ntohl(host.sin_addr.s_addr); //Build hex ip string //<< ends; //cerr << "HEX Ip= " << ip_hex_alias << endl; //DEBUG //pcp->alias = ip_hex_alias; pcp->alias = os_iphex.str(); if ((rc = connect(clientSocket,(struct sockaddr *)&host, length)) < 0) { close(clientSocket); ostringstream os; os << "Connection attempt failed " << pcp->RemoteName << " " << pcp->RemoteSocket; WriteLog(os.str(), MAINLOG); { char* cp = new char[256]; memset(cp, 0, 256); ostrstream msg(cp, 255); msg << szLog << endl << ends; conQueue.write(cp, 0); } gotID = false; state = 0; } else { state++; pcp->connected = true; pcp->starttime = time(NULL); pcp->bytesIn = 0; pcp->bytesOut = 0; ostringstream os; os << "Connected to " << pcp->RemoteName << " " << pcp->RemoteSocket; WriteLog(os.str(), MAINLOG); char* cp = new char[256]; memset(cp, 0, 256); ostrstream msg(cp, 255); msg << os.str() << endl << ends; conQueue.write(cp,0); //cp deleted in queue reader } } if (state == 2) { data = 1; //Set socket for non-blocking ioctl(clientSocket, FIONBIO, (char*)&data, sizeof(int)); int optval = 1; //Enable keepalive option setsockopt(clientSocket, SOL_SOCKET, SO_KEEPALIVE, (char*)&optval, sizeof(int)); /* If user and password are supplied we will send our Internet user and TNC data to the IGATE, otherwise we just read data from the IGATE. NEW IN 2.1.2: If only the user name is supplied without a password we send a password of "-1" and do not send any data. */ if (pcp->user.length() != 0) { cout << "IGATE Login: " << pcp->RemoteName << " " << pcp->user << " " << pcp->pass << endl; ostringstream logon; logon << "user " << pcp->user << " pass " << pcp->pass << " vers " << VERS << "\r\n"; //Send logon string to IGATE or Hub rc = send(clientSocket, logon.str().c_str(), logon.str().length(), 0); //Optionally send server control command if omniPort connection. for (int i = 0; i < pcp->nCmds; i++) { ts.tv_sec = 1; ts.tv_nsec = 0; nanosleep(&ts,NULL); //Sleep for 1 second string s_user = pcp->user; string s_cmd = pcp->serverCmd[i]; if (pcp->serverCmd[i]) sendMsg(clientSocket, s_user, "SERVER", s_cmd); } if ((pcp->EchoMask) && (pcp->mode == MODE_RECV_SEND)) { //If any bits are set in EchoMask then this add to sessions list. if (sp == NULL){ //Grab an output session now. Note: This takes away 1 avalable user connection sp = AddSession(clientSocket, pcp->EchoMask, true); //Add this to list of sockets to send on } else { // else already had an output session initSessionParams(sp, clientSocket, pcp->EchoMask, true); //Restore output session for sending } if (sp == NULL){ cerr << "Can't add Server or Hub to session list ."; WriteLog("Failed to add Server or Hub to session list", MAINLOG); } else { AddSessionInfo(clientSocket, "*", "To SERVER", -1, "*"); } } } do { // Reset the retry timer to 60 only if previous connection lasted more than 30 secs. // If less than 30 secs the retrys will increase from 60 to 120 to 240 to 480 and finally 960 secs. if (connectTime > 30) retryTimer = 60; //Retry connection in 60 seconds if it breaks buf[0] = 0; rc = recvline(clientSocket, buf, BUFSIZE, &err, 900); //900 sec (15 min) timeout value if (sp) { if (sp->dead) { rc = -1; // Force disconnect if OUTgoing connection is dead } pcp->bytesOut = sp->bytesOut; } if (rc > 1) { // rc: = chars recvd, 0 = timeout, -2 = socket error if (!gotID){ if (buf[0] == '#') { //First line starting with '#' should be the program name and version strncpy(remoteIgateInfo, buf, 250); //This gets used in the html status web page function gotID = true; pcp->remoteIgateInfo = remoteIgateInfo; } //cerr << pcp->RemoteName << ":" << remoteIgateInfo ; //Debug } countLock.get(); TotalServerChars += rc; //Tally up the bytes from the distant server. pcp->bytesIn += rc; countLock.release(); pcp->lastActive = time(NULL); //record time of this input bool sentOnRF = false; aprsString atemp(buf, clientSocket, srcIGATE, pcp->RemoteName.c_str(), "IGATE"); atemp.call = os_iphex.str(); //string(ip_hex_alias); //Tag packet with alias of this hub or server //One of the stations in the gate2rf list? bool RFalways = find_rfcall(atemp.ax25Source, rfcall); /* Send it on RF if it's 3rd party msg AND TCPXX is not in the path. The sendOnRF() function determines if the "to station" is local and the "from station" is not. It also reformats the packet in station to station 3rd party format before sending. */ if ((atemp.aprsType == APRSMSG) && (!atemp.tcpxx) && configComplete && (RFalways)) { cout << "DEBUG: TCPConnectThread - Sending to RF..." << endl; sentOnRF = sendOnRF(atemp, pcp->RemoteName, "IGATE", srcIGATE); // Try to send on RF if (sentOnRF) { //Now find the posit for this guy in the history list // and send it too. aprsString* posit = getPosit(atemp.ax25Source,srcIGATE | srcUSERVALID); if (posit != NULL) { time_t Time = time(NULL); //get current time if ((Time - posit->timeRF) >= 60*10) { //posit every 10 minutes only timestamp(posit->ID, Time); //Time stamp the original in hist. list if (posit->thirdPartyReformat(MyCall.c_str()))// Reformat it for RF delivery tncQueue.write(posit); //posit will be deleted elsewhere else delete posit; //Kill if conversion failed }else delete posit; } /*else cout << "Can't find matching posit for " << atemp.ax25Source << endl << flush; //Debug only */ } } /* Send it on TCPIP if it's NOT a 3rd party msg OR TCPXX is in path . */ if ((configComplete) && (atemp.aprsType != COMMENT)) { /* Send everything except COMMENT pkts back out to tcpip users */ aprsString* inetpacket = new aprsString(buf, clientSocket, srcIGATE, pcp->RemoteName.c_str(), "IGATE"); inetpacket->changePath("TCPIP*","TCPIP"); inetpacket->call = os_iphex.str(); //string(ip_hex_alias); //tag pkt with alias of this hub or server if (inetpacket->aprsType == APRSMIC_E) //Reformat Mic-E packets reformatAndSendMicE(inetpacket,sendQueue); else sendQueue.write(inetpacket); // send data to users. // Note: inetpacket is deleted in DeQueue } if (configComplete && (atemp.aprsType == APRSMSG)) { //find matching posit for 3rd party msg aprsString* posit = getPosit(atemp.ax25Source,srcIGATE | srcUSERVALID | srcTNC); if (posit != NULL) { posit->EchoMask = src3RDPARTY; sendQueue.write(posit); //send matching posit only to msg port } } //Here's where the priviledged get their posits sent to RF full time. if (configComplete && RFalways && (!StationLocal(atemp.ax25Source, srcTNC)) && (!atemp.tcpxx)) { aprsString* RFpacket = new aprsString(buf, clientSocket, srcIGATE, pcp->RemoteName.c_str(), "IGATE"); RFpacket->changePath("TCPIP*","TCPIP"); if (RFpacket->aprsType == APRSMIC_E) { //Reformat Mic-E packets if (ConvertMicE){ aprsString* posit = NULL; aprsString* telemetry = NULL; RFpacket->mic_e_Reformat(&posit,&telemetry); if (posit){ posit->thirdPartyReformat(MyCall.c_str()); // Reformat it for RF delivery tncQueue.write(posit); //Send reformatted packet on RF } if (telemetry) { telemetry->thirdPartyReformat(MyCall.c_str()); // Reformat it for RF delivery tncQueue.write(telemetry); //Send packet on RF } delete RFpacket; } else { if (RFpacket->thirdPartyReformat(MyCall.c_str())) tncQueue.write(RFpacket); // send raw MIC-E data to RF else delete RFpacket; } } else { if (RFpacket->thirdPartyReformat(MyCall.c_str())) tncQueue.write(RFpacket); // send data to RF if conversion successful else delete RFpacket; } } } } while (rc > 0); //Loop while rc is greater than zero else disconnect sendLock.get(); if (sp) sp->EchoMask = 0; //Turn off the session output data stream if it's enabled shutdown(clientSocket,2); close(clientSocket); sendLock.release(); pcp->connected = false; //set status to unconnected connectTime = time(NULL) - pcp->starttime ; //Save how long the connection stayed up pcp->starttime = time(NULL); //reset elapsed timer gotID = false; //Force new aquisition of ID string next time we connect pcp->alias = string(""); // reset this alias os_iphex.str(string("")); memset(szLog,0,MAX); ostrstream os(szLog,MAX-1); os << "Disconnected " << pcp->RemoteName << " " << pcp->RemoteSocket << ends; WriteLog(szLog, MAINLOG); { char* cp = new char[256]; memset(cp,0,256); ostrstream msg(cp,255); msg << szLog << endl << ends; conQueue.write(cp,0); } } //cerr << pcp->RemoteName << " retryTimer= " << retryTimer << endl; gotID = false; ts.tv_sec = retryTimer; ts.tv_nsec = 0; nanosleep(&ts,NULL); //Sleep for retryTimer seconds retryTimer *= 2; //Double retry time delay if next try is unsuccessful if (retryTimer >= (16 * 60)) retryTimer = 16 * 60; //Limit max to 16 minutes if (hubConn) { //string salias(""); pcp->remoteIgateInfo = string(""); pcp->alias = string("*"); pcp = getNextHub(pcp); retryTimer = 60; //Try next hub in 60 sec } } while (!ShutDownServer); pthread_exit(0); } //---------------------------------------------------------------------- bool sendOnRF(aprsString& atemp, string szPeer, char* userCall, const int src) { bool sentOnRF = false; bool stsmRFalways = find_rfcall(atemp.stsmDest, stsmDest_rfcall); //Always send on RF ? if ((!atemp.tcpxx) && (atemp.aprsType == APRSMSG)) { if (checkUserDeny(atemp.ax25Source) != '+') return false; //Reject if no RF or login permitted //Destination station active on VHFand source not? if (((!StationLocal(atemp.stsmDest, srcTNC)) || stsmRFalways) && (!StationLocal(atemp.ax25Source, srcTNC))) { aprsString* rfpacket = new aprsString(atemp.getChar(),atemp.sourceSock, src, szPeer.c_str(), userCall); //ofstream debug("rfdump.txt"); //debug << rfpacket->getChar << endl ; //Debug //debug.close(); if (rfpacket->thirdPartyReformat(MyCall.c_str())){ // Reformat it for RF delivery tncQueue.write(rfpacket); // queue read deletes rfpacket sentOnRF = true; } else delete rfpacket; //Kill it if 3rd party conversion failed } } return sentOnRF; } //---------------------------------------------------------------------- int SendFiletoClient(int session, char *szName) { char Line[256]; APIRET rc = 0; int n,retrys; int throttle; timespec ts; Lock sendFileLock(pmtxSendFile, false); Lock sendLock(pmtxSend, false); ts.tv_sec = 0; sendFileLock.get(); ifstream file(szName); if (!file) { cerr << "Can't open " << szName << endl; sendFileLock.release(); return -1; } do { file.getline(Line,253); //Read each line (up to 253 bytes) in file and send to client session if (!file.good()) break; if (strlen(Line) > 0) { strcat(Line,"\r\n"); n = strlen(Line); sendLock.get(); retrys = -0; do { rc = send(session,Line,n,0); throttle = n * 150000; ts.tv_nsec = throttle; nanosleep(&ts,NULL); // Limit max rate to about 50kbaud if (rc < 0) { ts.tv_nsec = 100000000; nanosleep(&ts,NULL); retrys++; } //0.1 sec between retrys } while((rc < 0) && (errno == EAGAIN) && (retrys <= MAXRETRYS)); if (rc == -1) { perror("SendFileToClient()"); shutdown(session,2); close(session); //close the socket if error happened } sendLock.release(); } } while (file.good() && (rc >= 0)); file.close(); sendFileLock.release(); return rc; } //---------------------------------------------------------------------- // Send the posits of selected users (in posit_rfcall array) to // RF every 14.9 minutes. Call this every second. // Stations are defined in the aprsd.conf file with the posit2rf command. // Posits are read from the history list. void schedule_posit2RF(time_t t) { static int ptr=0; static time_t last_t = 0; aprsString* abuff; if (difftime(t,last_t) < 14) return; //return if not time yet (14 seconds) last_t = t; if(posit_rfcall[ptr] != NULL) { abuff = getPosit(*posit_rfcall[ptr] , srcIGATE | srcUSERVALID | srcUSER); if (abuff){ if (abuff->thirdPartyReformat(MyCall.c_str())) //Convert to 3rd party format tncQueue.write(abuff); //Send to TNC else delete abuff; //Kill it if conversion failed } } ptr++; //point to next call sign if (ptr >= (MAXRFCALL-1)) ptr = 0; //wrap around if past end of array } //--------------------------------------------------------------------- int computeShortTermLoad(int t) { serverLoad_s = bytesSent_s / t; bytesSent_s = 0; return serverLoad_s; } //---------------------------------------------------------------------- void computeStreamRates(void) { time_t time_now,sampleTime; Lock countLock(pmtxCount, false); static time_t last_time = 0; static ULONG last_chars = 0; static ULONG last_tnc_chars=0; static ULONG last_user_chars=0; static ULONG last_server_chars=0; static ULONG last_msg_chars=0; static ULONG last_UDP_chars=0; static ULONG last_fullstream_chars=0; time(&time_now); sampleTime = time_now - last_time; countLock.get(); /* fullStreamRate = (TotalTncChars + TotalServerChars + TotalUserChars - last_chars) / sampleTime; */ fullStreamRate = (TotalFullStreamChars - last_fullstream_chars) / sampleTime; tncStreamRate = (TotalTncChars - last_tnc_chars) / sampleTime ; userStreamRate = (TotalUserChars - last_user_chars) / sampleTime; msgStreamRate = (TotalMsgChars - last_msg_chars) / sampleTime; udpStreamRate = (TotalUdpChars - last_UDP_chars) / sampleTime; serverStreamRate = (TotalServerChars - last_server_chars) / sampleTime; serverLoad = bytesSent / sampleTime; last_time = time_now; last_chars = TotalTncChars + TotalServerChars + TotalUserChars + TotalUdpChars; last_tnc_chars = TotalTncChars; last_user_chars = TotalUserChars; last_server_chars = TotalServerChars; last_msg_chars = TotalMsgChars; last_UDP_chars = TotalUdpChars; last_fullstream_chars = TotalFullStreamChars; bytesSent = 0; countLock.release(); return; } //---------------------------------------------------------------------- int getStreamRate(int stream) { int rv; switch (stream) { case STREAM_TNC: rv = tncStreamRate; break; case STREAM_USER: rv = userStreamRate; break; case STREAM_SERVER: rv = serverStreamRate; break; case STREAM_MSG: rv = msgStreamRate; break; case STREAM_FULL: rv = fullStreamRate; break; case STREAM_UDP: rv = udpStreamRate; break; default: rv = 0; } return (rv*8); // convert to bits } //---------------------------------------------------------------------- string getStats() { std::ostringstream os; //Lock countLock(pmtxCount); time_t time_now; time(&time_now); //upTime = (double) (time_now - serverStartTime) / 3600; upTime = (time_now - serverStartTime); //countLock.get(); computeStreamRates() ; os << setiosflags(ios::showpoint | ios::fixed) << setprecision(1) << "#\r\n" << "Server Up Time = " << convertUpTime(upTime) << " " << upTime << "\r\n" << "Total TNC packets = " << TotalLines << "\r\n" << "UDP stream rate = " << getStreamRate(STREAM_UDP) << " bits/sec" << "\r\n" << "Msg stream rate = " << getStreamRate(STREAM_MSG) << " bits/sec" << "\r\n" << "TNC stream rate = " << getStreamRate(STREAM_TNC) << " bits/sec" << "\r\n" << "User stream rate = " << getStreamRate(STREAM_USER) << " bits/sec" << "\r\n" << "Hub stream rate = " << getStreamRate(STREAM_SERVER) << " bits/sec" << "\r\n" << "Full stream rate = " << getStreamRate(STREAM_FULL) << " bits/sec" << "\r\n" << "Msgs gated to RF = " << msg_cnt << "\r\n" << "Connect count = " << TotalConnects << "\r\n" << "Users = " << getConnectedClients() << "\r\n" << "Peak Users = " << MaxConnects << "\r\n" << "Server load = " << serverLoad << " bits/sec" << "\r\n" << "History Items = " << ItemCount << "\r\n" << "aprsString Objs = " << aprsString::getObjCount() << "\r\n" << "Items in InetQ = " << sendQueue.getItemsQueued() << "\r\n" << "InetQ overflows = " << sendQueue.overrun << "\r\n" << "TncQ overflows = " << tncQueue.overrun << "\r\n" << "conQ overflows = " << conQueue.overrun << "\r\n" << "charQ overflow = " << charQueue.overrun << "\r\n" << "Hist. dump aborts = " << dumpAborts << "\r\n"; //countLock.release(); return os.str(); } //---------------------------------------------------------------------- //Here we check server load against MaxLoad and drop the last user //to logon if load is excessive. This executes once a minute. void enforceMaxLoad(void) { int i = 0, k = 0 ; time_t t; Lock addDelSessLock(pmtxAddDelSess, false); if(serverLoad <= MaxLoad) return; t = 0; addDelSessLock.get(); for (i = 0; i < MaxClients; i++) { if ((sessions[i].starttime > t) && (sessions[i].Socket != -1) && (sessions[i].EchoMask & srcIGATE) && (sessions[i].svrcon == false)){ //Check all established connections //receiving the full stream first. t = sessions[i].starttime; //Find most receint start time k = i; } } if (t > 0) { sessions[k].dead = true; //Kill off high bandwidth users first. } else { t = 0; for (i = 0; i < MaxClients; i++) { if ((sessions[i].starttime > t) && (sessions[i].Socket != -1) && (!(sessions[i].EchoMask & srcIGATE)) && (sessions[i].svrcon == false)){ //Check all established connections // not receiving the full stream next. t = sessions[i].starttime; //Find most receint start time k = i; } } sessions[k].dead = true; //Kill off low bandwidth user now. } addDelSessLock.release(); } //---------------------------------------------------------------------- void resetCounters() { dumpAborts = 0; sendQueue.overrun = 0 ; tncQueue.overrun = 0 ; conQueue.overrun = 0 ; charQueue.overrun = 0; TotalLines = 0; msg_cnt = 0; MaxConnects = getConnectedClients(); TotalConnects = MaxConnects; countREJECTED = 0; countLOOP = 0; countOVERSIZE = 0; countNOGATE = 0; countIGATED = 0; } //---------------------------------------------------------------------- inline string convertUpTime(int dTime) { std::ostringstream ostr; int x; int y; if (dTime > 86400) { // greater than a day x = (dTime / 86400); y = (dTime % 86400)/3600; ostr << x << ((x == 1) ? " Day " : " Days ") << y << ((y <= 1) ? " hour" : " hours"); } else if ((dTime >= 3600) && (dTime <= 86400)) { // 1 hr to 1 day x = (dTime / 3600); y = (dTime % 3600)/60; ostr << x << ((x == 1) ? " hour " : " hours ") << y << ((y <= 1) ? " minute" : " minutes"); } else { // hmm, must've just started... x = (dTime / 60); ostr << x << ((x <= 1) ? " minute" : " minutes"); } return ostr.str(); } aprsd-2.2.5-13/src/servers.h0000644000076400007640000001704607665274763011232 /* * $Id: servers.h,v 1.4 2003/05/29 03:09:39 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #ifndef SERVERS_H #define SERVERS_H #include #include #include "aprsd.h" #include "mutex.h" using namespace std; using namespace aprsd; #define SZPEERSIZE 16 #define USERCALLSIZE 10 #define PGMVERSSIZE 40 #define MAXRFCALL 65 //allow 64 of 'em including a NULL for last entry. #define BASE 0 #define USER 1 #define PASS 2 #define REMOTE 3 #define MAX 256 #define UMSG_SIZE MAX+BUFSIZE+3 #define MODE_RECV_ONLY 1 #define MODE_RECV_SEND 2 /*constants for the getStreamRate() function.*/ #define STREAM_TNC 1 #define STREAM_USER 2 #define STREAM_SERVER 3 #define STREAM_MSG 4 #define STREAM_FULL 5 #define STREAM_UDP 6 struct ConnectParams { int RemoteSocket; //char* RemoteName; string RemoteName; //char* alias; string alias; echomask_t EchoMask; unsigned long FilterMask; //char* user; string user; //char* pass; string pass; //char* remoteIgateInfo; string remoteIgateInfo; int nCmds; char* serverCmd[3]; //string serverCmd; long bytesIn; long bytesOut; time_t starttime; time_t lastActive; bool connected; bool hub; pthread_t tid; pid_t pid; int mode; }; struct ServerParams { int ServerPort; int ServerSocket; echomask_t EchoMask; unsigned long FilterMask; bool omni; pthread_t tid; pid_t pid; }; struct SessionParams { int Socket; echomask_t EchoMask; int ServerPort; int overruns; pid_t pid; time_t starttime; time_t lastActive; long bytesIn; long bytesOut; bool vrfy; bool dead; bool svrcon; char *szPeer; char *userCall; char *pgmVers; }; struct UdpParams { int ServerPort; pthread_t tid; pid_t pid; }; struct pidList{ pid_t main; pid_t SerialInp; pid_t TncQueue; pid_t InetQueue; }; //Stuff for trusted UDP source IPs struct sTrusted { in_addr sin_addr; //ip address in_addr sin_mask; //subnet mask }; struct sLogon{ char *user; char* pass; }; //------------------------------ extern sLogon logon; extern SessionParams *sessions; //points to array of active socket descriptors extern int MaxClients; //Limits how many users can log on at once extern int MaxLoad; //Limits maximum server load in Kbytes/sec extern bool tncPresent; //TRUE if TNC com port has been specified extern bool tncMute; //TRUE stops messages from going to the TNC extern bool traceMode; //TRUE causes our Server Call to be appended to all packets in the path extern ServerParams spMainServer, spMainServer_NH, spLinkServer; extern ServerParams spLocalServer, spMsgServer, spHTTPServer, spSysopServer; extern ServerParams spRawTNCServer, spIPWatchServer, spErrorServer,spOmniServer; extern UdpParams upUdpServer; extern const int maxIGATES; //Defines max number of IGATES you can connect to //extern char* szServerCall; // This servers "AX25 Source Call" (user defined) extern std::string szServerCall; //extern const char szJAVAMSG[] ; extern std::string szJAVAMSG; //extern char* szAPRSDPATH; // Servers "ax25 dest address + path" eg: >APD213,TCPIP*: extern std::string szAPRSDPATH; extern char *passDefault; //Default passcode is "-1" //extern char *MyCall; extern std::string MyCall; //extern char *MyLocation; extern std::string MyLocation; //extern char *MyEmail; extern std::string MyEmail; //extern char *NetBeacon; extern std::string NetBeacon; //extern char *TncBeacon; extern std::string TncBeacon; extern char *TncBaud; extern string szServerID; extern cpQueue sendQueue; // Internet transmit queue extern cpQueue tncQueue; // TNC RF transmit queue extern cpQueue charQueue; // A queue of single characters extern cpQueue conQueue; // data going to the console from various threads extern pidList pidlist; extern bool ShutDownServer, configComplete; extern int rfcall_idx; extern int posit_rfcall_idx; extern int stsmDest_rfcall_idx; extern string* posit_rfcall[]; extern string* stsmDest_rfcall[]; extern string* rfcall[]; //list of stations gated to RF full time (all packets) extern int TncBeaconInterval, NetBeaconInterval; extern long tncPktSpacing; extern bool igateMyCall; //Set TRUE if server will gate packets to inet with "MyCall" in the ax25 source field. extern bool logAllRF; extern bool ConvertMicE; //Set true causes Mic-E pkts to be converted to classic APRS pkts. extern bool APRS_PASS_ALLOW; extern bool History_ALLOW; //History dumps allowed: true/false extern int defaultPktTTL; //Holds default packet Time to live (hops) value. extern const int maxTRUSTED; //Max number of trusted UDP users extern sTrusted Trusted[]; //Array to store their IP addresses extern int nTrusted ; //Number of trusted UDP users defined extern ConnectParams cpIGATE[]; extern int nIGATES; extern bool RF_ALLOW, NOGATE_FILTER; extern int ackRepeats,ackRepeatTime; //Used by the ACK repeat thread extern time_t serverStartTime; extern ULONG WatchDog; extern int MaxConnects, serverLoad; extern int fullStreamRate, userStreamRate,tncStreamRate,serverStreamRate, msgStreamRate; //Server statistics extern int udpStreamRate; extern ULONG tickcount, TotalConnects, TotalLines; extern ULONG TotalTncChars, TotalMsgChars, TotalServerChars, TotalUserChars, bytesSent, webCounter; extern ULONG TotalUdpChars; extern ULONG TotalFullStreamChars; extern ULONG countREJECTED, countLOOP, countOVERSIZE, countNOGATE, countIGATED; extern int msg_cnt; //extern double upTime; extern int upTime; extern Mutex pmtxSendFile; extern Mutex pmtxSend; extern Mutex pmtxAddDelSess; extern Mutex pmtxCount; extern Mutex pmtxDNS; int initDefaults(void); void serverInit(void); void initSessionParams(SessionParams* sp, int s, int echo); int getConnectedClients(void); SessionParams* AddSession(int s, int echo); bool DeleteSession(int s); bool AddSessionInfo(int s, const char* userCall, const char* szPeer, int port, const char* pgmVers); void CloseAllSessions(void); void BroadcastString(const char *cp); int SendFiletoClient(int session, char *szName); void PrintStats(ostream &os) ; void dequeueTNC(void); void *HTTPServerThread(void *p); void *TCPConnectThread(void *p); void *UDPServerThread(void *p); void *TCPServerThread(void *p); void *DeQueue(void* vp); void schedule_posit2RF(time_t t); string getStats(); void resetCounters(); int getStreamRate(int stream); int recvline(int sock, char *buf, int n, int *err,int timeoutMax); void *HTTPServerThread(void* p); int computeShortTermLoad(int t); void enforceMaxLoad(void); string convertUpTime(int dTime); #endif // SERVERS_H aprsd-2.2.5-13/src/sniptype.h0000664000076400007640000000335507655343030011373 /* * $Id: sniptype.h,v 1.5 2003/03/31 04:49:41 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #ifndef SNIPTYPE__H #define SNIPTYPE__H #include /* For free() */ #include /* For NULL & strlen() */ typedef enum {Error_ = -1, Success_, False_ = 0, True_} Boolean_T; #if !defined(WIN32) && !defined(_WIN32) && !defined(__NT__) \ && !defined(_WINDOWS) #if !defined(OS2) typedef unsigned char BYTE; typedef unsigned long DWORD; #endif typedef unsigned short WORD; #else #define WIN32_LEAN_AND_MEAN #define NOGDI #define NOSERVICE #undef INC_OLE1 #undef INC_OLE2 #include #define HUGE #endif #define NUL '\0' #define LAST_CHAR(s) (((char *)s)[strlen(s) - 1]) #define TOBOOL(x) (!(!(x))) #define FREE(p) (free(p),(p)=NULL) #endif /* SNIPTYPE__H */ aprsd-2.2.5-13/src/string.cpp0000644000076400007640000000446107657351441011365 /* * $Id: string.cpp,v 1.1 2003/05/11 04:35:45 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2003 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #include "string.hpp" #include namespace aprsd { using namespace std; string trim(const string& str) { return rtrim(ltrim(str)); } string rtrim(const string& str) { string::const_reverse_iterator iter = str.rbegin(); while (iter != str.rend() && isspace(*iter)) iter++; return str.substr(0, str.length() - (iter - str.rbegin())); } string ltrim(const string& str) { string::const_iterator iter = str.begin(); while (iter != str.end() && isspace(*iter )) iter++; return string(iter, str.end()); } Strings split(const string& text, char sep) { Strings vec; string::size_type pos = 0; for (string::size_type newp; (newp = text.find(sep, pos)) != string::npos; pos = newp + 1) vec.push_back(text.substr(pos, newp - pos)); vec.push_back(text.substr(pos)); return vec; } Strings split(const string& text, const string& sep) { Strings vec; string::size_type pos = 0; for (string::size_type newp; (newp = text.find(sep, pos)) != string::npos; pos = newp + sep.length()) vec.push_back(text.substr(pos, newp - pos)); vec.push_back(text.substr(pos)); return vec; } }; aprsd-2.2.5-13/src/string.hpp0000644000076400007640000000464207657351441011373 /* * $Id: string.hpp,v 1.1 2003/05/11 04:35:45 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2003 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ // // string helper definitions and functions. // #ifndef STRING_H__ #define STRING_H__ #include #include #include "osdep.h" namespace aprsd { using namespace std; typedef vector Strings; /** Trim the string both left and right for whitespaces. @param str the string to trim @return the newly trimed string */ string trim(const string& str); /** Trim all whitespace on the left of the string. @param str the string to trim @return the newly trimed string */ string ltrim(const string& str); /** Trim all whitespace on the right of the string. @param str the string to trim @return the newly trimed string */ string rtrim(const string& str); /** Splits a string into substrings, using the specified character as a delimiter. @param text the string to be split. @param delim the character to be used as a delimiter. @return a Strings containing the substrings. */ Strings split(const string& text, char delim); /** Splits a string into substrings, using the specified string as a delimiter. @param text the string to be split. @param delim the string to be used as a delimiter. @return a Strings containing the substrings. */ Strings split(const string& text, const string& delim); } #endif // String_H__ aprsd-2.2.5-13/src/utils.cpp0000644000076400007640000003353407665443565011232 /* * $Id: utils.cpp,v 1.27 2003/05/13 04:58:53 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #include #include #include // ifstream #include #include #include #include "utils.h" #include "aprsd.h" #include "cpqueue.h" #include "mic_e.h" using namespace std; using namespace aprsd; int CountDefault = 7; //Max of 7 instances of one call sign in history list static Mutex pmtxLog; int WriteLog(const string& sp, const string& LogFile) { time_t ltime; char szTime[40]; string newTime; static Lock locker(pmtxLog, false); locker.get(); ofstream ofs(LogFile.c_str(), ios::out | ios::app); if (!ofs) cerr << "File I/O Error: Unable to open/create file " << LogFile << endl; time(<ime); // Timestamp ctime_r(<ime, szTime); // "threadsafe" ctime newTime = string(szTime); newTime = newTime.substr(0, newTime.length()-1); // Strip '\n' ofs << newTime << " " << sp << endl; if (ofs.is_open()) ofs.close(); locker.release(); return 0; } //---------------------------------------------------------------------- int WriteLog(const char* pch, const char* LogFile) { FILE* f; time_t ltime; char szTime[40]; char* p; int rc; static pthread_mutex_t* pmtxLog; //Mutual exclusion semi for WriteLog function static bool logInit = false; char* cp = strdup(pch); //Make local copy of input string. if (!logInit) { pmtxLog = new pthread_mutex_t; pthread_mutex_init(pmtxLog,NULL); logInit = true; } pthread_mutex_lock(pmtxLog); char* pLogFile = new char[CONFPATH.length() + strlen(LogFile) +1]; strcpy(pLogFile,CONFPATH.c_str()); strcat(pLogFile, LogFile); f = fopen(pLogFile, "a"); if (f == NULL) f = fopen(pLogFile, "w"); if (f == NULL) { cerr << "failed to open " << pLogFile << endl; rc = -1; } else { char *eol = strpbrk(cp,"\n\r"); if (eol) *eol = '\0'; //remove crlf time(<ime) ; //Time Stamp ctime_r(<ime,szTime); //Thread safe ctime() p = strchr(szTime, (int)'\n'); if (p) *p = ' '; //convert new line to a space fprintf(f,"%s %s\n", szTime, cp); //Write log entry with time stamp fflush(f); fclose(f); rc = 0; } delete cp; delete pLogFile; pthread_mutex_unlock(pmtxLog); return rc; } //------------------------------------------------------------------------ void removeHTML(string& sp) { string search("/<>"); unsigned int p = sp.find_first_of(search); while (p < sp.length()) { sp.replace(p, 1, "*"); p = sp.find_first_of(search, p + 1); } } //------------------------------------------------------------------------ //Convert all lower case characters in a string to upper case. // Assumes ASCII chars. char* strupr(char *cp) { int i; int l = strlen(cp); for (i = 0; i < l; i++) { if ((cp[i] >= 'a') && (cp[i] <= 'z')) cp[i] = cp[i] - 32; } return cp; } //----------------------------------------------------------------------- void printhex(char *cp, int n) { for (int i = 0; i < n; i++) printf("%02X ",cp[i]); printf("\n"); } //--------------------------------------------------------------------- //return true if destination of packet matches "ref" //This is for filtering out unwanted packets bool CmpDest(const char *line, const char *ref) { bool rv = false; char *cp = new char[strlen(ref)+3]; strcpy(cp,">"); strcat(cp,ref); strcat(cp,","); if (strstr(line,cp) != NULL) rv = true; delete cp; return rv; } //---------------------------------------------------------------------- //Return true if any string in the digi path matches "ref". bool CmpPath(const char *line, const char *ref) { bool rv = false; char *cp = new char[strlen(line)+1]; strcpy(cp,line); char *path_end = strchr(cp,':'); //find colon if (path_end != NULL) { *path_end = '\0'; //replace colon with a null if (strstr(cp,ref) != NULL) rv = true; } delete cp; return rv; } //--------------------------------------------------------------------- //Returns true if "call" matches first string in "s" //"call" must be less than 15 chars long. bool callsign(char *s, const char *call) { char cp[17]; if (strlen(call) > 14) return false; strncpy(cp,call,14); strcat(cp,">"); char *ss = strstr(s,cp); if (ss != NULL) return true ; else return false; } //--------------------------------------------------------------------- //Compares two packets and returns true if the source call signs are equal bool CompareSourceCalls(char *s1, char *s2) { char call[12]; strncpy(call,s2,10); char *eos = strchr(call,'>'); if (eos != NULL) eos[0] = '\0'; else return false; return callsign(s1,call); } //--------------------------------------------------------------------- // This sets the time-to-live and max count values for each packet received. void GetMaxAgeAndCount(int *MaxAge, int *MaxCount) { *MaxAge = ttlDefault; *MaxCount = CountDefault; } //-------------------------------------------------------------------- //Removes all control codes ( < 1Ch ) from a string void RemoveCtlCodes(char *cp) { int i,j; int len = strlen(cp); unsigned char *ucp = (unsigned char*)cp; unsigned char *temp = new unsigned char[len+1]; for(i = 0, j = 0; i < len; i++) { //ucp[i] &= 0x7f; //Clear 8th bit <-- removed in version 2.1.5 for 8 bit char sets if (ucp[i] >= 0x1C) { //Check for printable plus the Mic-E codes temp[j++] = ucp[i] ; //copy to temp if printable } } temp[j] = ucp[i]; //copy terminating NULL strcpy(cp,(char*)temp); //copy result back to original delete temp; } //--------------------------------------------------------------------- /*returns the number if instances of char "c" in string "s". */ int freq( string& s, char c) { int count=0; int len = s.length(); for (int i = 0; i < len; i++) if(s[i] == c) count++; return count; } //---------------------------------------------------------------------------- //returns the number of tokens delimited by 'delim'. //returns zero if error. //Each token copied into the 'sa' array. //Stops when no more delimiters are found or saSize is reached. int split( string& s, string sa[], int saSize, const char* delim) { int wordcount; unsigned long start, end; if (delim == NULL) return 0; try { start = s.find_first_not_of(delim); //find first token end = 0; wordcount = 0; while ((start != string::npos) && (wordcount < saSize)) { end = s.find_first_of(delim,start+1); if (end == string::npos) end = s.length(); sa[wordcount++] = s.substr(start,end-start); start = s.find_first_not_of(delim,end+1); } } catch(exception& error) { WriteLog(string("split function error"), ERRORLOG); WriteLog(s, ERRORLOG); return 0; } //if(sa[wordcount-1].length() == 0) wordcount--; return wordcount; } //---------------------------------------------------------------------------- void upcase(string& s) { for (unsigned i = 0; i < s.length(); i++) s[i] = toupper(s[i]); } //--------------------------------------------------------------------- #define MSB 0x8000 #define MASK 0x8005 void crc_byte(const char data, unsigned int *crc16) { int k; unsigned c,d ; c = data << 8 ; d = c; for (k = 0; k < 8; k++) { *crc16 = (c & MSB) ^ *crc16; if (*crc16 & MSB) { *crc16 = *crc16 << 1; *crc16 = *crc16 ^ MASK; } else *crc16 = *crc16 << 1; d = d << 1; c = d; } } //-------------------------------------------------------------------- unsigned int string_hash(const string& s) { int i,j; unsigned int hash = 0xffff; j = s.length(); string work = s; upcase(work); //Convert to upper case for(i = 0; i < j; i++) crc_byte(work[i], &hash); return hash; } //------------------------------------------------------------------ //Create an alias from a domain name. Use up to 6 characters //or until the first "." is encountered then append a 3 char hash code. //eg: third.aprs.net becomes thirdFCA void makeAlias(string& s) { unsigned hash; char shash[5]; int i; hash = string_hash(s); //Get hash value for input string hash &= 0xfff; //Limit to 12 bits s = s.substr(0,6); //use up to 6 characters of input string i = s.find(".",0); // up to first "." or 6 characters max. if (i <= 5) s = s.substr(0,i); sprintf(shash,"%03X",hash); //Convert int to hex string s = s + shash; //Append hex string to truncated original string } //-------------------------------------------------------------------- /* Return true if string s is in the list cl. Added wild card support in version 2.1.5 . Thank you VK3SB */ bool find_rfcall(const string& s, string **cl) { bool rc = false; int i = 0, pos; while((cl[i] != NULL) && (rc == false)) { pos = (cl[i])->find('*'); if ((pos != 0) && (s.substr(0, pos).compare(cl[i]->substr(0, pos)) == 0)) rc = true; i++; } return rc; } //------------------------------------------------------------------ //Case insensitive c char string compare function int stricmp(const char* szX, const char* szY) { int i; int len = strlen(szX); char* a = new char[len+1]; for (i = 0; i < len; i++) a[i] = tolower(szX[i]); a[i] = '\0'; len = strlen(szY); char* b = new char[len+1]; for (i = 0; i < len; i++) b[i] = tolower(szY[i]); b[i] = '\0'; int rc = strcmp(a,b); delete a; delete b; return rc; } //-------------------------------------------------------------------- /* Returns the deny code if user found or "+" if user not in list Deny codes: L = no login R = No RF access Note: ssid suffix on call sign is ignored */ char checkUserDeny(string& user) { const int maxl = 80; const int maxToken=32; int nTokens ; char Line[maxl]; string baduser; char rc = '+'; ifstream file(USER_DENY.c_str()); if (!file) return rc; string User = string(user); unsigned i = user.find("-"); if (i != string::npos) User = user.substr(0,i); //remove ssid do { file.getline(Line,maxl); //Read each line in file if (!file.good()) break; if (strlen(Line) > 0) { if (Line[0] != '#') { //Ignore comments string sLine(Line); string token[maxToken]; nTokens = split(sLine, token, maxToken, RXwhite); //Parse into tokens upcase(token[0]); baduser = token[0]; if ((stricmp(baduser.c_str(),User.c_str()) == 0) && (nTokens >= 2)) { rc = token[1][0]; break; } } } } while(file.good()); file.close(); return rc; } //--------------------------------------------------------------------- void reformatAndSendMicE(aprsString* inetpacket, cpQueue& sendQueue) { //WriteLog(inetpacket->getChar(),"mic_e.log"); if (ConvertMicE) { aprsString* posit = NULL; aprsString* telemetry = NULL; inetpacket->mic_e_Reformat(&posit,&telemetry); if (posit) sendQueue.write(posit); //Send reformatted packets if(telemetry) sendQueue.write(telemetry); delete inetpacket; //Note: Malformed Mic_E packets that failed to convert are discarded } else sendQueue.write(inetpacket); //Send raw Mic-E packet } //------------------------------------------------------------------------ /* return ascii H:M:S string with elapsed time ( NOW - starttime) */ void strElapsedTime(time_t starttime, char* timeStr) { if(starttime == -1) { sprintf(timeStr, "N/A"); return; } time_t endtime = time(NULL); double dConnecttime = difftime(endtime , starttime); int iMinute = (int)(dConnecttime / 60); iMinute = iMinute % 60; int iHour = (int)dConnecttime / 3600; int iSecond = (int)dConnecttime % 60; sprintf(timeStr, "%3d:%02d:%02d", iHour, iMinute, iSecond); } //-------------------------------------------------------------------------- aprsd-2.2.5-13/src/utils.h0000664000076400007640000000462507655343031010662 /* * $Id: utils.h,v 1.14 2003/03/31 04:49:41 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #ifndef UTILS_H #define UTILS_H //#include "constant.h" #include "aprsString.h" #include "cpqueue.h" #include #define BADUSER -1 #define BADGROUP -2 #define BADPASSWD -3 int WriteLog(const std::string& sp, const std::string& LogFile); int WriteLog(const char *cp, const char *LogFile); char* strupr(char *cp); void printhex(char *cp, int n); bool CmpDest(const char *line, const char *ref); bool CmpPath(const char *line, const char *ref); bool callsign(char *s, const char *call); bool CompareSourceCalls(char *s1, char *s2); void GetMaxAgeAndCount( int *MaxAge, int *MaxCount); int checkpass(const char *szUser, const char *szGroup, const char *szPass); void RemoveCtlCodes(char *cp); char* StripPath(char* cp); bool getMsgDestCall(char *data, char* cp, int n); bool getMsgSourceCall(char* data, char* cp, int n); char checkUserDeny(string& user); int stricmp(const char* szX, const char* szY); void removeHTML(string& sp); int split( string& s, string sa[], int saSize, const char* delim); int freq(string& s, char c); void upcase(string& s); void reformatAndSendMicE(aprsString* inetpacket, cpQueue& sendQueue); bool find_rfcall(const string& s, string* rfcall[]); bool find_rfcall(const string& s, vector& rfcall); void strElapsedTime(time_t starttime, char* timeStr); unsigned int string_hash(const string& s); void crc_byte(const char data, unsigned int *crc16); void makeAlias(string& s); #endif // UTILS_H aprsd-2.2.5-13/src/validate.cpp0000664000076400007640000002310507655343031011640 /* * $Id: validate.cpp,v 1.11 2003/03/31 04:49:41 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE #endif #include #include #include #include #include #include #include #include using namespace std; #ifdef USE_PAM #include #include struct user_info { const string username; const string password; const string group; }; #else #include #include #include #include #endif #include "validate.h" using namespace std; /* Steves servers response to a user logon: APRSERV>APRS,TCPIP*:USERLIST :Verified user KE3XY-4 logged on using WinAPRS 2.1.7.{3544 APRSERV>APRS,TCPIP*:USERLIST :Unverified user KE3XY-4 logged on using WinAPRS 2.1.7.{3544 Note: The doHash(char*) function is Copyright Steve Dimse 1998 */ short doHash(const char *theCall); #define kKey 0x73e2 // This is the key for the data //----------------------------------------------------------------------------------- #ifdef USE_PAM static int my_conv(int num_msg, const struct pam_message **msg, struct pam_response **response, void *data) { struct user_info *userInfo = (struct user_info *)data; struct pam_response *reply; reply = (struct pam_response *)malloc(num_msg * sizeof(struct pam_response)); if (reply == NULL) return PAM_CONV_ERR; for (int count = 0; count < num_msg; count++) { reply[count].resp_retcode = 0; reply[count].resp = NULL; switch (msg[count]->msg_style) { case PAM_PROMPT_ECHO_ON: reply[count].resp = strdup(userInfo->username); break; case PAM_PROMPT_ECHO_OFF: reply[count].resp = strdup(userInfo->password); break; default: for (int i = 0; i < count; i++) if (reply[i].resp != NULL) free(reply[i].resp); free(reply); return PAM_CONV_ERR; } } *response = reply; return PAM_SUCCESS; } #endif //----------------------------------------------------------------------------------- int checkSystemPass(const string szUser, const string szPass, const string szGroup) { #ifdef USE_PAM struct user_info userInfo; struct pam_conv conv = { my_conv, (void *)&userInfo }; pam_handle_t *pamh = NULL; userInfo.username = szUser; userInfo.password = szPass; userInfo.group = szGroup; if (pam_start("aprsd", szUser, &conv, &pamh) != PAM_SUCCESS) return BADUSER; if (pam_authenticate(pamh, 0) != PAM_SUCCESS) return BADPASSWD; if (pam_acct_mgmt(pamh, 0) != PAM_SUCCESS) return BADUSER; pam_end(pamh, PAM_SUCCESS); return 0; #else passwd *ppw = NULL; group *pgrp = NULL; spwd *pspwd = NULL; char *member = NULL; struct group grp; struct passwd pwd; int i; char salt[16]; int usrfound = 0 ; int pwLength = 0; int rc = BADGROUP; #ifdef DEBUG cout << szUser << " " << szPass << " " << szGroup << endl; //debug #endif size_t bufsize = sysconf(_SC_GETGR_R_SIZE_MAX); char *buffer1 = new char[bufsize]; //Thread-Safe getgrnam() getgrnam_r(szGroup.c_str(), /* Does group name szGroup exist? */ &grp, buffer1, bufsize, &pgrp); if (pgrp == NULL) { delete buffer1; return rc; /* return BADGROUP if not */ } bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); char *buffer2 = new char[bufsize]; //Thread-Safe getpwnam() getpwnam_r(szUser.c_str(), &pwd, buffer2, bufsize, &ppw); if (ppw == NULL){ delete buffer2; delete buffer1; return BADUSER ; /* return BADUSER if no such user */ } i = 0; /* find out if user is a member of szGroup */ while(((member = pgrp->gr_mem[i++]) != NULL) && (usrfound == 0 )) { #ifdef DEBUG cerr << member << endl; //debug code #endif if (strcmp(member, szUser.c_str()) == 0) usrfound = 1 ; } if (usrfound == 0) { delete buffer1; delete buffer2; return BADGROUP; /* return BADGROUP if user not in group */ } /* check the password */ #ifdef DEBUG cout << ppw->pw_passwd << endl << crypt(szPass.c_str(),salt) << endl; #endif pwLength = strlen(ppw->pw_passwd); if (ppw->pw_passwd[0] != '$') { /* DES salt */ strncpy(salt,ppw->pw_passwd,2); salt[2] = '\0'; } else { /* MD5 salt */ int i; for (i = 0; i < 3; i++) if (i < pwLength) salt[i] = ppw->pw_passwd[i]; while ((i < 14) && (ppw->pw_passwd[i] != '$')) salt[i++] = ppw->pw_passwd[i]; salt[i++] = '$'; salt[i] = '\0'; } #ifdef DEBUG cout << "salt=" << salt << endl; #endif if (strcmp(crypt(szPass.c_str(), salt), ppw->pw_passwd) == 0 ) rc = 0; else rc = BADPASSWD; if ((rc == BADPASSWD) && (strcmp("x",ppw->pw_passwd) == 0)) { #ifdef DEBUG cout << "Shadow passwords enabled\n"; #endif pspwd = getspnam(szUser.c_str()); //Get shadow password file data for user if (pspwd == NULL) { cout << "validate: Can't read shadowed password file. This program must run as root\n"; delete buffer1; delete buffer2; return MUSTRUNROOT; } pwLength = strlen(pspwd->sp_pwdp); #ifdef DEBUG cout << "pw=" << pspwd->sp_pwdp << endl; #endif if (pspwd->sp_pwdp[0] != '$') { /* DES salt */ strncpy(salt,pspwd->sp_pwdp,2); salt[2] = '\0'; } else { /* MD5 salt */ int i; for (i = 0; i < 3; i++) if (i < pwLength) salt[i] = pspwd->sp_pwdp[i]; while ((i < 14) && (pspwd->sp_pwdp[i] != '$')) salt[i++] = pspwd->sp_pwdp[i]; salt[i++] = '$'; salt[i] = '\0'; } #ifdef DEBUG cout << "salt=" << salt << endl; #endif if (strcmp(crypt(szPass.c_str(), salt), pspwd->sp_pwdp) == 0 ) rc = 0; else rc = BADPASSWD; #ifdef DEBUG cout << pspwd->sp_pwdp << " : " << crypt(szPass.c_str(), salt) << " : " << szPass << endl; #endif } delete buffer1; delete buffer2; return rc; #endif } //------------------------------------------------------------------------------------ bool validate(const string& user, const string& pass, const string& group, bool allow_hash) { if (allow_hash && (group.compare("tnc") != 0)) { // Don't allow tnc users to use aprs numerical password // "allow_hash" must be TRUE to use the HASH test. // If allow_hash is false only the Linux user/pass validation is used short iPass = atoi(pass.c_str()); if (iPass == -1) return BADUSER; // -1 is known to be not registered if (user.length() <= 9) { // Limit user call sign to 9 chars or less (2.1) if (doHash(user.c_str()) == iPass) return 0; // return Zero if hash test is passed } } //if hash fails, test for int rc = checkSystemPass(user, pass, group); // valid Linux system user/pass #ifdef DEBUG cout << "checkSystemPass returned: " << rc << endl; #endif if (rc == BADPASSWD) sleep(10); return rc; } //----------------------------------------------------------------------------------- /* As of April 11 2000 Steve Dimse has released this code to the open source aprs community */ short doHash(const char* theCall) { char rootCall[10]; // need to copy call to remove ssid from parse char *p1 = rootCall; while ((*theCall != '-') && (*theCall != 0)) *p1++ = toupper(*theCall++); *p1 = 0; short hash = kKey; // Initialize with the key value short i = 0; short len = strlen(rootCall); char *ptr = rootCall; while (i < len) { // Loop through the string two bytes at a time hash ^= (*ptr++)<<8; // xor high byte with accumulated hash hash ^= (*ptr++); // xor low byte with accumulated hash i += 2; } return hash & 0x7fff; // mask off the high bit so number is always positive } aprsd-2.2.5-13/src/validate.h0000664000076400007640000000244707655343032011314 /* * $Id: validate.h,v 1.4 2003/03/31 04:49:41 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #ifndef VALIDATE_H #define VALIDATE_H #include #define BADUSER -1 #define BADGROUP -2 #define BADPASSWD -3 #define MUSTRUNROOT -4 bool validate(const std::string& user, const std::string& pass, const std::string& group, const bool allow_hash); short doHash(const char *theCall); #endif // VALIDATE_H aprsd-2.2.5-13/support/0000777000000000000000000000000007665450621010314 5aprsd-2.2.5-13/support/Makefile.am0000664000076400007640000000012407645160272012323 ## Process this file with automake to produce Makefile.in EXTRA_DIST = aprsd.spec aprsd-2.2.5-13/support/Makefile.in0000644000000000000000000001216407665450603012301 # Makefile.in generated by automake 1.6.3 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 # 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. @SET_MAKE@ 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 pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_HEADER = $(INSTALL_DATA) transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : EXEEXT = @EXEEXT@ OBJEXT = @OBJEXT@ PATH_SEPARATOR = @PATH_SEPARATOR@ AMTAR = @AMTAR@ AWK = @AWK@ CC = @CC@ CXX = @CXX@ DEPDIR = @DEPDIR@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ PACKAGE = @PACKAGE@ STRIP = @STRIP@ VERSION = @VERSION@ am__include = @am__include@ am__quote = @am__quote@ install_sh = @install_sh@ EXTRA_DIST = aprsd.spec subdir = support mkinstalldirs = $(SHELL) $(top_srcdir)/support/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = DIST_SOURCES = DIST_COMMON = Makefile.am Makefile.in depcomp install-sh missing \ mkinstalldirs all: all-am .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu support/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) uninstall-info-am: tags: TAGS TAGS: DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = .. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) @list='$(DISTFILES)'; for file in $$list; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic uninstall-am: uninstall-info-am .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am info info-am install \ install-am install-data install-data-am install-exec \ install-exec-am install-info install-info-am install-man \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic uninstall uninstall-am uninstall-info-am # 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: aprsd-2.2.5-13/support/depcomp0000755000076400007640000002753307641730262011655 #! /bin/sh # depcomp - compile a program generating dependencies as side-effects # Copyright 1999, 2000 Free Software Foundation, Inc. # 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. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # `libtool' can also be set to `yes' or `no'. if test -z "$depfile"; then base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'` dir=`echo "$object" | sed 's,/.*$,/,'` if test "$dir" = "$object"; then dir= fi # FIXME: should be _deps on DOS. depfile="$dir.deps/$base" fi tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> $depfile echo >> $depfile # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> $depfile else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. This file always lives in the current directory. # Also, the AIX compiler puts `$object:' at the start of each line; # $object doesn't have directory information. stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'` tmpdepfile="$stripped.u" outname="$stripped.o" if test "$libtool" = yes; then "$@" -Wc,-M else "$@" -M fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi if test -f "$tmpdepfile"; then # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1="$dir.libs/$base.lo.d" tmpdepfile2="$dir.libs/$base.d" "$@" -Wc,-MD else tmpdepfile1="$dir$base.o.d" tmpdepfile2="$dir$base.d" "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi if test -f "$tmpdepfile1"; then tmpdepfile="$tmpdepfile1" else tmpdepfile="$tmpdepfile2" fi if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a space and a tab in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. We will use -o /dev/null later, # however we can't do the remplacement now because # `-o $object' might simply not be used IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M "$@" -o /dev/null $dashmflag | sed 's:^[^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # X makedepend shift cleared=no for arg in "$@"; do case $cleared in no) set ""; shift cleared=yes ;; esac case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; -*) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix="`echo $object | sed 's/^.*\././'`" touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. "$@" || exit $? IFS=" " for arg do case "$arg" in "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 aprsd-2.2.5-13/support/install-sh0000755000076400007640000001270107615210750012267 #!/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 : fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=$mkdirprog 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" ] || [ -d "$src" ] then : else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else : 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 : 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 : fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; 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 : 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 :;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 aprsd-2.2.5-13/support/missing0000755000076400007640000002403607615210750011666 #! /bin/sh # Common stub for a few missing GNU programs while installing. # Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. # Originally by Fran,cois 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. # 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. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. 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 --run try to run the given command, and emulate it if it fails 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 help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch]" ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing 0.4 - GNU automake" ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; aclocal*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. 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_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. 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$/.in/' | while read f; do touch "$f"; done ;; autom4te) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi 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. You can get \`$1Help2man' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; 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 ;; help2man) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then # We have makeinfo, but it failed. exit 1 fi 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 ;; tar) shift if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 fi # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) 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 aprsd-2.2.5-13/support/mkinstalldirs0000755000076400007640000000341107615210750013067 #! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain errstatus=0 dirmode="" usage="\ Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." # process command line arguments while test $# -gt 0 ; do case "${1}" in -h | --help | --h* ) # -h for help echo "${usage}" 1>&2; exit 0 ;; -m ) # -m PERM arg shift test $# -eq 0 && { echo "${usage}" 1>&2; exit 1; } dirmode="${1}" shift ;; -- ) shift; break ;; # stop option processing -* ) echo "${usage}" 1>&2; exit 1 ;; # unknown option * ) break ;; # first non-opt arg esac done for file do if test -d "$file"; then shift else break fi done case $# in 0) exit 0 ;; esac case $dirmode in '') if mkdir -p -- . 2>/dev/null; then echo "mkdir -p -- $*" exec mkdir -p -- "$@" fi ;; *) if mkdir -m "$dirmode" -p -- . 2>/dev/null; then echo "mkdir -m $dirmode -p -- $*" exec mkdir -m "$dirmode" -p -- "$@" fi ;; esac 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" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr else if test ! -z "$dirmode"; then echo "chmod $dirmode $pathcomp" lasterr="" chmod "$dirmode" "$pathcomp" || lasterr=$? if test ! -z "$lasterr"; then errstatus=$lasterr fi fi fi fi pathcomp="$pathcomp/" done done exit $errstatus # Local Variables: # mode: shell-script # sh-indentation: 3 # End: # mkinstalldirs ends here aprsd-2.2.5-13/support/aprsd.spec0000664000076400007640000000000007641742146012247 aprsd-2.2.5-13/doc/0000777000000000000000000000000007665450621007345 5aprsd-2.2.5-13/doc/Makefile.am0000664000076400007640000000011307651647304011355 EXTRA_DIST = aprsddoc.html \ ports.html \ qalgorithm.html \ q.html aprsd-2.2.5-13/doc/Makefile.in0000644000000000000000000001216207665450603011330 # Makefile.in generated by automake 1.6.3 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 # 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. @SET_MAKE@ 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 pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_HEADER = $(INSTALL_DATA) transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : EXEEXT = @EXEEXT@ OBJEXT = @OBJEXT@ PATH_SEPARATOR = @PATH_SEPARATOR@ AMTAR = @AMTAR@ AWK = @AWK@ CC = @CC@ CXX = @CXX@ DEPDIR = @DEPDIR@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ PACKAGE = @PACKAGE@ STRIP = @STRIP@ VERSION = @VERSION@ am__include = @am__include@ am__quote = @am__quote@ install_sh = @install_sh@ EXTRA_DIST = aprsddoc.html \ ports.html \ qalgorithm.html \ q.html subdir = doc mkinstalldirs = $(SHELL) $(top_srcdir)/support/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = DIST_SOURCES = DIST_COMMON = Makefile.am Makefile.in all: all-am .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) uninstall-info-am: tags: TAGS TAGS: DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = .. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) @list='$(DISTFILES)'; for file in $$list; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic uninstall-am: uninstall-info-am .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am info info-am install \ install-am install-data install-data-am install-exec \ install-exec-am install-info install-info-am install-man \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic uninstall uninstall-am uninstall-info-am # 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: aprsd-2.2.5-13/doc/aprsddoc.html0000644000076400007640000014446007651647334012025 WA4DSY Linux APRS server docs. 2.1.5 Aug. 2002

WA4DSY Linux APRS server docs. 2.1.5 Aug. 2002

Notes for 2.1.5

This is a bug fix release combined with several new features. It will now compile and run on Red Hat 7.x . For details see the revisions.txt file.

If upgrading, please replace your original aprsd.init file with the new one suppled in this release.
There are also some new features in the aprsd.conf file.

Also please add 2 new log files to your /etc/logrotate.conf file. They are loop.log and reject.log .

Please read README.STLport for information about a thread-safe stl library and how to build aprsd to use it.

Most noteworthy changes are:

0) Now will compile with both gnu 2.9 and 3.1 compilers. The 3.1 compiler will emit lots of "deprecated" warnings but they can be ignored.

1) Added wild card "*" support to "gate2rf" command in aprsd.conf. See gating to RF section for details.

2) Added filter code in aprsString to reject "EH?" and "cmd:" packets. Packets that don't look like ax25 format or are longer than 250 bytes are rejected.

3) Removed directed query responses. Fixed general query "?IGATE?" response to comply with APRS spec 1.0.
Example query response:
testaprsd>APD215,TCPIP*:<IGATE,MSG_CNT=0,LOC_CNT=0,CALL=WA4DSY,LOCATION=Atlanta_GA,
HOST=lab1.wa4dsy.net,IP=216.27.174.141,EMAIL=sysop@myisp.net,VERS=aprsd 2.1.5
Also blocked ?IGATE? queries from RF to Internet. A query from RF will only trigger a single response from the igate(s) that hear the station on RF.

4) Stopped sending System Status messages on Link port (1313) and Message Port (1314).
You will no longer get
"aprsdATL>JAVA::javaMSG :Atlanta_GA Linux APRS Server: 127.0.0.1 connected 2 users online."
and other such messages on these ports as other users connect and disconnect. However, to provide compatibility with some applicaitons that verify their own logon with these messages, the apps own connect and logon status messages still be sent back. In other words, you see your own logon activity by no one elses.

5) Removed code which cleared the 8th bit of users data. This allows 8 bit wide characrter sets to be passed.

6) Added support for NOGATE or RFONLY in path. If a packet from any source has NOGATE or RFONLY in the path it will discarded and not be put on the Internet.

7) The server now adds information to the end of the ax25 PATH indicating the source of each packet . eg: qAR,WA4DSY. This is known as the "q Construct". As of beta 8 the format complies with modifications and improvements made by Pete Loveall AE5PL.

8) Added OmniPort. This new port lets the users define their own custom streams. It defaults to 14600.

9 ) Added new keyword "Server" to aprsd.conf file. It replaces the old "Igate" command (although Igate is still honored). A command such as "server first.aprs.net 23 hub-sr" defines the connection to first.aprs.net as a send/receive hub connection. The user passcode is supplied with another keyword "pass". See aprsd.conf docs for details.

10) Added a new page of data to the html status page. Clicking on the users port number opens port filter status in a new window. There you can observe which streams each user is being sent. This became importaint because of the new OmniPort and its user definable streams.

11) Added bandwidth controls. Sysop may now specify the maximum allowed server load in bytes/sec. New users are rejected when the limit would be exceeded and the latest high bandwith users are disconnected if the load increases beyond the specfied limit. Keyword is "MaxLoad" in aprsd.conf .

12) TNC sysop mode can only be accessed from the new TncSysopPort 14500. Aprsd will now automatically put your telnet client into character-at-a-time mode for better operation with the TNC command line.

To conform to standard practice I suggest changing your BEACON strings to show a GATEWAY diamond with an "I" overlay. Below is an example from the aprsd.conf file. Your existing file may have the symbol set to "TCPIP" if you are upgrading from previous aprsd versions.

EXAMPLE:
NetBeacon 10 !0000.00NI00000.00W& aprsd Linux APRS Server
The symbols are defined in the APRS Spec document in appendix 2 and on page 89.


Everyone: You will need to compile the code get a working executable for your system. This is done automatically by the install script. Be advised you need the c++ compiler installed on your system. You can also type "make" to compile the program. It is designed to work on RedHat 5.1 and later Linux distributions. This includes Mandrake. Others may or may not work. Early versions before 5.1 will not work. Go the the Installing for more details.

Index

Revisions
Legal Stuff
Program description
aprsd Files
File Locations
Installing as a daemon
Starting and Stopping the Server
Installing as a user program
Server configuration file aprsd.conf
Com port configuration
Server shutdown
Remote TNC sysop access
Log Files
Station to Station 3rd Party Messages
Message Acks
User Validation
Filtering abusive users
Selective Internet to RF gating
NOGATE or RFONLY in path
Mic-E packet translation
AEA to TAPR conversion
The qAc construct. Packet source path insertions.
OmniPort and user defined data streams.
UDP input port
The ?IGATE? Query
Java Applets
The aprs passcode calculator
Monitoring system operation with a web browser
Determining the source IP address of aprs packets
Known Bugs


LEGAL STUFF

Copyright 1997-2002 by Dale A. Heatherington, WA4DSY
Web page:
http://www.wa4dsy.net/aprs/

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA


APRS is a registered trademark, and APRS protocols are copyrighted by Bob Bruninga, WB4APR. The owner reserves all rights and privileges to their use.

HAMS may apply the APRS formats in the TRANSMISSION of position, weather, and status packets. However, the author reserves the ownership of these protocols for exclusive commercial application and for all reception and plotting applications. Other persons desiring to include APRS RECEPTION in their software for sale within or outside of the amateur community will require a license from the author. Also TRANSMISSION of APRS protocols in any NON-AMATEUR commercial application or software will require a license from the author.

Bob Bruninga, WB4APR
115 Old Farm CT
Glen Burnie, MD 21060


DESCRIPTION

This is an APRS Internet server program. It acts as a gateway between the Internet and a local ham VHF APRS packet network. It is interfaced to directly to a TNC via one of the PC serial ports and does not use the Linux ax25 sockets interface. Hamish Moffatt has a
modified version of aprsd with ax25 support.

It has only been tested on RedHat Linux 5.1 , 5.2, 6.0 and Mandrake 5.3 - 8.1 . It requires libstdc++ 2.8.0 or later to run. It will NOT run on RedHat 4.2.

The program gets data from a TNC connected to a serial port and sends it to all clients who have connected to any of several user defined tcp ports. Some defaults are 1313, 10151, 10152 and 14579. It was designed to duplicate most if not all of the functionality of APRServe, a Macintosh APRS server designed and coded by Steve Dimse, K4HG.
See http://www.aprs.net/aprserve.dcc.html
It can also gate data coming from the Internet to the TNC for transmission on the local VHF RF network.

CLIENT SOFTWARE

Users can connect using several client programs such as Mac/WinAPRS, javAPRS, Xastir for Linux and Telnet. The logon protocol used by Mac/WinAPRS and others is recognized and properly handled giving registered users the privilige of sending 3rd party messages into the local VHF network.

Clients can use telnet to watch TNC data.
eg: telnet www.wa4dsy.net 14579
If raw TNC data is desired port 14580 can be used.

Scripts written in languages such as perl can connect to the server and interact with the data. A UDP port is provided to simplify injection of data into the aprs stream by scripts.

The system operator can use telnet to monitor the server status by connecting to any port and enter entering his callsign and passcode and entering "monitor" for the version field. eg: user WA4ZZZ pass 12345 vers monitor
Also he can enter remote sysop mode and gain direct control of the TNC on sysop port 14500.

HISTORY LIST

A history of data from the TNC and IGATES going back 35 minutes (time also user defined) is kept in memory and delivered to each user when he connects. This history data is filtered to remove duplicates and certain other unwanted information. Duplicate data are detected by looking for any packets with the same data and source call sign that have been seen in the last 20 seconds. When duplicates are found they are discarded.

There is also a quota system to further reduce the quanity of data in the history list. Each AX25 source call sign is allowed three packets in the history list. One position report, one weather report and one "other". Only the most receint of each type is retained.


FILES


Documenation Files:

aprsddoc.html                   This file.
ports.html                      Detailed info about aprsd ports
revisions.txt                   Detailed list of revisions by version number
q.htm, qalgorithm.htm           Q construct docs by Pete Loveall.

Executable files:

aprsd				The APRS server executable
aprspass                        Computes aprs passcodes from callsigns
aprsd.init                      Script that starts and stops aprsd

Configuration files:

aprsd.conf                      Main configuration file for aprsd
user.deny			List of users with restrictions placed on them
welcome.txt			This file is sent to users when they connect
INIT.TNC			This file is read into the TNC when the server starts
RESTORE.TNC			This file is read into the TNC when the server closes

				

Log Files:

aprsd.log			Created by server to log all user connections
thirdparty.log			Third party packets gated to RF
udp.log				Data from the UDP port logged here
rf.log				Data from our TNC after being digipeated
history.txt			Created by the server when it closes to save the 
                                history buffer. Data is read when it restarts.


Install files:

INSTALLDAEMON			Installation script for running as a daemon 
INSTALLPGM			Installation script for running as a program
REMOVE				UnInstall script - deletes /home/aprsd2/*


FILE LOCATIONS

/home/aprsd2
	aprsd
        aprspass
        user.deny
	welcome.txt
	INIT.TNC
	RESTORE.TNC
	aprsd.log
	thirdparty.log
	rf.log
	udp.log
	aprsd.conf
	history.txt


/etc/rc.d/init.d
	aprsd.init

/etc/rc.d/rc3.d
	link to aprsd.init

/etc/rc.d/rc5.d
	link to aprsd.init

/etc/rc.d/rc6.d
	link to aprsd.init


 

INSTALLING AS A DAEMON

(** also see Installing as a Program below **)

Note that this also compiles the program if the executable "aprsd" does NOT exist in the source directory. To re-compile updates in this directory you must do: "make clean" then "make".

  • Login as root.
  • Copy the archive into your home directory.
  • Issue the following command:
  • tar zxvf aprsd215.tgz
  • Of course you already did it or you wouldn't be reading this ;-)
  • cd aprsd215
  • Note: The following command will also compile the source files
  • ./INSTALLDAEMON
  • cd /home/aprsd2
  • Now make any changes you may require to these files (in /home/aprsd2/):
    Note: The install program will not overwrite these if they already exist.
    • aprsd.conf
    • user.deny
    • welcome.txt
    • INIT.TNC
    • RESTORE.TNC
Note: If you have defined a serial port in aprsd.conf (eg: tncport /dev/ttyS0) the value of "MyCall" specified in aprsd.conf will be replaced with whatever it is in INIT.TNC. This action is new in version 2.1.2.

At this point INSTALL has created a directory /home/aprsd2/ and copied several files into it. It also has copied aprsd.init to various /etc/rc.d/ directories.


Starting and Stopping the Server

After you run INSTALL the server will start when the machine is booted up. To start without rebooting cd to /etc/rc.d/init.d and run the aprsd.init script with "start" as the parameter. eg: ./aprsd.init start

You can also start it as a daemon by using the -d option. eg: ./aprsd -d

The serial device for TNC data and tcp port numbers are set in the /home/aprsd2/aprsd.conf file. You can edit this file in the directory you used to uncompress the distribution files then run INSTALL to make the changes effective. INSTALL also will copy the distribution welcome.txt, INIT.TNC and RESTORE.TNC to /home/aprsd so be sure you make changes to these in the distribution directory before running INSTALL.

To stop the server go to the /etc/rc.d/init.d directory and enter "./aprsd.init stop". To restart enter "./aprsd.init start" . Also, you can use the "service" command. eg: service aprsd.init start .


RUNNING AS A PROGRAM

The server can be run as a regular program for testing purposes or if you don't want it to auto start when Linux boots.

First, stop the aprsd daemon by entering: /etc/rc.d/init.d/aprsd.init stop or "service aprsd.init stop" .

It can be re-started as a user program changing to the /home/aprsd2 directory and typing its name " ./aprsd " Note: you will need to be logged on as root unless your user name has write priviliges on the directory /home/aprsd2 and all the files in it.

If you want to be able to log on as remote sysop and take control of the TNC you will need to add a "tnc" group to the /etc/group file. See "REMOTE TNC SYSOP ACCESS" below for more details.


INSTALLING AS A PROGRAM

(You may want to do this first to try it out)

Note that this also compiles the program if the executable "aprsd" does NOT exist in the source directory. To re-compile updates in this directory you must do: "make clean" then "make".

  • Login as root.
  • Copy the archive into your home directory.
  • Issue the following commands:
    • tar zxvf aprsd215.tgz
    • cd aprsd215
    • Note: The following command will also compile the source files
    • ./INSTALLPGM
    • cd /home/aprsd2
    Now make any changes you may require to welcome.txt, INIT.TNC, RESTORE.TNC and aprsd.conf to reflect your call sign, location and TNC paramters.
    Note: The install program will not overwrite these if they already exist.
The program and configuration files are copied to /home/aprsd2. You will need to change the permissions on /home/aprsd2 and all the files in it if you want to run it as a user other than root. The Linux password validator will only work if aprsd run as root.

COMMAND LINE PARAMETERS

The server has two command line arguments, the name of the server configuration file and one switch "-d" for daemon mode. If no file name is provided the server will use /home/aprsd2/aprsd.conf .

While running, once each minute this server will emit a status message to the console. Also, it tells you each time it sends out a packet and to how many users. It also shows you what it's sending to the TNC. One field in the status message is aprsString Objs. This is a debugging tool to help find memory leaks. It should be no more than 1 or 2 higher than the History items field. Sometimes it will read much higher but should return to a difference of 1 or 2 within a minute or so.

Ctrl-C or "q" will shut down the server in an orderly manner and save the current history list (last 30 mins of select received data) to disk.


SERVER CONFIGURATION FILE

The default configuration file is /home/aprsd2/aprsd.conf. The file is read on start up. Lines starting with "#" are comments and are ignored. Documentation on syntax and key words are in the file. More information on the tcpip ports used by the server can be found in
ports.html

igateMyCall

The "igateMyCall <yes|no>" command is new in version 2.1.0 . If the "yes" option is chosen packets sent from your TNC and digipeated will be igated to the Internet. If you have a beacon sending the same position as in your NetBeacon both will be overlayed and unreadable on the users map. If you must igate your own TNC beacons you can offset the location of one of them about .02 north or south so they show as separate objects.


SAMPLE CONFIGURATION FILE


#aprsd 2.1.5 server configuration file
#
#This file is read ONCE on server startup.
#You must restart aprsd for changes to take effect.
#eg: /etc/rc.d/init.d/aprsd.init stop (then start)
# OR:  service aprsd.init stop
#
#Lines starting with "#" are comments and are ignored
#Key words such as "mycall" and "maxusers" are NOT case sensitive.
#MyCall is the same as mycall.
#
#*** There is no error checking so be careful ******
#
#
#Servercall is the ax25 source call used in packets
#sent from the server to Internet users. (9 chars max)
#Note: Does not go out on the air.
#
servercall aprsdATL
#
#MyCall  This is over-written by the MYCALL string in INIT.TNC
MyCall N0CALL
MyLocation Atlanta_GA
#
#This email address will be sent in replies to ?IGATE? queries.
#It also appears on the HTML status page.
#
MyEmail sysop@myisp.net
#
#Set MaxUsers to a value that your Internet connection can support.
MaxUsers 25
#
#Set maximum server load in Bytes/sec.
MaxLoad 3000
#
#This determines if Mic-E packets are converted to classic APRS packets.
#Put 'no' unless you have a very good reason to do conversions. 
#This option must also be enabled in the SOURCE CODE. To turn it on
#you must edit "constant.h" and change CONVERT_MIC_E from FALSE to TRUE.
#then recompile aprsd. 
ConvertMicE no
#
#Define beacon text. The server will supply the ax25 path header.
#The first number after "NetBeacon" is the time interval in minutes.
#Comment out the line or set time interval to 0 to disable beacon.
#The rest of the line can be any aprs protocol conforming packet.
#
NetBeacon 10 !0000.00N/00000.00W& aprsd Linux APRS Server
#
#Define the TNC beacon. The TNC will supply the ax25 path header.
#It's optional and you may use the TNC BTEXT in the INIT.TNC file instead.
#
#TncBeacon 15 !0000.00N/00000.00W& aprsd Linux APRS Server
#
#
#Send 2 extra message acks is addition to each received ack to TNC
#Range 0 to 9
ackrepeats 2
#
#Send extra acks at 5 second intervals
#Range 1 to 30 seconds
ackrepeattime 5
#
#Set history list items to expire in 35 minutes
expire 35
#
#Define the TNC serial port (9600 baud)
#Note: This device must have write permissions
#If undefined all TNC related functions are disabled.
tncport /dev/ttyS0
#
#Set TNC baudrate. Values are: 1200,2400,4800,9600,19200 .
tncbaud 9600
#
# Allow Internet to RF message passing.
rf-allow yes
#
#TRACE causes the server to append its own callsign to the end
#of the AX25 path of every packet processed.  
#To conserver bandwidth this should only be
#done for short periods to track sources of problems.
#
Trace no
#
#Set filterNoGate YES to block RFONLY and NOGATE packets
filterNoGate yes
#
#Set history-allow to NO if you do not want users to get history dumps.
history-allow yes
#
#Set the minimum time between TNC transmit packets in milliseconds
TncPktSpacing 1500
#
# Disallow packets transmitted from our own TNC from 
# being igated back to the Internet after being digipeated.
igateMyCall no
#
#Set this to 'yes' if you want to log ALL PACKETS heard on RF to /home/aprsd2/rf.log
#If 'no' then only packets with your callsign will be logged.  (New in 2.1.4)
logAllRF no
#
#-------------------------------
#Server connection definitions
#usage: Server <host name> <host port> <TYPE-DIR> <optional OmniPort filter command>
#The TYPE-DIR field sets the connection type and data flow.
#TYPE is  either "SERVER" or "HUB"
#SERVER connections attempt to maintain a connection to the designated host.
#HUB connections maintain a connection to only ONE hub and rotate to the next
#if the connection fails.
#DIR is either "RO" or "SR"  RO is Receive Only. SR is Send and Receive.
#Eamples: HUB-RO   HUB-SR  SERVER-RO SERVER-SR
#If you select -SR to send data you must also supply a passcode
#using the "PASS" command.
#These commands are NOT case sensitive.
#
#The PASS command.  The callsign supplied in MyCall and this
# passcode allow you to send data to distant servers.
# PASS can be computed from MYCALL with the aprspass program.
# Note: this example is invalid.
#
pass 93456
#
#Example send-receive  HUB connections
#Hub is like Server except only ONE hub connection is active at a time.
#If the hub connection fails the next hub is tried in rotation until one accepts a connection.
#
Server second.aprs.net 23 hub-sr
Server first.aprs.net 23 hub-sr
Server third.aprs.net 23 hub-sr
#
#
#Example Receive-Only HUB connecton
#Server first.aprs.net 23 hub-ro
#
#Example Send-Receive SERVER connection.  The SERVER type maintains a connection to
#the specified server.  No rotation.
#Server first.aprs.net 23 server-sr
#
#Example of OmniPort connection to receive the local stream (tnc).
#Note: OmniPort is currently available only on aprsd 2.1.5
#
#Server wa4dsy.net 14600 server-ro portfilter(local)
#
#Define server listen ports (see ports.html)
rawtncport 14580
localport 14579
mainport 10151
mainport-nh 10152
linkport 1313
msgport 1314
udpport 1315
httpport 14501
ipwatchport 14502
errorport 14503
omniport 14600
sysopport 14500
#
#define trusted users of the UDP port.
#usage: trust <ip address>  <subnet mask>
#trust 208.148.145.151
#trust 208.148.145.144 255.255.255.240
#
#Selected call signs which are always gated to RF
#if they are not seen locally. All packets from
#these are gated in real time. Do not use unless
#you really need real time data.  Consider posit2rf below.
#They are case sensitive! Use upper case. Up to 64 may be defined.
#As of version 2.1.5 the * wild card character is supported.
#All characters beyond the * are ignored.  
#ie: WA4* would match ALL call signs beginning with "WA4"
#gate2rf K4HG-8 N4NEQ* 
#gate2rf W7LUS-14
#
#Call signs of stations whose posits are gated
#to RF every 15 minutes.  Only posit packets are
#gated.  Posits are taken from the history list.
#They are case sensitive! Use upper case.
#posit2rf N4NEQ-9 
#posit2rf W7LUS-14
#
#Define a list of message destination call signs or aliases 
#to gate to RF full time.  Note: the CQGA example 
#below is CQ GA (Georgia). Edit to suite your locale.
#Up to 64 of these may be defined. They are case sensitive.
#
msgdest2rf SCOUTS KIDS CQGA
#
#end


IGATE PORTS

The "Server" commands in the configuration file above define the distant APRServe and other Servers or HUBS you want to establish connections to. You may choose zero to 100. Duplicate data will not be relayed to your users. Connections which drop will be reestablished automatically. After a connection drops it will attempt to reconnect after 1 minute. If that attempt fails it will try again in 2 minutes. The time will double each time until it hits 16 minutes. Then it will retry forever at 16 minute intervals. These connection attempts appear in the aprsd.log file.

Use the HUB mode (hub-sr) only with APRS servers which carry the full global feed such as first.aprs.net, second.aprs.net and third.aprs.net. Using HUB with all 3 of these establishes a single connection to one of them. When that connection fails the next one will be tried until a new connection is established.

Server mode (server-ro or server-sr) connections should be used for regional servers that do not carry the full aprs data stream.

This server has a port (1314) which only supplies station to station messages and corresponding posits. Other servers which will be used ONLY to relay 3rd party station to station messages to their local VHF network may want to connect to this port to greatly reduce the amount of data on their tcpip connection.

Click here for a list of APRS servers and active port numbers.


COM PORT CONFIGURATION

The TNC COM port default to 9600 baud, 1 stop bit, 8 data bits and no parity. You may change the baud rate with the "TNCBAUD" command in aprsd.conf. Be sure the TNC is configured to these parameters. You can use the terminal program "minicom" that comes with Linux to prepare the TNC. Make sure the TNC is NOT in KISS mode.

Be sure the device ( dev/ttyS* ) has the proper read/write permissions or the server will not be able to access it.

Root can set the serial port so it can be written to by anyone with the following command:

chmod ugo+w /dev/ttyS0

NOTE: If you don't define a device for the com port in the aprsd.conf file all TNC related functions in the server are disabled.


SHUTTING DOWN THE SERVER WHEN RUNNING AS A PROGRAM

Ctrl-C or "q" will shut down the server in an orderly manner and saves the current history list (last 30 mins of received TNC data) to disk.

Ctrl-\ shuts down without saving anything.

When running as a daemon you can shut it down when logged on as root by issuing this command: "service aprsd.init stop".


REMOTE TNC SYSOP ACCESS on Port 14500

You may telnet to the APRS server and connect to the TNC for the purpose of changing parameters or even sending data out over the radio channel. As of version 215 you must use the SysOpPort (default 14500). Use the (ESC) key from a telnet session to enter remote access mode. You'll be prompted for your user name and password. These must match an entry in the Linux password file. In other words, a valid Linux login user/password. Also, aprsd must be running as root to be able to validate Linux passwords. If the password is incorrect remote sysop mode will be exited. The user must also belong to the "tnc" group. This group must be created in the /etc/group file. Here is an example line:

tnc::102:root,wa4dsy,bozo

In this example users root,wa4dsy and bozo are assigned to the tnc group.

After you have logged on, everything you type goes to the TNC and all TNC output data goes only to you. The TNC is effectivly disconnected from all other internet users. Hit control-C to get the TNC into command mode.

To exit remote TNC access hit the key. You may also need to hit if your Telnet program sends data a line at a time. Some Telnet programs can be configured for character at a time mode. Check your documentation for details. As of version 2.1.5 aprsd should put your telnet client into character-at-a-time mode automatically.

REMEMBER TO ENTER THE TNC "K" COMMAND BEFORE YOU EXIT.

To disconnect hit ctrl-D .


LOG FILES

/home/aprsd2/aprsd.log	User logons and logoffs and some system activity msgs.

/home/aprsd2/thirdparty.log	 3rd party messages sent on RF.

/home/aprsd2/udp.log	Record of data entering from the UDP port.

/home/aprsd2/rf.log     Record our own packets heard on RF by the TNC. 
                        (After being digipeated)
                        
/home/aprsd2/loop.log   Packets that were NOT flaged as duplicates and
                        rejected by the LOOP detector.

/home/aprsd2/reject.log Packets rejected by aprsd excluding dups.

These can be viewed in real time with: tail -f /home/aprsd2/aprsd.log or the name of the log you want to monitor.

You can also use the "less" program to view it. After entering "less /home/aprsd2/aprsd.log" you type "F" to follow it in real time. Type ctrl-C to exit "F" mode.

All 3rd party station to station messages relayed from the Internet to RF are logged in /home/aprsd2/thirdparty.log

3rd party formatted packets received by the TNC with "TCPIP" in the 3rd party path will never be sent anywhere.

Data from the UDP port are logged in /home/aprsd2/udp.log .

All data heard on RF with the "MYCALL" callsign with be logged in rf.log . This feature lets you see what you have sent out on RF if you are being digipeated by someone else.

To keep the log files from getting too large they need to be rotated on a regular basis. Add the following to your /etc/logrotate.conf file. Log files will be rotated daily or weekly and the oldest deleted after 4 rotations. Feel free to modify the schedule to suit your needs.


/home/aprsd2/aprsd.log {
        weekly
        rotate 4
}

/home/aprsd2/thirdparty.log {
        daily
        rotate 4
}
/home/aprsd2/udp.log {
        daily
        rotate 4
}
/home/aprsd2/rf.log {
        daily
        rotate 4
}

/home/aprsd2/loop.log {
        daily
        rotate 4
}

/home/aprsd2/reject.log {
        daily
        rotate 2
}





I use the "joe" editor to edit my configuration files remotely. It isn't installed by default so you may need to install it from the cdrom. To install mount the CD and do rpm -iv /mnt/cdrom/RedHat/RPMS/joe-2.8-13.i386.rpm .

STATION TO STATION 3RD PARTY MESSAGES

This program will reformat and relay APRS messages from the Internet to the TNC for RF transmission under the following conditions.

It came from a logged on verified registered user.

and

The originator was not seen on the TNC RF data stream in the past 30 minutes.

and

The destination HAS been seen on the TNC RF data stream in the past 30 minutes and doesn't have "GATE*" in his path and has been repeated less than 3 times.

and

The line "rf-allow yes" is in the /home/aprsd2/aprsd.conf file.

Version 2.0.8 and later allows you to define up to 64 message destination call signs or aliases which will always be gated to RF if "rf-allow yes" has been defined. See the example aprsd.conf file for an example of how to use the "msgdest2rf" command to enable this feature. For each 3rd party messge delivered to RF the latest position report packet of the originating station will also be sent after reformating the path in 3rd party format. The program pulls the posit from the history list if it's in there.

eg:

KE6DJZ>AP0917,KB6TLJ-5,RELAY,WIDE:=3415.99N/11844.34WyAPRS+SA

becomes:

}KE6DJZ>AP0917,TCPIP,WA4DSY*:=3415.99N/11844.34WyAPRS+SA

(assuming "MyCall" is WA4DSY )

During a series of messages the position packet will only be sent with a message every 10 minutes unless the station emits and new one.

This server will NOT igate a 3rd party _reformatted_ message from RF to the Internet which has been previously on the Internet. ie: has TCPIP in the 3rd party path. 3rd party packets without TCPIP in the 3rd party path will be converted to normal packets and processed in the usual way.

Users of unregisterd client programs can send their own station-to-station messages to other Internet users. These messages will not go out on the TNC RF channel and the path will be modified (TCPIP is changed to TCPXX*) so other hubs will know not to send these messages out on their RF channels. Unregistered users cannot Igate packets other than their own. In other words, the ax25 source call in their packets must match their logon call and "TCPIP" must be in the path. (TCPIP* or TCPXX* will not work either)

eg: assume N0CALL is unregistered and attempts to send the following into the server.

N0CALL>APRS,TCPIP:>TESTING
This will be converted to N0CALL>APRS,TCPXX*:>TESTING and gated to other users (but not to RF!)

However...
W4ZZZ>APRS,TCPIP:>TESTING
or
N0CALL>APRS,TCPIP*:>TESTING
will be deleted and not sent anywhere.
Telnet users must provide a user name or call sign before any of their data can be relayed to the internet. They need to enter "user callsign pass -1" so the server will accept the data. The ax25 FROM call in packets they send must match the call sign they loggon with. If they provide a valid password full priviliges are granted since they used the keyboard to emulate a client program logon string. (Not that anyone would want to do this except for testing)

This server will also accept valid user/password combinations for the Linux system it is running on. These users must be in the aprs group. This group can be added by editing the /etc/group file.

Note:

This program trusts other versions of itself and APRServe to flag the paths of data from unregistered Internet users with "TCPXX*". Station to station messages flagged this way will not be sent out on RF. The IGATE commands in the aprsd.conf file should specify a remote host port which is secure. For IGATES it must be a port which doesn't echo any Internet user data, only TNC data. Full function servers such as APRServe and this version (2.x.x) of aprsd will change TCPIP* to TCPXX* in the paths of unregistered users on all ports.

Users of the current java APRS applet don't log in at all and are granted read-only access


MESSAGE ACKS (New in 2.0.7)

At the suggestion of Bob Bruninga I have implemented redundent message acks. Message packets of the form "WA4DSY>APRS::W4XYZ :ack{1" will be reformatted to 3rd party format and sent to the TNC as usual. However, the packet will be repeated several times at intervals of 5 (typical) seconds. The number of repeats and the time between them are defined by the "ackrepeats" and "ackrepeattime" statements in the aprsd.conf file. The defaults are 2 repeats at 5 second intervals. You can set the repeats to any value from 0 to 9 and the time interval from 1 to 30 seconds. Note the "ackrepeats" value is in additon to the first message ack. You will always send at least one.


USER VALIDATION

I obtained the user validation code from Steve Dimse K4HG. He has recently allowed the source code to be released. The source is in validate.cpp.

If the users APRS name and pass code aren't valid the validate module tries the Linux pass word validator for the "aprs" group. If that also fails it waits 10 seconds then returns the bad news to aprsd which notifies the user.

NOTE: aprsd must be run as root for the Linux password validator to work. However, the APRS user and passwords (from Mac/WinAPRS users) will be properly tested regardless of what user is running aprsd if "aprsPass yes" is in the aprsd.conf file.

The logon format:

user pass vers

eg: user N0CALL pass 00001 vers MacAPRS 3.0
might be sent by a MacAPRS user.
As pass code of -1 means you are an unregistered user, not a hacker trying out an bogus password.

You can telent to a port and enter the following, assuming your Linux user name is bozo and you password is xyzzy and you are part of the aprs group as defined in the /etc/group file.

user bozo pass xyzzy

To monitor some server status data you can enter:

user bozo pass xyzzy vers monitor

The aprs data stream is turned off and "Monitor Mode" is entered. Once a minute the server will send a status message to you.

Once you have logged on, ctrl-D will not cause a disconnect. You have to use your Telnet escape key then do a quit. I had to do this to prevent inadvertant disconnects due to possible spurious control codes in some users data.


KEEPING ABUSERS OUT OF THE SYSTEM (New in 2.1.0)

You can put the call signs of the users you want to restrict in the users.deny file. The format is the users call sign followed by either the letter "L" or "R". The "L" prevents logons and RF access. The "R" prevents only RF access while allowing the user to send packets into the aprs network.

user.deny example:

W4EVIL L   <--- Prevents sending of packets into the server or RF
W4SOB R    <--- Prevents any of his packets from getting on RF
		even if they came from another igate.


NOTE: This file is read every time aprsd needs to check users
so you will NOT need to restart the server when you change it.
If the abuse becomes serious enough you might consider putting "aprsPass no" in the aprsd.conf file. This turns off the checking of aprs passcodes and only allows Linux user/passwords. You will need to have all your users in the Linux passwd file.

Full time gating of selected stations from Internet to RF

For special events or personal reasons it may be desirable to allow the transfer of packets of selected stations from the Internet to RF. Allowing all stations to do this would overload the 1200 baud VHF packet frequency and isn't allowed. These packets are only sent on RF if they came from the Internet and were NOT heard on the local VHF frequency.

There are three "modes" of doing this. The most permissive allows all packets from a selected station to be sent to RF in real time. The second mode only allows position report packets to be sent on RF every 14.9 minutes. This puts much less strain on the RF network and is the recommended mode.

The third mode which was new in version 2.0.8 gates 3rd party station to station messages to RF full time if the DESTINATION call sign or alias is defined in the aprsd.conf file after the msgdest2rf keyword.

You select the stations by entering them in the /home/aprsd2/aprsd.conf file. Up to 64 stations can be defined. Several can be put on each line. The server must be restarted before any changes to aprsd.conf take effect.

In version 2.1.5 the "*" wild card character is supported. Characters past the "*" will be ignored in the compare operation. For example W7LUS* would allow all W7LUS ssids to match. Examples:

These stations posits are sent to RF every 15 minutes: 
posit2rf K4HG-8 N4NEQ-9 
posit2rf W7LUS-14

All packets from this station are gated to RF full time.
gate2rf N0CLU-9

Any call with the first 5 characters matching W7LUS will
be gated to RF full time. eg: W7LUS-1 and W7LUS-13.
gate2rf W7LUS*




This allows any message addressed to SCOUTS, KIDS or CQGA to go to
RF even though these "call signs" were not heard locally.
msgdest2rf SCOUTS KIDS CQGA

Note: The posits of stations in the "posit2rf" list are sent at 14 second intervals. It takes 14.9 minutes to scan the list of 64 before it repeats. The posits are taken from the 30 minute history list. If no posit is available for the station then no data is transmitted.

NOGATE and RFONLY

Version 2.1.5 adds support for NOGATE and RFONLY in the path. Any packet from any source with "NOGATE" or "RFONLY" in its path will be discarded.


MIC_E PACKET TRANSLATION

If you have "ConvertMicE yes" in your aprsd.conf file AND have set "#define CONVERTMICE TRUE" in the source file constant.h and recompiled the code, compressed TAPR Mic_E packets are converted to standard APRS format before being sent anywhere else. I used the Mic_E decoder written by Alan Crosswell, N2YGK to do the conversion. This is the same code that's in his aprsmon program.

The unconverted raw Mic_E packets from the local TNC can be observed by telneting to port 14580.


AEA to TAPR conversion

All packets in the AEA format are converted to TAPR format before any other processing. Clients never see an AEA formatted packet except from the RAW TNC port (14580) if the system operator is using an AEA TNC.


Packet Source path insertions

To aid in determining where packets were inserted into the APRS Internet stream, aprsd 2.1.5 appends identifier path elements at the end of the existing path if not present. Incoming packets with the "qAc,callsign" in them are not modified.

The first added path elemement is a three letter code indicating data protocol and info about the source of the packet. This code can be expanded in the future as needed.

The first character is always "q". The second character is a protocol identifier for the data payload. Currently only A=APRS is defined. The third character is a code that identifies the source of the packet. The possible codes are C, X, R, , r, S, U, I, Z. They are defined as follows:

Code          Source

C        Validated Client (User). Packet had no q construct.
X        Unvalidated Client
R        RF packet from local TNC or converted from CALLSIGN,I construct
r        Same as above but received indirectly via another server.
S        Server or Hub
U        UDP port on aprsd server
I        Internal status message from aprsd server and Trace Packet
Z        Zero hops and Internal, do not repeat this packet

Following the qAc path element is the identifier callsign:

Source            Identifier

C or X User   Users Login Call sign. 
S APRS Hub    IP address of distant server in HEX. This is the "Hex IP Alias".
I Internal    Server callsign.  (ServerCall in aprsd.conf)
R TNC         IGATE callsign or Callsign preceeding the "I" if converted from CALLSIGN,I .
r             Callsign preceeding the "I"
U UDP         Server callsign.
Z             Server callsign.

Here are some examples.
Assuming MyCall is WA4DSY, ServerCall is aprsdATL, Logged on user is WA4ABC, we are connected to and receiving data from first.aprs.net and the path does NOT already have an qAc, we add:

qAC,WA4ABC     from validated internet Client WA4ABC
qAX,WA4ABC     from unvalidated client
qAR,WA4DSY     from local TNC (RF) 
qAR,W4ABC      from logged on client "W4ABC" and converted from W4ABC,I.
qAr,N4ZZ       from a server and converted from N4ZZ,I format.
qAS,C6581502   from Server/Hub third.aprs.net (IP address = 198.88.21.2) (no q and no I )
qAU,aprsdATL   from UDP port
qAI,aprsdATL   from Internal source (server beacon, etc). Packet will be traced.
qAZ,aprsdATL   from Internal source that should not be repeated (server status messages)

If a packet comes in from directly connected client "MYCALL" and already has a MYCALL,I on the end of the path aprsd 2.1.5 swaps the position of the "I" and preceeding callsign and changes the I to qAR. WA4DSY>APRS,WA4ABC,I:data becomes WA4DSY>APRS,qAR,WA4ABC:data .

If a packet is received from another server and has MYCALL,I in the path, the packet is converted to the qAr,MYCALL format.

The path will be either zero or 2 elements longer than the original.

If trace is enabled by setting "TRACE YES" in aprsd.conf, all packets passing through aprsd will have the servers call appended to the end of the AX25 path.

Click here for more about the qAc,Callsign construct written by Pete Loveall.

UDP PORT

The UDP input port (default 1315) is provided for interface with scripts. Only IP addresses listed in the "trust" line(s) in the aprsd.conf file are can send data to this port. You can enter up to 20 trust commands.

Example:

trust 198.162.50.5 

You may also provide a subnet mask after the ip address to open up an entire sub net. The example below allows 16 address from 198.162.50.0 to 198.162.50.15 .

Example:

trust 198.162.50.0 255.255.255.240 

The script can format packets to be sent to the TNC for RF transmission or TCPIP. The routing is determined by the "TO-CALL" field. If it's "TNC" the packet goes on on RF via the TNC after the path is striped off.

This goes to the TNC: WA4DSY>TNC:Data for TNC here
This goes to TCPIP: WA4DSY>APRS:Data for the Internet

The complete string including the path goes out on the Internet.

See the file "udp_example" for a sample perl script.


RESPONDING TO QUERIES

The aprsd 2.1.5 server will respond the general ?IGATE? query as follows:
Query:
WA4DSY>APRS:?IGATE? 
Response:
aprsdATL>APD215,TCPIP*:<IGATE,MSG_CNT=11,LOC_CNT=59,CALL=WA4DSY,
LOCATION=Atlanta_GA,HOST=wa4dsy.net,IP=216.27.174.144,
EMAIL=sysop@myisp.com,VERS=aprsd 2.1.5

Most of the data comes from the aprsd.conf file.

  • MSG_CNT=11 is number of packets sent to RF
  • LOC_CNT=59 is number of items defined as "LOCAL" in the history buffer
  • CALL=WA4DSY is from mycall from INIT.TNC
  • LOCATION=Atlanta_GA is from mylocation
  • HOST=wa4dsy.net is host name obtained from Linux OS
  • IP=216.27.174.144 is IP address from Linux OS
  • EMAIL=sysop@myisp.com is from myemail
  • VERS=aprsd 2.1.5 is internal version number string.
A query from the RF side will not be passed to the Internet but will be responded to on RF only. Internet queries will be passed to other connected servers and will result in replies from every query enabled IGATE connected to the Internet.

Note that directed queries are no longer supported because of problems with RF flooding.


Java Applet

The JavAPRS applet by Steve Dimse is a completely separate product and is not supported by me. Surf over to
www.ae5pl.net/html/javAPRS.htm for more information.

APRS passcode calculator (new in 2.1.1)

The aprspass program is located in the /home/aprsd2 directory. You may move it to another more convienient location if you wish. To determine the aprs passcode required for a callsign "N0CALL":
Change to the /home/aprsd2 directory.
./aprspass N0CALL
APRS passcode for N0CALL = 12345
The program will print the passcode "12345". You may use this 5 digit number as a password to connect and login to other igates and APRServe. The callsign and passcode are used as follows in aprsd.conf.
igate second.aprs.net 23 N0CALL 12345
This causes aprsd to connect the second.aprs.net, port 23. Data from that server becomes available at your server. Your TNC data and logged on Internet user data is sent to second.aprs.net over the two way connection.
Please use your real callsign!

Monitoring system status with a web browser (new in 2.1.2)

System operators can now check the operational status of their aprsd server with a web browser. The default port is 14501. To see the information simply enter the URL into the browser.
Example: To see the Miami server: http://first.aprs.net:14501/
To refresh the data click the browser reload button. Notice the igate domain names and user IP addresses are links. If the host is running aprsd 212 or later you can click on the link to see the status of that server. This is an open port, no passwords are required.

To disable this feature add to your aprsd.conf file: httpport 0

Determining the source IP address of aprs packets (new in 2.1.2)

This TCPIP port (default 14502) supplies all data streams without dup filtering with a special header prepended. The header contains the source IP address of the packet and the user login name, "IGATE" or "UDP". An example: !44.36.16.48:WA4DSY! Packets from other igates this server connected to will show the domain name instead of the IP address and the user will be "IGATE". Packets from the UDP port will have the IP address and the user field will be "UDP". Packets from the TNC will have "TNC" in the IP address field and "*" in the user field . Use telnet or nc optionally with grep to determine the source of packets.
eg: telnet first.aprs.net 23 | grep '199.45.66.88'
Will display only packets from IP address 199.45.66.88.

To disable this feature add to your aprsd.conf file: ipwatchport 0

KNOWN BUGS

Memory Leak Under RedHat 5.1 this program leaks 8K of memory for each user connect/disconnect event. This appears to be a problem with one or more C libraries in the thread creation/destruction code. It has been fixed in 5.2.

To get the fix for 5.1surf over to ftp://ftp.redhat.com/pub/redhat/upgrades/5.1/i386/

Then get this file:
glibc-2.0.7-19.i386.rpm

The memory leak seems to be fixed in this version. To install do: rpm -U glibc-2.0.7-19.i386.rpm then reboot. You don't need to recompile aprsd!


aprsd-2.2.5-13/doc/ports.html0000644000076400007640000003274707651647334011401 aprsd TCP port functions

aprsd TCP port functions for versions 2.1.5 July 2002

All port numbers are defined in /home/aprsd2/aprsd.conf. If a port is not defined there it is inactive. The exceptions are the ipwatchport and httpport ports which are enabled unless defined to zero in aprsd.conf.

Omni Port #14600 (or system operator defined)

  • aprsd.conf key word: omniport
  • Function: User may select any available data stream on this port.
  • Bidirectional
  • Echos: User requested data streams. Data streams may be selected either before logon with simple ascii strings or after logon with aprs messages. Click here for details.

Main Port #10151 (or System operator defined)**

  • aprsd.conf key word: mainport
  • Function: User access via various aprs clients to all data streams.
  • Bidirectional
  • echos:
    • Internet user data
    • Data from other IGATES and hubs
    • TNC data
    • Internal system status messages
    • UDP data
  • Sends 30 minute* history of all data streams when user connects

Main Port-NH #10152 (or System operator defined)**

  • aprsd.conf key word: mainport-nh
  • Same as Main Port above but doesn't send 30 minute history when user connects.

Local Port #14579 (or System operator defined)

  • aprsd.conf key word: localport
  • Function: User access via various aprs clients to local TNC data only.
  • Bidirectional
  • echos:
    • TNC data
    • UDP data
    • Internal system status messages
  • Sends 30 minute history of TNC data only

Raw TNC Port #14580 (or System operator defined)

  • aprsd.conf key word: rawtncport
  • Function: User access via various aprs clients to RAW local TNC data only.
  • Bidirectional
  • echos: TNC data
  • No 30 minute history dump.
Note: This port doesn't reformat the TNC data or filter duplicates. Every packet the TNC hears is sent the the user unchanged.

Link Port #1313 (or System operator defined)

  • aprsd.conf key word: linkport
  • Function: Other hubs such as APRServe connect here to get local TNC data and Internet user data. As of version 2.1.5 status messages (javamsg) are no longer echoed here.
  • Bidirectional
  • echos:
    • TNC data
    • Internet user data (from other ports)
    • UDP data
  • Does NOT send 30 minute history
  • Does NOT echo data from other IGATEs

Messsage Port #1314 (or System operator defined)

  • aprsd.conf key word: msgport
  • Function: Other hubs such as APRServe or aprsd connect here to get 3rd party station to station messages. All station to station messages from all data sources and a corresponding position report are available on this port. All other packets are filtered out. This is useful for clients that need to conserve Internet link bandwidth but want access to the global station to station message stream for Internet to RF messaging.
  • Bidirectional
  • echos:
    • 3rd party staton to station messages from all sources.
  • Does NOT send 30 minute history.

UDP Port #1315 or defined by system operator

  • aprsd.conf key word: udpport
  • Function: Allows other programs such as Perl scripts to send short packets of data into the aprs stream or the TNC. Packets addressed to the TNC are directed to RF. All others go to the Internet. I use it to inject weather packets from a Perl script.
    The path data (up to and including the colon) are stripped off before the TNC gets it.
    eg:
    WA4DSY>TNC:This data goes to the TNC
    WA4DSY>APRS:This whole line goes to the Internet (no path stripping)
  • Unidirectional (Input only)
  • echos: nothing
  • security: System operator defines IP addresses of trusted users. These will usually be a local host or subnet but could be any host.

HTTP Port #14501 or defined by system operator [New in 2.1.2]

  • aprsd.conf keyword: httpport
  • Note: You don't need to add this to your aprsd.conf file unless you want to change it to a port other than 14501. To disable it, set it to zero.
  • Function: Defines the port which suppiles server status information in HTML format. This port is accessed with any web browser by entering the URL: http://wa4dsy.net:14501/ (replace "wa4dsy.net" with the domain name of the aprsd server you want ) To refresh the data click the RELOAD button on your browser.

IP Source monitor port #14502 or system operator defined.

  • aprsd.conf keyword: ipwatchport
  • Note: You don't need to add this to your aprsd.conf file unless you want to change it to a port other than 14502. To disable it, set it to zero.
  • Function: Supplies all data streams without dup filtering with a special header prepended. The header contains the source IP address of the packet and the user login name, "IGATE" or "UDP". An example: !44.36.16.48:WA4DSY! Packets from other igates this server connected to will show the domain name instead of the IP address and the user will be "IGATE". Packets from the UDP port will have the IP address and the user field will be "UDP". Packets from the TNC will have "TNC" in the IP address field and "*" in the user field . Use telnet or nc optionally with grep to determine the source of packets.
    eg: telnet first.aprs.net 23 | grep '199.45.66.88'
    Will display only packets from IP address 199.45.66.88.

Error Port 14503 [New in 2.1.5]

  • aprsd.conf keyword: errorport
  • Note: You don't need to add this to your aprsd.conf file unless you want to change it to a port other than 14503. To disable it, set it to zero.
  • Function: Supplies the packets that were rejected for various reasons. Duplicates do not appear here. A special header is prepended to indicate the IP address and logon call.

IGATE connection ports

These are client ports which connect to distant IGATEs, Servers or Hubs to harvest their data streams. Connections are reestablished when they drop. The system operator defines the domain names and optional user/pass logon. If the optional user/pass information is supplied the server will send out to the distant Servers the same data provided by port 1313 above. This is usefull for those who use a dialup connection without a static IP address. Up to 100 distant Servers can be defined. (this limit can be increased by editing an recompiling)


* The 30 minute time is now user definable.
** All ports are optional. They will not be activated unless a port number is defined in the aprsd.conf file.

REFORMATTING

Mic-E packets may optionally be converted to standard APRS format before being sent to clients. Generally Mic-E conversion is undesirable. There is an option in the aprsd.conf file to control conversion.

Data from AEA TNCs is converted to TAPR format before being sent to clients.


Station to station messages of the 3rd party kind:

This program will reformat and relay aprs station to station messages from the Internet to the TNC for RF transmission under the following conditions.


If it came from a logged on verified registered user.
and
The originator was not seen on the TNC RF data stream in the past 30 minutes.
and
The destination HAS been seen on the TNC RF data stream in the past 30 minutes and doesn't have "GATE*" in his path and has been repeated less than 3 times.

For each 3rd party messge delivered to RF the latest position report packet of the originating station will also be sent after reformating the path in 3rd party format. The program pulls the posit from the history list.

eg:
KE6DJZ>AP0917,KB6TLJ-5,RELAY,WIDE:=3415.99N/11844.34WyAPRS+SA
becomes:
}KE6DJZ>AP0917,TCPIP,WA4DSY*:=3415.99N/11844.34WyAPRS+SA
(assuming "MyCall" is WA4DSY )

During a series of messages the position packet will only be sent with a message every 10 minutes unless the station emits a new one.

This server will NOT igate a 3rd party reformatted message from RF to the Internet if the packet has been previously Igated from Internet to RF. A packet from any source that does not have TCPIP in the 3rd party path will be converted to normal format and handled in the usually way.

Users of unregisterd client programs can send their own station-to-station messages to other Internet users. These messages will not go out on the TNC RF channel and the path will be modified (TCPIP* is changed to TCPXX*) so other hubs will know not to send these messages out on their RF channels. Unregistered users cannot Igate packets other than their own. In other words, the ax25 source call in their packets must match their logon call.

eg; assume N0CLU is unregistered and attempts to send the following into the server.

N0CLU>APRS,TCPIP:>TESTING This will be converted to N0CLU>APRS,TCPXX*:>TESTING and gated to other users (but not to RF ever!)

However... W4ZZZ>APRS,TCPIP:>TESTING will be deleted and not sent anywhere.

Telnet users must provide a user name or call sign before any of their data can be relayed to the internet. They need to enter "user callsign pass -1" so the server will accept the data. The ax25 FROM call in packets they send must match the call sign they loggon with. If they provide a valid password full priviliges are granted since they used the keyboard to emulate a client program logon string. (Not that anyone would want to do this except for testing)

This server will also accept valid user/password combinations for the Linux system it is running on. These users must be in the aprs group. This group can be added by editing the /etc/group file. See the README for details. This program trusts other versions of itself and APRServe to flag the paths of data from unregistered Internet users with "TCPXX*". Station to station messages flagged this way will not be sent out on RF. The IGATE commands in the aprsd.conf file should specify a remote host port which is secure. For IGATES it must be a port which doesn't echo any Internet user data, only TNC data. Full function servers such as APRServe and this version (2.x.x) of aprsd will change TCPIP* to TCPXX* in the paths of unregistered users on all ports.


Omni Port operation

The Omni Port provides user requested data streams. The streams are selected by filter commands. Currently the only filter available is the Port Filter. The syntax of the Port Filter command is "portfilter(arg1,arg2,arg3,.....)". The short form "pf(arg1,arg2,arg3,...)" may also be used. The command may be issued in raw ascii form prior to user logon or as a message addressed to "SERVER" after logon. Messages addressed to "SERVER" can be sent from any aprs client program capable of sending messages. The command may be issued any number of times. The commands and arguments are not case sensitive.
Examples.
Raw: pf(all,history)
In message: WA4DSY>APRS::SERVER :pf(all,history)

Port Filter arguments.

  • ALL: All data streams
  • FULL: Same as above
  • LOCAL: Data from TNC, UDP port, internal system msgs, and server beacon
  • LINK: Data from TNC, UDP port, users, and server beacon
  • MSG: Messages and associated posits only
  • HISTORY: History list dump

  • TNC: Data from the TNC attached to the server
  • USER: Data from connected users
  • HUB: Data from Hub or Server connections
  • SERVER: Same as above
  • UDP: Data from aprsds UDP port
  • RAW: Unfiltered TNC data
  • DUP: Duplicate packets
  • SYSTEM: System generated packets
  • STATS: Non-ax25 formated server system status info
  • REJECT: Data that the server has rejected
  • HEADER: Same data as ipwatchport 14502 described above
  • ECHO: Users own data is echoed back to him
  • CLEAR: No data streams

  • -HUB: remove data from Hubs/Servers
  • -TNC: remove TNC data
  • -USER: remove user data
  • -SYSTEM: remove system messages
  • -BEACON: remove system beacon packets

Arguments are scanned in the order they appear. For example, if you want everything including a history dump but don't want the system status messages:

pf(all,-system,history)

You may connect to the Omni Port with telnet and watch the servers operaton in real time.

telnet wa4dsy.net 14600
pf(stats)

If you require you own data echoed back to you simply add the "ECHO" argument to the list.

pf(all,-system,echo)

Note: Filter messages are only accepted from your logon callsign. If you want to freeze the filter configuration for the duration of the connecton issue the "LOCK" command. eg: lock(). No more commands will be accepted.

The Omniport will be easier to user if client software authors add automatic transmission of the stream requests at logon. They could be specified with simple checkboxes in a dialog window.


aprsd-2.2.5-13/doc/qalgorithm.html0000644000076400007640000001443107651647334012367 All packets

Q Algorithm
Construct ] [ Algorithm ]

All packets:
{
    If there is a q construct in the path:
        Skip to "All packets with q constructs"

    If the packet entered the server from an UDP port:
    {
        Append ,qAU,SERVERLOGIN
        Quit q processing
    }

    If the packet entered the server from an unverified connection and has been converted to TCPXX format (per current validation algorithm):
    {
        (All packets not deemed "OK" from an unverified connection should never make it here.)
        Append ,qAX,FROMCALL
        Skip to "All packets with q constructs"
    }

    If packet entered the server from a verified connection:
    {
        If header is terminated with ,I:
        {
            If the VIACALL preceding the ,I matches the login:

                Change from ,VIACALL,I to ,qAR,VIACALL
            Else
                Change from ,VIACALL,I to ,qAr,VIACALL
        }
        Else If the FROMCALL matches the login:
            Append ,qAC,FROMCALL
        Else
            Append ,qAS,login
        Skip to "All packets with q constructs"
    }

    If packet entered the server from an outbound connection (to another server's port 1313, for instance):
    {
        If header is terminated with ,I:
            Change from ,VIACALL,I to ,qAr,VIACALL
        
Else
            Append ,qAS,IPADDR (IPADDR is an 8 character hex representation of the IP address of the remote server)
    }
}

All packets with q constructs:
{
    if ,qAZ, is the q construct:
    {
        Dump to the packet to the reject log
        Quit processing the packet
    }

    If ,SERVERLOGIN or IGATECALL is found after the q construct:
    {

        Dump to the loop log with the sender's IP address for identification
        Quit processing the packet
    }

    If the packet is from a verified port and the login is found after the q construct but is not the LAST VIACALL:
    {
        Dump to the loop log with the sender's IP address for identification
        Quit processing the packet
    }

    If trace is on, the q construct is qAI, or the FROMCALL is on the server's trace list:
    {
        If the packet is from a verified port where the login is not found after the q construct:
            Append ,login
        Append ,SERVERLOGIN
    }
}

aprsd-2.2.5-13/doc/q.html0000644000076400007640000001162307651647334010460 Q Construct

Q Construct
[ Construct ] Algorithm ]

The "q-construct" is being implemented on APRS-IS to add the following capabilities to the Internet APRS transport mechanism.

  • APRS-IS Entry Identification
  • Support for a Future Authorization Algorithm
  • Support for Loop Detection
  • Support for Automatic Loop Protection
  • Compatibility with Existing IGate and Client Software
  • Only Server Support Needed for Implementation

The currently defined q constructs are:

Server Generated:

  • qAC - Packet was received from the client directly via a verified connection (FROMCALL=login).  The callSSID following the qAC is the login of the client.
  • qAX - Packet was received from the client directly via a unverified connection (FROMCALL=login).  The callSSID following the qAX is the login of the client.  This construct is in addition to the TCPIP*/TCPXX* construct currently in place.
  • qAU - Packet was received from the client directly via a UDP connection.  The callSSID following the qAU is the login of the server.
  • qAS - Packet was received from another server or generated by this server.  The latter case would be for a beacon generated by the server.  Due to the virtual nature of APRS-IS, use of beacon packets by servers is strongly discouraged.  The callSSID following the qAS is the login or IP address of the first identifiable server (see algorithm).
  • qAr - Packet was received indirectly (via an intermediate server) from an IGate using the ,I construct.  The callSSID following the qAr it the callSSID of the IGate.
  • qAR - Packet was received directly (via a verified connection) from an IGate using the ,I construct.  The callSSID following the qAR it the callSSID of the IGate.

Client Generated:

  • qAR - Packet is placed on APRS-IS by an IGate from RF.  The callSSID following the qAR it the callSSID of the IGate.
  • qAZ - Packet is generated by the server/client/IGate and should not be propagated.  The callSSID following the qAZ is the callSSID of the server/client/IGate.
  • qAI - Trace packet.  This packet tells each server to add login identification to the packet.  This packet starts with the callSSID of the originating station following the qAI.  See algorithm for more details.

Client generated q constructs will be verified if a new authorization algorithm is created.

Servers MUST have unique logins from any other server/IGate/client that insert data onto APRS-IS.  This is to prevent packets from being erroneously detected as looping.  For instance, if my server's login is AE5PL and my weather client is AE5PL, my server will see ,qAC,AE5PL and consider this packet a looped packet.  As logins can be any combination of 9 alphanumeric characters, this should not pose a problem.

IGates which append IGATECALL,I to the end of packets and which are directly connected to a server which supports the q construct will have the IGATECALL,I converted to qAR,IGATECALL or qAr,IGATECALL to support the extended capabilities of the q construct.

Servers will have the ability to selectively enable tracing on all packets through server configuration.  This must be used judiciously and only when a loop condition is suspected due to the increased bandwidth demands that tracing creates.

q constructs will only appear on APRS-IS and are not to be used elsewhere due to bandwidth considerations.

For example, this is what happens to a packet without a q construct which enters the system via a verified connection:

Original packet:
AE5PL>APRS,TCPIP*:payload

Packet leaving the serve if trace is off:
AE5PL>APRS,TCPIP*,qAC,AE5PL:payload

or, if trace is on:
AE5PL>APRS,TCPIP*,qAC,AE5PL,AE5PLjvs:payload

aprsd-2.2.5-13/admin/0000777000000000000000000000000007665450621007670 5aprsd-2.2.5-13/admin/Makefile.am0000664000076400007640000000022407655345423011704 EXTRA_DIST = aprsd.conf \ aprsd.init \ chkaprsd \ INIT.TNC \ Makefile.am \ REMOVE \ RESTORE.TNC \ welcome.txt \ udp_example \ user.deny aprsd-2.2.5-13/admin/Makefile.in0000644000000000000000000001227707665450603011662 # Makefile.in generated by automake 1.6.3 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 # 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. @SET_MAKE@ 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 pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_HEADER = $(INSTALL_DATA) transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : EXEEXT = @EXEEXT@ OBJEXT = @OBJEXT@ PATH_SEPARATOR = @PATH_SEPARATOR@ AMTAR = @AMTAR@ AWK = @AWK@ CC = @CC@ CXX = @CXX@ DEPDIR = @DEPDIR@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ PACKAGE = @PACKAGE@ STRIP = @STRIP@ VERSION = @VERSION@ am__include = @am__include@ am__quote = @am__quote@ install_sh = @install_sh@ EXTRA_DIST = aprsd.conf \ aprsd.init \ chkaprsd \ INIT.TNC \ Makefile.am \ REMOVE \ RESTORE.TNC \ welcome.txt \ udp_example \ user.deny subdir = admin mkinstalldirs = $(SHELL) $(top_srcdir)/support/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = DIST_SOURCES = DIST_COMMON = Makefile.am Makefile.in all: all-am .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu admin/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) uninstall-info-am: tags: TAGS TAGS: DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = .. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) @list='$(DISTFILES)'; for file in $$list; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic uninstall-am: uninstall-info-am .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am info info-am install \ install-am install-data install-data-am install-exec \ install-exec-am install-info install-info-am install-man \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic uninstall uninstall-am uninstall-info-am # 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: aprsd-2.2.5-13/admin/aprsd.conf0000644000076400007640000002021207665443770011632 # $Id: aprsd.conf,v 1.14 2003/05/29 03:09:39 kg4ijb Exp $ #aprsd 2.2.5 server configuration file # #This file is read ONCE on server startup. #You must restart aprsd for changes to take effect. #eg: /etc/rc.d/init.d/aprsd.init stop (then start) # #Lines starting with "#" are comments and are ignored #Key words such as "mycall" and "maxusers" are NOT case sensitive. #MyCall is the same as mycall. # #*** There is no error checking so be careful ****** # # #Servercall is the ax25 source call used in packets #sent from the server to Internet users. (9 chars max) #Note: Does not go out on the air. # servercall testCHO # #MyCall will be over written by the MYCALL string in INIT.TNC #if "tncport" has been defined. # MyCall KG4IJB-3 # MyLocation Charlottesville_VA # #This email address will be sent in replies to ?IGATE? queries. # Also, it will be on the status web pages on port 14501. MyEmail you@yourdomain.com # #Set MaxUsers and MaxLoad to values that your Internet connection can support. # Set MaxLoad in bytes/sec. If either value is exceeded # new users can't connect. MaxUsers 150 MaxLoad 100000000000 # # #Define beacon text. The server will supply the ax25 path header. #The first number after "NetBeacon" is the time interval in minutes. #Comment out the line or set time interval to 0 to disable beacon. #The rest of the line can be any aprs protocol conforming packet. # NetBeacon 10 !3802.21NI07830.61W& APRS Server # #Define the TNC beacon. The TNC will supply the ax25 path header. #It's optional and you may use the TNC BTEXT in the INIT.TNC file instead. # TncBeacon 10 !3802.21N/07830.61W& Linux APRS Server # # #Send 2 extra message acks is addition to each received ack to TNC #Range 0 to 9 ackrepeats 2 # #Send extra acks at 5 second intervals #Range 1 to 30 seconds ackrepeattime 5 # #Set history list items to expire in 35 minutes expire 35 # #Define the TNC serial port and baud rate. #Note: This device must have write permissions #If undefined all TNC related functions are disabled. #Permissable baud rates are 1200,2400,4800,9600 and 19200. # #tncport /dev/ttyS0 tncport radio #tncbaud 1200 #Define the path for transmitted packets #This is only used when using Linux sockets, not the TNC. #For the TNC, set this in INIT.TNC. Note the format is #slightly different to the TNC command. aprspath APRS v WIDE # # Allow Internet to RF message passing. rf-allow yes # #Set filterNoGate "yes" to block RFONLY and NOGATE packets filterNoGate yes # #Set history-allow to NO if you do not want users to get history dumps. history-allow no # #TRACE causes the server to append its own callsign to the end #of the AX25 path of every packet processed. #To conserver bandwidth this should only be #done for short periods to track sources of problems. # Trace no # #Set this to 'yes' if you want to log ALL PACKETS heard on RF to /home/aprsd2/rf.log #If 'no' then only packets with your callsign will be logged. logAllRF no # # Allow the insecure aprs passcodes to be used # Note: "no" means all users need Linux user names and passwords # and aprsd must be run as root for that to work. aprsPass yes # #Set the minimum time between TNC transmit packets in milliseconds TncPktSpacing 1500 # # Disallow packets transmitted from our own TNC from # being igated back to the Internet after being digipeated. igateMyCall no # #This determines if Mic-E packets are converted to classic APRS packets. #Put 'no' unless you have a very good reason to do conversions. #This option must also be enabled in the SOURCE CODE. To turn it on #you must edit "constant.h" and change CONVERT_MIC_E from FALSE to TRUE. #then recompile aprsd. ConvertMicE no # # #The PASS command. The callsign supplied in MyCall and this # passcode allow you to send data to distant servers. # PASS can be computed from MYCALL with the aprspass program. # Note: This example is invalid. Use your passcode. # pass 18094 # #------------------------------- #Server connection definitions # #usage: < host port> # #The TYPE-DIR field sets the connecton type and data flow. # TYPE is either "SERVER" or "HUB" # SERVER connections attempts to maintain a connection to the designated host # HUB connections maintain a connection to only ONE hub and rotate to the next # if the connectin fails. # DIR is either "RO" or "SR" RO is Receive Only. SR is Send and Receive. #Eamples: HUB-RO HUB-SR SERVER-RO SERVER-SR # If you select -SR to send data you must also supply a passcode # using the "PASS" command. See above. # #These commands are NOT case sensitive. # ** Defaults to Server-RO if TYPE-DIR not specified. ** # # #Example send-receive HUB connections #Hub is like Server except only ONE hub connection is active at a time. #If the hub connection fails the next hub is tried in rotation until one accepts a connection. # #Server second.aprs.net 23 hub-sr Server first.aprs.net 23 hub-sr #Server 128.143.202.191 23 hub-sr #Server third.aprs.net 23 hub-sr #Server rotate.aprs.net 23 hub-sr # # #Example Receive-Only HUB connecton #Server first.aprs.net 23 hub-ro # #Example Send-Receive SERVER connection. The SERVER type maintains a connection to #the specified server. No rotation. #Server first.aprs.net 23 server-sr # #Example of OmniPort connection to receive the local stream (tnc). #Note: OmniPort is currently available only on aprsd 2.1.5 # #Server atlanta.aprs.net 14600 server-ro portfilter(local) # #Receive the full stream. #Server atlanta.aprs.net 14600 server-ro portfilter(full) # # #These servers are provided as a reference. Some may no longer be active. #You really only need the two or three HUB connections above unless # you are doing something unusual. # #server second.aprs.net 1313 server-ro #server third.aprs.net 1313 server-ro #server socal-igate.aprs.claremont.edu 1313 server-ro #server first.aprs.net 23 #server atlanta.aprs.net 1313 server-ro #server aprsdkw.dyndns.org 1313 #server aprs.k9iu.ampr.org 1313 #server atlanta.aprs.net 1313 #server baltimore.aprs.net 1313 #server calgary.aprs.net 1313 #server concord.aprs.net 1313 #server cosprings.aprs.net 1313 #server dayton.aprs.net 14439 #server elansing.aprs.net 1313 #server gw.officine.it 1313 #server hamgate.cs.usu.edu 1313 #server kb2ear.aprs.net 1313 #server kd6wxd.dynip.com 10148 #server marconi.ece.cmu.edu 14579 #server michigan.aprs.net 1313 #server milwaukee.aprs.net 1313 #server montreal.aprs.net 1313 #server mulvey.dyndns.com 1313 #server netherlands.aprs.net 1313 #server newyork.aprs.net 1313 #server ontario.aprs.net 1313 #server orlando.aprs.net 1313 #server radio.artsfac.csuohio.edu 1313 #server radio-active.net.au 1313 #server sandiego.aprs.net 1313 #server santabarbara.aprs.net 1313 #server saopaulo.aprs.net 1313 #server swiss.aprs.net 14579 #server temple.aprs.net 1313 #server tucson.aprs.net 1313 #server wv.aprs.net 1313 #--------------------------------- # #Define server listen ports #Read ports.html for more info. # rawtncport 14580 localport 14579 mainport 10151 mainport-nh 23 linkport 1313 msgport 1314 udpport 1315 sysopPort 14500 httpport 14501 ipwatchport 14502 errorport 14503 omniport 14600 # #define trusted users of the UDP port. #usage: trust #trust 208.148.145.151 #trust 208.148.145.144 255.255.255.240 # #Selected call signs which are always gated to RF #if they are not seen locally. All packets from #these are gated in real time. Do not use unless #you really need real time data. Consider posit2rf below. #They are case sensitive! Use upper case. Up to 64 may be defined. #As of version 2.1.5 the * wild card character is supported. #All characters beyond the * are ignored. #ie: WA4* would match ALL call signs beginning with "WA4" # gate2rf K4HG* N4NEQ* KA7PBI* WE7U* #gate2rf W7LUS-14 #gate2rf KG4IJB-5 # #Call signs of stations whose posits are gated #to RF every 15 minutes. Only posit packets are #gated. Posits are taken from the history list. #They are case sensitive! Use upper case. # #posit2rf K4HG-8 # #Define a list of message destination call signs or aliases #to gate to RF full time. Note: the CQGA example #below is CQ GA (Georgia). Edit to suite your locale. #Up to 64 of these may be defined. They are case sensitive. # msgdest2rf SCOUTS KIDS CQGA # #end aprsd-2.2.5-13/admin/aprsd.init0000775000076400007640000000110107651127544011642 #!/bin/sh # # aprsd.init for version 2.1.5. starts or stops aprsd server. # This file should be placed in /etc/rc.d/init.d/ # # # # Author: Dale Heatherington # # Source function library. #. /etc/rc.d/init.d/functions # See how we were called. case "$1" in start) echo "Starting aprs server daemon. " /home/aprsd2/aprsd -d echo touch /var/lock/subsys/aprsd ;; stop) echo "Stopping aprs server daemon. " killall -INT aprsd rm -f /var/lock/subsys/aprsd ;; *) echo "Usage: aprsd.init {start|stop}" exit 1 esac exit 0 aprsd-2.2.5-13/admin/chkaprsd0000664000076400007640000000211707651127544011373 #! /bin/sh # $Id: chkaprsd,v 1.3 2003/03/22 22:20:32 kg4ijb Exp $ # # This is a script suitable for use in a crontab. It checks to make sure # aprsd is running. If aprsd is not running, it'll try to start it back up. # # To check aprsd every 10 minutes, put the following line in your # crontab: # 0,10,20,30,40,50 * * * * /home/aprsd2/chkaprsd # And if you don't want to get email from crontab when it checks aprsd, # put the following in your crontab: # 0,10,20,30,40,50 * * * * /home/aprsd2/chkaprsd >/dev/null 2>&1 # # Note: Most implementations of crontab will accepts stepping; */5 * * * * for example # will step every 5 minutes cd /home/crb6x/projects/aprsd225/admin if test -r /var/run/aprsd.pid then aprsdpid=`cat /var/run/aprsd.pid` # echo "found pid, trying to kill" if `kill -CHLD $aprsdpid > /dev/null 2>&1` then # echo "Oops, this is for real, I'll leave alone" #it's still running, back out quietly exit 0 fi echo "" echo "Stale $bin.pid file, erasing..." echo "" rm -f /var/run/aprsd.pid ./aprsd -d echo "restarted." fi aprsd-2.2.5-13/admin/INIT.TNC0000664000076400007640000000202607653634375010770 # These TNC cmds will be executed each time you start aprsd. # Modify the MYCALL and BTEXT lines with your data. # Add/delete any other commands your TNC needs for configuration. # The last command "K" puts the TNC in communication mode and must be present. # These sample commands are for a Kantronics KPC-3 # A ctrl-C is sent to the TNC from the server just before these commands are issued. # Note: The TNCs user interface must have already been set for 9600 baud. # # INTFACE TERMINAL ECHO OFF MCOM OFF MSTAMP OFF PASSALL OFF MRPT ON XMITOK ON FILTER ON CD SOFTWARE NEWMODE OFF #MYCALL must match MyCall in aprsd.conf MYCALL KG4IJB-3 #You may turn off BTEXT here and use the "tncbeacon" command in aprsd.conf instead. #BTEXT _0000.00NI00000.00W& APRS Linux Internet Server BEACON EVERY 10 #Note: The "APRS" in the next line will be overwritten by APDxxx where xxx is the version number. # So, it matters not what you put there. UNPROTO APRS VIA WIDE,WIDE HEADERLN OFF DIGI OFF HID OFF PACLEN 0 SCREENL 0 Monitor ON K # # end of file aprsd-2.2.5-13/admin/REMOVE0000775000076400007640000000063207651127544010574 #!/bin/sh # pushd . cd /home echo "Saving aprsd2 directory contents in /home/aprsd2.tgz" tar zcvf aprsd2.tgz aprsd2 popd >/dev/null echo "Deleting files..." APRSDIR=/home/aprsd2 rm $APRSDIR/* rmdir $APRSDIR rm /etc/rc.d/init.d/aprsd.init rm /etc/rc.d/rc3.d/S95aprsd rm /etc/rc.d/rc5.d/S95aprsd rm /etc/rc.d/rc6.d/K23aprsd echo "aprsd removed. Contents of $APRSDIR have been saved in /home/aprsd2.tgz" exit 0 aprsd-2.2.5-13/admin/RESTORE.TNC0000664000076400007640000000016707651127544011345 # Place here any TNC commands you want restored after aprsd quits. MONITOR OFF NEWMODE ON ECHO ON FLOW ON BK ON AX ON aprsd-2.2.5-13/admin/welcome.txt0000664000076400007640000000017107651127544012043 # Welcome to first.aprs.net (aprs core server). # Direct comments to cbyam at virginia.edu . Type ctrl-D to disconnect. aprsd-2.2.5-13/admin/udp_example0000775000076400007640000000163707651127544012110 #!/usr/bin/perl #Example of how to send data into the APRS server #via the UDP port from a perl script . #NOTE: Running this more than once each 30 seconds #will trigger the duplicate filter in aprsd and your #packet will be rejected. # use Socket; #$aprsServer = "www.wa4dsy.radio.org"; $aprsServer = "localhost"; $port = 1315; ($d1, $d2, $d3, $d4, $rawserver) = gethostbyname($aprsServer); $serveraddr = pack("Sna4x8",2,$port,$rawserver); $prototype = getprotobyname('udp'); socket(SOCKET,2,SOCK_DGRAM,$prototype) || die("No Socket\n"); #Send to the TNC... Note: you must end the string with a NULL send SOCKET, "N0CLU>TNC:>Testing on RF\0" , 0 , $serveraddr; #Note that only the data after the ":" is sent to the TNC. #Send to the Internet... send SOCKET, "N0CLU>APRS:>Testing on TCPIP\0", 0, $serveraddr; #Note that the entire string is sent to the internet including #the path "N0CLU>APRS:". close(SOCKET); aprsd-2.2.5-13/admin/user.deny0000664000076400007640000000025707651127544011513 #user.deny #format: user R|L #use "L" to deny login and RF access #use "R" to deny RF access but allow login #ssid is ignored, eg: W4EVIL and W4EVIL-7 are the same. N0CALL L aprsd-2.2.5-13/aprspass/0000777000000000000000000000000007665450621010434 5aprsd-2.2.5-13/aprspass/Makefile.am0000644000076400007640000000025607655350545012454 bin_PROGRAMS = aprspass aprspass_SOURCES = aprspass.cpp ../src/validate.cpp INCLUDES = -I$(top_srcdir)/src callpass_LINK=$(CC) $(AM_CPPFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ aprsd-2.2.5-13/aprspass/Makefile.in0000644000000000000000000002406107665450603012420 # Makefile.in generated by automake 1.6.3 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 # 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. @SET_MAKE@ 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 pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_HEADER = $(INSTALL_DATA) transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : EXEEXT = @EXEEXT@ OBJEXT = @OBJEXT@ PATH_SEPARATOR = @PATH_SEPARATOR@ AMTAR = @AMTAR@ AWK = @AWK@ CC = @CC@ CXX = @CXX@ DEPDIR = @DEPDIR@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ PACKAGE = @PACKAGE@ STRIP = @STRIP@ VERSION = @VERSION@ am__include = @am__include@ am__quote = @am__quote@ install_sh = @install_sh@ bin_PROGRAMS = aprspass aprspass_SOURCES = aprspass.cpp ../src/validate.cpp INCLUDES = -I$(top_srcdir)/src callpass_LINK = $(CC) $(AM_CPPFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ subdir = aprspass mkinstalldirs = $(SHELL) $(top_srcdir)/support/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = bin_PROGRAMS = aprspass$(EXEEXT) PROGRAMS = $(bin_PROGRAMS) am_aprspass_OBJECTS = aprspass.$(OBJEXT) validate.$(OBJEXT) aprspass_OBJECTS = $(am_aprspass_OBJECTS) aprspass_LDADD = $(LDADD) aprspass_DEPENDENCIES = aprspass_LDFLAGS = DEFS = @DEFS@ DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ depcomp = $(SHELL) $(top_srcdir)/support/depcomp am__depfiles_maybe = depfiles @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/aprspass.Po ./$(DEPDIR)/validate.Po CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ CXXFLAGS = @CXXFLAGS@ DIST_SOURCES = $(aprspass_SOURCES) DIST_COMMON = Makefile.am Makefile.in SOURCES = $(aprspass_SOURCES) all: all-am .SUFFIXES: .SUFFIXES: .cpp .o .obj $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu aprspass/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(bindir) @list='$(bin_PROGRAMS)'; for p in $$list; do \ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ if test -f $$p \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \ $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f; \ else :; fi; \ done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; for p in $$list; do \ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ echo " rm -f $(DESTDIR)$(bindir)/$$f"; \ rm -f $(DESTDIR)$(bindir)/$$f; \ done clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) validate.$(OBJEXT): ../src/validate.cpp aprspass$(EXEEXT): $(aprspass_OBJECTS) $(aprspass_DEPENDENCIES) @rm -f aprspass$(EXEEXT) $(CXXLINK) $(aprspass_LDFLAGS) $(aprspass_OBJECTS) $(aprspass_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) core *.core distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aprspass.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/validate.Po@am__quote@ distclean-depend: -rm -rf ./$(DEPDIR) .cpp.o: @AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< .cpp.obj: @AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ $(CXXCOMPILE) -c -o $@ `cygpath -w $<` validate.o: ../src/validate.cpp @AMDEP_TRUE@ source='../src/validate.cpp' object='validate.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@ depfile='$(DEPDIR)/validate.Po' tmpdepfile='$(DEPDIR)/validate.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o validate.o `test -f '../src/validate.cpp' || echo '$(srcdir)/'`../src/validate.cpp validate.obj: ../src/validate.cpp @AMDEP_TRUE@ source='../src/validate.cpp' object='validate.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@ depfile='$(DEPDIR)/validate.Po' tmpdepfile='$(DEPDIR)/validate.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o validate.obj `cygpath -w ../src/validate.cpp` CXXDEPMODE = @CXXDEPMODE@ uninstall-info-am: ETAGS = etags ETAGSFLAGS = tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = .. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) @list='$(DISTFILES)'; for file in $$list; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: $(mkinstalldirs) $(DESTDIR)$(bindir) install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-compile distclean-depend \ distclean-generic distclean-tags dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-exec-am: install-binPROGRAMS install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic uninstall-am: uninstall-binPROGRAMS uninstall-info-am .PHONY: GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic distclean distclean-compile distclean-depend \ distclean-generic distclean-tags distdir dvi dvi-am info \ info-am install install-am install-binPROGRAMS install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic tags uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-info-am # 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: aprsd-2.2.5-13/aprspass/aprspass.cpp0000644000076400007640000000266307657351214012760 /* * $Id: aprspass.cpp,v 1.1 2003/05/11 04:33:16 kg4ijb Exp $ * * aprsd, Automatic Packet Reporting System Daemon * Copyright (C) 1997,2002 Dale A. Heatherington, WA4DSY * Copyright (C) 2001-2002 aprsd Dev Team * * 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. * * Look at the README for more information on the program. */ #include #include #include #include #include #include #include #include "../src/validate.h" using namespace std; int main(int argc, char *argv[]) { if(argc < 2) { cout << "Usage: aprspass " << endl; exit(1); } cout << "APRS passcode for " << argv[1] << " = " << doHash(argv[1]) << endl; return 0; }