dircproxy-1.0.5/0000777000175000017500000000000007567165533007326 5dircproxy-1.0.5/Makefile.in0000644000175000017500000002536307567165530011315 # Makefile.in generated automatically by automake 1.4-p6 from Makefile.am # Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. SHELL = @SHELL@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ libexecdir = @libexecdir@ datadir = @datadir@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include DESTDIR = pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = . ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : host_alias = @host_alias@ host_triplet = @host@ AWK = @AWK@ CC = @CC@ LN_S = @LN_S@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ PACKAGE = @PACKAGE@ RANLIB = @RANLIB@ VERSION = @VERSION@ EXTRA_DIST = FAQ PROTOCOL README.inetd README.dcc-via-ssh SUBDIRS = conf contrib getopt crypt doc src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = DIST_COMMON = README ./stamp-h.in AUTHORS COPYING ChangeLog INSTALL \ Makefile.am Makefile.in NEWS acconfig.h aclocal.m4 config.guess \ config.h.in config.sub configure configure.in install-sh missing \ mkinstalldirs DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP_ENV = --best all: all-redirect .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in cd $(srcdir) && $(ACLOCAL) config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) cd $(srcdir) && $(AUTOCONF) config.h: stamp-h @if test ! -f $@; then \ rm -f stamp-h; \ $(MAKE) stamp-h; \ else :; fi stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES= CONFIG_HEADERS=config.h \ $(SHELL) ./config.status @echo timestamp > stamp-h 2> /dev/null $(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@$(srcdir)/stamp-h.in @if test ! -f $@; then \ rm -f $(srcdir)/stamp-h.in; \ $(MAKE) $(srcdir)/stamp-h.in; \ else :; fi $(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h cd $(top_srcdir) && $(AUTOHEADER) @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null mostlyclean-hdr: clean-hdr: distclean-hdr: -rm -f config.h maintainer-clean-hdr: # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. @SET_MAKE@ all-recursive install-data-recursive install-exec-recursive \ installdirs-recursive install-recursive uninstall-recursive \ check-recursive installcheck-recursive info-recursive dvi-recursive: @set fnord $(MAKEFLAGS); amf=$$2; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @set fnord $(MAKEFLAGS); amf=$$2; \ dot_seen=no; \ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ rev="$$subdir $$rev"; \ test "$$subdir" != "." || dot_seen=yes; \ done; \ test "$$dot_seen" = "no" && rev=". $$rev"; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ awk ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ here=`pwd` && cd $(srcdir) \ && mkid -f$$here/ID $$unique $(LISP) TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP) tags=; \ here=`pwd`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ awk ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \ || (cd $(srcdir) && etags -o $$here/TAGS $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP)) mostlyclean-tags: clean-tags: distclean-tags: -rm -f TAGS ID maintainer-clean-tags: distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist -rm -rf $(distdir) GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz mkdir $(distdir)/=build mkdir $(distdir)/=inst dc_install_base=`cd $(distdir)/=inst && pwd`; \ cd $(distdir)/=build \ && ../configure --srcdir=.. --prefix=$$dc_install_base \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) dist -rm -rf $(distdir) @banner="$(distdir).tar.gz is ready for distribution"; \ dashes=`echo "$$banner" | sed s/./=/g`; \ echo "$$dashes"; \ echo "$$banner"; \ echo "$$dashes" dist: distdir -chmod -R a+r $(distdir) GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) -rm -rf $(distdir) dist-all: distdir -chmod -R a+r $(distdir) GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) -rm -rf $(distdir) distdir: $(DISTFILES) -rm -rf $(distdir) mkdir $(distdir) -chmod 777 $(distdir) @for file in $(DISTFILES); do \ d=$(srcdir); \ if test -d $$d/$$file; then \ cp -pr $$d/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file || :; \ fi; \ done for subdir in $(SUBDIRS); do \ if test "$$subdir" = .; then :; else \ test -d $(distdir)/$$subdir \ || mkdir $(distdir)/$$subdir \ || exit 1; \ chmod 777 $(distdir)/$$subdir; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ || exit 1; \ fi; \ done info-am: info: info-recursive dvi-am: dvi: dvi-recursive check-am: all-am check: check-recursive installcheck-am: installcheck: installcheck-recursive all-recursive-am: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive install-exec-am: install-exec: install-exec-recursive install-data-am: install-data: install-data-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am install: install-recursive uninstall-am: uninstall: uninstall-recursive all-am: Makefile config.h all-redirect: all-recursive-am install-strip: $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install installdirs: installdirs-recursive installdirs-am: mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* maintainer-clean-generic: mostlyclean-am: mostlyclean-hdr mostlyclean-tags mostlyclean-generic mostlyclean: mostlyclean-recursive clean-am: clean-hdr clean-tags clean-generic mostlyclean-am clean: clean-recursive distclean-am: distclean-hdr distclean-tags distclean-generic clean-am distclean: distclean-recursive -rm -f config.status maintainer-clean-am: maintainer-clean-hdr maintainer-clean-tags \ maintainer-clean-generic distclean-am @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." maintainer-clean: maintainer-clean-recursive -rm -f config.status .PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \ install-data-recursive uninstall-data-recursive install-exec-recursive \ uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \ all-recursive check-recursive installcheck-recursive info-recursive \ dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \ maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ dvi-am dvi check check-am installcheck-am installcheck all-recursive-am \ install-exec-am install-exec install-data-am install-data install-am \ install uninstall-am uninstall all-redirect all-am all installdirs-am \ installdirs mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: dircproxy-1.0.5/README0000664000175000017500000001355307537110562010120 dircproxy: Detachable IRC Proxy Server ------------------------------------- dircproxy is an IRC proxy server ("bouncer") designed for people who use IRC from lots of different workstations or clients, but wish to remain connected and see what they missed while they were away. You connect to IRC through dircproxy, and it keeps you connected to the server, even after you detach your client from it. While you're detached, it logs channel and private messages as well as important events, and when you re-attach it'll let you know what you missed. This can be used to give you roughly the same functionality as using ircII and screen together, except you can use whatever IRC client you like, including X ones! Features ======== o Runs on console, as a daemon or from inetd. o Able to proxy many simultaneous users and IRC connections. o Uses IRC server passwords to authenticate. o Remains connected to server when you detach. To reattach you just use the IRC server password again, no special commands! o Completely non-blocking throughout. o Can connect to servers that also require a password. o Can have a list of servers on the same network to connect to, it will cycle this list. o Throttles data sent to server to ensure you are never flooded off. o Can check servers to make sure they don't become "stoned". o Reconnects to servers if connection is dropped. o Can automatically join channels for you on first attach. o Rejoins channels if you are kicked off. o Can leave channels when you detach and rejoin when you come back. o Can take measures to ensure you don't appear "idle" on IRC. o Drop's unwanted user modes when you detached, if you forget to de-opper yourself. o Will refuse to connect to servers that set certain modes such as +r. o Can bind to any IP on your host to change your appearance on IRC. o Can change what username is presented on IRC without affecting other users its proxying for. o Can send a message to all channels to indicate when you detach and reattach. o Can change your nickname when you detach. o Sets you /AWAY when you detach, if you forget to do so. o Fully configurable logging support so when you reattach you can see what you missed. o Can limit the size of log files to avoid eating diskspace. o Log text recalled to your client is sent so your client sees it as ordinary IRC text. o Can timestamp text in log files so you know when it was sent, also can adjust the timestamp you see depending on how long ago it was sent. o Can make permanent log files for your own use of everything on channels or all private messages. o Can pass log text to a program of your choice (to send you an SMS for example). o Can adjust log timestamps depending on timezone difference between you and dircproxy. o Can proxy DCC chat and sends through itself. o Can capture DCC sends and store them on the dircproxy machine while you're detached, and even while you're attached. o Captured DCC sends can be made subject to a size limit and have the sender's nickname included in the filename. o Can tunnel DCC sends and chats through ssh tunnels. See the included README.dcc-via-ssh for more information. o Customisable message of the day for users which can include stats about log file sizes. o /DIRCPROXY command interface for users to do extra things with the proxy. Fully documented through /DIRCPROXY HELP command, and the admin can enable and disable any command on a user-by-user basis. o Host and password based security. o Easy to configure and get running. All of dircproxy's features are completely configurable and can be enabled, disabled and adjusted through the configuration file. Installation ============ See the file INSTALL for building and installation instructions. Running dircproxy ================= Once you have installed and configured dircproxy, you can run it from the console. It will automatically enter the background (unless you supply the '-D' parameter) and begin listening for incoming connections. You should not need to modify your IRC client or add any special scripts to support dircproxy. Authentication is done using the standard IRC server password, your IRC client should support this. If you're not sure, try something like '/server localhost:57000:password' from your IRC client's console. Connect to it with your IRC client, supplying the same password as you set in the config file, dircproxy will then connect to the IRC server for you and begin proxying your session. When you detach, dircproxy will remain running and remain connected to the IRC server, logging any channel or private messages for you until your return. To re-attach, just connect with your IRC client, again supplying the password. dircproxy will see you have left a session running and re-attach you to that instead of creating a new one. Messages you missed while you were away will be sent to you in such a way that they will fill your IRC windows as if they'd just arrived. You can also run dircproxy from inetd if you wish, although their are very few reasons to do this. See the file README.inetd for more information on this feature. Adjusting the Proxy =================== While you are connected to the proxy you may perform a number of actions to adjust your proxy session using the '/dircproxy' command. For example, to end your proxy session, disconnecting you from the server, use '/dircproxy quit'. For more information on what other commands are available, see '/dircproxy help'. More Information ================ The dircproxy home page is at: http://www.dircproxy.net/ Please submit bug reports at: http://bugzilla.dircproxy.net/ Also join us on the #dircproxy IRC channel on irc.openprojects.net. dircproxy is distributed according to the GNU General Public License. See the file COPYING for details. Copyright (C) 2002 Scott James Remnant . All Rights Reserved. dircproxy-1.0.5/stamp-h.in0000644000175000017500000000000007567164507011131 dircproxy-1.0.5/AUTHORS0000664000175000017500000000100307410714172010270 Authors and Acknowledgments ---------------------------- dircproxy is written by Scott James Remnant , with the occasional patch from the odd random individual. If you have contributed any major patches or enhancements, and you want to be credited for it, then just nag me to add you to this file. Also, a big thanks to Stephen Cope for doing the original documentation for dircproxy. Copyright (C) 2002 Scott James Remnant . All Rights Reserved. dircproxy-1.0.5/COPYING0000664000175000017500000004311007151204246010256 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. dircproxy-1.0.5/ChangeLog0000644000175000017500000027475007567164571011034 2002-11-21 14:10 Scott James Remnant * autogen.sh: Oops, autoheader is part of autoconf 2002-11-21 14:09 Scott James Remnant * autogen.sh: Fix so it'll work on my Debian box 2002-11-21 14:06 Scott James Remnant * conf/dircproxyrc, doc/dircproxy.1, src/dircproxy.h: [MFH] Change the default setting for refuse_modes to "" from "+r", it seems DALnet have decided to use +r to indicate you are registered with NickServ, not that your connection is restricted like most sensible networks! 2002-09-09 12:51 Scott James Remnant * configure.in, contrib/dircproxy.spec: CVS version now 1.0.5 2002-09-09 12:38 Scott James Remnant * ChangeLog, NEWS: Version 1.0.4 released. 2002-09-09 12:29 Scott James Remnant * configure.in: Use maintainer mode, it's good 2002-09-09 12:27 Scott James Remnant * src/main.c: MFH: Significantly fluffier signal handling, all we do now is use the HUP signal to set a variable which causes the configuration to be reloaded in the main loop. All we do now for HUP is catch it, so it causes things to be interrupted, then in the main loop we ALWAYS call waitpid() until all children have been reaped. This gets around every signal semantic that causes problems on exotic OSs (and FreeBSD :) 2002-09-09 12:24 Scott James Remnant * src/irc_log.c: MFH: Use a static counter to create log directories, rather than the client socket number which can get reused in some circumstances 2002-09-09 12:22 Scott James Remnant * contrib/dircproxy.spec: MFH: Eliminate mentions of evil SourceForge 2002-09-09 12:20 Scott James Remnant * conf/dircproxyrc: s/configuration classes/connection classes/, no idea how I missed that 2002-09-09 12:19 Scott James Remnant * RELEASING: MFH: New releasing procedure (adjusted for 1.0) 2002-09-09 12:18 Scott James Remnant * README: MFH: Remove irc.linux.com from list (no longer on OpenProjects) and fix an old typo 2002-09-09 12:17 Scott James Remnant * NEWS: MFH: Fix time in NEWS file 2002-09-09 12:16 Scott James Remnant * INSTALL: MFH: AIX support 2002-09-09 12:16 Scott James Remnant * FAQ: MFH: New FAQs 2002-09-09 12:11 Scott James Remnant * TODO: Removed TODO file. 2002-02-08 17:48 Scott James Remnant * ChangeLog, NEWS, RELEASING: Version 1.0.3 released. 2002-02-06 10:10 Scott James Remnant * src/irc_client.c: Added /DIRCPROXY USERS and /DIRCPROXY KILL commands, improved the STATUS command a little too 2002-02-06 10:08 Scott James Remnant * src/help.h: Documented /DIRCPROXY USERS and /DIRCPROXY KILL commands 2002-02-06 10:08 Scott James Remnant * src/main.c: Write pid file on startup and unlink on close. This is specified by the 'pid_file' config directive or the new -p command line parameter 2002-02-06 10:07 Scott James Remnant * src/: cfgfile.c, cfgfile.h, dircproxy.h, irc_net.h: Added config file code for allow_users, allow_kill and pid_file directives 2002-02-06 10:06 Scott James Remnant * conf/dircproxyrc, doc/dircproxy-crypt.1, doc/dircproxy.1: Added new pid_file, allow_users and allow_kill config documentation 2002-02-06 10:05 Scott James Remnant * contrib/: Makefile.am, README, cronchk.sh: Added the much-asked-for crontab checking script, and a spot of documentation about what all these things are. 2002-02-05 10:07 Scott James Remnant * FAQ: Added a few more FAQs 2002-02-05 10:05 Scott James Remnant * src/: help.h, irc_client.c: Implemented new /DIRCPROXY STATUS command to dump the interesting members of struct ircproxy 2002-02-05 10:01 Scott James Remnant * contrib/: Makefile.am, privmsg-log.pl: Added an other_log_program script to log private messages to seperate files (fixes a FAQ) 2002-02-05 10:00 Scott James Remnant * conf/dircproxyrc, doc/dircproxy.1: Documented that nick_keep generally only works while you DON'T connect a client 2002-02-05 09:56 Scott James Remnant * TODO: Not going to do automatic connection to server 2002-02-05 09:55 Scott James Remnant * src/irc_client.c: Only run the client_resetnick timer if nick_keep is set in the configuration file 2002-01-31 14:56 Scott James Remnant * src/irc_server.c: Removed extra brace that broke it 2002-01-31 13:55 Scott James Remnant * conf/dircproxyrc, doc/dircproxy.1, src/cfgfile.c, src/irc_net.h, src/irc_server.c: Log topic changes too 2002-01-28 04:00 Scott James Remnant * src/main.c: That bad patch has left a haunting bug ever since 0.8.0 that I only spotted by reading the source for some random reason. If the config file couldn't be re-read, the global variables (all 3 of them) would be reset to their default values, because the memcpy() had been duplicated inside the failure if {} 2002-01-27 23:43 Scott James Remnant * FAQ, README: Changed URLs to dircproxy.net now, yay 2002-01-24 01:00 Scott James Remnant * src/irc_server.c: Resend the detach message to each channel we rejoin when the server gets disconnected while the client is detached. 2002-01-24 00:37 Scott James Remnant * configure.in, contrib/dircproxy.spec: CVS version now 1.0.3 2002-01-01 18:14 Scott James Remnant * ChangeLog, NEWS, README, TODO: Version 1.0.2 released. 2002-01-01 18:05 Scott James Remnant * AUTHORS.map: Moved CVS server so adjusted AUTHORS.map to reflect my different username 2002-01-01 17:55 Scott James Remnant * src/net.c: Missed out an & 2002-01-01 17:42 Scott James Remnant * RELEASING: Releasing has changed slightly 2002-01-01 17:41 Scott James Remnant * FAQ: Changed a couple of URLs to the new netsplit ones 2001-12-21 20:25 Scott James Remnant * RELEASING: Releasing has changed slightly 2001-12-21 20:17 Scott James Remnant * src/: cfgfile.c, dcc_send.c: Removed hard tabs from source 2001-12-21 20:15 Scott James Remnant * AUTHORS, FAQ, INSTALL, NEWS, PROTOCOL, README, README.dcc-via-ssh, README.inetd, crypt/main.c, doc/dircproxy-crypt.1, doc/dircproxy.1, src/cfgfile.c, src/cfgfile.h, src/dcc_chat.c, src/dcc_chat.h, src/dcc_net.c, src/dcc_net.h, src/dcc_send.c, src/dcc_send.h, src/dircproxy.h, src/dns.c, src/dns.h, src/help.h, src/irc_client.c, src/irc_client.h, src/irc_log.c, src/irc_log.h, src/irc_net.c, src/irc_net.h, src/irc_prot.c, src/irc_prot.h, src/irc_server.c, src/irc_server.h, src/irc_string.c, src/irc_string.h, src/logo.h, src/main.c, src/match.c, src/match.h, src/memdebug.c, src/memdebug.h, src/net.c, src/net.h, src/sprintf.c, src/sprintf.h, src/stringex.c, src/stringex.h, src/timers.c, src/timers.h: Updated the Copyright to 2002, since I plan to make the next release in the first couple of days of January 2001-12-21 20:07 Scott James Remnant * TODO, src/irc_server.c: ERRORs should now get sent to the client before first authorisation 2001-12-21 19:59 Scott James Remnant * TODO, conf/dircproxyrc, doc/dircproxy.1, src/cfgfile.c, src/dircproxy.h, src/irc_net.h, src/irc_server.c, src/net.c, src/net.h: Implented requested KEEPALIVE checking. 2001-12-13 23:45 Scott James Remnant * INSTALL: Compiles on a MicroVAX, whee! 2001-11-12 21:08 Scott James Remnant * TODO: Added some stuff that needs doing 2001-07-13 15:27 Scott James Remnant * RELEASING: E-mail the FreeBSD port maintainer as well 2001-07-12 16:24 Scott James Remnant * configure.in, contrib/dircproxy.spec: CVS version now 1.0.2 2001-07-12 16:15 Scott James Remnant * ChangeLog, NEWS, TODO: Version 1.0.1 released. 2001-07-12 16:15 Scott James Remnant * FAQ, README: Added "bouncer" to the text, changed bugs URL 2001-07-12 14:47 Scott James Remnant * src/dcc_send.c: Used the wrong variable, heh 2001-07-12 14:47 Scott James Remnant * src/dcc_send.c: Drop dcc connections if queue() fails at any point 2001-07-12 14:43 Scott James Remnant * src/net.c: If malloc()s fail within the majority of the socket handler, it shouldn't crash anymore, just return bad flags 2001-07-12 14:37 Scott James Remnant * src/irc_log.c: When rotating log files, keep the permissions as 0600. 2001-07-12 14:36 Scott James Remnant * src/: irc_client.c, irc_log.c: Only strip those characters from the end we really want to treat as whitespace. Doing otherwise strips high characters and control characters 2001-07-12 14:29 Scott James Remnant * src/irc_server.c: Only do the getsockname() call if the client is active, otherwise it'll fail. We cope with not having a client if it is supposed to have succeeeded anyway. 2001-05-07 17:41 Scott James Remnant * TODO: Another bug, will fix these soon. 2001-05-01 21:25 Scott James Remnant * TODO: Got a couple of bugs to fix. 2001-01-11 15:54 Scott James Remnant * configure.in, contrib/dircproxy.spec: CVS version now 1.0.1 2001-01-11 15:29 Scott James Remnant * AUTHORS, FAQ, INSTALL, NEWS, PROTOCOL, README, README.dcc-via-ssh, README.inetd, crypt/main.c, doc/dircproxy-crypt.1, doc/dircproxy.1, src/cfgfile.c, src/cfgfile.h, src/dcc_chat.c, src/dcc_chat.h, src/dcc_net.c, src/dcc_net.h, src/dcc_send.c, src/dcc_send.h, src/dircproxy.h, src/dns.c, src/dns.h, src/help.h, src/irc_client.c, src/irc_client.h, src/irc_log.c, src/irc_log.h, src/irc_net.c, src/irc_net.h, src/irc_prot.c, src/irc_prot.h, src/irc_server.c, src/irc_server.h, src/irc_string.c, src/irc_string.h, src/logo.h, src/main.c, src/match.c, src/match.h, src/memdebug.c, src/memdebug.h, src/net.c, src/net.h, src/sprintf.c, src/sprintf.h, src/stringex.c, src/stringex.h, src/timers.c, src/timers.h: Last minute update of all (C) to 2001 2001-01-11 15:23 Scott James Remnant * ChangeLog, NEWS, README, TODO: Version 1.0.0 released. 2001-01-11 15:14 Scott James Remnant * ChangeLog, configure.in, contrib/dircproxy.spec: CVS version now 1.0.0 2000-12-27 18:28 Scott James Remnant * FAQ, README: Included IRC channel in the documentation 2000-12-27 18:04 Scott James Remnant * src/net.c: Wasn't handling read events if the socket was marked as closed, this includes error events obviously. This could cause 100% CPU usage if there's data waiting to be written on the socket. Instead just make sure we don't call the error_func if socket is closed (it'd get confused). 2000-12-27 17:50 Scott James Remnant * FAQ: Added the most FAQ to the FAQ :) 2000-12-26 18:26 Scott James Remnant * configure.in, contrib/dircproxy.spec: CVS version now 0.99.1 2000-12-26 18:07 Scott James Remnant * ChangeLog, NEWS: Version 0.99.0 released. 2000-12-26 17:34 Scott James Remnant * TODO, configure.in: CVS version now 0.99.0, time to freeze it. 2000-12-26 17:33 Scott James Remnant * src/irc_server.c: Fixed it so it only replies when the client isn't connected (oops) 2000-12-26 17:26 Scott James Remnant * conf/dircproxyrc, doc/dircproxy.1, src/cfgfile.c, src/dircproxy.h, src/irc_client.c, src/irc_net.h, src/irc_server.c: Added support for CTCP replies while the client is detached. 2000-12-26 16:07 Scott James Remnant * src/: irc_client.c, irc_net.c, irc_server.c, irc_server.h, main.c: Completely replaced ircserver_send_command() with ircserver_send_peercmd() as we never really should prefix stuff. 2000-12-22 13:24 Scott James Remnant * src/dcc_net.c: Do a connect() before a listen() so that they've both got a chance of binding to the same port. 2000-12-21 13:27 Scott James Remnant * TODO, src/irc_client.c, src/irc_client.h, src/irc_net.c, src/irc_server.c, src/irc_string.h: * Changed the way all the NICK code works, so it keeps it inline with what the client AND server think the nick is. * Use peercmd everywhere now, its safer * Adjusted the detach autowash order, so it works properly without errors * Use new net_close syntax everywhere * New dcc stuff 2000-12-21 13:24 Scott James Remnant * src/: dcc_net.c, dcc_net.h: Added notification to dcc's, so if they timeout we can send a NOTICE back to the user who initiated it. * Also bind the outgoing connect port, it doesn't matter if this doesn't work (like if there's only one port available) but if it does work it'll help people behind firewalls. * Updated to use new net_close syntax 2000-12-21 13:22 Scott James Remnant * src/: dcc_chat.c, dcc_send.c: Updated to new net_close syntax 2000-12-21 13:21 Scott James Remnant * src/: net.c, net.h: Made net_close explicitly set the socket to -1 (changed to take a pointer) and also made sure no read events occur if the socket is already closed 2000-12-21 13:21 Scott James Remnant * conf/dircproxyrc, doc/dircproxy.1, src/cfgfile.c, src/dircproxy.h, src/irc_net.h: Added new 'nick_keep' configuration option and the associated variables etc. 2000-12-11 21:50 Scott James Remnant * TODO: Updated 2000-12-10 14:36 Scott James Remnant * contrib/Makefile.am: Oops, inadvertently set the spec file to be installed into the share directory, when it shouldn't get installed at all. 2000-12-10 03:06 Scott James Remnant * RELEASING, TODO, contrib/Makefile.am, contrib/dircproxy.spec: Added dircproxy.spec provided by Hollis R Blanchard 2000-12-08 14:29 Scott James Remnant * RELEASING: Another new step in releasing dircproxy, e-mail nidd@debian.org to inform him of any changes that could affect his debian package. I need a secretary *laughs* :o) 2000-12-07 18:27 Scott James Remnant * src/irc_log.c: Lowercase the filename used for log files 2000-12-07 18:06 Scott James Remnant * RELEASING: Updated slightly 2000-12-07 18:05 Scott James Remnant * configure.in: CVS version now 0.8.5 2000-12-07 17:42 Scott James Remnant * ChangeLog, NEWS, TODO: Version 0.8.4 released. 2000-12-07 17:21 Scott James Remnant * src/dcc_send.c: Got rid of the extraneous debug stuff that's not actually needed 2000-12-07 17:17 Scott James Remnant * src/dcc_send.c: Large rework of DCC Send proxying. We now store everything we get from the sender in an internal buffer until we can send it out to the sendee. This means the sender can disconnect part way through without the whole lot going *splegh* all over the place. 2000-12-07 17:05 Scott James Remnant * src/dircproxy.h: New #define variable - DCC_BLOCK_SIZE, the maximum size of a block to send while doing dcc proxying. Its not a config file parameter because the logic behind it isn't exactly spock-like. Basically, it'll only be used when there is LOTS of data in the buffer. If the sendee connects before the sender then it won't be used at all because the data will hopefully be ack'd fast enough to not care. 2000-12-07 17:03 Scott James Remnant * src/dcc_net.h: Need to now know how much data total we've received from the sender (bytes_recvd) [should always be bytes_sent + bufsz, but I ain't risking using that in case i fuck up], need a buffer and a variable to tell us how big it is, and a new status for dcc sender socket's (DCC_SENDER_GONE) 2000-12-07 17:01 Scott James Remnant * src/dcc_net.c: Adjusted the logic of the timer code now, as it isn't quite as clear cut as "are they both connected"? * Made sure all sockets are set to -1 after being closed, just in case the sender leaves, and the client connects just after and gets the same socket number (and confuses the living buggery out of us). * Free the buffer when freeing the proxy 2000-12-07 16:59 Scott James Remnant * src/: dcc_chat.c, irc_client.c, irc_server.c: Just to be on the safe side, set any socket to -1 after closing it. Otherwise there's a *slight* possibility that we could accidentally mistake it for another (especially with the dcc code). 2000-12-07 16:00 Scott James Remnant * RELEASING: Updated release procedures. 2000-12-06 15:25 Scott James Remnant * src/dircproxy.h: Added initial_modes stuf 2000-12-06 15:17 Scott James Remnant * src/: irc_net.c, irc_net.h: Added initial_modes variable 2000-12-06 15:15 Scott James Remnant * src/irc_client.c: if JUMP is done without paramters, pick the next server in the list. * Always match IP address as well as hostname with 'from' * Set initial_modes on first authentication 2000-12-06 15:10 Scott James Remnant * src/help.h: Added new JUMP syntax 2000-12-06 15:08 Scott James Remnant * src/cfgfile.c: Added initial_modes config option and at the same time made all non-fatal errors have a (warning) prefix 2000-12-06 15:06 Scott James Remnant * conf/dircproxyrc, doc/dircproxy.1: New initial_modes config option added 2000-12-05 16:20 Scott James Remnant * TODO: Updated 2000-12-04 12:47 Scott James Remnant * src/irc_server.c: Its possible that ircserver_close_sock can be called without a connection class, so always delete the timers 2000-12-03 21:44 Scott James Remnant * src/irc_client.c: Changed message to be less confusing 2000-12-03 19:25 Scott James Remnant * TODO: More stuff to do 2000-11-30 12:57 Scott James Remnant * TODO: Updated to reflect whats gonna be happening 2000-11-28 15:52 Scott James Remnant * src/dcc_net.c: Wasn't setting the DCC_SENDEE_LISTENING flag, so if they never connect to us, then we never close the listening socket. 2000-11-28 12:14 Scott James Remnant * src/: dcc_net.c, irc_net.c: Dunno why I was using %p in debug() messages - that uses my internal format stuff which ignores them. 2000-11-28 12:12 Scott James Remnant * src/net.c: If poll() or select() was interrupted, or replied that there were no events, then for efficiency reasons I didn't go into the loop and read/write from the sockets. However, this mean't that until something happened, the activity function wouldn't get called if there was data queued internally for the socket. This affected things like DCCs and made them stalled. Always do this loop now. 2000-11-24 14:00 Scott James Remnant * configure.in: CVS version now 0.8.4. 2000-11-24 13:52 Scott James Remnant * ChangeLog, NEWS: Version 0.8.3 released. 2000-11-24 13:44 Scott James Remnant * src/: irc_client.c, irc_net.c, irc_net.h, irc_server.c: Grab a hostname from the one we lookup until we get something better. Accept any number of PASS/NICK/USER in any variation until we have all three *then* authenticate them. This mean't restructuring the login sequence a bit - but it means its a lot more server-like now and actually probably a bit easier to figure out new things with. Fixed the nickname desync problems by always using change_nick everywhere and forcing a NICK command back to the user if we get a 433 or something similar. Also instead of "forgetting" the nickname when its juped during server reconnect while client connected - we keep it, but simply ask for a new one. That way we can generate the required back NICK command. QUIT's and NICK's are only logged to the private message log - not all of them! Made sure connection loss while not online is logged. 2000-11-23 12:33 Scott James Remnant * configure.in: CVS version now 0.8.3. 2000-11-23 12:19 Scott James Remnant * ChangeLog, NEWS: Version 0.8.2 released. 2000-11-21 13:50 Scott James Remnant * README.dcc-via-ssh: Bit of clarification on when you actually need the tunnels 2000-11-21 13:42 Scott James Remnant * INSTALL: Further instructions on MacOS X compile (thanks BillyH btw!) 2000-11-21 13:35 Scott James Remnant * INSTALL: It works on a Mac too! 2000-11-20 15:25 Scott James Remnant * src/: dcc_chat.c, dcc_send.c, irc_client.c, irc_server.c: If we ever get an unexpected socket, then close it. 2000-11-20 12:49 Scott James Remnant * INSTALL: Updated slightly 2000-11-20 12:42 Scott James Remnant * src/net.c: Slightly altered to suppress warnings on older libcs 2000-11-20 12:22 Scott James Remnant * src/: dcc_chat.c, dcc_send.c: Made sure we actually close dcc sockets and not just declare them dead. This will hopefully cure the "lots of read error" problems people have been getting. 2000-11-20 11:12 Scott James Remnant * src/irc_client.c: Somehow lost the #include for sys/types.h - broke compilation on FreeBSD 2000-11-15 16:37 Scott James Remnant * configure.in: CVS version now 0.8.2. 2000-11-15 16:23 Scott James Remnant * ChangeLog, NEWS: Version 0.8.1 released. 2000-11-15 16:10 Scott James Remnant * acconfig.h, configure.in, src/dcc_net.h, src/dcc_send.c: Instead of mucking around with typedefs, use the uint32_t type defined by ISO C 9x to be in inttypes.h - we can then check for this header file and if it doesn't exist #define uint32_t to be unsigned long. 2000-11-15 15:56 Scott James Remnant * acconfig.h: Added new typedefs to stop autoconf moaning 2000-11-15 15:52 Scott James Remnant * configure.in: [ Bug #122324 ] fixed configure issues on other platforms 2000-11-15 15:48 Scott James Remnant * crypt/Makefile.am: Forgot to LDADD libgetopt.a 2000-11-15 15:32 Scott James Remnant * src/dns.c: Save the address being looked up if we can, then if the dns lookup fails we can pretend it worked because we use the addr they looked up and the inet_ntoa() version of it for a name. This was supposed to do this, but for some reason only if result.success (oops) 2000-11-15 14:59 Scott James Remnant * src/: irc_net.c, main.c: A few bugs relating to inetd operation. Specifically I wasn't hooking the socket into the fancy new socket stuff I wrote, so it'd get bored and exit thinking there weren't any. 2000-11-14 11:49 Scott James Remnant * src/irc_log.c: [ Bug #122189 ] Use the TEMP envvar if TMPDIR isn't defined. Also make sure that p->temp_logdir isn't 0 before using it to generate a log filename 2000-11-10 16:28 Scott James Remnant * configure.in: CVS version now 0.8.1. 2000-11-10 15:54 Scott James Remnant * ChangeLog, NEWS, README, TODO, RELEASING: Version 0.8.0 released. 2000-11-10 15:18 Scott James Remnant * conf/dircproxyrc: Accidentally dropped an '=' in there 2000-11-10 15:14 Scott James Remnant * src/irc_log.h: Use signed longs for log file offsets 2000-11-10 15:13 Scott James Remnant * src/net.c: Made net_poll() a little more efficient by only realloc()ing if the number of ufds changes 2000-11-10 15:13 Scott James Remnant * src/memdebug.c: Left in some code so I can enable reporting of all malloc()s if I want it 2000-11-10 15:12 Scott James Remnant * src/main.c: Mostly general neatening 2000-11-10 15:12 Scott James Remnant * src/irc_string.c: Made irc_strcasecmp a little more efficient seeing as we use it so much 2000-11-10 15:10 Scott James Remnant * src/irc_server.c: switch_user support done through seteuid() Added code to do dcc send capturing 2000-11-10 15:09 Scott James Remnant * src/irc_log.c: _irclog_read needs to take a FILE * not a log file, so it will read if the log isn't open (but a file to it is). Use long's as log offsets when recalling. Removed the last of the is_chan code Freeing memory we forgot to when filtering Adjusted the relative timestamps so > 7 days you don't see a time 2000-11-10 15:08 Scott James Remnant * src/irc_client.c: Use *signed* longs for log offsets, and actually detach on /QUIT so we don't wait for a socket to notice they've gone 2000-11-10 15:08 Scott James Remnant * src/dns.c: Added an extra pipe to avoid race conditions, also actually check the wait() status properly 2000-11-10 15:07 Scott James Remnant * src/: cfgfile.c, dircproxy.h, irc_net.c, irc_net.h: Added the dcc_capture_* options and the switch_user option 2000-11-10 15:06 Scott James Remnant * src/: dcc_net.c, dcc_net.h, dcc_send.c: Added dcc capture support 2000-11-10 15:04 Scott James Remnant * conf/dircproxyrc: Added the new dcc_* and switch_user options 2000-11-10 15:03 Scott James Remnant * doc/dircproxy.1: Added documentation for dcc_* options and the switch_user option 2000-11-10 15:02 Scott James Remnant * doc/dircproxy-crypt.1: dircproxy-crypt now has command line options - updated the man page 2000-11-10 15:01 Scott James Remnant * FAQ, README.inetd: Documentation updates 2000-11-10 15:00 Scott James Remnant * configure.in: A few more checks, and added getopt and crypt dirs 2000-11-10 15:00 Scott James Remnant * contrib/log.pl: Added in docs for unfiltered ctcp 2000-11-10 14:59 Scott James Remnant * getopt/.cvsignore: Accidentally committed binaries, removed them and added a .cvsignore 2000-11-10 14:57 Scott James Remnant * crypt/.cvsignore: Accidentally checked in the binaries (wakey, wakey!) Removed them and added in a .cvsignore file 2000-11-10 14:55 Scott James Remnant * contrib/Makefile.am, src/Makefile.am, Makefile.am, crypt/Makefile.am, crypt/main.c, getopt/Makefile.am, getopt/getopt.c, getopt/getopt.h, getopt/getopt1.c: Moved the getopt files out of src into their own getopt directory, which gets compiled into a libgetopt.a we include to make dircproxy itself. Also moved the crypt.c out of contrib and into its own crypt directory, improved this a bit and linked it to libgetopt.a to make it a bit neater 2000-11-06 17:02 Scott James Remnant * src/: irc_net.c, irc_net.h: Extra config options added and freed. Ports are int not shorts 2000-11-06 17:00 Scott James Remnant * src/: irc_client.c, irc_server.c: DCC code modified to work a lot better, and be configurable and take advantage of tunnel ports and stuff. Debug code should be inside ''s Fixed memory leak of not freeing p->serverpassword Made sure that msg.src contains information for server code (irc client code doesn't need this) 2000-11-06 16:57 Scott James Remnant * src/: dns.c, dns.h: Use an extra pipe to tell the child when the parent is able to reap it, this avoids the race condition that happens on really fast machines where the child exits before the parent's had time to realise its a dns query (therefore never finishes the request and hangs). Also use ints not shorts for ports! 2000-11-06 16:56 Scott James Remnant * src/: dcc_net.c, dcc_net.h: Code to do port ranges added, timeout code added, dcc send hooks added and p->type changed to be a mask 2000-11-06 16:55 Scott James Remnant * src/: dcc_chat.c, dcc_chat.h: Made data+error functions tatic as they aren't used outside of here. Also extra warning if connection fails. 2000-11-06 16:54 Scott James Remnant * src/: cfgfile.c, dircproxy.h: New config file options: dcc_proxy_incoming [bool] dcc_proxy_outgoing [bool] dcc_proxy_ports [specially handled] dcc_proxy_timeout [numeric] dcc_proxy_sendreject [bool] dcc_send_fast [bool] dcc_tunnel_incoming [int] dcc_tunnel_outgoing [int] 2000-11-06 16:47 Scott James Remnant * src/: Makefile.am, dcc_send.c, dcc_send.h: Added the code to do both simple and fast dcc send proxying. The dcc capture code will also go in here somewhere. 2000-11-06 16:47 Scott James Remnant * FAQ, README.dcc-via-ssh, TODO: Documentation updates 2000-11-02 16:48 Scott James Remnant * src/irc_server.c: Dropped the DCC code in wholesale, and it worked, whoo! 2000-11-02 16:39 Scott James Remnant * src/irc_string.c: Whoa, irc_strupr actually tolower()d things 2000-11-02 16:36 Scott James Remnant * src/irc_prot.c: Upper case the DCC command name according to IRC rules 2000-11-02 16:36 Scott James Remnant * src/irc_client.c: Twiddling 2000-11-02 16:15 Scott James Remnant * src/irc_server.c: Really cleaned this up by using msg.src.orig all over the place instead of trying to build it manually each time. Also made sure we never use msg.src without checking its there, and if not always use p->servername instead. 2000-11-02 16:14 Scott James Remnant * src/: irc_prot.c, irc_prot.h: Keep the original prefix so we don't have to rebuild it each time 2000-11-02 16:13 Scott James Remnant * src/irc_client.c: Cleaned up CTCP handling a fair bit, making it less indented and more streamlined 2000-11-02 16:13 Scott James Remnant * src/dcc_net.c: Slightly more useful debug information 2000-11-02 16:12 Scott James Remnant * src/dcc_chat.c: Was hooking the wrong socket (erk) and also need to check that the other side is connected before sending the data to it. 2000-11-02 13:29 Scott James Remnant * src/: dcc_chat.c, dcc_chat.h, dcc_net.c: Slight tidying to give a bit more response to the user. 2000-11-01 17:58 Scott James Remnant * src/dcc_chat.c: Changed the debug direction indicators to make it clear this is dcc 2000-11-01 17:57 Scott James Remnant * src/irc_prot.c: Don't dequote until we actually parse the CTCP message. This is so s->str can be guaranteed to be within \001's inside the msg.orig 2000-11-01 15:04 Scott James Remnant * src/: Makefile.am, main.c: Intergrated DCC chat stuff so its all cleaned up. Still need to actually do it though :o) 2000-11-01 15:03 Scott James Remnant * src/: dcc_chat.c, dcc_chat.h, dcc_net.c, dcc_net.h: Got a bit enthusiastic and wrote all the code necessary to do a dcc chat proxying. Well, still a bit to do (listen_port ranges and stuff for example) plus it could do with being a LOT cleaner - but hey! its getting there 2000-11-01 15:02 Scott James Remnant * src/net.c: If net_read() is called with a len of 0 just return how much data is in the buffer 2000-11-01 15:01 Scott James Remnant * src/: irc_client.c, irc_net.c, irc_server.c, net.h: new _FUNCTION() macros for the net stuff, made the code use these. Also cleaned up the CTCP stuff and made server work properly 2000-11-01 14:59 Scott James Remnant * src/: irc_log.c, irc_log.h: CTCP logging needs to be done a little differently to make sure the timestamp is fully inside the CTCP and after the command. New irclog_ctcp function to do this. 2000-10-31 13:11 Scott James Remnant * TODO, conf/dircproxyrc, doc/dircproxy.1, src/cfgfile.c, src/dircproxy.h, src/irc_client.c, src/irc_log.c, src/irc_net.h, src/irc_prot.c, src/irc_prot.h, src/irc_server.c: time_offset changed to log_timeoffset because of new log_events option that sits quite nicely with it in the config file. Lots more logging, which is done according to how log_events is set. We also now strip CTCP out of messages sensibly and are able to parse and act on the CTCP's we get out including logging them, or logging ACTION's now (yay!) and even in future doing DCC stuff. Also fixed: when kicked, channel wouldn't get deleted properly, join option in config file didn't like ",," or ", #chan" - appropriate errors added 2000-10-30 13:44 Scott James Remnant * FAQ, conf/dircproxyrc, doc/dircproxy.1, src/cfgfile.c, src/dircproxy.h, src/irc_client.c, src/irc_log.c, src/irc_log.h, src/irc_net.c, src/irc_net.h: Quite a large change to the way logging code works now. Made it a hell of a lot neater in the process too. The idea is that all dircproxy logs always end up in /tmp, and you can use the new _log_copydir (replacing the old _log_dir) option to specify a place to store ALL text logged, or the program to do stuff with it. 2000-10-30 13:42 Scott James Remnant * src/irc_server.c: Don't need to send a NICK command to the client on receipt of a bad nickname numeric, they'll respond to it anyway. 2000-10-30 13:41 Scott James Remnant * src/main.c: Prettied up the error/warning output a bit 2000-10-27 13:12 Scott James Remnant * src/irc_net.c: Should probably set c->key to 0 after freeing it 2000-10-27 13:11 Scott James Remnant * src/irc_server.c: Didn't bother to check whether p->modes was set or refuse_mode itself was set before doing a strcspn()... I must have written THAT at 4am! 2000-10-23 12:47 Scott James Remnant * src/net.c: Sockets with data to write now write that data before they close, and have a few seconds to write it during a shutdown as well. Fixed a few bugs here as well. 2000-10-23 12:39 Scott James Remnant * src/net.h: Added the net_closeall() prototype 2000-10-23 12:33 Scott James Remnant * src/irc_client.c: Made sure we don't net_gets() on a closed socket, tested and fixed the nickname generation so its much nicer now, fixed up the QUIT messages to try and get more irc clients to show them and finally modified to use the new dns/timer syntax 2000-10-23 12:32 Scott James Remnant * src/irc_server.c: Fixed KICK without a source bug, made sure we don't net_gets() a closed socket and modified the rest to use the new dns/timer syntax 2000-10-23 12:30 Scott James Remnant * src/irc_net.c: Modified the use of dns and timers 2000-10-23 12:29 Scott James Remnant * src/main.c: Bit of cleanup of the stop stuff, made errors more obvious in debug mode and calling net_closeall() 2000-10-23 12:26 Scott James Remnant * src/memdebug.c: Added some code to produce pretty statistics of which .c files are doing the most malloc()s. Also made it so if file is 0 it doesn't count it (but still checks it) so I can hide debug() mallocs 2000-10-23 12:19 Scott James Remnant * src/dircproxy.h: Added new define for net linger time 2000-10-23 12:03 Scott James Remnant * src/: timers.c, timers.h: Made it so that timers don't depend on a struct ircproxy, just a random void pointer 2000-10-23 12:03 Scott James Remnant * src/: dns.c, dns.h: Made it so that the DNS stuff doesn't rely on a struct ircproxy, just any random void pointer. 2000-10-23 11:56 Scott James Remnant * configure.in: Allow poll() and select() to be disabled through configure 2000-10-23 11:55 Scott James Remnant * TODO: Another bug to fix :( 2000-10-23 11:55 Scott James Remnant * FAQ, conf/dircproxyrc, doc/dircproxy.1: Lots of documentation improvements and documented the new dircproxy-crypt program too 2000-10-23 11:53 Scott James Remnant * doc/Makefile.am: Install the dircproxy man page 2000-10-23 11:53 Scott James Remnant * doc/dircproxy-crypt.1, contrib/.cvsignore, contrib/Makefile.am: Made the 'crypt' program into something called 'dircproxy-crypt' that gets installed with dircproxy and even has a man page too! 2000-10-20 12:44 Scott James Remnant * TODO, conf/dircproxyrc, doc/dircproxy.1, src/cfgfile.c, src/dircproxy.h, src/irc_log.c, src/irc_net.h: Added fancy new log timestamping and time offset code. 2000-10-20 11:03 Scott James Remnant * TODO, conf/dircproxyrc, doc/dircproxy.1, src/cfgfile.c, src/dircproxy.h, src/irc_client.c, src/irc_log.c, src/irc_net.c, src/irc_net.h, src/irc_server.c, src/irc_server.h, src/main.c, src/net.c, src/net.h: Completely moved over to new socket code now, so its all non-blocking and sexy. Also throttling of server sockets and appropriate server_throttle configuration file option. 2000-10-20 11:00 Scott James Remnant * configure.in: Check for poll.h,sys/poll.h and poll() itself 2000-10-18 17:23 Scott James Remnant * src/net.c: More static functions 2000-10-18 13:26 Scott James Remnant * TODO, src/Makefile.am, src/net.c, src/net.h: Replacing sock.c/sock.h with a new net.c/net.h which is much more advanced, and will also do things like the poll() / select() loop. 2000-10-16 12:48 Scott James Remnant * src/irc_server.c: Still need to check whether username/hostname are actually set, even if we're IRC_USER 2000-10-16 11:26 Scott James Remnant * src/irc_net.c: Code to do channel keys (yay!) 2000-10-16 11:23 Scott James Remnant * src/irc_server.c: Code to send and check MODE's for channel keys now added 2000-10-16 11:17 Scott James Remnant * src/irc_server.c: Couple of bugs with the privmsg/notice code, including a %s%s%s vulnerability These have been fixed 2000-10-16 10:59 Scott James Remnant * src/irc_server.c: Changed to use irc_strcasecmp for the commands, won't make any difference but its nicer 2000-10-16 10:52 Scott James Remnant * src/irc_client.c: Changed to use irc_strcasecmp for the commands, won't make any difference but its nicer 2000-10-16 10:51 Scott James Remnant * src/irc_client.c: Updated dircproxy persist docs 2000-10-16 10:49 Scott James Remnant * src/irc_client.c: Made sure you can't /DIRCPROXY PERSIST (and kill off any other possible users) if die_on_close is 1 because of the config file. If it is because of the config file, then just set die_on_close to 0 and announce that they can persist. 2000-10-16 10:46 Scott James Remnant * src/irc_net.h: Added header code for the new channel mode monitoring stuff, this means that irc_net.h will need irc_prot.h 2000-10-16 10:45 Scott James Remnant * src/irc_prot.c: Make sure that IRC_USER is only set if there's definitly a nickname, username and hostname 2000-10-16 10:45 Scott James Remnant * TODO: *sigh* Updates to the TODO file 2000-10-16 10:44 Scott James Remnant * conf/dircproxyrc, doc/dircproxy.1: Added a bit of extra text to try to explain that you shouldn't set chan_log_dir/other_log_dir unless you really want that 2000-10-16 10:43 Scott James Remnant * src/sprintf.h: Clive D.W. Feather himself came up with the prettiest suggestion for my sprintf() trick, so his gets to be in the code :) 2000-10-16 10:42 Scott James Remnant * src/help.h: Fixed the /DIRCPROXY PERSIST documentation so its a little more helpful 2000-10-16 10:42 Scott James Remnant * Makefile.am: Need to include the dcc-via-ssh docs with the distribution too 2000-10-16 10:41 Scott James Remnant * Makefile.am: The FAQ goes with the distribution 2000-10-16 10:41 Scott James Remnant * FAQ: Put some frequently questioned answers in 2000-10-13 17:02 Scott James Remnant * src/: sprintf.c, sprintf.h: Yay, thanks to l33t Demon staff, they dug out a new C99 syntax feature that GCC supports that lets you do variable argument macros. Because this is debug mode I'm happy to put this C99 stuff in :) 2000-10-13 14:33 Scott James Remnant * INSTALL: Got word that dircproxy 0.7.3 compiles under Windows NT without any modification, so added that to the list. 2000-10-13 13:56 Scott James Remnant * TODO: Traditional update to the TODO file 2000-10-13 13:55 Scott James Remnant * conf/dircproxyrc, doc/dircproxy.1, src/cfgfile.c, src/irc_client.c, src/irc_net.c, src/irc_net.h, src/irc_server.c: Channels can have keys locking them, so we should do our best to find out what these are and remember them so we can join channels and provide the right key. First step: Allowing the "join" config option to have keys in it '#chan key,#chan key' etc. 2000-10-13 13:50 Scott James Remnant * conf/dircproxyrc, doc/dircproxy.1, src/cfgfile.c, src/dircproxy.h, src/irc_client.c, src/irc_net.c, src/irc_net.h: Another new config option, detach_nickname - changes your nickname for you when you detach 2000-10-13 13:42 Scott James Remnant * conf/dircproxyrc, doc/dircproxy.1, src/cfgfile.c, src/dircproxy.h, src/irc_server.c: Removed the server_dnsretry config option. Now that we have non-blocking DNS, there's no real need to wait longer after a DNS retry - especially as it'll probably try another server anyway! 2000-10-13 13:36 Scott James Remnant * src/main.c: Oops, mucked up a sync patch somewhere 2000-10-13 13:35 Scott James Remnant * conf/dircproxyrc, doc/dircproxy.1, src/cfgfile.c, src/cfgfile.h, src/dircproxy.h, src/dns.c, src/irc_client.c, src/main.c: Instead of a few #define's which aren't easy to change for timeouts I've moved them into a new "globalvars" structure which is passed to cfg_read and be accessed everywhere as g. - this means these variables can now be altered inside the config file 2000-10-13 13:27 Scott James Remnant * src/irc_client.c: Improved the /DIRCPROXY HELP command so the command list gives a quick idea what the command does 2000-10-13 13:24 Scott James Remnant * conf/dircproxyrc, doc/dircproxy.1, src/cfgfile.c, src/dircproxy.h, src/help.h, src/irc_client.c, src/irc_net.h: Added in a new /DIRCPROXY DIE command and the appropriate allow_die config option (no by default!) 2000-10-13 13:17 Scott James Remnant * src/irc_server.c: Make sure the server_recon timer is deleted just in case they jump or quit during a reconnection phase 2000-10-13 13:15 Scott James Remnant * src/irc_server.c: Better feedback during server connections 2000-10-13 13:13 Scott James Remnant * src/irc_client.c: Included the code to actually make the new quit_message config actually do something 2000-10-13 13:06 Scott James Remnant * doc/dircproxy.1: Improved the documentation a bit 2000-10-13 13:02 Scott James Remnant * conf/dircproxyrc: Improved the documentation and general layout of dircproxyrc 2000-10-13 12:53 Scott James Remnant * src/: sprintf.c, sprintf.h: x_strdup() and x_sprintf() are now specially designed so that when DEBUG_MEMORY is enabled they talk to the memdebug layer directly and are able to tell you where x_strdup() was called instead of just the line inside x_strdup() that did the malloc(). Will make debugging a LOT easier. 2000-10-13 12:50 Scott James Remnant * src/irc_server.c: Improved the documentation 2000-10-13 12:47 Scott James Remnant * src/irc_client.c: Added more info to the top 2000-10-13 12:46 Scott James Remnant * src/irc_net.c: Fixed up the documentation 2000-10-13 12:44 Scott James Remnant * src/irc_log.c: Improved the top description 2000-10-13 12:43 Scott James Remnant * src/irc_prot.c: Better description at the top. 2000-10-13 12:43 Scott James Remnant * src/irc_string.c: Better described this 2000-10-13 12:32 Scott James Remnant * src/dns.c: Forgot to check whether the child returned a status of 0 (everything ok) if it doesn't then its probably timeout or system failure 2000-10-13 12:31 Scott James Remnant * src/dns.c: Improved the top comments so they describe this file better now. 2000-10-13 12:29 Scott James Remnant * src/dircproxy.h: Added prototype for new stop() function 2000-10-13 12:26 Scott James Remnant * src/main.c: Added a function that can be called to end the main loop 2000-10-13 12:23 Scott James Remnant * src/main.c: More fully described what this does. 2000-10-13 12:22 Scott James Remnant * src/memdebug.h: Being picky and marked the #endif with a comment 2000-10-12 16:24 Scott James Remnant * doc/dircproxy.1, src/cfgfile.c, src/dircproxy.h, src/irc_net.c, src/irc_net.h: Added support for default /QUIT messages 2000-10-12 16:12 Scott James Remnant * TODO: New ideas 2000-10-12 16:10 Scott James Remnant * conf/dircproxyrc: Added support for default QUIT messages 2000-10-12 16:05 Scott James Remnant * src/irc_client.c: Recall the other_log file *after* channels, so private messages appear last in the window 2000-10-12 16:04 Scott James Remnant * TODO: Non-blocking DNS done 2000-10-12 16:02 Scott James Remnant * src/: irc_client.c, irc_net.c, irc_server.c: Changes to accomodate the new DNS system 2000-10-12 16:02 Scott James Remnant * src/main.c: Handle DNS children in the SIGCHLD handler, and also clear up any DNS child processes 2000-10-12 16:01 Scott James Remnant * src/irc_net.h: To accomodate two-stage DNS lookups we need an extra server status that indicates the server is connected (so don't check for connection) but we haven't yet been introduced to it. 2000-10-12 16:00 Scott James Remnant * src/: dns.c, dns.h: Almost total rewrite of the DNS code. Now you have to request a DNS and provide a function to run once the DNS lookup is complete. The code will then fork() off to do the lookup and continue with normal execution of the program. When the client exits, the result is on a pipe, and once read execution is continued from the function you give it. (ie non-blocking DNS :o) 2000-10-12 15:59 Scott James Remnant * src/dircproxy.h: Added a #define to set the DNS timeout 2000-10-11 16:33 Scott James Remnant * TODO: More things 2000-10-11 16:07 Scott James Remnant * README, TODO: Don't need contrib scripts, clients should just pass /dircproxy to us 2000-10-11 16:05 Scott James Remnant * src/irc_client.c: Made /DIRCPROXY QUIT and DETACH just use every paramter joined together rather than the last one (removing the need for quoting!) 2000-10-11 16:02 Scott James Remnant * src/: irc_prot.c, irc_prot.h: Also record where in the msg.orig string a paramter started, so we can just copy the whole lot to things like quit messages etc. 2000-10-11 15:48 Scott James Remnant * CTCPSPEC, DCCSPEC: Added the DCC and CTCP specifications for reference. Not needed in the distribution, just handy to have around for the CVS developer (me). 2000-10-10 13:08 Scott James Remnant * TODO, conf/dircproxyrc, doc/dircproxy.1, src/cfgfile.c, src/dircproxy.h, src/help.h, src/irc_client.c, src/irc_log.c, src/irc_net.c, src/irc_net.h, src/irc_server.c, src/irc_server.h, src/main.c, src/timers.c: Been working on dircproxy for a week while on holiday, so this is gonna be a VERY big patch (only problem with sourceforge really, you can't take the CVS offline :( ) New options: server_autoconnect channel_leave_on_detach channel_rejoin_on_attach refuse_modes chan_log_enabled chan_log_program other_log_enabled other_log_program motd_file allow_jump allow_jump_new allow_host join (for connection class) Changed options: Any option that accepted "none" also accepts "" New commands: /DIRCPROXY SERVERS /DIRCPROXY JUMP /DIRCPROXY HOST /DIRCPROXY MOTD New features not mentioned: Timeouts for client authorization and connection to a server Unjoined channels (channels we are on, but won't join until a client attaches) Only does certain things for joined + active channels Instead of ignoring everything (including disconnect) from clients until we have a server connection, we simply return a RPL_TRYAGAIN for everything but the /DIRCPROXY command if we don't have a server connection. This means dircproxy will notice things like disconnects finally (yay!) Cleaned up quit messages to make them a bit more amusing Made sure ERRORs are sent for any non-user-requested client disconnection Cleaned up motd stuff and moved to seperate function etc. Looks a lot nicer and works nicer now too. Debug code added so you can see what dircproxy sends extra to that which it proxies Spaced out irc_net.h into the same groups as the config file SERVER_READY does not necessarily mean SERVER_SEEN (this gets set on a 001) - so if a server denies our connection we treat it as still in the "initial" phase. New function to drop+restore server connection (treating it as new initial connection) Send PARTs when server connection is lost, JOINs are sent again on restoration of service (to prevent client from getting baffled). Made sure we never send stuff in timers without checking the server is ready Child reaping Timer debugging Bugs fixed: The pesky "+i No such channel" bug.. gonna fix this in 0.7 too 2000-10-10 12:39 Scott James Remnant * contrib/log.pl: Added a nice script to demonstrate the new {chan,other}_log_program options that are to be added. 2000-09-29 16:08 Scott James Remnant * src/irc_client.c: Slight bug - didn't check that idle_maxtime was set when resetting idle time - so it actually did this with a timer of 0 2000-09-29 15:55 Scott James Remnant * TODO, conf/dircproxyrc, doc/dircproxy.1: Added documentation for allow_persist, attach_message and detach_message 2000-09-29 15:55 Scott James Remnant * src/irc_client.c: Fixed a bug - was using p not tmp_p (bad!) 2000-09-29 15:51 Scott James Remnant * src/: cfgfile.c, dircproxy.h, irc_client.c, irc_net.c, irc_net.h: Added the code to do attach_message and detach_message stuff 2000-09-29 12:43 Scott James Remnant * TODO, src/cfgfile.c, src/dircproxy.h, src/help.h, src/irc_client.c, src/irc_net.h: Changed the config file code so that it uses a struct ircconnclass to store the globals in rather than a million ickle variables - makes it much neater. Added the allow_persist option, and adjusted the help code accordingly to make sure that it doesn't show PERSIST in the help unless its on. 2000-09-28 12:32 Scott James Remnant * README, README.dcc-via-ssh, TODO: Added DCC-via-SSH documentation, and cleaned up the README itself. 2000-09-28 10:37 Scott James Remnant * TODO: More TODO updates 2000-09-28 10:37 Scott James Remnant * src/: irc_client.c, irc_net.h, irc_server.c, irc_server.h: Added code to prevent idling - uses a timer which is set to be idle_maxtime seconds after the last privmsg/notice. Sends an empty PRIVMSG which generates a 411 error, so need to have a setting to squelch this when we've sent it. (note: doesn't use allow_411 type syntax, because its a single response that we can't tell whether will be generated or not.) 2000-09-28 10:35 Scott James Remnant * src/: cfgfile.c, dircproxy.h: Added config code for new idle_maxtime option 2000-09-28 10:34 Scott James Remnant * conf/dircproxyrc, doc/dircproxy.1: Added config option and documentation for new idle_maxtime option 2000-09-28 10:33 Scott James Remnant * README: Added documentation for /dircproxy command 2000-09-27 17:12 Scott James Remnant * configure.in: Development of 0.8 now beginning, any changes to 0.7 will be done on a branch off 0.7.3. CVS version now 0.8.0 2000-09-27 16:56 Scott James Remnant * ChangeLog, NEWS, TODO: Version 0.7.3 released. 2000-09-27 16:45 Scott James Remnant * conf/dircproxyrc, doc/dircproxy.1, src/irc_client.c, src/irc_net.h, src/irc_server.c: Changed the way that stoned server checking works. Instead of measuring times between PINGs from server, do our own PINGs and measure time between the PONGs we get back. 2000-09-27 16:11 Scott James Remnant * src/memdebug.c: Heh, that pesky memory leak turned out to be in memdebug.c itself, forgot to free ms->file 2000-09-27 12:11 Scott James Remnant * TODO: More stuff 2000-09-26 15:10 Scott James Remnant * conf/dircproxyrc: Spaced out a bit more for legibility 2000-09-26 15:07 Scott James Remnant * TODO: More stuff for 0.8 - its gonna be a big release 2000-09-26 13:24 Scott James Remnant * RFC1413: Added the ident RFC, because 0.8 will have its own miniature identd daemon with it. 2000-09-26 12:13 Scott James Remnant * TODO: TODO changes 2000-09-26 11:52 Scott James Remnant * src/main.c: Forced QUITs (as apposed to user quits) generate different error messages 2000-09-26 11:51 Scott James Remnant * src/: irc_client.c, irc_net.c, irc_server.c: Added a few more QUIT messages, to make sure we never leave the server with "EOF from client" if we can help it. Each message is *slightly* different to aid debugging. 2000-09-26 11:45 Scott James Remnant * src/: irc_client.c, main.c: Finally found the course of the "missing QUIT message" problem. Turned out to be me closing the client socket before the server socket (which automatically closes the server socket - thus the GETFL error too). 2000-09-26 11:31 Scott James Remnant * src/cfgfile.c: Forgot to change a line to enable the config file directive 2000-09-26 10:58 Scott James Remnant * conf/dircproxyrc, doc/dircproxy.1, src/cfgfile.c, src/dircproxy.h, src/irc_client.c, src/irc_net.h: New config file option that sets die_on_close to 1 if set to yes. Basically means that you can use dircproxy without its detachable bit now. 2000-09-25 12:24 Scott James Remnant * configure.in: CVS version now 0.7.3. 2000-09-25 12:16 Scott James Remnant * ChangeLog, NEWS, TODO: Version 0.7.2 released. 2000-09-18 10:07 Scott James Remnant * src/main.c: listen_port problem should return 3 [ port error ] not 2 [ config error ] from main. 2000-09-18 10:06 Scott James Remnant * src/main.c: The ~/.dircproxyrc file should only be able to be read/write/exec by the user. It has passwords in it. We don't make the same restrictions for the others though. thanks to: Scott Bronson 2000-09-18 09:54 Scott James Remnant * src/irc_client.c: [ Bug #114688 ] Need to break out of the big while() loop as well if we get a matching mask list, otherwise we never report success. 2000-09-14 12:27 Scott James Remnant * configure.in: CVS version now 0.7.2. 2000-09-14 12:14 Scott James Remnant * ChangeLog, NEWS: Version 0.7.1 released. 2000-09-14 12:07 Scott James Remnant * src/irc_server.c: [ Bug #114352 ] Thought dircproxy had none of these pesky format string problems, but one slipped through in the late stages. Oops. 2000-09-04 13:56 Scott James Remnant * conf/dircproxyrc, doc/dircproxy.1: Cleared up the documentation to state that drop_modes 0 *doesn't* unset this option. 2000-09-04 13:39 Scott James Remnant * src/irc_client.c: Removal of a mode flag when p->modes is 0 resulted in core dump. Fixed this by checking p->modes is set BEFORE doing a strchr() on it. 2000-09-04 13:22 Scott James Remnant * src/irc_log.c: Only do log spinning if log->maxlines isn't 0 (duh!) 2000-09-01 14:11 Scott James Remnant * configure.in: CVS version now 0.7.1 2000-09-01 13:40 Scott James Remnant * ChangeLog, NEWS, README, TODO: Version 0.7.0 released. 2000-09-01 12:58 Scott James Remnant * src/irc_net.c: Need string.h 2000-09-01 12:19 Scott James Remnant * src/irc_log.c: Only replace / its not worth replacing ., just makes it harder to find the logs 2000-09-01 12:17 Scott James Remnant * doc/dircproxy.1: Added config file documentation to the man page of muchness 2000-09-01 12:16 Scott James Remnant * src/irc_net.h: New member for stoned checking and log spinning 2000-09-01 12:15 Scott James Remnant * conf/dircproxyrc, src/cfgfile.c, src/dircproxy.h, src/irc_server.c: Check for stoned servers 2000-09-01 12:13 Scott James Remnant * src/irc_log.c: Put the sick puppy log spin code in 2000-09-01 12:13 Scott James Remnant * src/irc_client.c: Pure sugar, say "all" if we're gonna recall the whole file cause its small enough 2000-09-01 12:07 Scott James Remnant * src/main.c: Can't use the local config file in inetd mode 2000-09-01 12:05 Scott James Remnant * README.inetd: Fixed up the text now that /DIRCPROXY PERSIT exists for those inetders 2000-08-31 15:36 Scott James Remnant * TODO: Almost there ... 2000-08-31 15:34 Scott James Remnant * src/irc_client.c: Seperated the code to detach a user from ircclient_data() Fixed the 416/461 swapped numeric typo. Removed the /DQUIT command and added the /DIRCPROXY command in all of its glory. Neatened motd output 2000-08-31 15:32 Scott James Remnant * src/: irc_net.c, irc_net.h: Fixed up the dedicate routines to make them work sweeter 2000-08-31 15:30 Scott James Remnant * src/: irc_log.c, irc_log.h: Added the code to do manual log file recollection 2000-08-31 15:26 Scott James Remnant * src/: Makefile.am, help.h: Added in the help text for the /DIRCPROXY HELP command 2000-08-30 14:25 Scott James Remnant * TODO, src/irc_log.c: Recall everything/nothing code added 2000-08-30 14:17 Scott James Remnant * src/irc_client.c: Only log the disconnection if they were active and authenticated 2000-08-30 14:03 Scott James Remnant * src/cfgfile.c: Oops, accidental ` in the code 2000-08-30 13:40 Scott James Remnant * contrib/Makefile.am: Oops had a typo 2000-08-30 13:40 Scott James Remnant * src/irc_log.c: Moved this message below the close() 2000-08-30 13:39 Scott James Remnant * Makefile.am, configure.in: Added the contrib subdir 2000-08-30 13:14 Scott James Remnant * src/irc_client.c: Extra comment for clarity 2000-08-30 13:13 Scott James Remnant * contrib/: .cvsignore, Makefile.am: Added a contrib directory that will have the simple "crypt" program in it. 2000-08-30 13:09 Scott James Remnant * TODO: Not much left to do now (yay!) 2000-08-30 13:09 Scott James Remnant * src/irc_log.c: Added in the code to actually send log stuff to the client 2000-08-30 12:29 Scott James Remnant * src/irc_client.c: Include crypt.h after dircproxy.h to ensure we get configure info 2000-08-30 11:56 Scott James Remnant * configure.in, src/irc_client.c: Some unixen put crypt() in crypt.h, others in unistd.h 2000-08-30 11:37 Scott James Remnant * src/irc_client.c: Don't check whether the log file is open (it might not be), just check it has a filename. And to recall, just do it and worry later. 2000-08-30 11:36 Scott James Remnant * src/irc_log.c: Don't check we have a conn_class, its a programming error to call irc_log without one - let it core dump and let the bug show 2000-08-30 10:57 Scott James Remnant * TODO, src/irc_log.c: Quite a few changes to the log code. Making sure that we have a conn_class is probably a good idea, also fixed the fact that the other log got our nickname as a filename! Made irclog_free() and irclog_close() do slightly different things (close just closes the file handle, free actually unlinks and free's memory). This is so we can do log->nlines while the user is online for !always log files. Also added the recall code, all except the bit that sends stuff to the user. 2000-08-30 10:54 Scott James Remnant * src/: irc_client.c, irc_net.h: Added a quick time_t to ircproxy so we know when a proxy session began. Display in the 003 header sent to the client in place of "(unknown)" we had before. 2000-08-30 10:53 Scott James Remnant * src/: irc_client.c, irc_net.h, irc_server.c: Added a flag so that if the user uses the /MOTD we don't squelch the reply from them. We still squelch any other MOTD that comes from the server though. 2000-08-30 10:51 Scott James Remnant * src/irc_client.c: Was using conn_class at a pre-authentication point without actually checking the client was active. 2000-08-30 10:48 Scott James Remnant * src/: dircproxy.h, irc_net.c, irc_net.h, main.c: We've only got 1 global variable left now, the list of connection classes. The rest are all static to whatever .c file uses it. At the same time added the defaults for motd_* to dircproxy.h 2000-08-30 10:42 Scott James Remnant * src/Makefile.am: Added logo.h to the compilation 2000-08-30 10:41 Scott James Remnant * conf/dircproxyrc, src/cfgfile.c, src/irc_client.c, src/irc_net.h, src/logo.h: Made the message of the day stats optional, and at the same time added some code to display a l33t "dircproxy" logo if they want. 2000-08-29 11:12 Scott James Remnant * src/: irc_client.c, irc_log.c, irc_log.h, irc_net.c, irc_net.h, irc_server.c: New log code is in place, and modified all the other bits of code to use the new log code. Also a few modifications to use local_address and away_message properly. 2000-08-29 11:10 Scott James Remnant * conf/dircproxyrc, src/cfgfile.c, src/dircproxy.h, src/main.c: Rewrote the log file a bit, and changed the way cfgfile.c works a bit. Made local_address and away_message global options, and added in all the new log-related options. Finally got rid of log_autorecall global variable at the same time. Also by using error() instead of printing directly to standard out, may have removed the need for the progname global. 2000-08-29 11:04 Scott James Remnant * TODO: Updated the todo file 2000-08-29 11:03 Scott James Remnant * RELEASING: Modified to take into account features list and things 2000-08-29 10:45 Scott James Remnant * TODO, src/dircproxy.h, src/irc_client.c, src/irc_net.c, src/irc_net.h, src/main.c: Added code to reload configuration file on a HUP. Does pretty well everything including kicking off users who's passwords have changed, changing the listen port etc. Only thing it doesn't do is move any open log files, but thats an icky thing to do anyway imho. 2000-08-29 10:42 Scott James Remnant * conf/dircproxyrc, src/cfgfile.c, src/dircproxy.h, src/irc_client.c, src/irc_net.c, src/irc_net.h: Added new drop_modes configuration option to drop user modes on detach. 2000-08-29 10:42 Scott James Remnant * TODO: Added a new drop_modes config file option for security and niceness. 2000-08-29 10:37 Scott James Remnant * conf/dircproxyrc: Added a note about passwords being encrypted 2000-08-29 10:34 Scott James Remnant * TODO, conf/dircproxyrc, src/cfgfile.c, src/dircproxy.h, src/irc_client.c, src/irc_net.h: Added code and configuration option to choose between disconnecting an existing user or denying an attempt connect. At the same time added a new boolean configuration type that can be yes/true/y/t/1/no/false/n/f/0 and sets an int to 1 or 0 2000-08-25 10:52 Scott James Remnant * RELEASING: Added instruction to copy to ftp 2000-08-25 10:05 Scott James Remnant * RELEASING: Added note about running build-site.pl to update the website 2000-08-25 09:57 Scott James Remnant * TODO: Ooh, TODO file is getting smaller now 2000-08-25 09:56 Scott James Remnant * conf/dircproxyrc: Updated the configuration file to fit the new config stuff 2000-08-25 09:56 Scott James Remnant * src/main.c: Use PACKAGE ('dircproxy') not progname ('../dircproxy-binary') for syslog 2000-08-25 09:54 Scott James Remnant * src/main.c: We must use syslog as soon as possible with inetd 2000-08-25 09:50 Scott James Remnant * src/irc_server.c: Actually check a channel existed before announcing we couldn't rejoin. I think that a re-use of a "bad channel" numeric is causing the "Cannot rejoin +iw" bug, but even if its not its a good place to start. 2000-08-25 09:49 Scott James Remnant * src/irc_server.c: Added the code to seperate the server password from the server string, and send it to the server when we connect. 2000-08-25 09:47 Scott James Remnant * src/irc_net.c: Use a static function to make a listening port, avoids duplication of that rather specialist code. This is called by both ircnet_listen and ircnet_dedicate() and only binds if a local_addr is given. 2000-08-25 09:46 Scott James Remnant * src/main.c: Changed the start order to make it a little more realistic 2000-08-25 09:43 Scott James Remnant * src/main.c: Changed the config file order to alphabetical 2000-08-25 09:42 Scott James Remnant * src/main.c: Argh! Bloody patch, I knew there was something up with it. 2000-08-25 09:38 Scott James Remnant * src/: dircproxy.h, irc_client.c, irc_log.c, irc_net.c, irc_server.c, main.c, sprintf.c: Got rid of the DEBUG_SYSCALL_FAIL, DEBUG_SYSCALL_DOH macros and replaced them with a simple syscall_fail() function. Also added a debug() function to replace all those #ifdef DEBUG/printf things lying around. This meant adding a couple of headers to a few files too. 2000-08-25 09:26 Scott James Remnant * src/: irc_net.c, irc_net.h: Added a 'serverpassword' member to ircproxy 2000-08-25 09:20 Scott James Remnant * src/dns.c: Check port has a length. 'server irc.foo:' now means use default port, not 0. This is necessary so that '::' works (default port, but with password). 2000-08-25 09:19 Scott James Remnant * src/cfgfile.c: Adjusted the documentation for server, because thats gonna be able to have passwords in for the server 2000-08-25 09:15 Scott James Remnant * doc/dircproxy.1: Rearranged the man page so the options are in alphaspaghettical order. 2000-08-24 12:42 Scott James Remnant * .cvsignore: COPYING is in cvs ... don't ignore it. 2000-08-24 11:36 Scott James Remnant * COPYING: Physically adding the GNU GPL to the source, its automatically included by automake anyway, but I don't really want people downloading the CVS without a license, or people's own automake's applying a different license. Everything says its GPL anyway *but* this is just for safety and stuff. 2000-08-24 11:33 Scott James Remnant * configure.in: There's sufficient changes so far to warrant a new version jump, although not everything I want is in yet. CVS version now 0.7.0. 2000-08-24 11:32 Scott James Remnant * TODO: TODO changes. 2000-08-24 11:25 Scott James Remnant * src/: cfgfile.c, cfgfile.h, dircproxy.h, main.c: listen_port isn't a global variable anymore (yay!) This means the global variables have now been cut right down to essential state information (in_background, dedicated_proxy, progname) and the list of connection classes (*might* be able to get rid of this last one, with any luck) There's the log_autorecall one lagging still, but thats going with the new log code, so I'm not bothering about it right now. 2000-08-24 11:22 Scott James Remnant * src/irc_net.c: Adjusted the ircnet_listen() function so it doesn't close an existing listening socket until its absolutely sure that the new listening socket is working perfectly. This'll be handy for a HUP if they change the socket we're listening on. 2000-08-24 11:10 Scott James Remnant * src/: cfgfile.c, dircproxy.h, irc_net.h, irc_server.c, main.c: Nearly all options in a config file (except listen_port) can be listed in a connection { } now, providing even more customisability per connection class. The ones in the body *above it* are used as defaults (below serve as defaults for any further connection classes). This means that all the globals have gone, and are now just members of struct ircconnclass. 2000-08-24 11:08 Scott James Remnant * src/irc_net.c: Call sock_close() instead of close() just in case. Also ensure we close sockets when freeing a proxy (like when SIGTERM or SIGINT is sent). Due to changes in config file, look for all variables under conn_class now (except listen_port), and don't bother with checking awaymessage isn't -1. 2000-08-24 09:17 Scott James Remnant * doc/dircproxy.1: Made the man page even more spiffy, just gotta document the configuraton file options (which are changing soon anyway!). 2000-08-23 14:30 Scott James Remnant * src/main.c: Only do mem_report stuff if DEBUG_MEMORY is defined, although this is generally defined with DEBUG it *might* not be ... 2000-08-23 14:13 Scott James Remnant * src/Makefile.am: dircproxy binary is now installed in 'bin' 2000-08-23 13:38 Scott James Remnant * doc/dircproxy.1: Neatened the options and added the homepage 2000-08-23 13:34 Scott James Remnant * doc/dircproxy.1: Made the man page a .1 2000-08-23 13:34 Scott James Remnant * doc/: Makefile.am, dircproxy.1: Just had a bit of a decision change. dircproxy is now installed under "bin" not "sbin", this means the man page is a .1 as well. 2000-08-23 13:30 Scott James Remnant * doc/: Makefile.am, dircproxy.1: As dircproxy gets installed in sbin it should be an (8) man page. 2000-08-23 13:25 Scott James Remnant * Makefile.am, configure.in, doc/.cvsignore, doc/Makefile.am, doc/dircproxy.1: I figured out how to do it finally and wrote a quick man page for dircproxy. Its not complete, but is pretty good by man page standards. 2000-08-23 11:48 Scott James Remnant * src/irc_client.c: Changed the password code to make it compile without warnings, actually #ifdef'ing out the "if" statement now instead of magic with pointers. 2000-08-23 11:47 Scott James Remnant * src/: irc_client.c, irc_client.h, irc_net.c, irc_net.h: Moved the dedicated_proxy code itself out of irc_client, and into irc_net. Added the function to actually dedicate the proxy to one particular proxy session, and also added function to announce if we're not listening for connections. 2000-08-23 11:43 Scott James Remnant * src/: dircproxy.h, irc_net.c, irc_net.h, main.c: Moved the definition of dedicated_proxy from main to irc_net, as its a bit more suitable there. Also made it a simple boolean, not a port, because code in irc_net can check the listen_sock itself. 2000-08-23 11:39 Scott James Remnant * configure.in: Added check for crypt() function in default library and in -lcrypt too. 2000-08-23 11:38 Scott James Remnant * README: Spiffy new readme file 2000-08-23 11:38 Scott James Remnant * TODO: More stuff todo 2000-08-22 17:09 Scott James Remnant * TODO: More TODO 2000-08-22 16:37 Scott James Remnant * TODO: More stuff to do *sigh* 2000-08-22 13:08 Scott James Remnant * TODO, src/irc_client.c, src/irc_client.h, src/main.c: Put in the code to announce on attach if we're a dedicated proxy. 2000-08-22 12:55 Scott James Remnant * src/main.c: Running under inetd means we're backgrounded 2000-08-22 12:54 Scott James Remnant * RFC1459, RFC2810, RFC2811, RFC2812, RFC2813: Added the RFCs to CVS so that they are in the developer source, comes in handy for me. 2000-08-22 12:46 Scott James Remnant * src/: dircproxy.h, main.c: New "dedicated_proxy" variable. Set this to be a port number other than 0 if we're a listening daemon on a non-standard port that only has one connection class. (For those people running from inetd or under the planned "user" directive) 2000-08-21 14:54 Scott James Remnant * src/main.c: Added variable to say whether we're in the background or not 2000-08-21 14:54 Scott James Remnant * src/irc_server.c: Moved the "join hook" stuff so its activated by a 004, and not by the end of a motd. (Mainly so /motd doesn't trigger it :o) 2000-08-21 14:53 Scott James Remnant * src/irc_client.c: Passwords in the config file are now encrypted using crypt(), so use that to compare passwords. 2000-08-21 14:53 Scott James Remnant * src/: dircproxy.h, irc_prot.h: Moved the OLD_RFC1459_PARAM_SPACE definition to dircproxy.h to keep it with the rest of the config stuff. Added a new config directive which says to use encrypted passwords, so people can undef it if they want smaff to kill them. 2000-08-21 14:38 Scott James Remnant * conf/dircproxyrc: Fixed a documentation typo 2000-08-21 14:38 Scott James Remnant * TODO: updated todo file 2000-08-21 14:37 Scott James Remnant * PROTOCOL: Bit of a rewrite of this to make it nicer 2000-08-21 14:36 Scott James Remnant * NEWS: Added copyright 2000-08-21 14:34 Scott James Remnant * AUTHORS, INSTALL: Spell checked and fmt'd 2000-08-18 09:20 Scott James Remnant * .cvsignore, INSTALL: Added new custom INSTALLation documentation, instead of the default autoconf documentation. Removed INSTALL from .cvsignore so we could commit it :o) 2000-08-18 09:20 Scott James Remnant * AUTHORS: Doing a bit of a documentation re-work, so changed the AUTHORS file. 2000-08-17 16:52 Scott James Remnant * AUTHORS, AUTHORS.map: Removed Stephen as an active developer, still kept the credit for work on documentation. 2000-08-17 15:19 Scott James Remnant * conf/dircproxyrc: Realised that the listen_port config file directive has never been in the config file, despite the fact its available. Added it, so people don't have to edit dircproxy.h to change the listening port (not that they did anyway) 2000-08-17 15:03 Scott James Remnant * src/dircproxy.h: Header file documentation was a bit wrong 2000-08-16 16:12 Scott James Remnant * TODO: Amended the TODO list 2000-08-16 15:41 Scott James Remnant * src/dircproxy.h: Changed filename of system dircproxy config file to dircproxyrc from dircproxy.conf 2000-08-16 15:40 Scott James Remnant * conf/: Makefile.am, dircproxyrc: Changed the name of the default configuration file to dircproxyrc, this will be the name of the file wherever it goes (to avoid confusion) 2000-06-28 12:41 Scott James Remnant * src/irc_log.c: [ Bug #108464 ] The character replacement was replacing : with :, when it should have been replacing / with :. Oops. 2000-06-26 16:34 Scott James Remnant * configure.in: CVS version now 0.6.3 2000-06-26 16:24 Scott James Remnant * ChangeLog, NEWS: Version 0.6.2 released. 2000-06-26 16:21 Scott James Remnant * conf/Makefile.am: Adjusted these files so they reflect the way things now are. this file goes in share and isn't automatically installed. 2000-06-20 13:41 Scott James Remnant * src/main.c: Missed a space in the help text. 2000-06-20 13:40 Scott James Remnant * src/main.c: Fixed the --help which was wrong 2000-06-20 13:34 Scott James Remnant * README: Added Debian to the list too 2000-05-29 12:05 Scott James Remnant * AUTHORS, AUTHORS.map: Added Stephen Cope to the AUTHORS files, credited for documenting this thing. 2000-05-27 18:17 Scott James Remnant * README: Played with the VA compile farm, and added all the other architectures it offers to this list as its compiled on them all. 2000-05-27 18:02 Scott James Remnant * README: Added ia64 to the list of platforms, since I got access to the ones at VA. 2000-05-25 22:23 Scott James Remnant * src/main.c: Changed the logic behind the config file loading a bit. Now if one isn't explicitly specified, it'll use a ~/.dircproxyrc. If that doesn't exist it will use /etc/dircproxy.conf. This removed the need for -G. Also fixed missing options on --config-file= and --port= and made -P/--port override the config file 2000-05-25 22:20 Scott James Remnant * src/cfgfile.c: Removed fopen() error message, because we don't want to know! 2000-05-25 18:15 Scott James Remnant * src/irc_server.c: Checking the wrong parameter of a 437... doh! 2000-05-25 14:17 Scott James Remnant * configure.in: CVS version now 0.6.2 2000-05-25 14:07 Scott James Remnant * ChangeLog, NEWS: Version 0.6.1 released. 2000-05-25 14:00 Scott James Remnant * src/cfgfile.c: Heh who'd have thought an extra semi-colon could cause a nasty core dump. 2000-05-25 13:59 Scott James Remnant * src/: irc_client.c, memdebug.c: MIN() seems to be defined all over the place on different platforms. Just define it here, its not hard. 2000-05-25 13:58 Scott James Remnant * README: Added Solaris 2.7 to the platforms list seeing as I have an account on one now to test this on. 2000-05-24 22:21 Scott James Remnant * src/cfgfile.c: Argh! > didn't do what I expected here. This is one of those nasty "post release" bugs that causes the thing to core dump 2000-05-24 22:19 Scott James Remnant * README: Added FreeBSD 3.4 to this, because I have it running on that too 2000-05-24 22:04 Scott James Remnant * configure.in: CVS version now 0.6.1 2000-05-24 21:46 Scott James Remnant * ChangeLog, NEWS: Version 0.6.0 released. 2000-05-24 21:29 Scott James Remnant * src/dircproxy.h: Changed the default rejoin to 15 seconds 2000-05-24 21:29 Scott James Remnant * src/main.c: Oops, ignored the listen_port config variable 2000-05-24 21:26 Scott James Remnant * TODO: Updated the todo 2000-05-24 21:21 Scott James Remnant * src/: irc_client.c, irc_net.c, irc_net.h: Added code so that an inetd socket doesn't linger 2000-05-24 21:08 Scott James Remnant * TODO: Updated the TODO file 2000-05-24 21:06 Scott James Remnant * src/main.c: Close cleanly on a ^C 2000-05-24 21:03 Scott James Remnant * src/irc_log.c: Use 'dircproxy' as the source of notices 2000-05-24 21:02 Scott James Remnant * src/irc_client.c: I use notice to notify of nasty system things, so I might as well make it come from dircproxy itself. 2000-05-24 20:58 Scott James Remnant * src/irc_server.c: Oops, msg.cmd is a string not an integer 2000-05-24 20:58 Scott James Remnant * src/irc_client.c: Neatened the motd output 2000-05-24 20:54 Scott James Remnant * src/cfgfile.c: Fixed it so it doesn't add the server list backwards 2000-05-24 20:53 Scott James Remnant * src/irc_net.c: Fixed the bug where you are rejoined to channels in the opposite order to that which you joined them 2000-05-24 20:50 Scott James Remnant * src/irc_client.c: Fixed the output so it doesn't keep repeating itself 2000-05-24 20:48 Scott James Remnant * src/irc_net.c: Bit of a bug, forgot to increment l, so if you got kicked the last channel you joined, it kinda forgot about the rest (oops) 2000-05-24 20:48 Scott James Remnant * src/irc_log.c: Whoa, scary, I wasn't freeing any log memory - talk about memleak! sheesh! 2000-05-24 20:47 Scott James Remnant * src/memdebug.c: Copied across the neatening from maestro - specifically this adds a little bit of code to show what is stored in the memory still allocated 2000-05-24 20:31 Scott James Remnant * src/irc_server.c: Fixed a couple of typo-bugs 2000-05-24 20:30 Scott James Remnant * src/irc_log.h: Removed dead function definition 2000-05-24 20:29 Scott James Remnant * src/irc_server.c: Added code for non-recoverable JOIN errors 2000-05-24 20:25 Scott James Remnant * src/irc_server.c: Removed the auto-rejoin code (its in irc_net.c now) Made a special case for the 437 numeric, because it can be either nickname or channel related. Added code so that while a client is detached, we attempt to rejoin channels if its full/invite only/banned/juped Also on join, we can reactive a channel, and then spool the log back to the client (in case of kick). 2000-05-24 20:22 Scott James Remnant * src/irc_client.c: Make log directory on successful first auth now - much better place to do it. Also make the misclog when we loose the client. Added code to spool stats about sizes of log files and channels user was on in the message of the day 2000-05-24 20:20 Scott James Remnant * src/irc_net.c: Moved the code to rejoin channels automatically to here. Moved the misclog code about, this log only gets created when the user disconnects now and then is removed when they connect. 2000-05-24 20:18 Scott James Remnant * src/irc_net.h: New 'inactive' variable for channels. This is set to 1 when we are removed from the channel while a client isn't connected. All the time this is one we attempt to rejoin the channel every few seconds until the join is successfull or the client comes back. 2000-05-24 20:17 Scott James Remnant * src/irc_log.c: When closing a log, make sure we set 'open' to 0 2000-05-24 19:11 Scott James Remnant * src/sprintf.c: Need to have some memory allocated to avoid buffer underruns, also need to null terminate after strncpy() 2000-05-24 19:05 Scott James Remnant * src/sprintf.c: Fixed a few bugs 2000-05-24 19:02 Scott James Remnant * src/sprintf.c: Added in an (almost) complete implementation of vsprintf() 2000-05-24 19:01 Scott James Remnant * configure.in: When in debug mode, don't even detect vsnprintf(), use our own implementation of vsprintf() 2000-05-24 18:30 Scott James Remnant * configure.in: [ Bug #106153 ] compiler error, partial make fix Added check to see whether socket() is in -lsocket and whether gethostbyname() is in -lnsl 2000-05-24 18:18 Scott James Remnant * README: There is a config file now :o) 2000-05-24 18:09 Scott James Remnant * TODO: Updated the TODO file with whats left to do 2000-05-24 18:05 Scott James Remnant * src/: irc_client.c, irc_log.c, irc_prot.c, irc_server.c, timers.c: Removed a lot of the printf() debug code, that which I still want to see I've placed inside #ifdef DEBUG stuff 2000-05-24 17:57 Scott James Remnant * src/: irc_client.c, irc_net.h, irc_server.c: Took out all the hacky defines and replaced them with the nice sexy config file variables 2000-05-24 17:52 Scott James Remnant * src/: irc_net.c, irc_net.h: Added new function to clean up a connection class structure, and made expunge clean them up too 2000-05-24 17:45 Scott James Remnant * src/main.c: Whoohoo, lets read some config file baby! 2000-05-24 17:42 Scott James Remnant * src/main.c: Changed the command line options a bit, especially added checks whether to use the global config file or not, and alternate local config file. I've decided not to do all the -p/-s stuff because it'll show up in a 'ps' list which isn't a good idea! 2000-05-24 17:39 Scott James Remnant * src/: dircproxy.h, main.c: Added the global variables and initialise them to the values in dircproxy.h Removed those horrid TODO_CFG things finally 2000-05-24 17:34 Scott James Remnant * src/main.c: Using an ALARM single to stop the main loop was pretty pointless, might as well just use the TERM signal which will let dircproxy clean itself up if its 'kill'd 2000-05-24 17:31 Scott James Remnant * src/dircproxy.h: Fixed a mistake in the comments 2000-05-24 17:30 Scott James Remnant * src/: Makefile.am, dircproxy.h: Added some defines to set the name and locations of the configuration files 2000-05-24 17:28 Scott James Remnant * src/Makefile.am: Added the new cfgfile.c and .h files to the Makefile 2000-05-24 17:23 Scott James Remnant * configure.in: Changing CVS version to 0.6.0 seeing as thats the version I said the config file code would be in 2000-05-24 17:22 Scott James Remnant * Makefile.am, configure.in: Added the new conf directory to Makefile.am and configure.in 2000-05-24 17:18 Scott James Remnant * src/: cfgfile.c, cfgfile.h: Wrote the code to read in a configuration file 2000-05-24 17:16 Scott James Remnant * conf/: .cvsignore, Makefile.am: Written the default configuration files, and everything. So adding them to CVS :o) 2000-05-24 12:38 Scott James Remnant * TODO: More stuff todo, gonna work on a lot of this today 2000-05-14 20:56 Scott James Remnant * TODO: Updated the TODO file based on user-feedback and my own grudges 2000-05-14 20:55 Scott James Remnant * README: Added a quick meme that there is no config file at the moment ... Also fixed the bugs url so its not https 2000-05-13 17:05 Scott James Remnant * AUTHORS.map, RELEASING: Added a file detailing the steps to do a new release, to make sure I do it right. Also added the AUTHORS.map file cvs2cl.pl uses. 2000-05-13 16:20 Scott James Remnant * configure.in: CVS version becomes 0.5.5 (although potentially might be 0.6 if no more bugs appear and I can work on the config file). 2000-05-13 16:14 Scott James Remnant * ChangeLog, configure.in: Version 0.5.4 released. 2000-05-13 16:11 Scott James Remnant * src/main.c: Logic on the -D option was wrong, should set no_daemon to 1. 2000-05-13 16:05 Scott James Remnant * src/match.c: Requires sprintf.c because it uses strdup() 2000-05-13 16:04 Scott James Remnant * configure.in, src/sprintf.c: If --enable-debug is set, we actually don't want to check for strdup(), that way we are only checking for vsnprintf() and the code at the top of sprintf.c isn't required. (This gets rid of all those pesky "Free of illegal block" messages). 2000-05-13 15:47 Scott James Remnant * ChangeLog, NEWS, TODO: Version 0.5.3 released. 2000-05-13 05:25 Scott James Remnant * configure.in, src/dns.c, src/irc_client.c, src/irc_log.c, src/irc_net.c, src/irc_prot.c, src/irc_server.c, src/irc_string.c, src/match.c, src/sprintf.c, src/sprintf.h, src/timers.c: Using strdup() isn't entirely portably apparently, and also it pisses off memdebug.c something chronic. Check for it in configure.in, and use it as x_strdup() everwhere. If it does exist, x_strdup() is just a wrapper for strdup(), if it doesn't exist, or DEBUG_MEMORY is defined, then it does its own malloc/strcpy. 2000-05-13 05:12 Scott James Remnant * src/: dircproxy.h, irc_client.c, irc_prot.c, irc_server.c, main.c: Made some of the TODO_CFG macros into the proper macros they will be as the defaults for the config file. Gave them documentation too. Also added two FALLBACK defines for those things not in the config file that I/users might want to change 2000-05-13 04:43 Scott James Remnant * src/.cvsignore: Added the name of the executable to the ignore file 2000-05-13 04:43 Scott James Remnant * src/irc_log.c: fchmod() doesn't take a FILE *, grrr. Changed to just chmod() the filename, seeing as we have that anyway 2000-05-13 04:41 Scott James Remnant * src/: dns.c, irc_client.c, irc_log.c, irc_net.c, irc_prot.c, irc_server.c, irc_string.c, match.c, timers.c: Decided to embrace the fruit that is strdup() and in the process cleaned up a lot of code (yay!) 2000-05-13 04:23 Scott James Remnant * src/irc_log.c: Heh, anyone on the machine could not only see what channels you were on, not only read everything on those channels, they could also read your private messages. This isn't good. Made the dir be created 0700 and files 0600 now. 2000-05-13 04:17 Scott James Remnant * src/irc_client.c: Set bind to 0 after strdup(), heh 2000-05-13 04:13 Scott James Remnant * src/irc_client.c: Fixed a missing bracket problem that crept in and prevented compilation... doh! damned "TODO" code 2000-05-13 02:38 Scott James Remnant * src/dircproxy.h: PACKAGE and VERSION will always be defined in config.h unless something has really gone wrong, and that'll need fixing anyway. Define them in the elsif to save code and make things look neeter. 2000-05-13 02:34 Scott James Remnant * README, src/main.c: Changed the homepage and bug reporting locations now we're all fully sourceforge'd up 2000-05-13 02:28 Scott James Remnant * configure.in: CVS version is 0.5.3 2000-05-13 02:23 Scott James Remnant * .cvsignore, src/.cvsignore: Removed the FILES.autoconf file, and replaced it with a .cvsignore in each directory. This means that 'cvs update' etc will ignore any files generated by auto{conf,make}. This is a good-thing. Means you can run autogen.sh on your checked out version without it getting in the way of CVS. 2000-05-13 02:13 Scott James Remnant * autogen.sh: Imported version 0.5.2 into the CVS tree. Its in a CLEAN state that requires autoconf and automake (run autogen.sh) to build. 2000-05-13 02:13 Scott James Remnant * AUTHORS, ChangeLog, Makefile.am, NEWS, PROTOCOL, README, TODO, acconfig.h, README.inetd, configure.in, src/Makefile.am, src/dircproxy.h, src/dns.c, src/dns.h, src/irc_prot.c, src/main.c, src/match.c, src/match.h, src/sprintf.c, src/sprintf.h, src/irc_string.c, src/stringex.h, src/irc_net.c, src/memdebug.h, src/irc_prot.h, src/irc_string.h, src/stringex.c, src/irc_log.c, src/irc_log.h, src/irc_net.h, src/irc_client.c, src/irc_client.h, src/irc_server.h, src/memdebug.c, src/irc_server.c, src/timers.c, src/timers.h: Initial revision dircproxy-1.0.5/INSTALL0000664000175000017500000001363607537110440010266 Installing and Configuring dircproxy ------------------------------------ dircproxy is designed to run on any modern UNIX system, and should require little or no modification to work on yours. The only requisite it has is a modern libc with TCP/IP networking code. I have seen or heard about it running on the following types of system: Linux 2.x+ on i386 (Debian, RedHat, Slackware, etc) Linux 2.4+ on ia64 (TurboLinux) Solaris 2.5.1, 2.6, 7, 8, 9 FreeBSD 3.x, 4.x+ AIX 4.3.3 NetBSD on a MicroVAX 3100 (yes, really!) Windows NT (with cygwin compiler) Mac OS X on G3 (you may need to configure with --host=darwin) If (and you should) get it to work on any other type of system, please e-mail me so I can it to this list. Compiling dircproxy =================== Installing dircproxy is fairly easy, and this overview will get it up and running for you in no time. You'll need to unpack the distribution file 'dircproxy-X.X.X.tar.gz' (where X.X.X is the version number you have downloaded) somewhere on your machine, if you don't know where to do it, your home directory is a good bet. (You've probably already done this to read this file anyway!) $ gunzip -c dircproxy-X.X.X.tar.gz | tar xf - This will place the source code for dircproxy in a directory called 'dircproxy-X.X.X'. To compile the program, you should be in this directory, so change to it now (again you've probably already done this). $ cd dircproxy-X.X.X You're now ready to begin. dircproxy uses the GNU standard 'configure' program to examine your system and find where required libraries and header files are. Most of the time this needs little or no interaction to get it to work. You should be able to get away with the following command: $ ./configure If it terminates with an error (it hopefully won't!) you should be able to use its output to discover what it needs, and fix the problem. By default, dircproxy is installed under the '/usr/local' hierarchy, if you wish to install it somewhere else you can pass the '--prefix' option to the 'configure' script. If you only wish to run it from your home directory, don't worry about this bit, it'll work for you with the default option. 'configure' accepts lots of other options, for more information run it with the --help option, or see "Configuring the Compilation" below. If you want to tinker with some of the more advanced configuration options of dircproxy, you can edit the src/dircproxy.h file at this point. This is not recommended unless you are an expert and wish to change something specific. You can now build the dircproxy binary, this is accomplished by the following command: $ make The dircproxy binary should now be in the src directory. If you only want to run it from your home directory, copy it somewhere sensible and skip down to "Configuring dircproxy" below. Otherwise, if you want to install dircproxy so it is available for anyone on the machine to use, then you will need to install it. You will most-likely need to switch to the 'root' user, either by using your system's 'su' command, or by logging in as 'root' onto another terminal. Once you are 'root', go to the dircproxy source directory (if necessary) and issue the following command: # make install The default binaries have debugging symbols left in them as this tends to be more useful than not. If you're tight on disk-space, you can install 'stripped' versions of the binaries without these debugging symbols by using the following command instead: # make install-strip Configuring dircproxy ===================== dircproxy requires a configuration file in order to run. This configuration file includes information on who can use the proxy and other options such as log file locations etc. An example file is in the 'conf' directory of the source code, and is called 'dircproxyrc'. If you installed using 'make install', then it will also be available for you and other users in the '/usr/local/share/dircproxy' directory. This file contains documentation on each of the configuration options. It is recommended that to create your configuration file, you copy the example and edit it, rather than simply writing your own from scratch. Exactly where you copy it depends on how you wish to run dircproxy. If you are going to be running it as a daemon on your system, for many people to use simultaneously, then '/usr/local/etc/dircproxyrc' is the recommended location. If you want to run it under your own user account, then '~/.dircproxyrc' is the best location. dircproxy automatically looks at these two locations for the config file, if you don't like either of them, then place the configuration file wherever you want and tell dircproxy using the '-f' command-line parameter, for example: $ dircproxy -f ./dircproxyrc Configuring the Compilation =========================== If have problems compiling dircproxy, or wish to customise the compilation, then you can pass various options to the 'configure' script to hopefully do you want you want. There are a large number of possible arguments, and only the more useful ones are documented here. '--help' Print a summary of all the options available. '--prefix=DIR' This is the root directory dircproxy is installed under when you do a 'make install'. The default is '/usr/local'. '--enable-debug' Enables the dircproxy debug mode, only useful if you want to help fix a bug you've found. Not recommended for normal use. If compilation fails for any reason, you can pass shell variables to the 'configure' script to tell it about your system. A complete list of these variables can be found in the 'autoconf' documentation if you have it. You can do that on the command-line in a sh-like shell (such as bash) like this: $ CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure Or on systems that have the 'env' program, you can do it like this: env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure Copyright (C) 2002 Scott James Remnant . All Rights Reserved. dircproxy-1.0.5/Makefile.am0000664000175000017500000000030007203006105011241 ## Process this file with automake to produce Makefile.in EXTRA_DIST = \ FAQ \ PROTOCOL \ README.inetd \ README.dcc-via-ssh SUBDIRS = \ conf \ contrib \ getopt \ crypt \ doc \ src dircproxy-1.0.5/NEWS0000644000175000017500000001166407567165352007750 NEWS about changes for existing users. -------------------------------------- Version 1.0.5 - Thu Nov 21 14:15:00 GMT 2002 * Default value of 'refuse_modes' config directive changed from "+r" to "". Version 1.0.4 - Mon Sep 9 13:45:00 BST 2002 * Just bug fixes. No changes to worry about. Version 1.0.3 - Fri Feb 8 17:45:00 GMT 2002 * New 'pid_file', 'allow_users' and 'allow_kill' config directives. * New -p command line parameter (adjusts pid_file). * Included contrib scripts, cronchk.sh and privmsg-log.pl Version 1.0.2 - Tue Jan 1 18:15:00 GMT 2001 * New 'server_keepalive' config directive. Version 1.0.1 - Wed Jul 12 17:00:00 BST 2001 * Just bug fixes. No changes to worry about. Version 1.0.0 - Thu Jan 11 15:20:00 GMT 2001 * Just bug fixes. No changes to worry about. Version 0.99.0 - Tue Dec 26 17:55:00 GMT 2000 * New 'nick_keep' config directive. The nickname code has been reworked to accomodate this, as such if the connecting client has a different nickname to dircproxy, the connecting client is now corrected (not dircproxy, as it used to be). * New 'ctcp_replies' config directive. Version 0.8.4 - Thu Dec 7 17:35:00 GMT 2000 * New 'initial_modes' config directive. Version 0.8.3 - Thu Nov 24 13:45:00 GMT 2000 * Just bug fixes. No changes to worry about. Version 0.8.2 - Thu Nov 23 12:30:00 GMT 2000 * Just bug fixes. No changes to worry about. Version 0.8.1 - Wed Nov 15 16:25:00 GMT 2000 * Just bug fixes. No changes to worry about. Version 0.8.0 - Fri Nov 10 15:20:00 GMT 2000 * 'chan_log_dir' and 'other_log_dir' have been removed because they cause usage and security problems. These have been replaced with 'chan_log_copydir' and 'other_log_copydir' which have a slightly different purpose. * The log file format on disk has changed slightly to allow for the new 'relative timestamping'. * DCC chat's and send's are now proxied by default through dircproxy. * Removed config file options: server_dnsretry * New config file options: client_timeout connect_timeout dns_timeout server_throttle server_autoconnect channel_leave_on_detach channel_rejoin_on_attach idle_maxtime refuse_modes quit_message attach_message detach_message chan_log_enabled chan_log_relativetime chan_log_program other_log_enabled other_log_relativetime other_log_program log_timeoffset log_events dcc_proxy_incoming dcc_proxy_outgoing dcc_proxy_ports dcc_proxy_timeout dcc_proxy_sendreject dcc_send_fast dcc_capture_directory dcc_capture_always dcc_capture_withnick dcc_capture_maxsize dcc_tunnel_incoming dcc_tunnel_outgoing switch_user motd_file allow_persist allow_jump allow_jump_new allow_host allow_die Version 0.7.3 - Wed Sep 27 17:55:00 BST 2000 * New config file option - "disconnect_on_detach" Version 0.7.2 - Mon Sep 25 13:13:00 BST 2000 * If you use a .dircproxyrc in your home directory, this must now have no more then 0700 permissions. If this is not the case then dircproxy will not start. This does not apply to the global config file or any supplied with the -f parameter. Version 0.7.1 - Thu Sep 14 13:15:00 BST 2000 * Just bug fixes. No changes to worry about. Version 0.7.0 - Fri Sep 1 15:00:00 BST 2000 * The global configuration file is now called dircproxyrc not dircproxy.conf * dircproxy is now installed in 'bin' not 'sbin', its a user program after all. * Passwords for connection classes must be encrypted in the configuration file using the crypt() function (or contrib/crypt), if you don't like this then edit src/dircproxy.h and turn it off, but thats silly. * /DQUIT is gone, try /DIRCPROXY QUIT instead * Try /DIRCPROXY HELP * Try "man dircproxy" :-) Version 0.6.2 - Mon Jun 26 16:58:00 BST 2000 * Changed the logic behind how configuration files are loaded. If you supply one with -f, that is loaded. If you don't it first tries ~/.dircproxyrc and then tries etc/dircproxy.conf. This means that the config file is no longer installed, and can be found as dircproxy.conf in share/dircproxy or the conf dir of the source. Also the -G option is no longer valid. Version 0.6.1 - Thu May 25 15:04:00 BST 2000 * Just bug fixes. No changes to worry about. Version 0.6.0 - Wed May 24 22:33:00 BST 2000 * There is now a configuration file. Copy the dircproxyrc.example from the conf directory to your home directory and call it .dircproxyrc - this file contains all the documentation for configuring dircproxy. Version 0.5.3 - Sat May 13 16:32:00 BST 2000 * Many of the TODO_CFG_* options defined in dircproxy.h have now been given documentation and renamed. You'll need to recheck this file if you've changed them. The PASS/SERVER/BIND ones are still at the bottom and still the same however. Version 0.5.2 - Fri May 12 23:00:00 BST 2000 * Initial public release Copyright (C) 2002 Scott James Remnant . All Rights Reserved. dircproxy-1.0.5/acconfig.h0000664000175000017500000000032407204532561011150 /* General name of the package */ #undef PACKAGE /* Version number of the package */ #undef VERSION /* Do we debug stuff */ #undef DEBUG /* Turn on expensive (but cool) memory debugging */ #undef DEBUG_MEMORY dircproxy-1.0.5/aclocal.m40000644000175000017500000002277607567164506011117 dnl aclocal.m4 generated automatically by aclocal 1.4-p6 dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl This program is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A dnl PARTICULAR PURPOSE. # Do all the work for Automake. This macro actually does too much -- # some checks are only needed if your package does certain things. # But this isn't really a big deal. # serial 1 dnl Usage: dnl AM_INIT_AUTOMAKE(package,version, [no-define]) AC_DEFUN([AM_INIT_AUTOMAKE], [AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL]) PACKAGE=[$1] AC_SUBST(PACKAGE) VERSION=[$2] AC_SUBST(VERSION) dnl test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi ifelse([$3],, AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) AC_REQUIRE([AM_SANITY_CHECK]) AC_REQUIRE([AC_ARG_PROGRAM]) dnl FIXME This is truly gross. missing_dir=`cd $ac_aux_dir && pwd` AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}, $missing_dir) AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}, $missing_dir) AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) AC_REQUIRE([AC_PROG_MAKE_SET])]) # 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.4"]) # 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.4-p6])]) # # Check to make sure that the build environment is sane. # AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftestfile # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` if test "[$]*" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftestfile` fi if test "[$]*" != "X $srcdir/configure conftestfile" \ && test "[$]*" != "X conftestfile $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "[$]2" = conftestfile ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi rm -f conftest* AC_MSG_RESULT(yes)]) dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) dnl The program must properly implement --version. AC_DEFUN([AM_MISSING_PROG], [AC_MSG_CHECKING(for working $2) # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if ($2 --version) < /dev/null > /dev/null 2>&1; then $1=$2 AC_MSG_RESULT(found) else $1="$3/missing $2" AC_MSG_RESULT(missing) fi AC_SUBST($1)]) # Like AC_CONFIG_HEADER, but automatically create stamp file. AC_DEFUN([AM_CONFIG_HEADER], [AC_PREREQ([2.12]) AC_CONFIG_HEADER([$1]) dnl When config.status generates a header, we must update the stamp-h file. dnl This file resides in the same directory as the config header dnl that is generated. We must strip everything past the first ":", dnl and everything past the last "/". AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>, <>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>, <>; do case " <<$>>CONFIG_HEADERS " in *" <<$>>am_file "*<<)>> echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx ;; esac am_indx=`expr "<<$>>am_indx" + 1` done<<>>dnl>>) changequote([,]))]) # Add --enable-maintainer-mode option to configure. # From Jim Meyering # serial 1 AC_DEFUN([AM_MAINTAINER_MODE], [AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) dnl maintainer-mode is disabled by default AC_ARG_ENABLE(maintainer-mode, [ --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer], USE_MAINTAINER_MODE=$enableval, USE_MAINTAINER_MODE=no) AC_MSG_RESULT($USE_MAINTAINER_MODE) AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes) MAINT=$MAINTAINER_MODE_TRUE AC_SUBST(MAINT)dnl ] ) # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_SUBST($1_TRUE) AC_SUBST($1_FALSE) if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi]) #serial 1 # This test replaces the one in autoconf. # Currently this macro should have the same name as the autoconf macro # because gettext's gettext.m4 (distributed in the automake package) # still uses it. Otherwise, the use in gettext.m4 makes autoheader # give these diagnostics: # configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX # configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX undefine([AC_ISC_POSIX]) AC_DEFUN([AC_ISC_POSIX], [ dnl This test replaces the obsolescent AC_ISC_POSIX kludge. AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"]) ] ) # serial 1 # @defmac AC_PROG_CC_STDC # @maindex PROG_CC_STDC # @ovindex CC # If the C compiler in not in ANSI C mode by default, try to add an option # to output variable @code{CC} to make it so. This macro tries various # options that select ANSI C on some system or another. It considers the # compiler to be in ANSI C mode if it handles function prototypes correctly. # # If you use this macro, you should check after calling it whether the C # compiler has been set to accept ANSI C; if not, the shell variable # @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source # code in ANSI C, you can make an un-ANSIfied copy of it by using the # program @code{ansi2knr}, which comes with Ghostscript. # @end defmac AC_DEFUN([AM_PROG_CC_STDC], [AC_REQUIRE([AC_PROG_CC]) AC_BEFORE([$0], [AC_C_INLINE]) AC_BEFORE([$0], [AC_C_CONST]) dnl Force this before AC_PROG_CPP. Some cpp's, eg on HPUX, require dnl a magic option to avoid problems with ANSI preprocessor commands dnl like #elif. dnl FIXME: can't do this because then AC_AIX won't work due to a dnl circular dependency. dnl AC_BEFORE([$0], [AC_PROG_CPP]) AC_MSG_CHECKING(for ${CC-cc} option to accept ANSI C) AC_CACHE_VAL(am_cv_prog_cc_stdc, [am_cv_prog_cc_stdc=no ac_save_CC="$CC" # 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 -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" AC_TRY_COMPILE( [#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; ], [ return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ], [am_cv_prog_cc_stdc="$ac_arg"; break]) done CC="$ac_save_CC" ]) if test -z "$am_cv_prog_cc_stdc"; then AC_MSG_RESULT([none needed]) else AC_MSG_RESULT($am_cv_prog_cc_stdc) fi case "x$am_cv_prog_cc_stdc" in x|xno) ;; *) CC="$CC $am_cv_prog_cc_stdc" ;; esac ]) dircproxy-1.0.5/config.guess0000755000175000017500000011576307567164507011577 #! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002 Free Software Foundation, Inc. timestamp='2002-09-03' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner . # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit 0 ;; --version | -v ) echo "$version" ; exit 0 ;; --help | --h* | -h ) echo "$usage"; exit 0 ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # This shell variable is my proudest work .. or something. --bje set_cc_for_build='tmpdir=${TMPDIR-/tmp}/config-guess-$$ ; (old=`umask` && umask 077 && mkdir $tmpdir && umask $old && unset old) || (echo "$me: cannot create $tmpdir" >&2 && exit 1) ; dummy=$tmpdir/dummy ; files="$dummy.c $dummy.o $dummy.rel $dummy" ; trap '"'"'rm -f $files; rmdir $tmpdir; exit 1'"'"' 1 2 15 ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; rm -f $files ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; unset files' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit 0 ;; amiga:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; arc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; hp300:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mac68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; macppc:OpenBSD:*:*) echo powerpc-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme88k:OpenBSD:*:*) echo m88k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvmeppc:OpenBSD:*:*) echo powerpc-unknown-openbsd${UNAME_RELEASE} exit 0 ;; pmax:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sgi:OpenBSD:*:*) echo mipseb-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sun3:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; wgrisc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; *:OpenBSD:*:*) echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} exit 0 ;; alpha:OSF1:*:*) if test $UNAME_RELEASE = "V4.0"; then UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` fi # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. eval $set_cc_for_build cat <$dummy.s .data \$Lformat: .byte 37,100,45,37,120,10,0 # "%d-%x\n" .text .globl main .align 4 .ent main main: .frame \$30,16,\$26,0 ldgp \$29,0(\$27) .prologue 1 .long 0x47e03d80 # implver \$0 lda \$2,-1 .long 0x47e20c21 # amask \$2,\$1 lda \$16,\$Lformat mov \$0,\$17 not \$1,\$18 jsr \$26,printf ldgp \$29,0(\$26) mov 0,\$16 jsr \$26,exit .end main EOF $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null if test "$?" = 0 ; then case `$dummy` in 0-0) UNAME_MACHINE="alpha" ;; 1-0) UNAME_MACHINE="alphaev5" ;; 1-1) UNAME_MACHINE="alphaev56" ;; 1-101) UNAME_MACHINE="alphapca56" ;; 2-303) UNAME_MACHINE="alphaev6" ;; 2-307) UNAME_MACHINE="alphaev67" ;; 2-1307) UNAME_MACHINE="alphaev68" ;; 3-1307) UNAME_MACHINE="alphaev7" ;; esac fi rm -f $dummy.s $dummy && rmdir $tmpdir echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit 0 ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit 0 ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit 0 ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit 0;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit 0 ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit 0 ;; *:OS/390:*:*) echo i370-ibm-openedition exit 0 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit 0;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit 0;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit 0 ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit 0 ;; DRS?6000:UNIX_SV:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7 && exit 0 ;; esac ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit 0 ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit 0 ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit 0 ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit 0 ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit 0 ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit 0 ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit 0 ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit 0 ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit 0 ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit 0 ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit 0 ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit 0 ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD $dummy.c -o $dummy \ && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 rm -f $dummy.c $dummy && rmdir $tmpdir echo mips-mips-riscos${UNAME_RELEASE} exit 0 ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit 0 ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit 0 ;; Night_Hawk:*:*:PowerMAX_OS) echo powerpc-harris-powermax exit 0 ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit 0 ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit 0 ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit 0 ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit 0 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit 0 ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit 0 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit 0 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit 0 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit 0 ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit 0 ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit 0 ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit 0 ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF $CC_FOR_BUILD $dummy.c -o $dummy && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 rm -f $dummy.c $dummy && rmdir $tmpdir echo rs6000-ibm-aix3.2.5 elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit 0 ;; *:AIX:*:[45]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit 0 ;; *:AIX:*:*) echo rs6000-ibm-aix exit 0 ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit 0 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit 0 ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit 0 ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit 0 ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit 0 ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit 0 ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`$dummy` if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi rm -f $dummy.c $dummy && rmdir $tmpdir fi ;; esac echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit 0 ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit 0 ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD $dummy.c -o $dummy && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 rm -f $dummy.c $dummy && rmdir $tmpdir echo unknown-hitachi-hiuxwe2 exit 0 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit 0 ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit 0 ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit 0 ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit 0 ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit 0 ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit 0 ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit 0 ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit 0 ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit 0 ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit 0 ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit 0 ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*T3D:*:*:*) echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit 0 ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit 0 ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:FreeBSD:*:*) # Determine whether the default compiler uses glibc. eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #if __GLIBC__ >= 2 LIBC=gnu #else LIBC= #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` rm -f $dummy.c && rmdir $tmpdir echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} exit 0 ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit 0 ;; i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit 0 ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit 0 ;; x86:Interix*:3*) echo i386-pc-interix3 exit 0 ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i386-pc-interix exit 0 ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit 0 ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit 0 ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; *:GNU:*:*) echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit 0 ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit 0 ;; arm*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; mips:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips #undef mipsel #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mipsel #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` rm -f $dummy.c && rmdir $tmpdir test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0 ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit 0 ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit 0 ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit 0 ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit 0 ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit 0 ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit 0 ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit 0 ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; a.out-i386-linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" exit 0 ;; coff-i386) echo "${UNAME_MACHINE}-pc-linux-gnucoff" exit 0 ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. echo "${UNAME_MACHINE}-pc-linux-gnuoldld" exit 0 ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #ifdef __INTEL_COMPILER LIBC=gnu #else LIBC=gnuaout #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` rm -f $dummy.c && rmdir $tmpdir test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit 0 ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit 0 ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit 0 ;; i*86:*:5:[78]*) case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit 0 ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit 0 ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit 0 ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit 0 ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit 0 ;; paragon:*:*:*) echo i860-intel-osf1 exit 0 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit 0 ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit 0 ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit 0 ;; M68*:*:R3V[567]*:*) test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4.3${OS_REL} && exit 0 /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4 && exit 0 ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit 0 ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit 0 ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit 0 ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit 0 ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit 0 ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit 0 ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit 0 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit 0 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit 0 ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit 0 ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit 0 ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit 0 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit 0 ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit 0 ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit 0 ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit 0 ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit 0 ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit 0 ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit 0 ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Darwin:*:*) echo `uname -p`-apple-darwin${UNAME_RELEASE} exit 0 ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit 0 ;; *:QNX:*:4*) echo i386-pc-qnx exit 0 ;; NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit 0 ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit 0 ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit 0 ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit 0 ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit 0 ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit 0 ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit 0 ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit 0 ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit 0 ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit 0 ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit 0 ;; *:ITS:*:*) echo pdp10-unknown-its exit 0 ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit 0 ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit 0 ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 rm -f $dummy.c $dummy && rmdir $tmpdir # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit 0 ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; c34*) echo c34-convex-bsd exit 0 ;; c38*) echo c38-convex-bsd exit 0 ;; c4*) echo c4-convex-bsd exit 0 ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: dircproxy-1.0.5/config.h.in0000644000175000017500000000656707567164507011303 /* config.h.in. Generated automatically from configure.in by autoheader 2.13. */ /* Define if using alloca.c. */ #undef C_ALLOCA /* Define to empty if the keyword does not work. */ #undef const /* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. This function is required for alloca.c support on those systems. */ #undef CRAY_STACKSEG_END /* Define to `int' if doesn't define. */ #undef gid_t /* Define if you have alloca, as a function or macro. */ #undef HAVE_ALLOCA /* Define if you have and it should be used (not on Ultrix). */ #undef HAVE_ALLOCA_H /* Define if you have the strftime function. */ #undef HAVE_STRFTIME /* Define to `int' if doesn't define. */ #undef pid_t /* Define as the return type of signal handlers (int or void). */ #undef RETSIGTYPE /* Define to `unsigned' if doesn't define. */ #undef size_t /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #undef STACK_DIRECTION /* Define if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* Define to `int' if doesn't define. */ #undef uid_t /* Do we debug stuff */ #undef DEBUG /* Turn on expensive (but cool) memory debugging */ #undef DEBUG_MEMORY /* Define if you have the mkdir function. */ #undef HAVE_MKDIR /* Define if you have the poll function. */ #undef HAVE_POLL /* Define if you have the rmdir function. */ #undef HAVE_RMDIR /* Define if you have the select function. */ #undef HAVE_SELECT /* Define if you have the seteuid function. */ #undef HAVE_SETEUID /* Define if you have the strcspn function. */ #undef HAVE_STRCSPN /* Define if you have the strdup function. */ #undef HAVE_STRDUP /* Define if you have the strerror function. */ #undef HAVE_STRERROR /* Define if you have the strspn function. */ #undef HAVE_STRSPN /* Define if you have the strstr function. */ #undef HAVE_STRSTR /* Define if you have the strtoul function. */ #undef HAVE_STRTOUL /* Define if you have the vasprintf function. */ #undef HAVE_VASPRINTF /* Define if you have the vsnprintf function. */ #undef HAVE_VSNPRINTF /* Define if you have the header file. */ #undef HAVE_CRYPT_H /* Define if you have the header file. */ #undef HAVE_FCNTL_H /* Define if you have the header file. */ #undef HAVE_INTTYPES_H /* Define if you have the header file. */ #undef HAVE_POLL_H /* Define if you have the header file. */ #undef HAVE_SYS_POLL_H /* Define if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define if you have the header file. */ #undef HAVE_SYSLOG_H /* Define if you have the header file. */ #undef HAVE_UNISTD_H /* Define if you have the crypt library (-lcrypt). */ #undef HAVE_LIBCRYPT /* Define if you have the nsl library (-lnsl). */ #undef HAVE_LIBNSL /* Define if you have the socket library (-lsocket). */ #undef HAVE_LIBSOCKET /* Name of package */ #undef PACKAGE /* Version number of package */ #undef VERSION dircproxy-1.0.5/config.sub0000755000175000017500000007167407567164507011244 #! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002 Free Software Foundation, Inc. timestamp='2002-09-05' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit 0 ;; --version | -v ) echo "$version" ; exit 0 ;; --help | --h* | -h ) echo "$usage"; exit 0 ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit 0;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | freebsd*-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ | clipper \ | d10v | d30v | dlx | dsp16xx \ | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k \ | m32r | m68000 | m68k | m88k | mcore \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64vr | mips64vrel \ | mips64orion | mips64orionel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mipsisa32 | mipsisa32el \ | mipsisa64 | mipsisa64el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | ns16k | ns32k \ | openrisc | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ | strongarm \ | tahoe | thumb | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xscale | xstormy16 | xtensa \ | z8k) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* \ | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* \ | clipper-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* \ | m32r-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | mcore-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64vr-* | mips64vrel-* \ | mips64orion-* | mips64orionel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39 | mipstx39el \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* | tic30-* | tic4x-* | tic54x-* | tic80-* | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ | xtensa-* \ | ymp-* \ | z8k-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; c90) basic_machine=c90-cray os=-unicos ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; crds | unos) basic_machine=m68k-crds ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; mmix*) basic_machine=mmix-knuth os=-mmixware ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; or32 | or32-*) basic_machine=or32-unknown os=-coff ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2) basic_machine=i686-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3d) basic_machine=alpha-cray os=-unicos ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic4x | c4x*) basic_machine=tic4x-unknown os=-coff ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; windows32) basic_machine=i386-pc os=-windows32-msvcrt ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele) basic_machine=sh-unknown ;; sh64) basic_machine=sh64-unknown ;; sparc | sparcv9 | sparcv9b) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* | -powermax*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto*) os=-nto-qnx ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-ibm) os=-aix ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -ptx*) vendor=sequent ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: dircproxy-1.0.5/configure0000755000175000017500000030271007567164510011146 #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.13 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer" ac_help="$ac_help --enable-debug turn on debugging [default=no]" ac_help="$ac_help --disable-poll disable use of the poll() function [default=no]" ac_help="$ac_help --disable-select disable use of the select() function [default=no]" # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. build=NONE cache_file=./config.cache exec_prefix=NONE host=NONE no_create= nonopt=NONE no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= target=NONE verbose= x_includes=NONE x_libraries=NONE bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi case "$ac_option" in -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) ac_optarg= ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case "$ac_option" in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir="$ac_optarg" ;; -build | --build | --buil | --bui | --bu) ac_prev=build ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build="$ac_optarg" ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file="$ac_optarg" ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir="$ac_optarg" ;; -disable-* | --disable-*) ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` eval "enable_${ac_feature}=no" ;; -enable-* | --enable-*) ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "enable_${ac_feature}='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix="$ac_optarg" ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he) # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat << EOF Usage: configure [options] [host] Options: [defaults in brackets after descriptions] Configuration: --cache-file=FILE cache test results in FILE --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [same as prefix] --bindir=DIR user executables in DIR [EPREFIX/bin] --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] --libexecdir=DIR program executables in DIR [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data in DIR [PREFIX/share] --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com] --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] --libdir=DIR object code libraries in DIR [EPREFIX/lib] --includedir=DIR C header files in DIR [PREFIX/include] --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] --infodir=DIR info documentation in DIR [PREFIX/info] --mandir=DIR man documentation in DIR [PREFIX/man] --srcdir=DIR find the sources in DIR [configure dir or ..] --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names EOF cat << EOF Host type: --build=BUILD configure for building on BUILD [BUILD=HOST] --host=HOST configure for HOST [guessed] --target=TARGET configure for TARGET [TARGET=HOST] Features and packages: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR EOF if test -n "$ac_help"; then echo "--enable and --with options recognized:$ac_help" fi exit 0 ;; -host | --host | --hos | --ho) ac_prev=host ;; -host=* | --host=* | --hos=* | --ho=*) host="$ac_optarg" ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir="$ac_optarg" ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir="$ac_optarg" ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir="$ac_optarg" ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir="$ac_optarg" ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir="$ac_optarg" ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir="$ac_optarg" ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir="$ac_optarg" ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix="$ac_optarg" ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix="$ac_optarg" ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix="$ac_optarg" ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name="$ac_optarg" ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir="$ac_optarg" ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir="$ac_optarg" ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site="$ac_optarg" ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir="$ac_optarg" ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir="$ac_optarg" ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.13" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "with_${ac_package}='$ac_optarg'" ;; -without-* | --without-*) ac_package=`echo $ac_option|sed -e 's/-*without-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` eval "with_${ac_package}=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes="$ac_optarg" ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries="$ac_optarg" ;; -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } ;; *) if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then echo "configure: warning: $ac_option: invalid host type" 1>&2 fi if test "x$nonopt" != xNONE; then { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } fi nonopt="$ac_option" ;; esac done if test -n "$ac_prev"; then { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } fi trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 # File descriptor usage: # 0 standard input # 1 file creation # 2 errors and warnings # 3 some systems may open it to /dev/tty # 4 used on the Kubota Titan # 6 checking for... messages and results # 5 compiler messages saved in config.log if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>./config.log echo "\ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. " 1>&5 # Strip out --no-create and --no-recursion so they do not pile up. # Also quote any args containing shell metacharacters. ac_configure_args= for ac_arg do case "$ac_arg" in -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set these to C if already set. These must not be set unconditionally # because not all systems understand e.g. LANG=C (notably SCO). # Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! # Non-C LC_CTYPE values break the ctype check. if test "${LANG+set}" = set; then LANG=C; export LANG; fi if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. ac_unique_file=src/dircproxy.h # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_prog=$0 ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } else { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } fi fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then echo "loading site script $ac_site_file" . "$ac_site_file" fi done if test -r "$cache_file"; then echo "loading cache $cache_file" . $cache_file else echo "creating cache $cache_file" > $cache_file fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross ac_exeext= ac_objext=o if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break fi done if test -z "$ac_aux_dir"; then { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } fi ac_config_guess=$ac_aux_dir/config.guess ac_config_sub=$ac_aux_dir/config.sub ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. am__api_version="1.4" # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 echo "configure:566: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" for ac_dir in $PATH; do # Account for people who put trailing slashes in PATH elements. case "$ac_dir/" in /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do if test -f $ac_dir/$ac_prog; then if test $ac_prog = install && grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : else ac_cv_path_install="$ac_dir/$ac_prog -c" break 2 fi fi done ;; esac done IFS="$ac_save_IFS" fi if test "${ac_cv_path_install+set}" = set; then INSTALL="$ac_cv_path_install" else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL="$ac_install_sh" fi fi echo "$ac_t""$INSTALL" 1>&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 echo "configure:619: checking whether build environment is sane" >&5 # Just in case sleep 1 echo timestamp > conftestfile # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftestfile` fi if test "$*" != "X $srcdir/configure conftestfile" \ && test "$*" != "X conftestfile $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". { echo "configure: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" 1>&2; exit 1; } fi test "$2" = conftestfile ) then # Ok. : else { echo "configure: error: newly created file is older than distributed files! Check your system clock" 1>&2; exit 1; } fi rm -f conftest* echo "$ac_t""yes" 1>&6 if test "$program_transform_name" = s,x,x,; then program_transform_name= else # Double any \ or $. echo might interpret backslashes. cat <<\EOF_SED > conftestsed s,\\,\\\\,g; s,\$,$$,g EOF_SED program_transform_name="`echo $program_transform_name|sed -f conftestsed`" rm -f conftestsed fi test "$program_prefix" != NONE && program_transform_name="s,^,${program_prefix},; $program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" # sed with no file args requires a program. test "$program_transform_name" = "" && program_transform_name="s,x,x," echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 echo "configure:676: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftestmake <<\EOF all: @echo 'ac_maketemp="${MAKE}"' EOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` if test -n "$ac_maketemp"; then eval ac_cv_prog_make_${ac_make}_set=yes else eval ac_cv_prog_make_${ac_make}_set=no fi rm -f conftestmake fi if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then echo "$ac_t""yes" 1>&6 SET_MAKE= else echo "$ac_t""no" 1>&6 SET_MAKE="MAKE=${MAKE-make}" fi PACKAGE=dircproxy VERSION=1.0.5 if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } fi cat >> confdefs.h <> confdefs.h <&6 echo "configure:722: checking for working aclocal-${am__api_version}" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if (aclocal-${am__api_version} --version) < /dev/null > /dev/null 2>&1; then ACLOCAL=aclocal-${am__api_version} echo "$ac_t""found" 1>&6 else ACLOCAL="$missing_dir/missing aclocal-${am__api_version}" echo "$ac_t""missing" 1>&6 fi echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 echo "configure:735: checking for working autoconf" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if (autoconf --version) < /dev/null > /dev/null 2>&1; then AUTOCONF=autoconf echo "$ac_t""found" 1>&6 else AUTOCONF="$missing_dir/missing autoconf" echo "$ac_t""missing" 1>&6 fi echo $ac_n "checking for working automake-${am__api_version}""... $ac_c" 1>&6 echo "configure:748: checking for working automake-${am__api_version}" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if (automake-${am__api_version} --version) < /dev/null > /dev/null 2>&1; then AUTOMAKE=automake-${am__api_version} echo "$ac_t""found" 1>&6 else AUTOMAKE="$missing_dir/missing automake-${am__api_version}" echo "$ac_t""missing" 1>&6 fi echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 echo "configure:761: checking for working autoheader" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if (autoheader --version) < /dev/null > /dev/null 2>&1; then AUTOHEADER=autoheader echo "$ac_t""found" 1>&6 else AUTOHEADER="$missing_dir/missing autoheader" echo "$ac_t""missing" 1>&6 fi echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 echo "configure:774: checking for working makeinfo" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if (makeinfo --version) < /dev/null > /dev/null 2>&1; then MAKEINFO=makeinfo echo "$ac_t""found" 1>&6 else MAKEINFO="$missing_dir/missing makeinfo" echo "$ac_t""missing" 1>&6 fi # Make sure we can run config.sub. if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 echo "configure:797: checking host system type" >&5 host_alias=$host case "$host_alias" in NONE) case $nonopt in NONE) if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } fi ;; *) host_alias=$nonopt ;; esac ;; esac host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$host" 1>&6 echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6 echo "configure:818: checking whether to enable maintainer-specific portions of Makefiles" >&5 # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then enableval="$enable_maintainer_mode" USE_MAINTAINER_MODE=$enableval else USE_MAINTAINER_MODE=no fi echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6 if test $USE_MAINTAINER_MODE = yes; then MAINTAINER_MODE_TRUE= MAINTAINER_MODE_FALSE='#' else MAINTAINER_MODE_TRUE='#' MAINTAINER_MODE_FALSE= fi MAINT=$MAINTAINER_MODE_TRUE for ac_prog in mawk gawk 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 $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:846: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_AWK="$ac_prog" break fi done IFS="$ac_save_ifs" fi fi AWK="$ac_cv_prog_AWK" if test -n "$AWK"; then echo "$ac_t""$AWK" 1>&6 else echo "$ac_t""no" 1>&6 fi test -n "$AWK" && break done # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:878: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:908: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_prog_rejected=no ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" break fi done IFS="$ac_save_ifs" if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# -gt 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift set dummy "$ac_dir/$ac_word" "$@" shift ac_cv_prog_CC="$@" fi fi fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then case "`uname -s`" in *win32* | *WIN32*) # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:959: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="cl" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi ;; esac fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo "configure:991: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF #line 1002 "configure" #include "confdefs.h" main(){return(0);} EOF if { (eval echo configure:1007: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then ac_cv_prog_cc_cross=no else ac_cv_prog_cc_cross=yes fi else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_cv_prog_cc_works=no fi rm -fr conftest* ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo "configure:1033: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo "configure:1038: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no fi fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes else GCC= fi ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 echo "configure:1066: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ac_cv_prog_cc_g=yes else ac_cv_prog_cc_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 if test "$ac_test_CFLAGS" = set; then CFLAGS="$ac_save_CFLAGS" elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi echo $ac_n "checking for strerror in -lcposix""... $ac_c" 1>&6 echo "configure:1099: checking for strerror in -lcposix" >&5 ac_lib_var=`echo cposix'_'strerror | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lcposix $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -lcposix" else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for ${CC-cc} option to accept ANSI C""... $ac_c" 1>&6 echo "configure:1144: checking for ${CC-cc} option to accept ANSI C" >&5 if eval "test \"`echo '$''{'am_cv_prog_cc_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else am_cv_prog_cc_stdc=no ac_save_CC="$CC" # 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 -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" cat > conftest.$ac_ext < #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; } EOF if { (eval echo configure:1197: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* am_cv_prog_cc_stdc="$ac_arg"; break else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -f conftest* done CC="$ac_save_CC" fi if test -z "$am_cv_prog_cc_stdc"; then echo "$ac_t""none needed" 1>&6 else echo "$ac_t""$am_cv_prog_cc_stdc" 1>&6 fi case "x$am_cv_prog_cc_stdc" in x|xno) ;; *) CC="$CC $am_cv_prog_cc_stdc" ;; esac # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 echo "configure:1232: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" for ac_dir in $PATH; do # Account for people who put trailing slashes in PATH elements. case "$ac_dir/" in /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do if test -f $ac_dir/$ac_prog; then if test $ac_prog = install && grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : else ac_cv_path_install="$ac_dir/$ac_prog -c" break 2 fi fi done ;; esac done IFS="$ac_save_IFS" fi if test "${ac_cv_path_install+set}" = set; then INSTALL="$ac_cv_path_install" else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL="$ac_install_sh" fi fi echo "$ac_t""$INSTALL" 1>&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 echo "configure:1285: checking whether ln -s works" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else rm -f conftestdata if ln -s X conftestdata 2>/dev/null then rm -f conftestdata ac_cv_prog_LN_S="ln -s" else ac_cv_prog_LN_S=ln fi fi LN_S="$ac_cv_prog_LN_S" if test "$ac_cv_prog_LN_S" = "ln -s"; then echo "$ac_t""yes" 1>&6 else echo "$ac_t""no" 1>&6 fi # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:1308: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_RANLIB="ranlib" break fi done IFS="$ac_save_ifs" test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" fi fi RANLIB="$ac_cv_prog_RANLIB" if test -n "$RANLIB"; then echo "$ac_t""$RANLIB" 1>&6 else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 echo "configure:1336: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftestmake <<\EOF all: @echo 'ac_maketemp="${MAKE}"' EOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` if test -n "$ac_maketemp"; then eval ac_cv_prog_make_${ac_make}_set=yes else eval ac_cv_prog_make_${ac_make}_set=no fi rm -f conftestmake fi if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then echo "$ac_t""yes" 1>&6 SET_MAKE= else echo "$ac_t""no" 1>&6 SET_MAKE="MAKE=${MAKE-make}" fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 echo "configure:1365: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # This must be in double quotes, not single quotes, because CPP may get # substituted into the Makefile and "${CC-cc}" will confuse make. CPP="${CC-cc} -E" # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1386: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1403: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1420: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP=/lib/cpp fi rm -f conftest* fi rm -f conftest* fi rm -f conftest* ac_cv_prog_CPP="$CPP" fi CPP="$ac_cv_prog_CPP" else ac_cv_prog_CPP="$CPP" fi echo "$ac_t""$CPP" 1>&6 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 echo "configure:1445: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1458: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "memchr" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "free" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF if { (eval echo configure:1525: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_header_stdc=no fi rm -fr conftest* fi fi fi echo "$ac_t""$ac_cv_header_stdc" 1>&6 if test $ac_cv_header_stdc = yes; then cat >> confdefs.h <<\EOF #define STDC_HEADERS 1 EOF fi for ac_hdr in crypt.h fcntl.h inttypes.h sys/time.h syslog.h unistd.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:1552: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1562: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done echo $ac_n "checking for working const""... $ac_c" 1>&6 echo "configure:1590: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; } ; return 0; } EOF if { (eval echo configure:1644: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_c_const=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_c_const" 1>&6 if test $ac_cv_c_const = no; then cat >> confdefs.h <<\EOF #define const EOF fi echo $ac_n "checking for pid_t""... $ac_c" 1>&6 echo "configure:1665: checking for pid_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_pid_t=yes else rm -rf conftest* ac_cv_type_pid_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_pid_t" 1>&6 if test $ac_cv_type_pid_t = no; then cat >> confdefs.h <<\EOF #define pid_t int EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 echo "configure:1698: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_size_t=yes else rm -rf conftest* ac_cv_type_size_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_size_t" 1>&6 if test $ac_cv_type_size_t = no; then cat >> confdefs.h <<\EOF #define size_t unsigned EOF fi echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 echo "configure:1731: checking whether time.h and sys/time.h may both be included" >&5 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include int main() { struct tm *tp; ; return 0; } EOF if { (eval echo configure:1745: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_time=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_time=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_header_time" 1>&6 if test $ac_cv_header_time = yes; then cat >> confdefs.h <<\EOF #define TIME_WITH_SYS_TIME 1 EOF fi echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6 echo "configure:1766: checking for uid_t in sys/types.h" >&5 if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "uid_t" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_uid_t=yes else rm -rf conftest* ac_cv_type_uid_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_uid_t" 1>&6 if test $ac_cv_type_uid_t = no; then cat >> confdefs.h <<\EOF #define uid_t int EOF cat >> confdefs.h <<\EOF #define gid_t int EOF fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 echo "configure:1803: checking for working alloca.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { char *p = alloca(2 * sizeof(int)); ; return 0; } EOF if { (eval echo configure:1815: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_header_alloca_h=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_alloca_h=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_header_alloca_h" 1>&6 if test $ac_cv_header_alloca_h = yes; then cat >> confdefs.h <<\EOF #define HAVE_ALLOCA_H 1 EOF fi echo $ac_n "checking for alloca""... $ac_c" 1>&6 echo "configure:1836: checking for alloca" >&5 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < # define alloca _alloca # else # if HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ char *alloca (); # endif # endif # endif # endif #endif int main() { char *p = (char *) alloca(1); ; return 0; } EOF if { (eval echo configure:1869: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_alloca_works=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_func_alloca_works=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_func_alloca_works" 1>&6 if test $ac_cv_func_alloca_works = yes; then cat >> confdefs.h <<\EOF #define HAVE_ALLOCA 1 EOF fi if test $ac_cv_func_alloca_works = no; then # The SVR3 libPW and SVR4 libucb both contain incompatible functions # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. ALLOCA=alloca.${ac_objext} cat >> confdefs.h <<\EOF #define C_ALLOCA 1 EOF echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 echo "configure:1901: checking whether alloca needs Cray hooks" >&5 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5 | egrep "webecray" >/dev/null 2>&1; then rm -rf conftest* ac_cv_os_cray=yes else rm -rf conftest* ac_cv_os_cray=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_os_cray" 1>&6 if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:1931: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:1959: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <&6 fi done fi echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 echo "configure:1986: checking stack direction for C alloca" >&5 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then ac_cv_c_stack_direction=0 else cat > conftest.$ac_ext < addr) ? 1 : -1; } main () { exit (find_stack_direction() < 0); } EOF if { (eval echo configure:2013: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_stack_direction=1 else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_c_stack_direction=-1 fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_c_stack_direction" 1>&6 cat >> confdefs.h <&6 echo "configure:2035: checking return type of signal handlers" >&5 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #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; } EOF if { (eval echo configure:2057: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_signal=void else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_type_signal=int fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_signal" 1>&6 cat >> confdefs.h <&6 echo "configure:2076: checking for strftime" >&5 if eval "test \"`echo '$''{'ac_cv_func_strftime'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char strftime(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_strftime) || defined (__stub___strftime) choke me #else strftime(); #endif ; return 0; } EOF if { (eval echo configure:2104: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_strftime=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_strftime=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'strftime`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_STRFTIME 1 EOF else echo "$ac_t""no" 1>&6 # strftime is in -lintl on SCO UNIX. echo $ac_n "checking for strftime in -lintl""... $ac_c" 1>&6 echo "configure:2126: checking for strftime in -lintl" >&5 ac_lib_var=`echo intl'_'strftime | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lintl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_STRFTIME 1 EOF LIBS="-lintl $LIBS" else echo "$ac_t""no" 1>&6 fi fi for ac_func in mkdir rmdir seteuid strcspn strerror strspn strstr strtoul do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:2174: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:2202: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done echo $ac_n "checking for socket""... $ac_c" 1>&6 echo "configure:2227: checking for socket" >&5 if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char socket(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_socket) || defined (__stub___socket) choke me #else socket(); #endif ; return 0; } EOF if { (eval echo configure:2255: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_socket=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_socket=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'socket`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6 echo "configure:2273: checking for socket in -lsocket" >&5 ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo socket | sed -e 's/^a-zA-Z0-9_/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 echo "configure: warning: couldn't find your socket() function" 1>&2 fi fi echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 echo "configure:2323: checking for gethostbyname" >&5 if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostbyname(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) choke me #else gethostbyname(); #endif ; return 0; } EOF if { (eval echo configure:2351: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_gethostbyname=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_gethostbyname=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6 echo "configure:2369: checking for gethostbyname in -lnsl" >&5 ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo nsl | sed -e 's/^a-zA-Z0-9_/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 echo "configure: warning: couldn't find your gethostbyname() function" 1>&2 fi fi echo $ac_n "checking for crypt""... $ac_c" 1>&6 echo "configure:2419: checking for crypt" >&5 if eval "test \"`echo '$''{'ac_cv_func_crypt'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char crypt(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_crypt) || defined (__stub___crypt) choke me #else crypt(); #endif ; return 0; } EOF if { (eval echo configure:2447: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_crypt=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_crypt=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'crypt`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6 echo "configure:2465: checking for crypt in -lcrypt" >&5 ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lcrypt $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo crypt | sed -e 's/^a-zA-Z0-9_/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 echo "configure: warning: couldn't find your crypt() function" 1>&2 fi fi # Check whether --enable-debug or --disable-debug was given. if test "${enable_debug+set}" = set; then enableval="$enable_debug" if eval "test x$enable_debug = xyes"; then CFLAGS="-g -Wall $CFLAGS" cat >> confdefs.h <<\EOF #define DEBUG 1 EOF cat >> confdefs.h <<\EOF #define DEBUG_MEMORY 1 EOF else for ac_func in strdup vasprintf vsnprintf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:2532: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:2560: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done fi else for ac_func in strdup vasprintf vsnprintf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:2589: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:2617: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done fi # Check whether --enable-poll or --disable-poll was given. if test "${enable_poll+set}" = set; then enableval="$enable_poll" if eval "test x$enable_poll = xyes"; then for ac_func in poll do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:2652: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:2680: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done for ac_hdr in poll.h sys/poll.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:2708: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:2718: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done fi else for ac_func in poll do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:2749: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:2777: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done for ac_hdr in poll.h sys/poll.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:2805: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:2815: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done fi # Check whether --enable-select or --disable-select was given. if test "${enable_select+set}" = set; then enableval="$enable_select" if eval "test x$enable_select = xyes"; then for ac_func in select do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:2851: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:2879: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done fi else for ac_func in select do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:2908: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:2936: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done fi trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote substitution # turns \\\\ into \\, and sed turns \\ into \). sed -n \ -e "s/'/'\\\\''/g" \ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' ;; esac >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Any assignment to VPATH causes Sun make to only execute # the first set of double-colon rules, so remove it if not needed. # If there is a colon in the path, we need to keep it. if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' fi trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 DEFS=-DHAVE_CONFIG_H # Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} echo creating $CONFIG_STATUS rm -f $CONFIG_STATUS cat > $CONFIG_STATUS </dev/null | sed 1q`: # # $0 $ac_configure_args # # Compiler output produced by configure, useful for debugging # configure, is in ./config.log if it exists. ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.13" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir ac_given_INSTALL="$INSTALL" trap 'rm -fr `echo "Makefile conf/Makefile contrib/Makefile getopt/Makefile crypt/Makefile doc/Makefile src/Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@SHELL@%$SHELL%g s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@FFLAGS@%$FFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g s%@INSTALL_DATA@%$INSTALL_DATA%g s%@PACKAGE@%$PACKAGE%g s%@VERSION@%$VERSION%g s%@ACLOCAL@%$ACLOCAL%g s%@AUTOCONF@%$AUTOCONF%g s%@AUTOMAKE@%$AUTOMAKE%g s%@AUTOHEADER@%$AUTOHEADER%g s%@MAKEINFO@%$MAKEINFO%g s%@SET_MAKE@%$SET_MAKE%g s%@host@%$host%g s%@host_alias@%$host_alias%g s%@host_cpu@%$host_cpu%g s%@host_vendor@%$host_vendor%g s%@host_os@%$host_os%g s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g s%@MAINT@%$MAINT%g s%@AWK@%$AWK%g s%@CC@%$CC%g s%@LN_S@%$LN_S%g s%@RANLIB@%$RANLIB%g s%@CPP@%$CPP%g s%@ALLOCA@%$ALLOCA%g CEOF EOF cat >> $CONFIG_STATUS <<\EOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. ac_more_lines=: ac_sed_cmds="" while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file else sed "${ac_end}q" conftest.subs > conftest.s$ac_file fi if test ! -s conftest.s$ac_file; then ac_more_lines=false rm -f conftest.s$ac_file else if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f conftest.s$ac_file" else ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" fi ac_file=`expr $ac_file + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_cmds` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dir_suffix. ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dir_suffix= ac_dots= fi case "$ac_given_srcdir" in .) srcdir=. if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac case "$ac_given_INSTALL" in [/$]*) INSTALL="$ac_given_INSTALL" ;; *) INSTALL="$ac_dots$ac_given_INSTALL" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g s%@INSTALL@%$INSTALL%g " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file fi; done rm -f conftest.s* # 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='\3' ac_dD='%g' # ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='\([ ]\)%\1#\2define\3' ac_uC=' ' ac_uD='\4%g' # ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_eB='$%\1#\2define\3' ac_eC=' ' ac_eD='%g' if test "${CONFIG_HEADERS+set}" != set; then EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF fi for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac echo creating $ac_file rm -f conftest.frag conftest.in conftest.out ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` cat $ac_file_inputs > conftest.in EOF # Transform confdefs.h into a sed script conftest.vals that substitutes # the proper values into config.h.in to produce config.h. 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.vals cat > conftest.hdr <<\EOF s/[\\&%]/\\&/g s%[\\$`]%\\&%g s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp s%ac_d%ac_u%gp s%ac_u%ac_e%gp EOF sed -n -f conftest.hdr confdefs.h > conftest.vals rm -f conftest.hdr # 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.vals <<\EOF s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% EOF # Break up conftest.vals because some shells have a limit on # the size of here documents, and old seds have small limits too. rm -f conftest.tail while : do ac_lines=`grep -c . conftest.vals` # grep -c gives empty output for an empty file on some AIX systems. if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi # Write a limited-size here document to conftest.frag. echo ' cat > conftest.frag <> $CONFIG_STATUS sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS echo 'CEOF sed -f conftest.frag conftest.in > conftest.out rm -f conftest.in mv conftest.out conftest.in ' >> $CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail rm -f conftest.vals mv conftest.tail conftest.vals done rm -f conftest.vals cat >> $CONFIG_STATUS <<\EOF rm -f conftest.frag conftest.h echo "/* $ac_file. Generated automatically by configure. */" > conftest.h cat conftest.in >> conftest.h rm -f conftest.in if cmp -s $ac_file conftest.h 2>/dev/null; then echo "$ac_file is unchanged" rm -f conftest.h else # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" fi rm -f $ac_file mv conftest.h $ac_file fi fi; done EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 dircproxy-1.0.5/configure.in0000664000175000017500000000411107537114466011546 dnl Process this file with autoconf to produce a configure script. AC_INIT(src/dircproxy.h) AM_INIT_AUTOMAKE(dircproxy, 1.0.5) AM_CONFIG_HEADER(config.h) AC_CANONICAL_HOST AM_MAINTAINER_MODE dnl Checks for programs. AC_PROG_AWK AC_PROG_CC AC_ISC_POSIX AM_PROG_CC_STDC AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_RANLIB AC_PROG_MAKE_SET dnl Checks for libraries. dnl Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS(crypt.h fcntl.h inttypes.h sys/time.h syslog.h unistd.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_PID_T AC_TYPE_SIZE_T AC_HEADER_TIME AC_TYPE_UID_T dnl Checks for library functions. AC_FUNC_ALLOCA AC_TYPE_SIGNAL AC_FUNC_STRFTIME AC_CHECK_FUNCS(mkdir rmdir seteuid strcspn strerror strspn strstr strtoul) AC_CHECK_FUNC(socket, , AC_CHECK_LIB(socket, socket, , AC_MSG_WARN([couldn't find your socket() function]))) AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(nsl, gethostbyname, , AC_MSG_WARN([couldn't find your gethostbyname() function]))) AC_CHECK_FUNC(crypt, , AC_CHECK_LIB(crypt, crypt, , AC_MSG_WARN([couldn't find your crypt() function]))) dnl Do strange debug stuff. AC_ARG_ENABLE(debug, [ --enable-debug turn on debugging [default=no]],if eval "test x$enable_debug = xyes"; then CFLAGS="-g -Wall $CFLAGS" AC_DEFINE(DEBUG) AC_DEFINE(DEBUG_MEMORY) else AC_CHECK_FUNCS(strdup vasprintf vsnprintf) fi, AC_CHECK_FUNCS(strdup vasprintf vsnprintf) ) dnl Allow me to turn on/off poll and select to debug stuff AC_ARG_ENABLE(poll, [ --disable-poll disable use of the poll() function [default=no]], if eval "test x$enable_poll = xyes"; then AC_CHECK_FUNCS(poll) AC_CHECK_HEADERS(poll.h sys/poll.h) fi, AC_CHECK_FUNCS(poll) AC_CHECK_HEADERS(poll.h sys/poll.h) ) AC_ARG_ENABLE(select, [ --disable-select disable use of the select() function [default=no]], if eval "test x$enable_select = xyes"; then AC_CHECK_FUNCS(select) fi, AC_CHECK_FUNCS(select) ) dnl Output the Makefiles. AC_OUTPUT([Makefile conf/Makefile contrib/Makefile getopt/Makefile crypt/Makefile doc/Makefile src/Makefile]) dircproxy-1.0.5/install-sh0000755000175000017500000001273707567164507011260 #!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 dircproxy-1.0.5/missing0000755000175000017500000001452007567164507010643 #! /bin/sh # Common stub for a few missing GNU programs while installing. # Copyright (C) 1996, 1997, 2001, 2002 Free Software Foundation, Inc. # Franc,ois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.in; then configure_ac=configure.ac else configure_ac=configure.in fi case "$1" in -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file yacc create \`y.tab.[ch]', if possible, from existing .[ch]" ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing - GNU libit 0.0" ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; aclocal*) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acinclude.m4' or \`$configure_ac'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`$configure_ac'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acconfig.h' or \`$configure_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*) 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 ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; makeinfo) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` fi touch $file ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequirements for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 dircproxy-1.0.5/mkinstalldirs0000755000175000017500000000132207567164507012046 #! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain # $Id: mkinstalldirs,v 1.13 1999/01/05 03:18:55 bje Exp $ errstatus=0 for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr fi fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here dircproxy-1.0.5/FAQ0000664000175000017500000005440307537110435007570 dircproxy: Frequently Asked Questions ------------------------------------- Questions ========= 1. Introduction 1.1 What is dircproxy? 1.2 Where can I get dircproxy? 1.3 Are there any mailing lists? 1.4 Is there a dircproxy IRC channel? 1.5 How do I report bugs? 1.6 Is there an anonymous CVS server? 1.7 How do I add a question to the FAQ? 2. Installation 2.1 How do I compile and install dircproxy? 2.2 I get "couldn't find your xxx() function" from configure 2.3 Compilation fails with "xxx.h: No such file or directory" 2.4 Compilation fails with "undefined reference to `xxx'" 2.5 What does --enable-debug do? 2.6 Is dircproxy supported on Windows 2000? 3. Usage 3.1 What are configuration classes? 3.2 Can dircproxy be used as an "open proxy"? 3.3 Where in the config file do I put my nickname? 3.4 Can dircproxy be run from inetd? 3.5 dircproxy won't start and says I need to define connection classes, how do I do this? 3.6 I started dircproxy, but it hasn't connected to any servers yet, what have I done wrong? 3.7 dircproxy will not accept my password, I know its right as its exactly what I typed into the configuration file. 3.8 How do I get a running dircproxy to reread its configuration file? 3.9 How do I detach from dircproxy? 3.10 How can I get dircproxy to disconnect from the server? 3.11 Can I connect multiple clients to the same running session? 3.12 Can one dircproxy connection class be used to connect to multiple servers? 3.13 Why doesn't dircproxy ever keep my nickname? 3.14 Can I get dircproxy to automatically connect to the server without connecting at least once? 3.15 Does dircproxy support user scripts to extend it? 3.16 Does dircproxy provide auto-op or auto-voice support? 4. Logging 4.1 Why does dircproxy by default log channels while I'm attached? 4.2 How do I log everything and keep it for my own reference in years to come? 4.3 Why does the permanent copy contain text from all the clients dircproxy is proxying? 4.4 How do I log private messages to individual files? 4.5 How do I log outgoing private messages? 5. DCC Proxying 5.1 Why would I want dircproxy to proxy DCC requests as well? 5.2 What's "DCC over ssh" and how do I use it? 5.3 Does text I type before dircproxy tells me the remote peer has connected ever reach them? 5.4 Why doesn't dircproxy support DCC RESUME? 6. Advanced Use 6.1 How do I change what username is presented on IRC? Answers ======= 1.1 What is dircproxy? dircproxy is an IRC proxy server designed for people who use IRC from lots of different workstations or clients, but wish to remain connected and see what they missed while they were away. You connect to IRC through dircproxy, and it keeps you connected to the server, even after you detach your client from it. While you're detached, it logs channel and private messages as well as important events, and when you re-attach it'll let you know what you missed. This can be used to give you roughly the same functionality as using ircII and screen together, except you can use whatever IRC client you like, including X ones! 1.2 Where can I get dircproxy? The dircproxy home page is at: http://www.dircproxy.net/ New releases along with other news are announced there. If you'd prefer an FTP site, there is one at: ftp://ftp.dircproxy.net/pub/dircproxy/ 1.3 Are there any mailing lists? Yes, there are two mailing lists. A low traffic one which only receives posts from myself announcing new releases and the occasional other announcement (dircproxy-announce) and a public mailing list for general dircproxy discussion (dircproxy-users). For more information, including how to subscribe, see: http://www.dircproxy.net/lists.html 1.4 Is there a dircproxy IRC channel? Yes, on the OpenProjects IRC network (irc.openprojects.net) called #dircproxy. I can usually be found with the nickname Keybuk. 1.5 How do I report bugs? Bug tracking is done using our Bugzilla bug tracking system at: http://bugzilla.dircproxy.net/ 1.6 Is there an anonymous CVS server? Yes. This can be used to retrieve any release, including the current developmental release. For more information see: http://www.dircproxy.net/cvs.html 1.7 How do I add a question to the FAQ? E-mail me at scott@dircproxy.net and I'll see if its suitable for inclusion. 2.1 How do I compile and install dircproxy? Read the INSTALL file in the dircproxy distribution, or see: http://www.dircproxy.net/install.html 2.2 I get "couldn't find your xxx() function" from configure dircproxy makes very few requirements on your system, and your libc. The only things it does require are TCP/IP support through the socket() function, DNS resolver support through the gethostbyname() function and encryption support through the crypt() function. The 'configure' program checks a few likely locations for these functions and if it can't find them will generate the appropriate warning. For example: checking for crypt... no checking for crypt in -lcrypt... no configure: warning: couldn't find your crypt() function If you know which library these functions are located in, you can pass the LDFLAGS shell variable to tell it. For example, if you know your crypt() function is in the libdes.so (example only!) library, you can do this: $ LDFLAGS=-ldes ./configure ... Then let me know what type of system you have and what you did, so I can make future versions of dircproxy detect this case automatically. If you can't find these functions, you'll need to chat to your local sysadmin or UNIX guru and get them to upgrade your libc to something a little more up to date. 2.3 Compilation fails with "xxx.h: No such file or directory" This most likely means that a system header file that dircproxy needs wasn't found on your system. It can also mean that the dircproxy source isn't complete. Find out which directory that header file is on your system, and pass that to the 'configure' program using the CFLAGS shell variable like this: $ CFLAGS=-I/path/to/directory ./configure ... If you can't find it, you'll need to find out what your system's equivalent is, then let me know all about it so I can enable future versions of dircproxy to support your system fully. If there is no equivalent you'll need to get your sysadmin or UNIX guru to upgrade your libc to something more up to date. 2.4 Compilation fails with "undefined reference to `xxx'" This means that a system function dircproxy uses wasn't found on your system. You'll need to find out in which library on your system that function is. Then if for example its in libmisc.so pass that using the LDFLAGS shall variable to 'configure' like this: $ LDFLAGS=-lmisc ./configure ... If you're system doesn't have that function, you'll need to get your sysadmin or local UNIX guru to upgrade your libc to something a little more up to date. 2.5 What does --enable-debug do? Its used primarily by myself to debug dircproxy, it can also be used by anyone else who wants to help out debugging it. One main difference is that dircproxy will not switch to the background, but will stay in the foreground and write a lot of strange information (including a record of all text received from the client and server) to the console. This reverses the meaning of the -D parameter. It also causes dircproxy to use its built-in versions of strdup() sprintf() and vsprintf() instead of any that might exist in your libc. Finally it switches on a lot of expensive memory debugging code that records every malloc(), realloc() and free(), notes what C file and line it occurred in and pads the memory with random junk to detect most buffer overruns. On termination you will see a memory report (hopefully saying "0 bytes in use"), you can also send a USR1 signal to dircproxy to see how much memory it thinks its using, and a USR2 signal to see exactly what is in its memory and where it was allocated. This slows down dircproxy a lot and makes it inconvenient to use. However, for people wanting to do dircproxy code work its invaluable. 2.6 Is dircproxy supported on Windows 2000? No, it is not supported and never will be supported. Get a real operating system(tm) :o) However, I've heard it works just fine. 3.1 What are configuration classes? A configuration class defines a possible client/server proxied connection. Basically you define a connection class, setting a password and server to connect to, then when you connect to dircproxy and give your password for the first time, it automatically connects you to a server. This connection class is then assigned to your proxy session and cannot be used by anyone else until you cause dircproxy to disconnect from the server (see 3.10). When you reconnect, all you need to do is supply the password again. dircproxy then sees that your connection class is already in use and simply attaches you to that. This means you don't need to specify any "one time passwords", or magic connection or reconnection commands etc. dircproxy can be used by simply telling your IRC client to supply a "server password" when it connects. Everything else is automatic. 3.2 Can dircproxy be used as an "open proxy"? Yes, only if each user knows the password. dircproxy does NOT support password-less proxy sessions, if you do that you'll just annoy the IRC operators and get yourself banned from the IRC network. Open IRC proxies are a BAD THING and lead to abuse of the IRC network. You may however use dircproxy as a proxy for many users who know the password. This can be accomplished by running it from inetd (one of the few reasons to do this). Set it up as described in README.inetd, and set up a single connection class with the appropriate password etc. By default, dircproxy will not remain attached to the server when each client quits, they'll need to explicitly do a /DIRCPROXY PERSIST to do that. 3.3 Where in the config file do I put my nickname? You don't. dircproxy doesn't connect to the IRC server until you connect to it. This means it can pick up the nickname from the one your IRC client sends. All you need to tell dircproxy is what server you want to connect to. The rest of the information such as your nickname, user name and full name etc are taken from your IRC client when it first connects to it. 3.4 Can dircproxy be run from inetd? Yes. See the README.inetd file in the dircproxy distribution. 3.5 dircproxy won't start and says I need to define connection classes, how do I do this? You need to create a configuration file. Best way is to get the example one in the conf subdirectory of the dircproxy (or if its just installed on a machine you are using, the /usr/local/share/dircproxy directory), copy it to your home directory, call it .dircproxyrc and make sure it has no more than 0600 permissions (-rw-------). Then edit this file, its very well documented. The configuration classes are defined right at the bottom. 3.6 I started dircproxy, but it hasn't connected to any servers yet, what have I done wrong? Nothing, dircproxy won't connect to the server until you connect an IRC client to it. 3.7 dircproxy will not accept my password, I know its right as it's exactly what I typed into the configuration file. dircproxy requires that IRC client passwords in the configuration file are encrypted so that anyone managing to read the file off the disk can't get the password and use your dircproxy session. Encrypt them using your systems crypt(3) function or by using the dircproxy-crypt(1) utility included with the dircproxy source. 3.8 How do I get a running dircproxy to reread its configuration file? Send it a hang-up (HUP) signal. The process ID can be obtained using the 'ps' command, and then signal sent using the 'kill' command. On BSD-like machines, this can be done like this: $ ps aux | grep dircproxy user 7410 0.0... $ kill -HUP 7410 Or on a SysV-like machine, like this: % ps -ef | grep dircproxy user 7410 388... $ kill -HUP 7410 Note that certain configuration options do not take effect until you reconnect to a server, or detach from dircproxy. 3.9 How do I detach from dircproxy? Close your IRC client, probably by typing /QUIT. You don't need tell dircproxy you're detaching, it can guess that by your connection to it closing. The exception to this is if you're running dircproxy from inetd, if this is the case you'll need to do a /DIRCPROXY PERSIST before you close to tell it that you want to reconnect later. dircproxy will tell you what port number to reconnect at. 3.10 How can I get dircproxy to disconnect from the server? Using the /DIRCPROXY QUIT command. You can specify an optional quit message if you like, for example. > /DIRCPROXY QUIT Right, four weeks in the sun, here I come! 3.11 Can I connect multiple clients to the same running session? No. After all, which one do you listen to? It could all get very schizophrenic with two people typing under the same nickname from different computers. 3.12 Can one dircproxy connection class be used to connect to multiple servers? No. It might sound fairly simple to implement at first, tracking channels is fairly easy, its tracking nicknames thats the problem. 3.13 Why doesn't dircproxy ever keep my nickname? First of all, check you've *not* got the following in your configuration file. nick_keep no "yes" is the default, so if this option isn't set, then it will be used. dircproxy will attempt to keep whatever nickname your client last set using the NICK command. This means that if you connect a client while dircproxy's attempting to restore your nickname, and your client reacts to the server messages (as most "clever" clients do) than dircproxy will accept the new nickname and stop guarding the old one. If it never restores your nickname when left without a client connected, it may be that the server believes dircproxy is changing it's nickname "too fast" or "too many times". The default is to attempt to restore the nickname once per minute. You can adjust this by changing the 'NICK_GUARD_TIME' #define in src/dircproxy.h. 3.14 Can I get dircproxy to automatically connect to the server without connecting at least once? No. dircproxy was never written to connect to an IRC server without seeing an IRC client first. 3.15 Does dircproxy support user scripts to extend it? No. dircproxy is intended purely as an IRC proxy. Scripting support would make it too much like a bot, if you want that kind of thing then a bot would serve you much better. Go download eggdrop, and get yourself K-Lined from your IRC server. :o) 3.16 Does dircproxy provide auto-op or auto-voice support? No, again this functionality would be better supplied by a bot. Chris Crowther has writtne a patch to provide this kind of support using dircproxy. This isn't an official patch, however it is available from: http://www.shad0w.org.uk/code/ 4.1 Why does dircproxy by default log channels while I'm attached? dircproxy was originally designed to give roughly the same functionality as using ircII and screen, but allowing you to use X clients (which can't be screen'd). This means it tries to give you a "full screen" of text when you reattach, so if you've only just disconnected, a full screen includes that which happened before you disconnected. Its actually quite useful when you think about it: Argh, I think my computer's about to crash? Hi there :) My name is X. -dircproxy- You disconnected Do you want to go out for a drink sometime? -dircproxy- You connected Hi X, sure :) You might not have seen your dream date's name :) Its also handy for reference. You can always switch it off though by setting this in the config file: chan_log_always no 4.2 How do I log everything and keep it for my own reference in years to come? Create a directory for dircproxy to store the logs in, and then tell dircproxy to store a "permanent copy" in that directory like this: chan_log_copydir /path/to/directory other_log_copydir /path/to/directory 4.3 Why does the permanent copy contain text from all the clients dircproxy is proxying? Because you've set the directory name globally for all connection classes in the configuration file. Because dircproxy doesn't use the logs itself, its not a security risk or anything to be able to do this, and if each person is on a different channel, its quite a handy thing to do. If you don't want it to do this, define the 'chan_log_copydir' and 'other_log_copydir' inside each connection class instead of the global level, like this: connection { : chan_log_copydir /path/to/directory other_log_copydir /path/to/directory : } connection { : chan_log_copydir /path/to/directory2 other_log_copydir /path/to/directory2 : } 4.4 How do I log private messages to individual files? Use the 'privmsg-log.pl' script in the contrib directory of the dircproxy source as a filter as an 'other_log_program'. You'll need to edit the script to set the directory to store these private message log files, and need to add the following to your dircproxy configuration file: other_log_program "/usr/local/share/dircproxy/privmsg-log.pl" 4.5 How do I log outgoing private messages? You can't, there's no way for dircproxy to replay them for you (every client I tested ignored them). 5.1 Why would I want dircproxy to proxy DCC requests as well? DCC proxying means that all DCC requests get proxied through dircproxy just like your normal IRC requests. This means your real IP address is just as hidden as it is on IRC. Also if you're running dircproxy on your NAT firewall so you can actually get on IRC, you'll be able to do DCCs to as it will be proxying them between the two networks for you. 5.2 What's "DCC over ssh" and how do I use it? For a complete description, including how to do it, see the README.dcc-via-ssh file in the dircproxy distribution. Simply its a way of doing DCCs over ssh tunnels to get around any firewalls that might be in the way that would normally prevent even the most determined proxy from allowing DCCs. 5.3 Does text I type before dircproxy tells me the remote peer has connected ever reach them? Yes, its simply queued until the remote side connects, then is sent to them. 5.4 Why doesn't dircproxy support DCC RESUME? The DCC RESUME protocol is an mIRC extension to the standard, and is documented at: http://www.mirc.co.uk/help/dccresum.txt dircproxy does not support this protocol, therefore you cannot resume DCC transfers if you are using dircproxy. DCC RESUME support will *never* be implemented in dircproxy, the reason for this is as follows. Ordinary DCC SENDs are offered by the sender sending a DCC SEND message to the receiver containing a ip address and port number. The receiver accepts the offer by connecting to it. [ sender ] --(1) DCC SEND--> [ receiver ] <---(2) accept--- When proxied through dircproxy, dircproxy accepts the offer itself, then makes a new offer to the receiver. This means that dircproxy has already usually received a fair portion of the file before the receiver accepts dircproxy's own offer. This greatly increases the speed of transfers. [ sender ] --(1) DCC SEND--> [ proxy ] --(3) DCC SEND--> [ receiver ] <---(2) accept--- <---(4) accept--- If the DCC RESUME protocol is used, the receiver indicates it wishes to do so by sending a DCC RESUME message to the sender instead of connecting to it, the connect is only done after a DCC ACCEPT is received from the sender. [ sender ] --(1) DCC SEND--> [ receiver ] <-(2) DCC RESUME- -(3) DCC ACCEPT-> <---(4) accept--- Of course, with dircproxy proxying, this is too late, it's already accepted the sender's offer and is receiving the file from the beginning. Ryan Tolboom has written a patch to enable DCC RESUME for files that dircproxy has captured, this is available from: http://www-ec.njit.edu/~rxt1077/dircproxy-resume/ 6.1 How do I change what username is presented on IRC? The obvious answer is to run dircproxy under that username, but that doesn't help if you're proxying for multiple people. Another option is to use one of the many fake ident daemons to return a false answer for you. There's also a third option, which is available to those running dircproxy as root (either as a daemon or from inetd). You can use the 'switch_user' configuration file directive. This ensures that the connection to the server appears as from whatever local username you give it (by seteuid()ing to that briefly) while the dircproxy process remains as root. Copyright (C) 2002 Scott James Remnant . All Rights Reserved. dircproxy-1.0.5/PROTOCOL0000664000175000017500000000422207410714172010412 IRC protocol notes ------------------ IRC has been for a long time notoriously under-documented. The original RFC was RFC1459 ("Internet Relay Chat Protocol") and was written way back in May 1993. Since that time the IRC protocol has changed quite a bit, especially in respect to the numeric codes sent to clients by the server. These have been recently updated to the modern 2.10 IRC protocol as used by the IRCnet network. They do differ in a few places, and where they do, dircproxy follows the new RFCs. For reference, the new RFCs are as follows: RFC2810 Internet Relay Chat: Architecture RFC2811 Internet Relay Chat: Channel Management RFC2812 Internet Relay Chat: Client Protocol RFC2813 Internet Relay Chat: Server Protocol Noteworthy differences ====================== RFC1459 says that parameters 2 and 3 of the USER command should be the hostname of the client, and of the server. With the advent of DNS and ident checking etc, these have been redundant for a while. RFC2812 changes the meaning of these parameters, defining the second parameter to be a bit mask of modes to set on connection, and the third to be unused. dircproxy completely ignores the 3rd parameter, and performs an atoi() on the second. If the second isn't 0 then it assumes the client follows RFC2812 and treats the bits accordingly. dircproxy always sends "0" as the second parameter and "*" as the third to any server it connects to. Modern servers send four numerics upon connection, 001 thru 004. These provide information about the server. These were not defined in RFC1459 but are defined in RFC2812. dircproxy requires these parameters to be sent by the server so it knows when the connection is completed. All servers send them anyway, so this should not cause a problem. RFC1459 says parameters in commands can be separated by one or more spaces. RFC2812 says they are separated by only ONE space (thus allowing for empty parameters). dircproxy follows RFC2812 by default, however if this causes problems for you then define the OLD_RFC1459_PARAM_SPACE in dircproxy.h Copyright (C) 2002 Scott James Remnant . All Rights Reserved. dircproxy-1.0.5/README.inetd0000664000175000017500000000303407410714172011210 Running dircproxy from inetd ---------------------------- If you are so inclined, you can run dircproxy from the standard UNIX inetd daemon. This means you can do things like wrap it with tcpd etc and add all your own perverse security restrictions on top. However you loose the automatic ability to detach and reattach to your session, which makes it slightly more inconvenient to use. To run from inetd add a line to /etc/services for the port you want to listen on, and give it a service name of "dircproxy". This is actually good practice anyway. dircproxy 57000/tcp # Detchable IRC Proxy Now add a line to /etc/inetd.conf for dircproxy. You'll need to decide a username to run dircproxy as, "nobody" will probably do, don't run dircproxy as "root" unless you plan to use the "switch_user" configuration directive! Also change the PATH/TO to point to where you installed dircproxy. The -I parameter tells it its running from inetd. You can specify any other options here, such as to specify the configuration file (dircproxy will only check the system-wide configuration file when running under inetd). dircproxy stream tcp nowait USERNAME /PATH/TO/dircproxy dircproxy -I You can connect to it as normal, however when you disconnect you will be disconnected from IRC too, and won't be able to reattach to your session. To keep your session connected use the /DIRCPROXY PERSIT command. This will tell you which port you can reconnect to your session at. Copyright (C) 2002 Scott James Remnant . All Rights Reserved. dircproxy-1.0.5/README.dcc-via-ssh0000664000175000017500000001335707410714172012217 Tunneling DCC over ssh using dircproxy --------------------------------------- WARNING, THIS IS NOT EASY TO DO. Don't read any further unless you are a fully qualified UNIX guru, complete with the long hair and sandals. Why do this? ============ DCC chats and sends will not work if your desktop is behind a firewall if that firewall prevents you from freely accessing the Internet, or prevents people from connecting to you. There are normal three ways around this. o Placing rules in the firewall that allow certain ports such as IRC through, and using the `dcc_proxy_ports` config option to limit dircproxy's port range to that which you've allowed. You probably don't have that kind of access to the firewall though, or wouldn't be allowed to if you did. o Install dircproxy on the firewall itself, so it can freely proxy between both networks without being affected by the rules on the firewall. Again, you probably don't have that kind of access. Its also not good practice anyway. o Piggy back your IRC traffic on something that the firewall does let through. Most firewalls let ssh traffic through, at least in the out-bound direction, and that's perfect. This is what this file tells you how to do. What do I need? =============== For this to work, the firewall must allow ssh traffic through and must allow connections to be made from inside the firewall to outside. It probably does, or you can probably persuade the firewall admin to let ssh through, its secure after all. You will also need two UNIX machines, one inside the firewall and one outside. The inside one must have dircproxy installed and ssh installed. The best choice is probably your desktop if that runs UNIX. (You *could* use a Windows machine if you can get dircproxy to compile on it and use something like SecureCRT of F-Secure SSH to do the tunnels). The outside machine must also have dircproxy installed, and must have the ssh daemon (sshd) installed and running. Setting up the Tunnels ====================== You'll need three different tunnels across the firewall from the machine inside to the machine outside. One to forward the IRC connection itself, and a further two for DCC traffic, one for incoming and one for outgoing. You can do this with one ssh command, specifying all three tunnels at the same time. (Replace 'outside.firewall' with the hostname of the machine outside). $ ssh -L 57010:localhost:57000 \ -L 57110:localhost:57100 \ -R 57110:localhost:57100 outside.firewall This will actually start a shell on the remote machine. Exiting from it will end the tunnels. For safety you may want to run this under screen or something (if you've got that), as it doesn't run in the background either. Its perfectly safe to close the tunnels while you are detatched though - so you could put these in a shell script or something instead and just run that when you want to attach. Configuring dircproxy on the Outside machine ============================================ This will be the master dircproxy, connecting to the IRC server itself and doing all the normal things such as logging etc. Configure it as you normally would, except for the following two options which need to be set as shown. dcc_proxy_ports 57100 dcc_tunnel_outgoing 57110 This tells dircproxy to listen for DCC connections on port 57100, which is pointed to by a tunnel, and that all outgoing DCCs from you (which require a connection to you) should be sent through the tunnel on port 57110. This dircproxy is probably best run as a daemon (i.e. normally). Configuring dircproxy on the Inside machine =========================================== This dircproxy will be a simple slave, forwarding to the one outside without doing anything clever. The configuration file should be left untouched, only add a connection class, which should look like this. connection { password "encpass" server "localhost:57010:pass" disconnect_on_detach yes dcc_proxy_ports 57100 dcc_tunnel_incoming 57110 } Replace "encpass" with an encrypted password that should match that you configure the IRC client with, and replace "pass" with the unencrypted version of whatever you set the password to on the dircproxy outside the firewall. This tells dircproxy that incoming DCC requests to you (which require you to connect to the remote server) should be sent through the tunnel on port 57110. You can run this dircproxy as a daemon or from inetd, whichever suits you best. Using dircproxy now =================== Connect your IRC client to the dircproxy inside the firewall. This will then connect through the tunnels to the dircproxy outside the firewall which will connect to the IRC server for you. When you detach your IRC client, the dircproxy inside the firewall will disconnect from the one on the outside. This means you can also exit the ssh session running the tunnels (thereby closing them). When you want to reconnect, just start up the tunnels and dircproxy again before you do (having left the one outside well alone). This means that if you are using your desktop, you can still switch it off over night etc without worrying about loosing your IRC link. Small note: Because you can only use one listening port, you will only be able to have one queued DCC request at a time. Others will be rejected until the outstanding request either times out or is accepted by you. Another worthy note is that when using tunnels, you will see two sets of messages from dircproxy informing you of its connections to remote peers. The first set is the link between the two proxies being established, the second set is the link being established to the remote peer itself. This is normal and nothing to worry about. Copyright (C) 2002 Scott James Remnant . All Rights Reserved. dircproxy-1.0.5/conf/0000777000175000017500000000000007567165530010250 5dircproxy-1.0.5/conf/Makefile.in0000644000175000017500000001201607567165530012231 # Makefile.in generated automatically by automake 1.4-p6 from Makefile.am # Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. SHELL = @SHELL@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ libexecdir = @libexecdir@ datadir = @datadir@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include DESTDIR = pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : host_alias = @host_alias@ host_triplet = @host@ AWK = @AWK@ CC = @CC@ LN_S = @LN_S@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ PACKAGE = @PACKAGE@ RANLIB = @RANLIB@ VERSION = @VERSION@ pkgdata_DATA = dircproxyrc EXTRA_DIST = $(pkgdata_DATA) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = DATA = $(pkgdata_DATA) DIST_COMMON = Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP_ENV = --best all: all-redirect .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps conf/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status install-pkgdataDATA: $(pkgdata_DATA) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(pkgdatadir) @list='$(pkgdata_DATA)'; for p in $$list; do \ if test -f $(srcdir)/$$p; then \ echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkgdatadir)/$$p"; \ $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkgdatadir)/$$p; \ else if test -f $$p; then \ echo " $(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p"; \ $(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \ fi; fi; \ done uninstall-pkgdataDATA: @$(NORMAL_UNINSTALL) list='$(pkgdata_DATA)'; for p in $$list; do \ rm -f $(DESTDIR)$(pkgdatadir)/$$p; \ done tags: TAGS TAGS: distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) subdir = conf distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ if test -d $$d/$$file; then \ cp -pr $$d/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file || :; \ fi; \ done info-am: info: info-am dvi-am: dvi: dvi-am check-am: all-am check: check-am installcheck-am: installcheck: installcheck-am install-exec-am: install-exec: install-exec-am install-data-am: install-pkgdataDATA install-data: install-data-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am install: install-am uninstall-am: uninstall-pkgdataDATA uninstall: uninstall-am all-am: Makefile $(DATA) all-redirect: all-am install-strip: $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install installdirs: $(mkinstalldirs) $(DESTDIR)$(pkgdatadir) mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* maintainer-clean-generic: mostlyclean-am: mostlyclean-generic mostlyclean: mostlyclean-am clean-am: clean-generic mostlyclean-am clean: clean-am distclean-am: distclean-generic clean-am distclean: distclean-am maintainer-clean-am: maintainer-clean-generic distclean-am @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." maintainer-clean: maintainer-clean-am .PHONY: uninstall-pkgdataDATA install-pkgdataDATA tags distdir info-am \ info dvi-am dvi check check-am installcheck-am installcheck \ install-exec-am install-exec install-data-am install-data install-am \ install uninstall-am uninstall all-redirect all-am all installdirs \ mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean # 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: dircproxy-1.0.5/conf/Makefile.am0000664000175000017500000000017207146532774012223 ## Process this file with automake to produce Makefile.in pkgdata_DATA = \ dircproxyrc EXTRA_DIST = \ $(pkgdata_DATA) dircproxy-1.0.5/conf/dircproxyrc0000644000175000017500000010067207567163774012475 # Welcome to dircproxy! # # This is an example configuration file, you can use it as a template to # write your own. Copy it to your home directory and name it # .dircproxyrc to get it automatically picked up when you run dircproxy. # # You can also place it as /usr/local/etc/dircproxyrc if you want it globally # installed, or anywhere else and load it with the -f parameter # # Before dircproxy will start you need to define a number of connection # classes. Instructions on how to do this are at the bottom of this file. # Skip down and do that if you are happy to go with the defaults for # everything else. # # All options are commented out, with their default value shown. To set # one you need to uncomment and change the value. #------------------------------------------------------------------------------# # GLOBAL OPTIONS # # These options may *not* be placed inside a configuration file, and affect # the general operation of dircproxy. # # listen_port # What port should dircproxy listen for connections from IRC clients # on? # # This can be a numeric port number, or a service name from /etc/services # #listen_port 57000 # pid_file # File to write the dircproxy process id to on startup. If you start # this with a "~/" then it refers to a file in a directory under your # home directory. # # none = Don't write pid file # #pid_file "none" # client_timeout # Maxmimum amount of time (in seconds) a client can take to connect to # dircproxy and provide their password and nickname etc. # #client_timeout 60 # connect_timeout # Maximum amount of time (in seconds) a client has to provide a server # to connect to after they've logged in. This only applies if # 'server_autoconnect' is 'no' for that class. # #connect_timeout 60 # dns_timeout # Maximum amount of time (in seconds) to wait for a reply from a DNS # server. If the time exceeds this then the lookup is cancelled. # #dns_timeout 20 #------------------------------------------------------------------------------# # LOCAL OPTIONS # # The rest of the options in this configuration file may be placed in # connection classes or in the main body of the configuration file. If # placed in the main body, they only affect connection classes # defined *after* them in the configuration file. # # SERVER OPTIONS # Options affecting the connection to the IRC server. # server_port # What port do we connect to IRC servers on if the server string doesn't # explicitly set one # # This can be a numeric port number, or a service name from /etc/services # #server_port 6667 # server_retry # How many seconds after disconnection or last connection attempt do we # wait before retrying again? # #server_retry 15 # server_maxattempts # If we are disconnected from the server, how many times should we iterate # the server list before giving up and declaring the proxied connection # dead? # # 0 = iterate forever # #server_maxattempts 0 # server_maxinitattempts # On first connection, how many times should we iterate the server list # before giving up and declaring the proxied connection dead? # # 0 = iterate forever. This isn't recommended. # #server_maxinitattempts 5 # server_keepalive # This checks whether the dircproxy to server connection is alive at the # TCP level. If no data is sent in either direction for a period of time, # a TCP keepalive probe is sent. # # yes = send keepalive probes # no = don't send keepalive probes # #server_keepalive no # server_pingtimeout # For some people, dircproxy doesn't notice that the connection to the # server has been dropped because the socket remains open. For example, # those behind a NAT'd firewall. dircproxy can ping the server and make # sure it gets replies back. If the time since the last reply was # received exceeds the number of seconds below the server is assumed to be # "stoned" and dircproxy leaves it. If you have a high latency connection # to the server, it can wrongly assume the server is stoned because the # PINGs don't arrive in time. Either raise the value, or use the # 'server_keepalive' option instead. # # 0 = don't send PINGs # #server_pingtimeout 0 # server_throttle # To prevent you from being flooded off the IRC network, dircproxy can # throttle the connection to the server to prevent too much being sent # within a certain time period. # # For this you specify a number of bytes, then optionally a time period # in seconds seperated by a colon. If the time period is ommitted then # per second is assmued. # # server_throttle 10 # 10 bytes per second # server_throttle 10:2 # 10 bytes per 2 seconds (5 per second) # # 0 = do not throttle the connection # #server_throttle 1024:10 # server_autoconnect # Should dircproxy automatically connect to the first server in the list # when you connect. If you set this to 'no', then 'allow_jump' is # automatically set to 'yes'. If 'allow_jump_new' is also 'yes', then you # can create connection classes with no 'server' lines. # # yes = Automatically connect to the first server # no = Wait for a /DIRCPROXY JUMP from the client # #server_autoconnect yes # CHANNEL OPTIONS # Options affecting channels you join. # channel_rejoin # If we are kicked off a channel, how many seconds do we wait before # attempting to rejoin. # # -1 = Don't rejoin # 0 = Immediately # #channel_rejoin 15 # channel_leave_on_detach # Should dircproxy automatically make you leave all the channels you # were on when you detach? # # yes = Leave them # no = Remain on them # #channel_leave_on_detach no # channel_rejoin_on_attach # If 'channel_leave_on_detach' is 'yes' then should dircproxy rejoin # those channels when you attach again? # # yes = Rejoin the channels dircproxy automatically left # no = Leave permanently on detach # #channel_rejoin_on_attach yes # IDLE OPTIONS # Options affecting idle times on IRC. # idle_maxtime # Set this to the maximum amount of time you want to appear idle for # while on IRC, if you set this then dircproxy will reset your idle # time if it reaches this limit (in seconds). # # 0 = Don't reset idle time # #idle_maxtime 0 # DISCONNECTION OPTIONS # Options affecting when dircproxy disconnects you. # disconnect_existing_user # If, when you connect to dircproxy, another client is already using # your connection class (ie, if you forgot to close that one), then # this option lets you automatically kill that one off. Make sure you # turn any "automatic reconnect to server" options off before using # this, otherwise you'll have a fight on your hands. # # yes = Yes, disconnect # no = No, don't let me on # #disconnect_existing_user no # disconnect_on_detach # When you detach from dircproxy it usually keeps you connected to the # server until you connect again. If you don't want this, and you want # it to close your server connection as well, then set this. # # yes = Close session on disconnection # no = Stay connected to server until reattachment # #disconnect_on_detach no # MODE OPTIONS # Options affecting user modes set by the IRC server. # initial_modes # Which user modes should we automatically set when you first connect # to a server. Just in case you forget to do it yourself with your # irc client. # # Set to "" to not set any modes. # #initial_modes "i" # drop_modes # Which user modes to drop automatically when you detach, handy to # limit the impact that your client has while connected, or for extra # security if you're an IRCop. # # Set to "" to not drop any modes. # #drop_modes "oOws" # refuse_modes # Which user modes to refuse to accept from a server. If the server # attempts to set one of these, then the connection to it will be dropped # and the next server in the list will be tried. # # A good setting for many people would be "+r", as most servers use that # to mean your connection is restricted. Don't set it to this if you're # on DALnet however, DALnet uses +r to indicate you have registered # with NickServ (gee, thanks guys!). # # Set to "" to not refuse any modes. # #refuse_modes "" # ADDRESS OPTIONS # Options affecting your address on IRC. # local_address # Local hostname to use when connecting to an IRC server. This provides # the same functionality as the ircII -H parameter. # # none = Do not bind any specific hostname # #local_address "none" # MESSAGE OPTIONS # Options affecting messages sent or set by dircproxy on behalf of you. # away_message # If you don't explicitly set an /AWAY message before you detach, dircproxy # can for you, so people don't think you are really at your keyboard # when you're not. # # none = Do not set an away message for you # #away_message "Not available, messages are logged" # quit_message # If you don't explicitly give a message when you /DIRCPROXY QUIT, this # will be used instead. Also used for when you've sent dircproxy not to # remain attached to the server on detachment. # # none = Use dircproxy version number as QUIT message # #quit_message "none" # attach_message # dircproxy can send an announcement onto every channel you are on when # you reattach to it, just to let everyone know you are back. If you # start this with "/ME " then it will be sent as an ACTION CTCP message # (just like the ircII /me command). # # none = Do not announce attachment # #attach_message "none" # detach_message # dircproxy can send an announcement onto every channel you are on when # you detach from it, just to let everyone know you are gone. If you # start this with "/ME " then it will be sent as an ACTION CTCP message # (just like the ircII /me command). # # none = Do not announce detachment # #detach_message "none" # detach_nickname # Nickname to change to automatically after you detach, to indicate you # are away for example. If this contains a '*' character, then that # character is replaced with whataver your nickname was before you # detached (ie "*_away" adds "_away" to the end of your nickname); # # none = Leave nickname as it is # #detach_nickname "none" # NICKNAME OPTIONS # Options affecting your nickname # nick_keep # Whether dircproxy should attempt to keep the nickname you last set # using your client. If this is 'yes' and your nickname is lost while # your client is disconnected, then it will keep on trying to get it back # until a client connects again. # # yes = try to keep my nickname while I'm disconnected # no = if it changes, leave it # #nick_keep yes # CTCP OPTIONS # Options affecting CTCP replies # ctcp_replies # Whether dircproxy should reply to the standard set of CTCP messages # while the client is detached. # # yes = reply to ctcp messages while client is detached # no = nothing but silence # #ctcp_replies yes # CHANNEL LOG OPTIONS # Options affecting logging of channel text. # chan_log_enabled # Whether logging of channel text to files should take place. If this # is 'yes', then you'll be able to recall channel text when you rejoin # and see what you missed. # # yes = Channel text is logged to files # no = Channel text is NOT logged to files # #chan_log_enabled yes # chan_log_always # Channel text will always be logged while you are offline, so when you # come back you can see what you missed. You can also, if you wish, log # channel text while online, so if you're only away a short time you can # get an idea of any context etc. # # This only applies if 'chan_log_enabled' is 'yes'. # # yes = Log channel text while offline and online # no = Log channel text only while offline # #chan_log_always yes # chan_log_maxsize # To preserve your harddisk space, you can limit the size of a channel # log file. Once the log file reaches this number of lines, every line # added will result in a line removed from the top. If you know you are # never going to want all that logged information, this might be a good # setting for you. # # This only applies if 'chan_log_enabled' is 'yes'. # # 0 = No limit to log files # #chan_log_maxsize 0 # chan_log_recall # Number of lines from each channel log file to automatically recall # to your IRC client when you attach. If this is low, you may not get # much useful information, if this is high, it may take a long time for # all the information to arrive. # # This only applies if 'chan_log_enabled' is 'yes'. # # -1 = Recall the whole log (not recommended if chan_log_always is yes) # 0 = Don't automatically recall anything # #chan_log_recall 128 # chan_log_timestamp # Channel text can have a timestamp added to the front to let you know # exactly when a message was logged. These timestamps are displayed when # you recall the log files, or when automatially dumped. # # This applies to ordinary channel logs if 'chan_log_enabled' is 'yes' # and also to the permanent copy if 'chan_log_copydir' is set to something # other than 'none'. # # yes = Include timestamp # no = Do not include timestamp # #chan_log_timestamp no # chan_log_relativetime # If 'chan_log_timestamp' is 'yes' then you also have the option of # using intelligent relative timestamps. If you do, the timestamp shown # when log file information is recalled depends on how old that line is, # making sure it displays enough information (including date if necessary). # Otherwise dircproxy will just tell you the time in HH:MM format which # may not be as useful. # # This does mean that the time itself won't be displayed in the log files # themselves, a timestamp is in place instead. This may cause problems # if you're doing things with the log files yourself. # # yes = Do fancy relative timestamping # no = Do normal timestamping # #chan_log_relativetime yes # chan_log_copydir # As well as dircproxy's own log files, it can also keep a permanent # copy somewhere for your use. dircproxy will append all channel text # seen to this file, but will not use it itself. # # If you do define it, it'll add to each log as you use it. If you # start with "~/" then it will use a directory under your home directory. # # This is done regardless of the 'chan_log_enabled' and 'chan_log_always' # options, although if those are off then you won't get that text # recalled to your client, despite it being in this file. The timestamping # options do apply however. # # none = Do not make a permanent copy # #chan_log_copydir "none" # chan_log_program # Program to pipe channel text into. If given, dircproxy will run this # program for each log file entry giving the full source information as # the first argument, the destination as the second and the text as a # single line on standard input. # # The program can be anywhere in your $PATH, or you can start it with # "~/" if its in a directory under your home directory. # # This is done regardless of the 'chan_log_enabled' and 'chan_log_always' # options. # # none = Do not pipe log messages to a program # #chan_log_program "none" # OTHER LOG OPTIONS # Options affecting logging of server and private messages. # other_log_enabled # Whether logging of server and private messages to files should take # place. If this is 'yes', then you'll be able to recall server and # private messages when you rejoined and see what you missed. # # yes = Server/private messages are logged to files # no = Server/private messages are NOT logged to files # #other_log_enabled yes # other_log_always # Server and private messages will always be logged while you are offline, # so when you come back you can see what you missed. You can also, if you # wish, log these messages while online, so if you're only away a short # time you can get an idea of any context etc. # # This only applies if 'other_log_enabled' is 'yes'. # # yes = Log server/private messages while offline and online # no = Log server/private messages only while offline # #other_log_always no # other_log_maxsize # To preserve your harddisk space, you can limit the size of the # server/private message log file. Once the log file reaches this number # of lines, every line added will result in a line removed from the top. # If you know you are never going to want all that logged information, # this might be a good setting for you. # # This only applies if 'other_log_enabled' is 'yes'. # # 0 = No limit to log file # #other_log_maxsize 0 # other_log_recall # Number of lines from the server/private message log file to automatically # recall to your IRC client when you attach. If this is low, you may not # get much useful information, if this is high, it may take a long time for # all the information to arrive. # # This only applies if 'other_log_enabled' is 'yes'. # # -1 = Recall the whole log (not recommended if other_log_always is yes) # 0 = Don't automatically recall anything # #other_log_recall -1 # other_log_timestamp # Server and private messages can have a timestamp added to the front to # let you know exactly when a message was logged. These timestamps are # displayed when you recall the log files, or when automatially dumped. # # This applies to the server/private message log if 'other_log_enabled' # is 'yes' and also the permanent copy if 'other_log_copydir' is set to # something other than 'none'. # # yes = Include timestamp # no = Do not include timestamp # #other_log_timestamp no # other_log_relativetime # If 'other_log_timestamp' is 'yes' then you also have the option of # using intelligent relative timestamps. If you do, the timestamp shown # when log file information is recalled depends on how old that line is, # making sure it displays enough information (including date if necessary). # Otherwise dircproxy will just tell you the time in HH:MM format which # may not be as useful. # # This does mean that the time itself won't be displayed in the log files # themselves, a timestamp is in place instead. This may cause problems # if you're doing things with the log files yourself. # # yes = Do fancy relative timestamping # no = Do normal timestamping # #other_log_relativetime yes # other_log_copydir # As well as dircproxy's own log file, it can keep a permanent copy # somewhere for your use. dircproxy will append all server and private # messages seen to this file, but will not use it itself. # # If you do define it, it'll add to the log as it uses it. If you start # with "~/" then it will use a directory under your home directory. # # This is done regardless of the 'other_log_enabled' and 'other_log_always' # options, although if those are off then won't get that text recalled # to your client, despite it being in this file. The timestamping options # do apply however. # # none = Do not make a permanent copy # #other_log_copydir "none" # other_log_program # Program to pipe server and private messages into. If given, dircproxy # will run this program for each log file entry giving the full source # information as the first argument, the destination as the second and # the text as a single line on standard input. # # The program can be anywhere in your $PATH, or you can start it with # "~/" if its in a directory under your home directory. # # This is done regardless of the 'other_log_enabled' and 'other_log_always' # options. # # none = Do not pipe log messages to a program # #other_log_program "none" # MISC LOG OPTIONS # Options affecting both channel and server/private message logs # log_timeoffset # Differenice in minutes from your IRC client to the dircproxy machine. # So if you're in GMT, but your dircproxy machine is in PST (which is # 8 hours behind), then this would be -(8 * 60) = -480. Used for log # file timestamps. # # 0 = Don't adjust log timestamps. # #log_timeoffset 0 # log_events # Events you want dircproxy to log for you. This is a comma seperated # list of event names, prefixed with '+' to add the event to the list or # '-' to remove an event. You can also specify 'all' to log all events # (the default) or 'none' to not log anything. # # Example, to just log text and action's: # log_events "none,+text,+action" # # Example, to log everything but server messages: # log_events "all,-server" # log_events -server # you don't need to specify 'all' # # The possible events are: # text Channel text and private messages # action CTCP ACTION events (/me) sent to you or channels # ctcp Whether to record whether a CTCP was sent to you # join People (including you) joining channels # part People (including you) leaving channels # kick People (including you) being kicked from channels # quit People quit'ing from IRC # nick People (including you) changing nickname # mode Changes in channel modes or your own personal mode # topic Changes to the channel topic # client You detaching and attaching # server Connections and disconnections from servers # error Problems and errors dircproxy encounters (recommended!) # #log_events all # DCC PROXY OPTIONS # Options affecting proxying and capturing of DCC chat and send # requests. # dcc_proxy_incoming # Whether dircproxy should proxy DCC chat and send requests sent # *to* you by others on IRC. # # yes = Proxy incoming requests. # no = Do not proxy incoming requests. # #dcc_proxy_incoming yes # dcc_proxy_outgoing # Whether dircproxy should proxy DCC chat and send requests sent # *by* you to others on IRC. # # yes = Proxy outgoing requests. # no = Do not proxy outgoing requests. # #dcc_proxy_outgoing yes # dcc_proxy_ports # Ports that dircproxy can use to listen for DCC connections on. # This is for when you're behind a firewall that only allows certain # ports through, or when doing DCC-via-ssh. # # It is a comma seperated list of port numbers or ranges of ports, # for example '57100-57199,57400,57500,57600-57800' # # any = Use any port given to us by the kernel. # #dcc_proxy_ports any # dcc_proxy_timeout # Maxmimum amount of time (in seconds) to allow for both sides of # a DCC proxy to be connected. # #dcc_proxy_timeout 60 # dcc_proxy_sendreject # Whether to send a physical REJECT message via CTCP back to the # source of the request in event of failure. # # yes = Send reject CTCP message back. # no = Do not send any message back. # #dcc_proxy_sendreject yes # dcc_send_fast # Whether to ignore the "acknowledgment" packets from the client and # just send the file to them as fast as possible. There should be no # real danger in doing this. # # yes = Send as fast as possible. # no = Wait for each packet to be acknowledged. # #dcc_send_fast no # dcc_capture_directory # dircproxy can capture files sent via DCC and store them on the # server. Especially useful while you are detached, whether it # does it while attached or not depends on 'dcc_capture_always'. # This is the directory to store those captured files in. # # If start with "~/" then it will use a directory under your home # directory. # # none = Do not capture files. # #dcc_capture_directory "none" # dcc_capture_always # If we're capturing DCC send's, should we do it while the client # is connected as well? If 'yes', then the client will never see # the file, it'll be just stored on the server with a notice sent # to the client telling them where. # # yes = Capture even when a client is connected. # no = Capture only when client detached. # #dcc_capture_always no # dcc_capture_withnick # Whether to start the filename of the captured file with the # nickname of the sender, so you know who it came from. # # yes = Start with nickname. # no = Do not alter the filename. # #dcc_capture_withnick no # dcc_capture_maxsize # Maximum size (in kilobytes) that a captured file can be. If # a captured file is larger than this, or becomes larger than # this, then the capture will be aborted and the file removed # from the disk. Prevents people from filling your disk up while # you're detached with a massive file. # # 0 = No limit to file size. # #dcc_capture_maxsize 0 # dcc_tunnel_incoming # Port of a local ssh tunnel leading to another dircproxy client that # we should use for incoming DCC requests. This should not be set if # 'dcc_tunnel_outgoing' is set. # # See the README.dcc-via-ssh file included with the dircproxy # distribution for more information. # # This can be a numeric port number, or a service name from /etc/services # # none = There is no tunnel. # #dcc_tunnel_incoming "none" # dcc_tunnel_outgoing # Port of a local ssh tunnel leading to another dircproxy client that # we should use for outgoing DCC requests. This should not be set if # 'dcc_tunnel_incoming' is set. # # See the README.dcc-via-ssh file included with the dircproxy # distribution for more information. # # This can be a numeric port number, or a service name from /etc/services # # none = There is no tunnel. # #dcc_tunnel_outgoing "none" # ADVANCED OPTIONS # Options for the advanced user. # switch_user # If you're running dircproxy as root, it can switch to a different # "effective user id" to create the server connection. This means # that your system ident daemon (and therefore IRC, if it queries it) # will see your server connection as the user you put here, instead of # root. # # This is most useful if you are sysadmin running a dircproxy server # for multiple people and want them to all appear as different usernames # without using a hacked identd. Because dircproxy is still running as # root, it will have those privileges for all operations, including the # bind(2) for the 'local_address' config option if you're using Secure # Linux patches. # # This can only be used if your system supports seteuid(2) and if you # are running dircproxy as the root user, and not just setuid. Attempting # otherwise will generate a warning as dircproxy starts. # # This can be a numeric uid or a username from /etc/passwd. # # none = Do not do this. # #switch_user "none" # MOTD OPTIONS # Options affecting the dircproxy message of the day. # motd_logo # If this is yes, then the dircproxy logo and version number will be # included in the message of the day when you connect. Only the picky # would turn this off, its pretty! # # yes = Show me the pretty logo # no = I don't like logos, I'm boring, I eat llamas. # #motd_logo yes # motd_file # Custom message of the day file to send when users connect to dircproxy. # The contents of this file will be sent after the logo and before the # stats. If you start this with a "~/" then it refers to a file in # a directory under your home directory. # # none = No custom motd # #motd_file "none" # motd_stats # Display information on what channels you were on, and log file sizes # etc in the message of the day. This is handy, and lets you know how # not only much information you missed, but how much will be sent to you. # # yes = Show the stats # no = They don't interest me, don't show them. # #motd_stats yes # COMMAND OPTIONS # Options allowing or disallowing use of /DIRCPROXY commands. # allow_persist # You can disable the /DIRCPROXY PERSIST command here if you do not want # people using your proxy to be able to do that. # # yes = Command enabled # no = Command disabled # #allow_persist yes # allow_jump # You can disable the /DIRCPROXY JUMP command here if you do not want # people to do that. # # yes = Command enabled # no = Command disabled # #allow_jump yes # allow_jump_new # If the /DIRCPROXY JUMP commmand is enabled, then you can disable it being # used to jump to a server:port not in the list specified in the # configuration file. # # yes = Can jump to any server # no = Only ones in the config file # #allow_jump_new yes # allow_host # You can disable the /DIRCPROXY HOST command here if you do not want # people to do that. # # yes = Command enabled # no = Command disabled # #allow_host yes # allow_die # You can enable the /DIRCPROXY DIE command here if you want people # to be able to kill your proxy. This isn't recommended, instead only # enable it for a specific connection class (ie yours). # # yes = Command enabled # no = Command disabled # #allow_die no # allow_users # You can enable the /DIRCPROXY USERS command here if you want people # to be able to see who's using your proxy. This isn't recommended, # instead only enable it for a specific connection class (ie yours). # # yes = Command enabled # no = Command disabled # #allow_users no # allow_kill # You can enable the /DIRCPROXY KILL command here if you want people # to be able to disconnect anyone using your proxy (including you!). # This isn't recommended, instead only enable it for a specific # connection class (ie yours). # # yes = Command enabled # no = Command disabled # #allow_kill no #------------------------------------------------------------------------------# # CONNECTION CLASSES # # Okay, thats the easy bit of the config file over and done with, now # you have to define "connection classes" to allow yourself, and others # if you wish, to connect to dircproxy. Only one person may use a # connection class at one time. # # You can define as many of these as you like! # # A connection class must have a password, and the address of at least # one server (except as noted above) to connect to. The password is # compared with the one you configure your IRC client to use, and if they # match then the connection class is used. # # Don't have two classes with the same password, as the second one will # never be seen. # # Please note that although the passwords are shown here in plain text, # they MUST be encrypted (unless you manually edit src/dircproxy.h and # remove the ENCRYPTED_PASSWORDS #define). Encrypt the passwords using # your system's standard crypt(3) function, there's a handy utility # installed with dircproxy called dircproxy-crypt(1) that can do this # for you. Its in the crypt directory of the source, or installed # in the same place as dircproxy. # #connection { # # this password must by encrypted using dircproxy-crypt(1) # password "foobar" # server "irc.linux.com" #} # You can specify multiple servers, they are iterated if one fails or # disconnects you. You can also specify specific ports and # optional passwords for a server, seperating the port and password with # a ':'. To use a default port, and a specific password, separate it # from the server with a '::'. (These passwords are *not* encrypted!) # # To provide extra security you can limit the places you can connect from # using the 'from' keyword, specifying the hostname and/or IP address # masks with * or ?. # from "*.myisp.com" # from "*.mywork.net" # # You can also specify an initial channel set to be joined using the # 'join' keyword. Note that the list of channels MUST be surrounded # by quotes (to distinguish from a comment) and seperated by commas. # join "#foo" # join "#foo,bar" # # Channel keywords should be seperated by the channel name with a space # as you'd expect. # join "#foo key,#bar,#baz key2" # # Additionally, as already noted, any local option from above can be included # to further configure the class. (but not the global options) # #connection { # # this password must by encrypted using dircproxy-crypt(1) # password "applejack" # # server "irc.linux.com" # server "irc.openprojects.net:6668" # server "irc.linux.com:6668" # server "oper.irc.netsplit.com:6660:scrumpy" # server "oper.irc.gurgle.org::scrumpy" # # from "*.myisp.com" # from "*.mywork.net" # # join "#foo key,#bar" # join "#baz" # # local_address "i.am.a.virtual.host.com" # away_message "I'm not here, go away!" # # channel_rejoin -1 # disconnect_existing_user yes # # allow_die yes #} dircproxy-1.0.5/contrib/0000777000175000017500000000000007567165531010764 5dircproxy-1.0.5/contrib/Makefile.in0000644000175000017500000001211207567165531012742 # Makefile.in generated automatically by automake 1.4-p6 from Makefile.am # Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. SHELL = @SHELL@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ libexecdir = @libexecdir@ datadir = @datadir@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include DESTDIR = pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : host_alias = @host_alias@ host_triplet = @host@ AWK = @AWK@ CC = @CC@ LN_S = @LN_S@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ PACKAGE = @PACKAGE@ RANLIB = @RANLIB@ VERSION = @VERSION@ pkgdata_DATA = log.pl privmsg-log.pl cronchk.sh EXTRA_DIST = README dircproxy.spec $(pkgdata_DATA) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = DATA = $(pkgdata_DATA) DIST_COMMON = README Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP_ENV = --best all: all-redirect .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps contrib/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status install-pkgdataDATA: $(pkgdata_DATA) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(pkgdatadir) @list='$(pkgdata_DATA)'; for p in $$list; do \ if test -f $(srcdir)/$$p; then \ echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkgdatadir)/$$p"; \ $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkgdatadir)/$$p; \ else if test -f $$p; then \ echo " $(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p"; \ $(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \ fi; fi; \ done uninstall-pkgdataDATA: @$(NORMAL_UNINSTALL) list='$(pkgdata_DATA)'; for p in $$list; do \ rm -f $(DESTDIR)$(pkgdatadir)/$$p; \ done tags: TAGS TAGS: distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) subdir = contrib distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ if test -d $$d/$$file; then \ cp -pr $$d/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file || :; \ fi; \ done info-am: info: info-am dvi-am: dvi: dvi-am check-am: all-am check: check-am installcheck-am: installcheck: installcheck-am install-exec-am: install-exec: install-exec-am install-data-am: install-pkgdataDATA install-data: install-data-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am install: install-am uninstall-am: uninstall-pkgdataDATA uninstall: uninstall-am all-am: Makefile $(DATA) all-redirect: all-am install-strip: $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install installdirs: $(mkinstalldirs) $(DESTDIR)$(pkgdatadir) mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* maintainer-clean-generic: mostlyclean-am: mostlyclean-generic mostlyclean: mostlyclean-am clean-am: clean-generic mostlyclean-am clean: clean-am distclean-am: distclean-generic clean-am distclean: distclean-am maintainer-clean-am: maintainer-clean-generic distclean-am @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." maintainer-clean: maintainer-clean-am .PHONY: uninstall-pkgdataDATA install-pkgdataDATA tags distdir info-am \ info dvi-am dvi check check-am installcheck-am installcheck \ install-exec-am install-exec install-data-am install-data install-am \ install uninstall-am uninstall all-redirect all-am all installdirs \ mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean # 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: dircproxy-1.0.5/contrib/README0000664000175000017500000000116607430177777011572 Contributed and unsupported extras ---------------------------------- These files are either contributed by dircproxy users, or useful to dircproxy users but not actually part of dircproxy. cronchk.sh script to run from crontab to check whether dircproxy is running or not, and restart it if necessary log.pl *_log_program script to send a mail on certain words or messages from certain people privmsg-log.pl other_log_program to log private messages to files named after the nickname of the sender (rather than all to the same file) Copyright (C) 2002 Scott James Remnant . All Rights Reserved. dircproxy-1.0.5/contrib/Makefile.am0000664000175000017500000000026107430177777012741 ## Process this file with automake to produce Makefile.in pkgdata_DATA = \ log.pl \ privmsg-log.pl \ cronchk.sh EXTRA_DIST = \ README \ dircproxy.spec \ $(pkgdata_DATA) dircproxy-1.0.5/contrib/dircproxy.spec0000664000175000017500000000346007537114471013576 Summary: irc proxy Name: dircproxy %define branch 1.0 %define version %{branch}.5 %define location /usr Version: %{version} Release: 1 Copyright: GPL Group: Applications/Internet URL: http://www.dircproxy.net/ Source: ftp://ftp.dircproxy.net/pub/dircproxy/%{branch}/dircproxy-%{version}.tar.gz BuildRoot: /var/tmp/%{name}-root Packager: Hollis Blanchard %description dircproxy is an IRC proxy server designed for people who use IRC from lots of different workstations or clients, but wish to remain connected and see what they missed while they were away. You connect to IRC through dircproxy, and it keeps you connected to the server, even after you detach your client from it. While you're detached, it logs channel and private messages as well as important events, and when you reattach it'll let you know what you missed. %prep %setup %build CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{location} make %install rm -rf $RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT/%{location}/bin mkdir -p $RPM_BUILD_ROOT/%{location}/share/dircproxy mkdir -p $RPM_BUILD_ROOT/%{location}/man/man1/ install src/dircproxy $RPM_BUILD_ROOT/%{location}/bin install crypt/dircproxy-crypt $RPM_BUILD_ROOT/%{location}/bin install conf/dircproxyrc $RPM_BUILD_ROOT/%{location}/share/dircproxy/ install contrib/log.pl $RPM_BUILD_ROOT/%{location}/share/dircproxy/ install doc/dircproxy-crypt.1 $RPM_BUILD_ROOT/%{location}/man/man1/ install doc/dircproxy.1 $RPM_BUILD_ROOT/%{location}/man/man1/ %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) %{location}/bin/dircproxy %{location}/bin/dircproxy-crypt %{location}/share/dircproxy/dircproxyrc %{location}/share/dircproxy/log.pl %{location}/man/man1/dircproxy-crypt.1* %{location}/man/man1/dircproxy.1* %doc AUTHORS COPYING ChangeLog FAQ INSTALL NEWS PROTOCOL README* TODO dircproxy-1.0.5/contrib/log.pl0000775000175000017500000000531507203006562012010 #!/usr/bin/perl # Perl script to take dircproxy log information and e-mail it to # an address if it contains certain words or is from certain people. # # To use, set the following in dircproxyrc: # chan_log_program "/path/to/log.pl" # or # other_log_program "/path/to/log.pl" # use vars qw/$mailto @match @from $sendmail/; use strict; # Address to e-mail to $mailto = 'nobody@localhost'; # Words to match on @match = ('rabbit', 'llama'); # People to always send @from = ('Joe', 'Bloggs'); # Path to sendmail $sendmail = '/usr/lib/sendmail'; #------------------------------------------------------------------------------# # The first argument to this script is the source of the text. Its in the # following formats # # -dircproxy- # Notice from dircproxy # # -servername- # Notice from a server # # # Private message from a person # # -nick!username@host- # Notice from a person # # [nick!username@host] # Unfiltered CTCP message (usually an ACTION) from a person # my $source = shift(@ARGV); die "No source given by dircproxy" unless $source && length $source; my $notice = ($source =~ /^-/ ? 1 : 0); $source =~ s/^.//; $source =~ s/.$//; my ($nickname, $username, $hostname); my $server = 0; if ($source =~ /^([^!]*)!([^\@]*)\@(.*)$/) { ($nickname, $username, $hostname) = ($1, $2, $3); } else { $nickname = $source; $server = 1 if $notice; } #------------------------------------------------------------------------------# # The second argument to this script is who it was to (your nickname or # a channel name) my $dest = shift(@ARGV); #------------------------------------------------------------------------------# # The text to log is on the standard input. my $text = ; die "No text given by dircproxy" unless $text && length $text; #------------------------------------------------------------------------------# my $mailit = 0; # Always mail server messages (including those from dircproxy) $mailit = 1 if $server; # Check the from foreach my $from (@from) { $mailit = 1 if lc($nickname) eq lc($from); } # Check the text foreach my $match (@match) { $mailit = 1 if $text =~ /$match/i; } #------------------------------------------------------------------------------# if ($mailit) { my $subject = ""; if ($server) { $subject .= "Server message"; } elsif ($notice) { $subject .= "Notice"; } else { $subject .= "Message"; } $subject .= " from " . $nickname; $subject .= " ($username\@$hostname)" unless $server; open MAILER, '|' . $sendmail . ' -t'; print MAILER "From: dircproxy\n"; print MAILER "To: $mailto\n"; print MAILER "Subject: $subject\n"; print MAILER "\n"; print MAILER "Sent to $dest\n" if $dest; print MAILER $text; close MAILER; } dircproxy-1.0.5/contrib/privmsg-log.pl0000775000175000017500000000310507427726551013507 #!/usr/bin/perl # Logs private messages to seperate files. # # To use, set the following in dircproxyrc: # other_log_program "/path/to/privmsg-log.pl" # use vars qw/$logdir/; use strict; # Directory to store files in $logdir = '/tmp'; #------------------------------------------------------------------------------# # The first argument to this script is the source of the text. Its in the # following formats # # -dircproxy- # Notice from dircproxy # # -servername- # Notice from a server # # # Private message from a person # # -nick!username@host- # Notice from a person # # [nick!username@host] # Unfiltered CTCP message (usually an ACTION) from a person # my $source = shift(@ARGV); die "No source given by dircproxy" unless $source && length $source; my $nickname; if ($source =~ /^[<-\[]([^!]*)![^\@]*\@.*[>-\]]$/) { $nickname = $1; } else { # Not a private message, don't want it exit 0; } #------------------------------------------------------------------------------# # The second argument to this script is who it was to (your nickname or # a channel name) my $dest = shift(@ARGV); if ($dest =~ /^#/) { # A channel message, don't want it exit 0; } #------------------------------------------------------------------------------# # The text to log is on the standard input. my $text = ; die "No text given by dircproxy" unless $text && length $text; #------------------------------------------------------------------------------# open LOGFILE, ">>$logdir/$nickname"; print LOGFILE $source . " " . $text; close LOGFILE; dircproxy-1.0.5/contrib/cronchk.sh0000775000175000017500000000204007430177777012670 #!/bin/sh # Script to run from crontab to check whether dircproxy is still running, # and if not, restart it # # You will need to set the 'pid_file' option in your .dircproxyrc # # To use, set the following in crontab # */10 * * * * cronchk.sh # or # */10 * * * * cronchk.sh /path/to/dircproxyrc # command to run dircproxy DIRCPROXY=dircproxy # config file can be specified as the first argument CONFFILE=$HOME/.dircproxyrc if test -n "$1"; then CONFFILE=$1 fi # look for the pid_file directive PIDFILE=`grep ^pid_file $CONFFILE | sed 's/^pid_file[ "]*//' | sed 's/"*$//'` PIDFILE=`eval echo \`echo $PIDFILE | sed 's/^~/$HOME/'\`` if test -n "$PIDFILE" -a "$PIDFILE" != "none"; then RUNNING=no if test -r "$PIDFILE"; then if kill -0 `cat $PIDFILE` > /dev/null 2>&1; then RUNNING=yes else echo "PID file, but no dircproxy. :(" fi else echo "No PID file" fi if test "$RUNNING" = "no"; then echo "Restarting dircproxy" $DIRCPROXY fi else echo "Couldn't locate pid_file directive in config file $CONFFILE" exit 1 fi dircproxy-1.0.5/getopt/0000777000175000017500000000000007567165532010627 5dircproxy-1.0.5/getopt/Makefile.in0000644000175000017500000001511407567165532012612 # Makefile.in generated automatically by automake 1.4-p6 from Makefile.am # Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. SHELL = @SHELL@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ libexecdir = @libexecdir@ datadir = @datadir@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include DESTDIR = pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : host_alias = @host_alias@ host_triplet = @host@ AWK = @AWK@ CC = @CC@ LN_S = @LN_S@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ PACKAGE = @PACKAGE@ RANLIB = @RANLIB@ VERSION = @VERSION@ noinst_LIBRARIES = libgetopt.a libgetopt_a_SOURCES = getopt.c getopt.h getopt1.c mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) DEFS = @DEFS@ -I. -I$(srcdir) -I.. CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ libgetopt_a_LIBADD = libgetopt_a_OBJECTS = getopt.o getopt1.o AR = ar CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ DIST_COMMON = Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP_ENV = --best SOURCES = $(libgetopt_a_SOURCES) OBJECTS = $(libgetopt_a_OBJECTS) all: all-redirect .SUFFIXES: .SUFFIXES: .S .c .o .s $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps getopt/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status mostlyclean-noinstLIBRARIES: clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) distclean-noinstLIBRARIES: maintainer-clean-noinstLIBRARIES: .c.o: $(COMPILE) -c $< .s.o: $(COMPILE) -c $< .S.o: $(COMPILE) -c $< mostlyclean-compile: -rm -f *.o core *.core clean-compile: distclean-compile: -rm -f *.tab.c maintainer-clean-compile: libgetopt.a: $(libgetopt_a_OBJECTS) $(libgetopt_a_DEPENDENCIES) -rm -f libgetopt.a $(AR) cru libgetopt.a $(libgetopt_a_OBJECTS) $(libgetopt_a_LIBADD) $(RANLIB) libgetopt.a tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ awk ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ here=`pwd` && cd $(srcdir) \ && mkid -f$$here/ID $$unique $(LISP) TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ awk ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ || (cd $(srcdir) && etags -o $$here/TAGS $(ETAGS_ARGS) $$tags $$unique $(LISP)) mostlyclean-tags: clean-tags: distclean-tags: -rm -f TAGS ID maintainer-clean-tags: distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) subdir = getopt distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ if test -d $$d/$$file; then \ cp -pr $$d/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file || :; \ fi; \ done getopt.o: getopt.c ../config.h getopt1.o: getopt1.c ../config.h getopt.h info-am: info: info-am dvi-am: dvi: dvi-am check-am: all-am check: check-am installcheck-am: installcheck: installcheck-am install-exec-am: install-exec: install-exec-am install-data-am: install-data: install-data-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am install: install-am uninstall-am: uninstall: uninstall-am all-am: Makefile $(LIBRARIES) all-redirect: all-am install-strip: $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install installdirs: mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* maintainer-clean-generic: mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \ mostlyclean-tags mostlyclean-generic mostlyclean: mostlyclean-am clean-am: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \ mostlyclean-am clean: clean-am distclean-am: distclean-noinstLIBRARIES distclean-compile \ distclean-tags distclean-generic clean-am distclean: distclean-am maintainer-clean-am: maintainer-clean-noinstLIBRARIES \ maintainer-clean-compile maintainer-clean-tags \ maintainer-clean-generic distclean-am @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." maintainer-clean: maintainer-clean-am .PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \ clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \ mostlyclean-compile distclean-compile clean-compile \ maintainer-clean-compile tags mostlyclean-tags distclean-tags \ clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ check-am installcheck-am installcheck install-exec-am install-exec \ install-data-am install-data install-am install uninstall-am uninstall \ all-redirect all-am all installdirs mostlyclean-generic \ distclean-generic clean-generic maintainer-clean-generic clean \ mostlyclean distclean maintainer-clean # 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: dircproxy-1.0.5/getopt/Makefile.am0000664000175000017500000000023107203006105012546 ## Process this file with automake to produce Makefile.in noinst_LIBRARIES = \ libgetopt.a libgetopt_a_SOURCES = \ getopt.c \ getopt.h \ getopt1.c dircproxy-1.0.5/getopt/getopt.c0000664000175000017500000005061407203006105012172 /* Getopt for GNU. NOTE: getopt is now part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu before changing it! Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* NOTE!!! AIX requires this to be the first thing in the file. Do not put ANYTHING before it! */ #if !defined (__GNUC__) && defined (_AIX) #pragma alloca #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef __GNUC__ #define alloca __builtin_alloca #else /* not __GNUC__ */ #if defined (HAVE_ALLOCA_H) || (defined(sparc) && (defined(sun) || (!defined(USG) && !defined(SVR4) && !defined(__svr4__)))) #include #else #ifndef _AIX char *alloca (); #endif #endif /* alloca.h */ #endif /* not __GNUC__ */ #if !__STDC__ && !defined(const) && IN_GCC #define const #endif /* This tells Alpha OSF/1 not to define a getopt prototype in . */ #ifndef _NO_PROTO #define _NO_PROTO #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #if defined (_LIBC) || !defined (__GNU_LIBRARY__) /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ #undef alloca /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ #include #else /* Not GNU C library. */ #define __alloca alloca #endif /* GNU C library. */ /* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a long-named option. Because this is not POSIX.2 compliant, it is being phased out. */ /* #define GETOPT_COMPAT */ /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. As `getopt' works, it permutes the elements of ARGV so that, when it is done, all the options precede everything else. Thus all application programs are extended to handle flexible argument order. Setting the environment variable POSIXLY_CORRECT disables permutation. Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ #include "getopt.h" /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ char *optarg = 0; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ /* XXX 1003.2 says this must be 1 before any call. */ int optind = 0; /* The next char to be scanned in the option-element in which the last option character we returned was found. This allows us to pick up the scan where we left off. If this is zero, or a null string, it means resume the scan by advancing to the next ARGV-element. */ static char *nextchar; /* Callers store zero here to inhibit the error message for unrecognized options. */ int opterr = 1; /* Set to an option character which was unrecognized. This must be initialized on some systems to avoid linking in the system's own getopt implementation. */ int optopt = '?'; /* Describe how to deal with options that follow non-option ARGV-elements. If the caller did not specify anything, the default is REQUIRE_ORDER if the environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. REQUIRE_ORDER means don't recognize them as options; stop option processing when the first non-option is seen. This is what Unix does. This mode of operation is selected by either setting the environment variable POSIXLY_CORRECT, or using `+' as the first character of the list of option characters. PERMUTE is the default. We permute the contents of ARGV as we scan, so that eventually all the non-options are at the end. This allows options to be given in any order, even with programs that were not written to expect this. RETURN_IN_ORDER is an option available to programs that were written to expect options and other ARGV-elements in any order and that care about the ordering of the two. We describe each non-option ARGV-element as if it were the argument of an option with character code 1. Using `-' as the first character of the list of option characters selects this mode of operation. The special argument `--' forces an end of option-scanning regardless of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return EOF with `optind' != ARGC. */ static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; #ifdef __GNU_LIBRARY__ /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ #include #define my_index strchr #define my_bcopy(src, dst, n) memcpy ((dst), (src), (n)) #else /* Avoid depending on library functions or files whose names are inconsistent. */ char *getenv (); static char * my_index (str, chr) const char *str; int chr; { while (*str) { if (*str == chr) return (char *) str; str++; } return 0; } static void my_bcopy (from, to, size) const char *from; char *to; int size; { int i; for (i = 0; i < size; i++) to[i] = from[i]; } #endif /* GNU C library. */ /* Handle permutation of arguments. */ /* Describe the part of ARGV that contains non-options that have been skipped. `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is the index after the last of them. */ static int first_nonopt; static int last_nonopt; /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) which contains all the non-options that have been skipped so far. The other is elements [last_nonopt,optind), which contains all the options processed since those non-options were skipped. `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ static void exchange (argv) char **argv; { int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *); char **temp = (char **) __alloca (nonopts_size); /* Interchange the two blocks of data in ARGV. */ my_bcopy ((char *) &argv[first_nonopt], (char *) temp, nonopts_size); my_bcopy ((char *) &argv[last_nonopt], (char *) &argv[first_nonopt], (optind - last_nonopt) * sizeof (char *)); my_bcopy ((char *) temp, (char *) &argv[first_nonopt + optind - last_nonopt], nonopts_size); /* Update records for the slots the non-options now occupy. */ first_nonopt += (optind - last_nonopt); last_nonopt = optind; } /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. If an element of ARGV starts with '-', and is not exactly "-" or "--", then it is an option element. The characters of this element (aside from the initial '-') are option characters. If `getopt' is called repeatedly, it returns successively each of the option characters from each of the option elements. If `getopt' finds another option character, it returns that character, updating `optind' and `nextchar' so that the next call to `getopt' can resume the scan with the following option character or ARGV-element. If there are no more option characters, `getopt' returns `EOF'. Then `optind' is the index in ARGV of the first ARGV-element that is not an option. (The ARGV-elements have been permuted so that those that are not options now come last.) OPTSTRING is a string containing the legitimate option characters. If an option character is seen that is not listed in OPTSTRING, return '?' after printing an error message. If you set `opterr' to zero, the error message is suppressed but we still return '?'. If a char in OPTSTRING is followed by a colon, that means it wants an arg, so the following text in the same ARGV-element, or the text of the following ARGV-element, is returned in `optarg'. Two colons mean an option that wants an optional arg; if there is text in the current ARGV-element, it is returned in `optarg', otherwise `optarg' is set to zero. If OPTSTRING starts with `-' or `+', it requests different methods of handling the non-option ARGV-elements. See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. Long-named options begin with `--' instead of `-'. Their names may be abbreviated as long as the abbreviation is unique or is an exact match for some defined option. If they have an argument, it follows the option name in the same ARGV-element, separated from the option name by a `=', or else the in next ARGV-element. When `getopt' finds a long-named option, it returns 0 if that option's `flag' field is nonzero, the value of the option's `val' field if the `flag' field is zero. The elements of ARGV aren't really const, because we permute them. But we pretend they're const in the prototype to be compatible with other systems. LONGOPTS is a vector of `struct option' terminated by an element containing a name which is zero. LONGIND returns the index in LONGOPT of the long-named option found. It is only valid when a long-named option has been found by the most recent call. If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ int _getopt_internal (argc, argv, optstring, longopts, longind, long_only) int argc; char *const *argv; const char *optstring; const struct option *longopts; int *longind; int long_only; { int option_index; optarg = 0; /* Initialize the internal data when the first call is made. Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ if (optind == 0) { first_nonopt = last_nonopt = optind = 1; nextchar = NULL; /* Determine how to handle the ordering of options and nonoptions. */ if (optstring[0] == '-') { ordering = RETURN_IN_ORDER; ++optstring; } else if (optstring[0] == '+') { ordering = REQUIRE_ORDER; ++optstring; } else if (getenv ("POSIXLY_CORRECT") != NULL) ordering = REQUIRE_ORDER; else ordering = PERMUTE; } if (nextchar == NULL || *nextchar == '\0') { if (ordering == PERMUTE) { /* If we have just processed some options following some non-options, exchange them so that the options come first. */ if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (last_nonopt != optind) first_nonopt = optind; /* Now skip any additional non-options and extend the range of non-options previously skipped. */ while (optind < argc && (argv[optind][0] != '-' || argv[optind][1] == '\0') #ifdef GETOPT_COMPAT && (longopts == NULL || argv[optind][0] != '+' || argv[optind][1] == '\0') #endif /* GETOPT_COMPAT */ ) optind++; last_nonopt = optind; } /* Special ARGV-element `--' means premature end of options. Skip it like a null option, then exchange with previous non-options as if it were an option, then skip everything else like a non-option. */ if (optind != argc && !strcmp (argv[optind], "--")) { optind++; if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (first_nonopt == last_nonopt) first_nonopt = optind; last_nonopt = argc; optind = argc; } /* If we have done all the ARGV-elements, stop the scan and back over any non-options that we skipped and permuted. */ if (optind == argc) { /* Set the next-arg-index to point at the non-options that we previously skipped, so the caller will digest them. */ if (first_nonopt != last_nonopt) optind = first_nonopt; return EOF; } /* If we have come to a non-option and did not permute it, either stop the scan or describe it to the caller and pass it by. */ if ((argv[optind][0] != '-' || argv[optind][1] == '\0') #ifdef GETOPT_COMPAT && (longopts == NULL || argv[optind][0] != '+' || argv[optind][1] == '\0') #endif /* GETOPT_COMPAT */ ) { if (ordering == REQUIRE_ORDER) return EOF; optarg = argv[optind++]; return 1; } /* We have found another option-ARGV-element. Start decoding its characters. */ nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-')); } if (longopts != NULL && ((argv[optind][0] == '-' && (argv[optind][1] == '-' || long_only)) #ifdef GETOPT_COMPAT || argv[optind][0] == '+' #endif /* GETOPT_COMPAT */ )) { const struct option *p; char *s = nextchar; int exact = 0; int ambig = 0; const struct option *pfound = NULL; int indfound; while (*s && *s != '=') s++; /* Test all options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, s - nextchar)) { if (s - nextchar == strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (opterr) fprintf (stderr, "%s: option `%s' is ambiguous\n", argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; return '?'; } if (pfound != NULL) { option_index = indfound; optind++; if (*s) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = s + 1; else { if (opterr) { if (argv[optind - 1][1] == '-') /* --option */ fprintf (stderr, "%s: option `--%s' doesn't allow an argument\n", argv[0], pfound->name); else /* +option or -option */ fprintf (stderr, "%s: option `%c%s' doesn't allow an argument\n", argv[0], argv[optind - 1][0], pfound->name); } nextchar += strlen (nextchar); return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (opterr) fprintf (stderr, "%s: option `%s' requires an argument\n", argv[0], argv[optind - 1]); nextchar += strlen (nextchar); return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } /* Can't find it as a long option. If this is not getopt_long_only, or the option starts with '--' or is not a valid short option, then it's an error. Otherwise interpret it as a short option. */ if (!long_only || argv[optind][1] == '-' #ifdef GETOPT_COMPAT || argv[optind][0] == '+' #endif /* GETOPT_COMPAT */ || my_index (optstring, *nextchar) == NULL) { if (opterr) { if (argv[optind][1] == '-') /* --option */ fprintf (stderr, "%s: unrecognized option `--%s'\n", argv[0], nextchar); else /* +option or -option */ fprintf (stderr, "%s: unrecognized option `%c%s'\n", argv[0], argv[optind][0], nextchar); } nextchar = (char *) ""; optind++; return '?'; } } /* Look at and handle the next option-character. */ { char c = *nextchar++; char *temp = my_index (optstring, c); /* Increment `optind' when we start to process its last character. */ if (*nextchar == '\0') ++optind; if (temp == NULL || c == ':') { if (opterr) { #if 0 if (c < 040 || c >= 0177) fprintf (stderr, "%s: unrecognized option, character code 0%o\n", argv[0], c); else fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c); #else /* 1003.2 specifies the format of this message. */ fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); #endif } optopt = c; return '?'; } if (temp[1] == ':') { if (temp[2] == ':') { /* This is an option that accepts an argument optionally. */ if (*nextchar != '\0') { optarg = nextchar; optind++; } else optarg = 0; nextchar = NULL; } else { /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { #if 0 fprintf (stderr, "%s: option `-%c' requires an argument\n", argv[0], c); #else /* 1003.2 specifies the format of this message. */ fprintf (stderr, "%s: option requires an argument -- %c\n", argv[0], c); #endif } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; nextchar = NULL; } } return c; } } int getopt (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { return _getopt_internal (argc, argv, optstring, (const struct option *) 0, (int *) 0, 0); } #endif /* _LIBC or not __GNU_LIBRARY__. */ #ifdef TEST /* Compile with -DTEST to make an executable for use in testing the above definition of `getopt'. */ int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; c = getopt (argc, argv, "abc:d:0123456789"); if (c == EOF) break; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ dircproxy-1.0.5/getopt/getopt.h0000664000175000017500000001047407203006105012177 /* Declarations for getopt. Copyright (C) 1989, 1990, 1991, 1992, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _GETOPT_H #define _GETOPT_H 1 #ifdef __cplusplus extern "C" { #endif /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ extern char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ extern int optind; /* Callers store zero here to inhibit the error message `getopt' prints for unrecognized options. */ extern int opterr; /* Set to an option character which was unrecognized. */ extern int optopt; /* Describe the long-named options requested by the application. The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector of `struct option' terminated by an element containing a name which is zero. The field `has_arg' is: no_argument (or 0) if the option does not take an argument, required_argument (or 1) if the option requires an argument, optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but left unchanged if the option is not found. To have a long-named option do something other than set an `int' to a compiled-in constant, such as set a value from `optarg', set the option's `flag' field to zero and its `val' field to a nonzero value (the equivalent single-letter option character, if there is one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ struct option { #if __STDC__ const char *name; #else char *name; #endif /* has_arg can't be an enum because some compilers complain about type mismatches in all the code that assumes it is an int. */ int has_arg; int *flag; int val; }; /* Names for the values of the `has_arg' field of `struct option'. */ #define no_argument 0 #define required_argument 1 #define optional_argument 2 #if __STDC__ #if defined(__GNU_LIBRARY__) /* Many other libraries have conflicting prototypes for getopt, with differences in the consts, in stdlib.h. To avoid compilation errors, only prototype getopt for the GNU C library. */ extern int getopt (int argc, char *const *argv, const char *shortopts); #else /* not __GNU_LIBRARY__ */ extern int getopt (); #endif /* not __GNU_LIBRARY__ */ extern int getopt_long (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); extern int getopt_long_only (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); /* Internal only. Users should not call this directly. */ extern int _getopt_internal (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind, int long_only); #else /* not __STDC__ */ extern int getopt (); extern int getopt_long (); extern int getopt_long_only (); extern int _getopt_internal (); #endif /* not __STDC__ */ #ifdef __cplusplus } #endif #endif /* _GETOPT_H */ dircproxy-1.0.5/getopt/getopt1.c0000664000175000017500000001005607203006105012247 /* getopt_long and getopt_long_only entry points for GNU getopt. Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "getopt.h" #if !__STDC__ && !defined(const) && IN_GCC #define const #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #if defined (_LIBC) || !defined (__GNU_LIBRARY__) /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ #include #else char *getenv (); #endif #ifndef NULL #define NULL 0 #endif int getopt_long (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. If an option that starts with '-' (not '--') doesn't match a long option, but does match a short option, it is parsed as a short option instead. */ int getopt_long_only (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 1); } #endif /* _LIBC or not __GNU_LIBRARY__. */ #ifdef TEST #include int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { {"add", 1, 0, 0}, {"append", 0, 0, 0}, {"delete", 1, 0, 0}, {"verbose", 0, 0, 0}, {"create", 0, 0, 0}, {"file", 1, 0, 0}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "abc:d:0123456789", long_options, &option_index); if (c == EOF) break; switch (c) { case 0: printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s", optarg); printf ("\n"); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case 'd': printf ("option d with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ dircproxy-1.0.5/crypt/0000777000175000017500000000000007567165532010466 5dircproxy-1.0.5/crypt/Makefile.in0000644000175000017500000001654507567165532012462 # Makefile.in generated automatically by automake 1.4-p6 from Makefile.am # Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. SHELL = @SHELL@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ libexecdir = @libexecdir@ datadir = @datadir@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include DESTDIR = pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : host_alias = @host_alias@ host_triplet = @host@ AWK = @AWK@ CC = @CC@ LN_S = @LN_S@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ PACKAGE = @PACKAGE@ RANLIB = @RANLIB@ VERSION = @VERSION@ bin_PROGRAMS = dircproxy-crypt dircproxy_crypt_SOURCES = main.c dircproxy_crypt_LDADD = ../getopt/libgetopt.a mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = PROGRAMS = $(bin_PROGRAMS) DEFS = @DEFS@ -I. -I$(srcdir) -I.. CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ dircproxy_crypt_OBJECTS = main.o dircproxy_crypt_DEPENDENCIES = ../getopt/libgetopt.a dircproxy_crypt_LDFLAGS = CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ DIST_COMMON = Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP_ENV = --best SOURCES = $(dircproxy_crypt_SOURCES) OBJECTS = $(dircproxy_crypt_OBJECTS) all: all-redirect .SUFFIXES: .SUFFIXES: .S .c .o .s $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps crypt/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status mostlyclean-binPROGRAMS: clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) distclean-binPROGRAMS: maintainer-clean-binPROGRAMS: install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(bindir) @list='$(bin_PROGRAMS)'; for p in $$list; do \ if test -f $$p; then \ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ else :; fi; \ done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) list='$(bin_PROGRAMS)'; for p in $$list; do \ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ done .c.o: $(COMPILE) -c $< .s.o: $(COMPILE) -c $< .S.o: $(COMPILE) -c $< mostlyclean-compile: -rm -f *.o core *.core clean-compile: distclean-compile: -rm -f *.tab.c maintainer-clean-compile: dircproxy-crypt: $(dircproxy_crypt_OBJECTS) $(dircproxy_crypt_DEPENDENCIES) @rm -f dircproxy-crypt $(LINK) $(dircproxy_crypt_LDFLAGS) $(dircproxy_crypt_OBJECTS) $(dircproxy_crypt_LDADD) $(LIBS) tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ awk ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ here=`pwd` && cd $(srcdir) \ && mkid -f$$here/ID $$unique $(LISP) TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ awk ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ || (cd $(srcdir) && etags -o $$here/TAGS $(ETAGS_ARGS) $$tags $$unique $(LISP)) mostlyclean-tags: clean-tags: distclean-tags: -rm -f TAGS ID maintainer-clean-tags: distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) subdir = crypt distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ if test -d $$d/$$file; then \ cp -pr $$d/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file || :; \ fi; \ done main.o: main.c ../config.h ../getopt/getopt.h info-am: info: info-am dvi-am: dvi: dvi-am check-am: all-am check: check-am installcheck-am: installcheck: installcheck-am install-exec-am: install-binPROGRAMS install-exec: install-exec-am install-data-am: install-data: install-data-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am install: install-am uninstall-am: uninstall-binPROGRAMS uninstall: uninstall-am all-am: Makefile $(PROGRAMS) all-redirect: all-am install-strip: $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install installdirs: $(mkinstalldirs) $(DESTDIR)$(bindir) mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* maintainer-clean-generic: mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-compile \ mostlyclean-tags mostlyclean-generic mostlyclean: mostlyclean-am clean-am: clean-binPROGRAMS clean-compile clean-tags clean-generic \ mostlyclean-am clean: clean-am distclean-am: distclean-binPROGRAMS distclean-compile distclean-tags \ distclean-generic clean-am distclean: distclean-am maintainer-clean-am: maintainer-clean-binPROGRAMS \ maintainer-clean-compile maintainer-clean-tags \ maintainer-clean-generic distclean-am @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." maintainer-clean: maintainer-clean-am .PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \ maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ mostlyclean-compile distclean-compile clean-compile \ maintainer-clean-compile tags mostlyclean-tags distclean-tags \ clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ check-am installcheck-am installcheck install-exec-am install-exec \ install-data-am install-data install-am install uninstall-am uninstall \ all-redirect all-am all installdirs mostlyclean-generic \ distclean-generic clean-generic maintainer-clean-generic clean \ mostlyclean distclean maintainer-clean # 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: dircproxy-1.0.5/crypt/Makefile.am0000664000175000017500000000026407204530074012423 ## Process this file with automake to produce Makefile.in bin_PROGRAMS = \ dircproxy-crypt dircproxy_crypt_SOURCES = \ main.c dircproxy_crypt_LDADD = \ ../getopt/libgetopt.a dircproxy-1.0.5/crypt/main.c0000664000175000017500000001131707410714172011462 /* dircproxy-crypt * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * main.c * - Encyrpt a password taken from stdin or the command line * * This is deliberately simple, it doesn't even malloc() anything (which, * for something I wrote, is amazing). * -- * @(#) $Id: main.c,v 1.3 2001/12/21 20:15:54 keybuk Exp $ * * 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. */ #include #include #include #include #ifdef HAVE_CONFIG_H #include #else /* HAVE_CONFIG_H */ #define PACKAGE "dircproxy" #define VERSION "-debug" #endif /* HAVE_CONFIG_H */ #ifdef HAVE_CRYPT_H #include #else /* HAVE_CRYPT_H */ #include #endif /* HAVE_CRYPT_H */ #include "getopt/getopt.h" /* forward declarations */ static void _encrypt(const char *); static void _saltchar(char *); static int _print_usage(void); static int _print_version(void); static int _print_help(void); /* This is so "ident" and "what" can query version etc - userful (not) */ const char *rcsid = "@(#) $Id: main.c,v 1.3 2001/12/21 20:15:54 keybuk Exp $"; /* The name of the program */ static char *progname; /* Long options */ static struct option long_opts[] = { { "help", 0, NULL, 'h' }, { "version", 0, NULL, 'v' }, { 0, 0, 0, 0} }; /* Options */ #define GETOPTIONS "hv" /* The main func */ int main(int argc, char *argv[]) { int optc, show_help, show_version, show_usage; /* Get arguments */ progname = argv[0]; show_help = show_version = show_usage = 0; while ((optc = getopt_long(argc, argv, GETOPTIONS, long_opts, NULL)) != -1) { switch (optc) { case 'h': show_help = 1; break; case 'v': show_version = 1; break; default: show_usage = 1; break; } } if (show_usage) { _print_usage(); return 1; } if (show_version) { _print_version(); if (!show_help) return 0; } if (show_help) { _print_help(); return 0; } /* Randomize */ srand(time(0)); if (optind < argc) { while (optind < argc) { _encrypt(argv[optind]); optind++; } } else { char pass[80], *ret; printf("Password: "); ret = fgets(pass, sizeof(pass), stdin); printf("\n"); if (ret) { char *ptr; ptr = pass + strlen(pass); while ((ptr >= ret) && (*ptr <= 32)) *(ptr--) = 0; _encrypt(pass); } } return 0; } /* Encrypt a password */ static void _encrypt(const char *pass) { char salt[3], *enc; _saltchar(&(salt[0])); _saltchar(&(salt[1])); salt[2] = 0; enc = crypt(pass, salt); printf("%s = %s\n", pass, enc); } /* Pick a random salt character */ static void _saltchar(char *c) { static char *chars = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "01234567890"; int ran; ran = (int)((double)(strlen(chars) - 1) * (rand() / (RAND_MAX + 1.0))); *c = chars[ran]; } /* Print the usage instructions to stderr */ static int _print_usage(void) { fprintf(stderr, "%s: Try '%s --help' for more information.\n", progname, progname); return 0; } /* Print the version number to stderr */ static int _print_version(void) { fprintf(stderr, "dircproxy-crypt (%s %s)\n", PACKAGE, VERSION); return 0; } /* Print the help to stderr */ static int _print_help(void) { fprintf(stderr, "dircproxy-crypt. Encyrpt passwords for %s.\n\n", PACKAGE); fprintf(stderr, "Usage: %s [OPTION]... [PASSWORD]...\n\n", progname); fprintf(stderr, "If a long option shows an argument as mandatory, then " "it is mandatory\nfor the equivalent short option also. " "Similarly for optional arguments.\n\n"); fprintf(stderr, " -h, --help Print a summary of the options\n"); fprintf(stderr, " -v, --version Print the version number\n\n"); fprintf(stderr, " PASSWORD Plaintext password to crypt\n\n"); fprintf(stderr, "If no passwords are given on the command line, you will " "be asked for one\non standard input.\n\n"); return 0; } dircproxy-1.0.5/doc/0000777000175000017500000000000007567165533010073 5dircproxy-1.0.5/doc/Makefile.in0000644000175000017500000001306407567165533012060 # Makefile.in generated automatically by automake 1.4-p6 from Makefile.am # Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. SHELL = @SHELL@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ libexecdir = @libexecdir@ datadir = @datadir@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include DESTDIR = pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : host_alias = @host_alias@ host_triplet = @host@ AWK = @AWK@ CC = @CC@ LN_S = @LN_S@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ PACKAGE = @PACKAGE@ RANLIB = @RANLIB@ VERSION = @VERSION@ man_MANS = dircproxy.1 dircproxy-crypt.1 EXTRA_DIST = $(man_MANS) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = man1dir = $(mandir)/man1 MANS = $(man_MANS) NROFF = nroff DIST_COMMON = Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP_ENV = --best all: all-redirect .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps doc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status install-man1: $(mkinstalldirs) $(DESTDIR)$(man1dir) @list='$(man1_MANS)'; \ l2='$(man_MANS)'; for i in $$l2; do \ case "$$i" in \ *.1*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ else file=$$i; fi; \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \ $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \ done uninstall-man1: @list='$(man1_MANS)'; \ l2='$(man_MANS)'; for i in $$l2; do \ case "$$i" in \ *.1*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \ rm -f $(DESTDIR)$(man1dir)/$$inst; \ done install-man: $(MANS) @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-man1 uninstall-man: @$(NORMAL_UNINSTALL) $(MAKE) $(AM_MAKEFLAGS) uninstall-man1 tags: TAGS TAGS: distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) subdir = doc distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ if test -d $$d/$$file; then \ cp -pr $$d/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file || :; \ fi; \ done info-am: info: info-am dvi-am: dvi: dvi-am check-am: all-am check: check-am installcheck-am: installcheck: installcheck-am install-exec-am: install-exec: install-exec-am install-data-am: install-man install-data: install-data-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am install: install-am uninstall-am: uninstall-man uninstall: uninstall-am all-am: Makefile $(MANS) all-redirect: all-am install-strip: $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install installdirs: $(mkinstalldirs) $(DESTDIR)$(mandir)/man1 mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* maintainer-clean-generic: mostlyclean-am: mostlyclean-generic mostlyclean: mostlyclean-am clean-am: clean-generic mostlyclean-am clean: clean-am distclean-am: distclean-generic clean-am distclean: distclean-am maintainer-clean-am: maintainer-clean-generic distclean-am @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." maintainer-clean: maintainer-clean-am .PHONY: install-man1 uninstall-man1 install-man uninstall-man tags \ distdir info-am info dvi-am dvi check check-am installcheck-am \ installcheck install-exec-am install-exec install-data-am install-data \ install-am install uninstall-am uninstall all-redirect all-am all \ installdirs mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean # 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: dircproxy-1.0.5/doc/Makefile.am0000664000175000017500000000020707175023301012021 ## Process this file with automake to produce Makefile.in man_MANS = \ dircproxy.1 \ dircproxy-crypt.1 EXTRA_DIST = \ $(man_MANS) dircproxy-1.0.5/doc/dircproxy.10000644000175000017500000007330007567164163012115 .TH dircproxy 1 "11 Jan 2001" .\" Copyright (C) 2002 Scott James Remnant . .\" All Rights Reserved. .\" .\" @(#) $Id: dircproxy.1,v 1.37.4.1 2002/11/21 14:06:43 scott Exp $ .\" .\" This file is distributed according to the GNU General Public .\" License. For full details, read the top of 'main.c' or the .\" file called COPYING that was distributed with this code. .SH NAME \fBdircproxy\fR \- Detachable Internal Relay Chat Proxy Server .SH SYNOPSIS \fBdircproxy\fR [\fB\-hvDI\fR] [\fB-f\fR \fIconfig_file\fR] [\fB-P\fR \fIlisten_port\fR] [\fB-p\fR \fIpid_file\fR] .SH DESCRIPTION .B dircproxy is an IRC proxy server designed for people who use IRC from lots of different workstations or clients, but wish to remain connected and see what they missed while they were away. .PP You connect to IRC through \fBdircproxy\fR, and it keeps you connected to the server, even after you detach your client from it. While you're detached, it logs channel and private messages as well as important events, and when you re-attach it'll let you know what you missed. .PP This can be used to give you roughly the same functionality as using ircII and .BR screen (8) together, except you can use whatever IRC client you like, including X ones! .PP Authentication is provided by a password, and optional hostname checking. This links it to a \fIconnection class\fR specified in the configuration file. Only one user may use a connection class at one time, when that user detaches, the connection to the server is kept open. When someone (usually the user) subsequently connects to \fBdircproxy\fR and provides the same password, they are reconnected to the connection to the server, instead of having a new connection created for them. .PP Multiple connection classes can be defined, allowing multiple people to use the same proxy. .PP \fBdircproxy\fR can use either a \fI.dircproxyrc\fR file in the user's home directory, or a system-wide \fIdircproxyrc\fR file. It will load the first it finds (home directory first, then system-wide). If no configuration file is specified, it will not start. .SH OPTIONS .TP .B -f \fIconfig_file\fR Specifies the configuration file to be used, overriding the default search list. .TP .B -h Displays a brief help message detailing the command-line arguments, then exits. .TP .B -v Displays the \fBdircproxy\fR version number, then exits. .TP .B -D Run in the foreground and do not fork into the background. .TP .B -I Use to indicate \fBdircproxy\fR is being run from the .BR inetd (8) daemon. This implies \fB-D\fR. For more information on running \fBdircproxy\fR under .BR inetd (8), see the \fIREADME.inetd\fR file. .TP .B -P \fIlisten_port\fR Specifies an alternate port to use, overriding the default and any value specified in the configuration file. .TP .B -p \fIpid_file\fR Specifies a file to write the process id to, overriding the default and any value specified in the configuration file. .SH CONFIGURATION The configuration file has the following format: .PP Empty lines and lines starting with '#' are comments. .PP Connection classes start with 'connection {' and end with '}'. They obtain default values from all the entries above them in the configuration file, and may contain values of their own. .PP Otherwise a line is of the format 'keywords arguments'. If the argument contains spaces it should be contained in double quotes ('"with spaces"'). The possible keywords and their meanings are as follows (note that the configuration file is not case-sensitive): .PP .B LOCAL OPTIONS .PP These options may not be placed inside a connection class as they affect the operation of the entire \fBdircproxy\fR server. .TP .B listen_port What port should \fBdircproxy\fR listen for connections from IRC clients on? This can be a numeric port number, or a service name from /etc/services .TP .B pid_file File to write the \fBdircproxy\fR process id to on startup. If you start this with a "~/" then it refers to a file in a directory under your home directory. none = Don't write pid file .TP .B client_timeout Maxmimum amount of time (in seconds) a client can take to connect to \fBdircproxy\fR and provide their password and nickname etc. .TP .B connect_timeout Maximum amount of time (in seconds) a client has to provide a server to connect to after they've logged in. This only applies if '\fBserver_autoconnect\fR' is 'no' for that class. .TP .B dns_timeout Maximum amount of time (in seconds) to wait for a reply from a DNS server. If the time exceeds this then the lookup is cancelled. .PP .B GLOBAL OPTIONS .PP These options may be placed in a connection class, or outside of one. If they are outside then they only affect those connection classes defined afterwards. .TP .B server_port What port do we connect to IRC servers on if the server string doesn't explicitly set one This can be a numeric port number, or a service name from /etc/services .TP .B server_retry How many seconds after disconnection or last connection attempt do we wait before retrying again? .TP .B server_maxattempts If we are disconnected from the server, how many times should we iterate the server list before giving up and declaring the proxied connection dead? 0 = iterate forever .TP .B server_maxinitattempts On first connection, how many times should we iterate the server list before giving up and declaring the proxied connection dead? 0 = iterate forever. This isn't recommended. .TP .B server_keepalive This checks whether the \fBdircproxy\fR to server connection is alive at the TCP level. If no data is sent in either direction for a period of time, a TCP keepalive probe is sent. yes = send keepalive probes no = don't send keepalive probes .TP .B server_pingtimeout For some people, \fBdircproxy\fR doesn't notice that the connection to the server has been dropped because the socket remains open. For example, those behind a NAT'd firewall. \fBdircproxy\fR can ping the server and make sure it gets replies back. If the time since the last reply was received exceeds the number of seconds below the server is assumed to be "stoned" and \fBdircproxy\fR leaves it. If you have a high latency connection to the server, it can wrongly assume the server is stoned because the PINGs don't arrive in time. Either raise the value, or use the '\fBserver_keepalive\fR' option instead. 0 = don't send PINGs .TP .B server_throttle To prevent you from being flooded off the IRC network, \fBdircproxy\fR can throttle the connection to the server to prevent too much being sent within a certain time period. For this you specify a number of bytes, then optionally a time period in seconds seperated by a colon. If the time period is ommitted then per second is assmued. server_throttle 10 # 10 bytes per second server_throttle 10:2 # 10 bytes per 2 seconds (5 per second) 0 = do not throttle the connection .TP .B server_autoconnect Should \fBdircproxy\fR automatically connect to the first server in the list when you connect. If you set this to 'no', then '\fBallow_jump\fR' is automatically set to 'yes'. If '\fBallow_jump_new\fR' is also 'yes', then you can create connection classes with no '\fBserver\fR' lines. yes = Automatically connect to the first server no = Wait for a /DIRCPROXY JUMP from the client .TP .B channel_rejoin If we are kicked off a channel, how many seconds do we wait before attempting to rejoin. -1 = Don't rejoin 0 = Immediately .TP .B channel_leave_on_detach Should \fBdircproxy\fR automatically make you leave all the channels you were on when you detach? yes = Leave them no = Remain on them .TP .B channel_rejoin_on_attach If '\fBchannel_leave_on_detach\fR' is '\fByes\fR' then should \fBdircproxy\fR rejoin those channels when you attach again? yes = Rejoin the channels \fBdircproxy\fR automatically left no = Leave permanently on detach .TP .B idle_maxtime Set this to the maximum amount of time you want to appear idle for while on IRC, if you set this then \fBdircproxy\fR will reset your idle time if it reaches this limit (in seconds). 0 = Don't reset idle time .TP .B disconnect_existing_user If, when you connect to \fBdircproxy\fR, another client is already using your connection class (ie, if you forgot to close that one), then this option lets you automatically kill that one off. Make sure you turn any "automatic reconnect to server" options off before using this, otherwise you'll have a fight on your hands. yes = Yes, disconnect no = No, don't let me on .TP .B disconnect_on_detach When you detach from \fBdircproxy\fR it usually keeps you connected to the server until you connect again. If you don't want this, and you want it to close your server connection as well, then set this. yes = Close session on disconnection no = Stay connected to server until reattachment .TP .B initial_modes Which user modes should we automatically set when you first connect to a server. Just in case you forget to do it yourself with your irc client. Set to "" to not set any modes. .TP .B drop_modes Which user modes to drop automatically when you detach, handy to limit the impact that your client has while connected, or for extra security if you're an IRCop. Set to "" to not drop any modes. .TP .B refuse_modes Which user modes to refuse to accept from a server. If the server attempts to set one of these, then the connection to it will be dropped and the next server in the list will be tried. A good setting for many people would be "+r", as most servers use that to mean your connection is restricted. Don't set it to this if you're on DALnet however, DALnet uses +r to indicate you have registered with NickServ (gee, thanks guys!). Set to "" to not refuse any modes. .TP .B local_address Local hostname to use when connecting to an IRC server. This provides the same functionality as the ircII -H parameter. none = Do not bind any specific hostname .TP .B away_message If you don't explicitly set an /AWAY message before you detach, \fBdircproxy\fR can for you, so people don't think you are really at your keyboard when you're not. none = Do not set an away message for you .TP .B quit_message If you don't explicitly give a message when you /DIRCPROXY QUIT, this will be used instead. Also used for when you've sent \fBdircproxy\fR not to remain attached to the server on detachment. none = Use \fBdircproxy\fR version number as QUIT message .TP .B attach_message \fBdircproxy\fR can send an announcement onto every channel you are on when you reattach to it, just to let everyone know you are back. If you start this with "/ME " then it will be sent as an ACTION CTCP message (just like the ircII /me command). none = Do not announce attachment .TP .B detach_message \fBdircproxy\fR can send an announcement onto every channel you are on when you detach from it, just to let everyone know you are gone. If you start this with "/ME " then it will be sent as an ACTION CTCP message (just like the ircII /me command). none = Do not announce detachment .TP .B detach_nickname Nickname to change to automatically after you detach, to indicate you are away for example. If this contains a '*' character, then that character is replaced with whataver your nickname was before you detached (ie "*_away" adds "_away" to the end of your nickname); none = Leave nickname as it is .TP .B nick_keep Whether \fBdircproxy\fR should attempt to keep the nickname you last set using your client. If this is 'yes' and your nickname is lost while your client is disconnected, then it will keep on trying to get it back until a client connects again. yes = try to keep my nickname while I'm disconnected no = if it changes, leave it .TP .B ctcp_replies Whether \fBdircproxy\fR should reply to the standard set of CTCP messages while the client is detached. yes = reply to ctcp messages while client is detached no = nothing but silence .TP .B chan_log_enabled Whether logging of channel text to files should take place. If this is 'yes', then you'll be able to recall channel text when you rejoin and see what you missed. yes = Channel text is logged to files no = Channel text is NOT logged to files .TP .B chan_log_always Channel text will always be logged while you are offline, so when you come back you can see what you missed. You can also, if you wish, log channel text while online, so if you're only away a short time you can get an idea of any context etc. This only applies if '\fBchan_log_enabled\fR' is 'yes'. yes = Log channel text while offline and online no = Log channel text only while offline .TP .B chan_log_maxsize To preserve your harddisk space, you can limit the size of a channel log file. Once the log file reaches this number of lines, every line added will result in a line removed from the top. If you know you are never going to want all that logged information, this might be a good setting for you. This only applies if '\fBchan_log_enabled\fR' is 'yes'. 0 = No limit to log files .TP .B chan_log_recall Number of lines from each channel log file to automatically recall to your IRC client when you attach. If this is low, you may not get much useful information, if this is high, it may take a long time for all the information to arrive. This only applies if '\fBchan_log_enabled\fR' is 'yes'. -1 = Recall the whole log (not recommended if chan_log_always is yes) 0 = Don't automatically recall anything .TP .B chan_log_timestamp Channel text can have a timestamp added to the front to let you know exactly when a message was logged. These timestamps are displayed when you recall the log files, or when automatially dumped. This applies to ordinary channel logs if '\fBchan_log_enabled\fR' is 'yes' and also to the permanent copy if '\fBchan_log_copydir\fR' is set to something other than 'none'. yes = Include timestamp no = Do not include timestamp .TP .B chan_log_relativetime If '\fBchan_log_timestamp\fR' is 'yes' then you also have the option of using intelligent relative timestamps. If you do, the timestamp shown when log file information is recalled depends on how old that line is, making sure it displays enough information (including date if necessary). Otherwise \fBdircproxy\fR will just tell you the time in HH:MM format which may not be as useful. This does mean that the time itself won't be displayed in the log files themselves, a timestamp is in place instead. This may cause problems if you're doing things with the log files yourself. yes = Do fancy relative timestamping no = Do normal timestamping .TP .B chan_log_copydir As well as \fBdircproxy\fR's own log files, it can also keep a permanent copy somewhere for your use. \fBdircproxy\fR will append all channel text seen to this file, but will not use it itself. If you do define it, it'll add to each log as you use it. If you start with "~/" then it will use a directory under your home directory. This is done regardless of the '\fBchan_log_enabled\fR' and '\fBchan_log_always\fR' options, although if those are off then you won't get that text recalled to your client, despite it being in this file. The timestamping options do apply however. none = Do not make a permanent copy .TP .B chan_log_program Program to pipe channel text into. If given, \fBdircproxy\fR will run this program for each log file entry giving the full source information as the first argument, the destination as the second and the text as a single line on standard input. The program can be anywhere in your $PATH, or you can start it with "~/" if its in a directory under your home directory. This is done regardless of the '\fBchan_log_enabled\fR' and '\fBchan_log_always\fR' options. none = Do not pipe log messages to a program .TP .B other_log_enabled Whether logging of server and private messages to files should take place. If this is 'yes', then you'll be able to recall server and private messages when you rejoined and see what you missed. yes = Server/private messages are logged to files no = Server/private messages are NOT logged to files .TP .B other_log_always Server and private messages will always be logged while you are offline, so when you come back you can see what you missed. You can also, if you wish, log these messages while online, so if you're only away a short time you can get an idea of any context etc. This only applies if '\fBother_log_enabled\fR' is 'yes'. yes = Log server/private messages while offline and online no = Log server/private messages only while offline .TP .B other_log_maxsize To preserve your harddisk space, you can limit the size of the server/private message log file. Once the log file reaches this number of lines, every line added will result in a line removed from the top. If you know you are never going to want all that logged information, this might be a good setting for you. This only applies if '\fBother_log_enabled\fR' is 'yes'. 0 = No limit to log file .TP .B other_log_recall Number of lines from the server/private message log file to automatically recall to your IRC client when you attach. If this is low, you may not get much useful information, if this is high, it may take a long time for all the information to arrive. This only applies if '\fBother_log_enabled\fR' is 'yes'. -1 = Recall the whole log (not recommended if other_log_always is yes) 0 = Don't automatically recall anything .TP .B other_log_timestamp Server and private messages can have a timestamp added to the front to let you know exactly when a message was logged. These timestamps are displayed when you recall the log files, or when automatially dumped. This applies to the server/private message log if '\fBother_log_enabled\fR' is 'yes' and also the permanet copy if '\fBother_log_copydir\fR' is set to something other than 'none'. yes = Include timestamp no = Do not include timestamp .TP .B other_log_relativetime If '\fBother_log_timestamp\fR' is 'yes' then you also have the option of using intelligent relative timestamps. If you do, the timestamp shown when log file information is recalled depends on how old that line is, making sure it displays enough information (including date if necessary). Otherwise \fBdircproxy\fR will just tell you the time in HH:MM format which may not be as useful. This does mean that the time itself won't be displayed in the log files themselves, a timestamp is in place instead. This may cause problems if you're doing things with the log files yourself. yes = Do fancy relative timestamping no = Do normal timestamping .TP .B other_log_copydir As well as \fBdircproxy\fR's own log file, it can keep a permanent copy somewhere for your use. \fBdircproxy\fR will append all server and private messages seen to this file, but will not use it itself. If you do define it, it'll add to the log as it uses it. If you start with "~/" then it will use a directory under your home directory. This is done regardless of the '\fBother_log_enabled\fR' and '\fBother_log_always\fR' options, although if those are off then won't get that text recalled to your client, despite it being in this file. The timestamping options do apply however. none = Do not make a permanent copy .TP .B other_log_program Program to pipe server and private messages into. If given, \fBdircproxy\fR will run this program for each log file entry giving the full source information as the first argument, the destination as the second and the text as a single line on standard input. The program can be anywhere in your $PATH, or you can start it with "~/" if its in a directory under your home directory. This is done regardless of the '\fBother_log_enabled\fR' and '\fBother_log_always\fR' options. none = Do not pipe log messages to a program .TP .B log_timeoffset Difference in minutes from your IRC client to the \fBdircproxy\fR machine. So if you're in GMT, but your \fBdircproxy\fR machine is in PST (which is 8 hours behind), then this would be -(8 * 60) = -480. Used for log file timestamps. 0 = Don't adjust log timestamps. .TP .B log_events Events you want \fBdircproxy\fR to log for you. This is a comma seperated list of event names, prefixed with '+' to add the event to the list or '-' to remove an event. You can also specify 'all' to log all events (the default) or 'none' to not log anything. Example, to just log text and action's: log_events "none,+text,+action" Example, to log everything but server messages: log_events "all,-server" # you don't need to specify 'all' log_events -server The possible events are: \fBtext\fR Channel text and private messages \fBaction\fR CTCP ACTION events (/me) sent to you or channels \fBctcp\fR Whether to record whether a CTCP was sent to you \fBjoin\fR People (including you) joining channels \fBpart\fR People (including you) leaving channels \fBkick\fR People (including you) being kicked from channels \fBquit\fR People quit''ing from IRC \fBnick\fR People (including you) changing nickname \fBmode\fR Changes in channel modes or your own personal mode \fBtopic\fR Changes to the channel topic \fBclient\fR You detaching and attaching \fBserver\fR Connections and disconnections from servers \fBerror\fR Problems and errors \fBdircproxy\fR encounters (recommended!) .TP .B dcc_proxy_incoming Whether \fBdircproxy\fR should proxy DCC chat and send requests sent \fBto\fR you by others on IRC. yes = Proxy incoming requests. no = Do not proxy incoming requests. .TP .B dcc_proxy_outgoing Whether \fBdircproxy\fR should proxy DCC chat and send requests sent \fBby\fR you to others on IRC. yes = Proxy outgoing requests. no = Do not proxy outgoing requests. .TP .B dcc_proxy_ports Ports that \fBdircproxy\fR can use to listen for DCC connections on. This is for when you're behind a firewall that only allows certain ports through, or when doing DCC-via-ssh. It is a comma seperated list of port numbers or ranges of ports, for example '57100-57199,57400,57500,57600-57800' any = Use any port given to us by the kernel. .TP .B dcc_proxy_timeout Maxmimum amount of time (in seconds) to allow for both sides of a DCC proxy to be connected. .TP .B dcc_proxy_sendreject Whether to send a physical REJECT message via CTCP back to the source of the request in event of failure. yes = Send reject CTCP message back. no = Do not send any message back. .TP .B dcc_send_fast Whether to ignore the "acknowledgment" packets from the client and just send the file to them as fast as possible. There should be no real danger in doing this. yes = Send as fast as possible. no = Wait for each packet to be acknowledged. .TP .B dcc_capture_directory \fBdircproxy\fR can capture files sent via DCC and store them on the server. Especially useful while you are detached, whether it does it while attached or not depends on '\fBdcc_capture_always\fR'. This is the directory to store those captured files in. If start with "~/" then it will use a directory under your home directory. none = Do not capture files. .TP .B dcc_capture_always If we're capturing DCC send's, should we do it while the client is connected as well? If 'yes', then the client will never see the file, it'll be just stored on the server with a notice sent to the client telling them where. yes = Capture even when a client is connected. no = Capture only when client detached. .TP .B dcc_capture_withnick Whether to start the filename of the captured file with the nickname of the sender, so you know who it came from. yes = Start with nickname. no = Do not alter the filename. .TP .B dcc_capture_maxsize Maximum size (in kilobytes) that a captured file can be. If a captured file is larger than this, or becomes larger than this, then the capture will be aborted and the file removed from the disk. Prevents people from filling your disk up while you're detached with a massive file. 0 = No limit to file size. .TP .B dcc_tunnel_incoming Port of a local ssh tunnel leading to another \fBdircproxy\fR client that we should use for incoming DCC requests. This should not be set if '\fBdcc_tunnel_outgoing\fR' is set. See the README.dcc-via-ssh file included with the \fBdircproxy\fR distribution for more information. This can be a numeric port number, or a service name from /etc/services none = There is no tunnel. .TP .B dcc_tunnel_outgoing Port of a local ssh tunnel leading to another \fBdircproxy\fR client that we should use for outgoing DCC requests. This should not be set if '\fBdcc_tunnel_incoming\fR' is set. See the README.dcc-via-ssh file included with the \fBdircproxy\fR distribution for more information. This can be a numeric port number, or a service name from /etc/services none = There is no tunnel. .TP .B switch_user If you're running \fBdircproxy\fR as root, it can switch to a different "effective user id" to create the server connection. This means that your system ident daemon (and therefore IRC, if it queries it) will see your server connection as the user you put here, instead of root. This is most useful if you are sysadmin running a \fBdircproxy\fR server for multiple people and want them to all appear as different usernames without using a hacked identd. Because \fBdircproxy\fR is still running as root, it will have those privileges for all operations, including the .BR bind (2) for the '\fBlocal_address\fR' config option if you're using Secure Linux patches. This can only be used if your system supports .BR seteuid (2) and if you are running \fBdircproxy\fR as the root user, and not just setuid. Attempting otherwise will generate a warning as \fBdircproxy\fR starts. This can be a numeric uid or a username from /etc/passwd. none = Do not do this. .TP .B motd_logo If this is yes, then the \fBdircproxy\fR logo and version number will be included in the message of the day when you connect. Only the picky would turn this off, its pretty! yes = Show me the pretty logo no = I don't like logos, I'm boring, I eat llamas. .TP .B motd_file Custom message of the day file to send when users connect to \fBdircproxy\fR. The contents of this file will be sent after the logo and before the stats. If you start this with a "~/" then it refers to a file in a directory under your home directory. none = No custom motd .TP .B motd_stats Display information on what channels you were on, and log file sizes etc in the message of the day. This is handy, and lets you know how not only much information you missed, but how much will be sent to you. yes = Show the stats no = They don't interest me, don't show them. .TP .B allow_persist You can disable the /DIRCPROXY PERSIST command if you do not want people using your proxy to be able to do that. yes = Command enabled no = Command disabled .TP .B allow_jump You can disable the /DIRCPROXY JUMP command if you do not want people to do that. yes = Command enabled no = Command disabled .TP .B allow_jump_new If the /DIRCPROXY JUMP commmand is enabled, then you can disable it being used to jump to a server:port not in the list specified in the configuration file. yes = Can jump to any server no = Only ones in the config file .TP .B allow_host You can disable the /DIRCPROXY HOST command if you do not want people to do that. yes = Command enabled no = Command disabled .TP .B allow_die You can enable the /DIRCPROXY DIE command if you want people to be able to kill your proxy. This isn't recommended as a global option, instead only enable it for a specific connection class (ie yours). yes = Command enabled no = Command disabled .TP .B allow_users You can enable the /DIRCPROXY USERS command if you want people to be able to see who's using your proxy. This isn't recommended as a global option, instead only enable it for a specific connection class (ie yours). yes = Command enabled no = Command disabled .TP .B allow_kill You can enable the /DIRCPROXY KILL command if you want people to be able to disconnect anyone using your proxy (including you!). This isn't recommended as a global option, instead only enable it for a specific connection class (ie yours). yes = Command enabled no = Command disabled .PP Additionally, the following keywords may go only inside a connection class definition. One '\fBpassword\fR' and at least one '\fBserver\fR' (unless '\fBserver_autoconnect\fR' is 'no' and '\fBallow_jump_new\fR' is 'yes') are mandatory. .TP .B password Password required to use this connection class. This should be encrypted using your system's .BR crypt (3) function. It must be the same as the password supplied by the IRC client on connection for this connection class to be used. You can use the included .BR dircproxy-crypt (1) utility to generate these passwords. .TP .B server Server to connect to. Multiple servers can be given, in which case they are iterated when the connection to one is dropped. This has the following format: [\fBhostname\fR[:[\fBport\fR][:\fBpassword\fR]] .TP .B from The connection hostname must match this mask, multiple masks can be specified to allow more hosts to connect. The * and ? wildcards may be used. .TP .B join Channels to join when you first connect. Multiple channels can be given, either by seperating the names with a comma, or by specifying multiple '\fBjoin\fR' lines. You may also include the channel key by seperating it from the channel name with a space. Note: You \fImust\fR surround the list of channels with quotes to distinguish from comments. For clarification, this is the format of this line: join "\fBchannel\fR[ \fBkey\fR][,\fBchannel\fR[ \fBkey\fR]]..." .SH SIGNALS \fBdircproxy\fR will reread its configuration file whenever it receives the hangup signal, \fISIGHUP\fR. .PP Sending an interrupt signal, \fISIGINT\fR, or a terminate signal, \fISIGTERM\fR, will cause \fBdircproxy\fR to exit cleanly. .SH NOTES More information, including announcements of new releases, can be found at: .PP .I http://www.dircproxy.net/ .SH SEE ALSO .BR dircproxy-crypt (1) .BR inetd (8) .BR crypt (3) .SH BUGS Please submit and review bug reports at: .PP .I http://bugzilla.dircproxy.net/ .SH AUTHOR Written by Scott James Remnant . .SH COPYRIGHT Copyright (C) 2002 Scott James Remnant. All Rights Reserved. \fBdircproxy\fR is distributed under the \fIGNU General Public License\fR. dircproxy-1.0.5/doc/dircproxy-crypt.10000664000175000017500000000324707430200060013231 .TH dircproxy-crypt 1 "11 Jan 2001" .\" Copyright (C) 2002 Scott James Remnant . .\" All Rights Reserved. .\" .\" @(#) $Id: dircproxy-crypt.1,v 1.5 2002/02/06 10:06:40 scott Exp $ .\" .\" This file is distributed according to the GNU General Public .\" License. For full details, read the top of 'main.c' or the .\" file called COPYING that was distributed with this code. .SH NAME \fBdircproxy-crypt\fR \- Generate encrypted password for \fBdircproxy\fR .SH SYNOPSIS \fBdircproxy-crypt\fR [\fB-hv\fR] [\fBpassword\fR]... .SH DESCRIPTION .B dircproxy-crypt generates encrypted passwords for the .BR dircproxy (1) configuration file. These passwords are used in the '\fBpassword\fR' configuration option of a connection class, and are compared to the password you configure your IRC client to use. .PP If you do not supply any plain text passwords to encrypt on the command line then \fBdircproxy-crypt\fR, when run, will ask you for one on standard input. It will display the encrypted version of each password, created using your system's .BR crypt (3) function and a random salt, on standard output. .SH OPTIONS .TP .B -h Displays a brief help message detailing the command-line arguments, then exits. .TP .B -v Displays the \fBdircproxy\fR version number that this version of \fBdircproxy-crypt\fR comes with, then exits. .SH SEE ALSO .BR dircproxy (1) .BR crypt (3) .SH BUGS Please submit and review bug reports at: .PP .I http://bugzilla.dircproxy.net/ .SH AUTHOR Written by Scott James Remnant . .SH COPYRIGHT Copyright (C) 2002 Scott James Remnant. All Rights Reserved. \fBdircproxy\fR is distributed under the \fIGNU General Public License\fR. dircproxy-1.0.5/src/0000777000175000017500000000000007567165534010116 5dircproxy-1.0.5/src/Makefile.in0000644000175000017500000002352607567165534012107 # Makefile.in generated automatically by automake 1.4-p6 from Makefile.am # Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. SHELL = @SHELL@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ libexecdir = @libexecdir@ datadir = @datadir@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include DESTDIR = pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : host_alias = @host_alias@ host_triplet = @host@ AWK = @AWK@ CC = @CC@ LN_S = @LN_S@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ PACKAGE = @PACKAGE@ RANLIB = @RANLIB@ VERSION = @VERSION@ INCLUDES = -DSYSCONFDIR="\"${sysconfdir}\"" bin_PROGRAMS = dircproxy dircproxy_SOURCES = main.c dircproxy.h irc_net.c irc_net.h irc_client.c irc_client.h logo.h help.h irc_server.c irc_server.h irc_prot.c irc_prot.h irc_log.c irc_log.h irc_string.c irc_string.h dcc_net.c dcc_net.h dcc_chat.c dcc_chat.h dcc_send.c dcc_send.h cfgfile.c cfgfile.h timers.c timers.h dns.c dns.h net.c net.h match.c match.h stringex.c stringex.h sprintf.c sprintf.h memdebug.c memdebug.h dircproxy_LDADD = ../getopt/libgetopt.a mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = PROGRAMS = $(bin_PROGRAMS) DEFS = @DEFS@ -I. -I$(srcdir) -I.. CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ dircproxy_OBJECTS = main.o irc_net.o irc_client.o irc_server.o \ irc_prot.o irc_log.o irc_string.o dcc_net.o dcc_chat.o dcc_send.o \ cfgfile.o timers.o dns.o net.o match.o stringex.o sprintf.o memdebug.o dircproxy_DEPENDENCIES = ../getopt/libgetopt.a dircproxy_LDFLAGS = CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ DIST_COMMON = Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP_ENV = --best SOURCES = $(dircproxy_SOURCES) OBJECTS = $(dircproxy_OBJECTS) all: all-redirect .SUFFIXES: .SUFFIXES: .S .c .o .s $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps src/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status mostlyclean-binPROGRAMS: clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) distclean-binPROGRAMS: maintainer-clean-binPROGRAMS: install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(bindir) @list='$(bin_PROGRAMS)'; for p in $$list; do \ if test -f $$p; then \ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ else :; fi; \ done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) list='$(bin_PROGRAMS)'; for p in $$list; do \ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ done .c.o: $(COMPILE) -c $< .s.o: $(COMPILE) -c $< .S.o: $(COMPILE) -c $< mostlyclean-compile: -rm -f *.o core *.core clean-compile: distclean-compile: -rm -f *.tab.c maintainer-clean-compile: dircproxy: $(dircproxy_OBJECTS) $(dircproxy_DEPENDENCIES) @rm -f dircproxy $(LINK) $(dircproxy_LDFLAGS) $(dircproxy_OBJECTS) $(dircproxy_LDADD) $(LIBS) tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ awk ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ here=`pwd` && cd $(srcdir) \ && mkid -f$$here/ID $$unique $(LISP) TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ awk ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ || (cd $(srcdir) && etags -o $$here/TAGS $(ETAGS_ARGS) $$tags $$unique $(LISP)) mostlyclean-tags: clean-tags: distclean-tags: -rm -f TAGS ID maintainer-clean-tags: distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) subdir = src distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ if test -d $$d/$$file; then \ cp -pr $$d/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file || :; \ fi; \ done cfgfile.o: cfgfile.c dircproxy.h ../config.h memdebug.h sprintf.h \ irc_net.h irc_prot.h stringex.h cfgfile.h dcc_chat.o: dcc_chat.c dircproxy.h ../config.h memdebug.h sprintf.h \ net.h dns.h timers.h dcc_net.h dcc_chat.h dcc_net.o: dcc_net.c dircproxy.h ../config.h memdebug.h net.h dns.h \ timers.h sprintf.h stringex.h dcc_chat.h dcc_net.h dcc_send.h dcc_send.o: dcc_send.c dircproxy.h ../config.h memdebug.h sprintf.h \ net.h dns.h timers.h dcc_net.h dcc_send.h dns.o: dns.c dircproxy.h ../config.h memdebug.h sprintf.h dns.h irc_client.o: irc_client.c dircproxy.h ../config.h memdebug.h sprintf.h \ net.h dns.h timers.h dcc_net.h irc_log.h irc_net.h irc_prot.h \ stringex.h irc_string.h match.h irc_server.h irc_client.h \ logo.h help.h irc_log.o: irc_log.c dircproxy.h ../config.h memdebug.h net.h sprintf.h \ irc_net.h irc_prot.h stringex.h irc_client.h irc_string.h \ match.h irc_log.h irc_net.o: irc_net.c dircproxy.h ../config.h memdebug.h net.h dns.h \ timers.h sprintf.h irc_log.h irc_net.h irc_prot.h stringex.h \ irc_string.h match.h irc_client.h irc_server.h irc_prot.o: irc_prot.c dircproxy.h ../config.h memdebug.h sprintf.h \ stringex.h irc_prot.h irc_string.h match.h irc_server.o: irc_server.c dircproxy.h ../config.h memdebug.h sprintf.h \ net.h dns.h timers.h dcc_net.h irc_log.h irc_net.h irc_prot.h \ stringex.h irc_string.h match.h irc_client.h irc_server.h irc_string.o: irc_string.c dircproxy.h ../config.h memdebug.h match.h \ sprintf.h irc_string.h main.o: main.c dircproxy.h ../config.h memdebug.h ../getopt/getopt.h \ sprintf.h cfgfile.h irc_net.h irc_prot.h stringex.h \ irc_client.h irc_server.h dcc_net.h timers.h dns.h net.h match.o: match.c dircproxy.h ../config.h memdebug.h sprintf.h stringex.h \ match.h memdebug.o: memdebug.c net.o: net.c dircproxy.h ../config.h memdebug.h sprintf.h net.h sprintf.o: sprintf.c dircproxy.h ../config.h memdebug.h stringex.h \ sprintf.h stringex.o: stringex.c dircproxy.h ../config.h memdebug.h stringex.h timers.o: timers.c dircproxy.h ../config.h memdebug.h sprintf.h timers.h info-am: info: info-am dvi-am: dvi: dvi-am check-am: all-am check: check-am installcheck-am: installcheck: installcheck-am install-exec-am: install-binPROGRAMS install-exec: install-exec-am install-data-am: install-data: install-data-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am install: install-am uninstall-am: uninstall-binPROGRAMS uninstall: uninstall-am all-am: Makefile $(PROGRAMS) all-redirect: all-am install-strip: $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install installdirs: $(mkinstalldirs) $(DESTDIR)$(bindir) mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* maintainer-clean-generic: mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-compile \ mostlyclean-tags mostlyclean-generic mostlyclean: mostlyclean-am clean-am: clean-binPROGRAMS clean-compile clean-tags clean-generic \ mostlyclean-am clean: clean-am distclean-am: distclean-binPROGRAMS distclean-compile distclean-tags \ distclean-generic clean-am distclean: distclean-am maintainer-clean-am: maintainer-clean-binPROGRAMS \ maintainer-clean-compile maintainer-clean-tags \ maintainer-clean-generic distclean-am @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." maintainer-clean: maintainer-clean-am .PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \ maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ mostlyclean-compile distclean-compile clean-compile \ maintainer-clean-compile tags mostlyclean-tags distclean-tags \ clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ check-am installcheck-am installcheck install-exec-am install-exec \ install-data-am install-data install-am install uninstall-am uninstall \ all-redirect all-am all installdirs mostlyclean-generic \ distclean-generic clean-generic maintainer-clean-generic clean \ mostlyclean distclean maintainer-clean # 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: dircproxy-1.0.5/src/Makefile.am0000664000175000017500000000117407203006104012041 ## Process this file with automake to produce Makefile.in INCLUDES = \ -DSYSCONFDIR="\"${sysconfdir}\"" bin_PROGRAMS = \ dircproxy dircproxy_SOURCES = \ main.c \ dircproxy.h \ irc_net.c irc_net.h \ irc_client.c irc_client.h logo.h help.h \ irc_server.c irc_server.h \ irc_prot.c irc_prot.h \ irc_log.c irc_log.h \ irc_string.c irc_string.h \ dcc_net.c dcc_net.h \ dcc_chat.c dcc_chat.h \ dcc_send.c dcc_send.h \ cfgfile.c cfgfile.h \ timers.c timers.h \ dns.c dns.h \ net.c net.h \ match.c match.h \ stringex.c stringex.h \ sprintf.c sprintf.h \ memdebug.c memdebug.h dircproxy_LDADD = \ ../getopt/libgetopt.a dircproxy-1.0.5/src/main.c0000644000175000017500000003645607537111636011127 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * main.c * - Program main loop * - Command line handling * - Initialisation and shutdown * - Signal handling * - Debug functions * -- * @(#) $Id: main.c,v 1.52.2.1 2002/09/09 12:27:10 scott Exp $ * * 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "getopt/getopt.h" #include "sprintf.h" #include "cfgfile.h" #include "irc_net.h" #include "irc_client.h" #include "irc_server.h" #include "dcc_net.h" #include "timers.h" #include "dns.h" #include "net.h" /* forward declarations */ static void _sig_term(int); static void _sig_hup(int); static void _sig_child(int); #ifdef DEBUG_MEMORY static void _sig_usr(int); #endif /* DEBUG_MEMORY */ static int _reload_config(void); static int _print_usage(void); static int _print_version(void); static int _print_help(void); /* This is so "ident" and "what" can query version etc - useful (not) */ const char *rcsid = "@(#) $Id: main.c,v 1.52.2.1 2002/09/09 12:27:10 scott Exp $"; /* The name of the program */ static char *progname; /* whether we went in the background or not */ static int in_background = 0; /* set to 1 to abort the main loop */ static int stop_poll = 0; /* set to 1 to reload the configuration file */ static int reload_config = 0; /* Port we're listening on */ static char *listen_port; /* File to write our pid to */ static char *pid_file; /* The configuration file we used */ static char *config_file; /* Global variables */ struct globalvars g; /* Long options */ static struct option long_opts[] = { { "config-file", 1, NULL, 'f' }, { "help", 0, NULL, 'h' }, { "version", 0, NULL, 'v' }, #ifndef DEBUG { "no-daemon", 0, NULL, 'D' }, #else /* DEBUG */ { "daemon", 0, NULL, 'D' }, #endif /* DEBUG */ { "inetd", 0, NULL, 'I' }, { "listen-port", 1, NULL, 'P' }, { "pid-file", 1, NULL, 'p' }, { 0, 0, 0, 0 } }; /* Options */ #define GETOPTIONS "f:hvDIP:" /* We need this */ int main(int argc, char *argv[]) { int optc, show_help, show_version, show_usage; char *local_file, *cmd_listen_port, *cmd_pid_file; int inetd_mode, no_daemon; /* Set up some globals */ progname = argv[0]; listen_port = x_strdup(DEFAULT_LISTEN_PORT); pid_file = (DEFAULT_PID_FILE ? x_strdup(DEFAULT_PID_FILE) : 0); #ifndef DEBUG no_daemon = 0; #else /* DEBUG */ no_daemon = 1; #endif /* DEBUG */ local_file = cmd_listen_port = cmd_pid_file = 0; show_help = show_version = show_usage = inetd_mode = 0; while ((optc = getopt_long(argc, argv, GETOPTIONS, long_opts, NULL)) != -1) { switch (optc) { case 'h': show_help = 1; break; case 'v': show_version = 1; break; case 'D': #ifndef DEBUG no_daemon = 1; #else /* DEBUG */ no_daemon = 0; #endif /* DEBUG */ break; case 'I': inetd_mode = 1; break; case 'P': free(cmd_listen_port); cmd_listen_port = x_strdup(optarg); break; case 'p': free(cmd_pid_file); cmd_pid_file = x_strdup(optarg); break; case 'f': free(local_file); local_file = x_strdup(optarg); break; default: show_usage = 1; break; } } if (show_usage || (optind < argc)) { _print_usage(); return 1; } if (show_version) { _print_version(); if (!show_help) return 0; } if (show_help) { _print_help(); return 0; } /* If no -f was specified use the home directory */ if (!local_file && !inetd_mode) { struct stat statinfo; struct passwd *pw; pw = getpwuid(geteuid()); if (pw && pw->pw_dir) { local_file = x_sprintf("%s/%s", pw->pw_dir, USER_CONFIG_FILENAME); debug("Local config file: %s", local_file); if (!stat(local_file, &statinfo) && (statinfo.st_mode & 0077)) { fprintf(stderr, "%s: Permissions of %s must be 0700 or " "more restrictive\n", progname, local_file); free(local_file); return 2; } if (cfg_read(local_file, &listen_port, &pid_file, &g)) { /* If the local one didn't exist, set to 0 so we open global one */ free(local_file); local_file = 0; } else { config_file = x_strdup(local_file); } } } else if (local_file) { if (cfg_read(local_file, &listen_port, &pid_file, &g)) { /* This is fatal! */ fprintf(stderr, "%s: Couldn't read configuration from %s: %s\n", progname, local_file, strerror(errno)); free(local_file); return 2; } else { config_file = x_strdup(local_file); } } /* Read global config file if local one not found */ if (!local_file) { char *global_file; /* Not fatal if it doesn't exist */ global_file = x_sprintf("%s/%s", SYSCONFDIR, GLOBAL_CONFIG_FILENAME); debug("Global config file: %s", global_file); cfg_read(global_file, &listen_port, &pid_file, &g); config_file = x_strdup(global_file); free(global_file); } else { free(local_file); } /* Check we got some connection classes */ if (!connclasses) { fprintf(stderr, "%s: No connection classes have been defined.\n", progname); return 2; } /* -P overrides config file */ if (cmd_listen_port) { free(listen_port); listen_port = cmd_listen_port; } /* -p overrides pid file */ if (cmd_pid_file) { free(pid_file); pid_file = cmd_pid_file; } /* Set signal handlers */ signal(SIGTERM, _sig_term); signal(SIGINT, _sig_term); signal(SIGHUP, _sig_hup); signal(SIGCHLD, _sig_child); #ifdef DEBUG_MEMORY signal(SIGUSR1, _sig_usr); signal(SIGUSR2, _sig_usr); #endif /* DEBUG_MEMORY */ /* Broken Pipe? This means that someone disconnected while we were sending stuff. Naughty! */ signal(SIGPIPE, SIG_IGN); if (!inetd_mode) { debug("Ordinary console dodge-monkey mode"); /* Make listening socket before we fork */ if (ircnet_listen(listen_port)) { fprintf(stderr, "%s: Unable to establish listen port\n", progname); return 3; } /* go daemon here */ if (!no_daemon) { switch (go_daemon()) { case -1: return -1; case 0: break; default: return 0; } } } else { /* running under inetd means we are backgrounded right *now* */ in_background = 1; debug("Inetd SuperTed mode!"); /* Hook STDIN into a new proxy */ ircnet_hooksocket(STDIN_FILENO); } /* Open a connection to syslog if we're in the background */ if (in_background) openlog(PACKAGE, LOG_PID, LOG_USER); if (pid_file) { FILE *pidfile; pidfile = fopen(pid_file, "w"); if (pidfile) { fprintf(pidfile, "%d\n", getpid()); fclose(pidfile); } else { syscall_fail("fopen", pid_file, 0); } } /* Main loop! */ while (!stop_poll) { int ns, nt, status; pid_t pid; ircnet_expunge_proxies(); dccnet_expunge_proxies(); ns = net_poll(); nt = timer_poll(); /* Reap any children */ while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { debug("Reaped process %d, exit status %d", pid, status); /* Handle any DNS children */ dns_endrequest(pid, status); } /* Reload the configuration file? */ if (reload_config) { _reload_config(); reload_config = 0; } if (!ns && !nt) break; } if (pid_file) { unlink(pid_file); } /* Free up stuff */ ircnet_flush(); dccnet_flush(); dns_flush(); timer_flush(); /* Do a lingering close on all sockets */ net_closeall(); net_flush(); /* Close down and free up memory */ if (!inetd_mode && !no_daemon) closelog(); free(listen_port); free(pid_file); free(config_file); #ifdef DEBUG_MEMORY mem_report("termination"); #endif /* DEBUG_MEMORY */ return 0; } /* Signal to stop polling */ static void _sig_term(int sig) { debug("Received signal %d to stop", sig); stop(); } /* Signal to reload configuration file */ static void _sig_hup(int sig) { debug("Received signal %d to reload config", sig); reload_config = 1; /* Restore the signal */ signal(sig, _sig_hup); } /* Signal to reap child process. Don't do anything other than interrupt * whatever we're doing so we reach the waitpid loop in the main loop quicker */ static void _sig_child(int sig) { debug("Received signal %d to reap", sig); /* Restore the signal */ signal(sig, _sig_child); } #ifdef DEBUG_MEMORY /* On USR signals, dump debug information */ static void _sig_usr(int sig) { mem_report(sig == SIGUSR1 ? 0 : "signal"); signal(sig, _sig_usr); } #endif /* DEBUG_MEMORY */ /* Reload the configuration file */ static int _reload_config(void) { struct ircconnclass *oldclasses, *c; struct globalvars newglobals; char *new_listen_port, *new_pid_file; debug("Reloading config from %s", config_file); new_listen_port = x_strdup(DEFAULT_LISTEN_PORT); new_pid_file = (DEFAULT_PID_FILE ? x_strdup(DEFAULT_PID_FILE) : 0); oldclasses = connclasses; connclasses = 0; if (cfg_read(config_file, &new_listen_port, &new_pid_file, &newglobals)) { /* Config file reload failed */ error("Reload of configuration file %s failed", config_file); ircnet_flush_connclasses(&connclasses); connclasses = oldclasses; free(new_listen_port); free(new_pid_file); return -1; } /* Copy over new globals */ memcpy(&g, &newglobals, sizeof(struct globalvars)); /* Listen port changed */ if (strcmp(listen_port, new_listen_port)) { debug("Changing listen_port from %s to %s", listen_port, new_listen_port); if (ircnet_listen(new_listen_port)) { /* This isn't fatal */ error("Unable to change listen_port from %s to %s", listen_port, new_listen_port); } else { free(listen_port); listen_port = new_listen_port; new_listen_port = 0; } } /* Change the pid file variable (don't bother rewriting it) */ free(pid_file); pid_file = new_pid_file; new_pid_file = 0; /* Match everything back up to the old stuff */ c = connclasses; while (c) { struct ircconnclass *o; o = oldclasses; while (o) { if (!strcmp(c->password, o->password)) { struct ircproxy *p; p = ircnet_fetchclass(o); if (p) p->conn_class = c; break; } o = o->next; } c = c->next; } /* Kill anyone who got lost in the reload */ c = oldclasses; while (c) { struct ircproxy *p; p = ircnet_fetchclass(c); if (p) { p->conn_class = 0; ircserver_send_command(p, "QUIT", ":Permission revoked - %s %s", PACKAGE, VERSION); ircserver_close_sock(p); ircclient_send_error(p, "No longer permitted to use this proxy"); ircclient_close(p); } c = c->next; } /* Clean up */ ircnet_flush_connclasses(&oldclasses); free(new_listen_port); return 0; } /* Print the usage instructions to stderr */ static int _print_usage(void) { fprintf(stderr, "%s: Try '%s --help' for more information.\n", progname, progname); return 0; } /* Print the version number to stderr */ static int _print_version(void) { fprintf(stderr, "%s %s\n", PACKAGE, VERSION); return 0; } /* Print the help to stderr */ static int _print_help(void) { fprintf(stderr, "%s. Detachable IRC proxy.\n\n", PACKAGE); fprintf(stderr, "Usage: %s [OPTION]...\n\n", progname); fprintf(stderr, "If a long option shows an argument as mandatory, then " "it is mandatory\nfor the equivalent short option also. " "Similarly for optional arguments.\n\n"); fprintf(stderr, " -h, --help Print a summary of the options\n"); fprintf(stderr, " -v, --version Print the version number\n"); #ifndef DEBUG fprintf(stderr, " -D, --no-daemon Remain in the foreground\n"); #else /* DEBUG */ fprintf(stderr, " -D, --daemon Run as a daemon to debug it\n"); #endif /* DEBUG */ fprintf(stderr, " -I, --inetd Being run from inetd " "(implies -D)\n"); fprintf(stderr, " -P, --listen-port=PORT Port to listen for clients on\n"); fprintf(stderr, " -p, --pid-file=FILE Write PID to this file\n"); fprintf(stderr, " -f, --config-file=FILE Use this file instead of the " "default\n\n"); return 0; } /* Called when a system call fails. Print it to stderr or syslog */ int syscall_fail(const char *function, const char *arg, const char *message) { char *msg; int err; err = errno; msg = x_sprintf("%s(%s) failed: %s", function, (arg ? arg : ""), (message ? message : strerror(err))); if (in_background) { syslog(LOG_NOTICE, "%s", msg); } else { #ifdef DEBUG fprintf(stderr, "%s: \033[33;1m%s\033[m\n", progname, msg); #else /* DEBUG */ fprintf(stderr, "%s: %s\n", progname, msg); #endif /* DEBUG */ } free(msg); return 0; } /* Called to log an error */ int error(const char *format, ...) { va_list ap; char *msg; va_start(ap, format); msg = x_vsprintf(format, ap); va_end(ap); if (in_background) { syslog(LOG_ERR, "%s", msg); } else { #ifdef DEBUG fprintf(stderr, "%s: \033[31;1m%s\033[m\n", progname, msg); #else /* DEBUG */ fprintf(stderr, "%s: %s\n", progname, msg); #endif /* DEBUG */ } free(msg); return 0; } /* Called to output debugging information to stderr or syslog */ int debug(const char *format, ...) { #ifdef DEBUG va_list ap; char *msg; va_start(ap, format); #ifdef DEBUG_MEMORY msg = xx_vsprintf(0, 0, format, ap); #else /* DEBUG_MEMORY */ msg = x_vsprintf(format, ap); #endif /* DEBUG_MEMORY */ va_end(ap); if (in_background) { syslog(LOG_DEBUG, "%s", msg); } else { printf("%s\n", msg); } free(msg); #endif /* DEBUG */ return 0; } /* Called to stop dircproxy */ int stop(void) { stop_poll = 1; return 0; } /* Called to go into the background */ int go_daemon(void) { if (in_background) return 0; debug("Running in the background"); switch (fork()) { case -1: syscall_fail("fork", "first", 0); return -1; case 0: break; default: return 1; } /* Become process group leader */ setsid(); switch (fork()) { case -1: syscall_fail("fork", "second", 0); return -1; case 0: break; default: return 2; } /* Set our umask */ umask(0); /* Okay, we're in the background now */ in_background = 1; return 0; } dircproxy-1.0.5/src/dircproxy.h0000644000175000017500000004050107567164164012224 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * dircproxy.h * -- * @(#) $Id: dircproxy.h,v 1.48.4.1 2002/11/21 14:06:44 scott Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #ifndef __DIRCPROXY_DIRCPROXY_H #define __DIRCPROXY_DIRCPROXY_H #ifdef HAVE_CONFIG_H #include #else /* HAVE_CONFIG_H */ #define PACKAGE "dircproxy" #define VERSION "-debug" #endif /* HAVE_CONFIG_H */ #include "memdebug.h" /* Configuration values that aren't in the config file */ /* OLD_RFC1459_PARAM_SPACE * RFC1459 says parameters are seperated by one or more spaces, * however RFC2812 says they are seperated by a single space (thus * allowing empty parameters). Define this to use the old RFC1459 * behaviour IF (and only IF) you have problems. */ #undef OLD_RFC1459_PARAM_SPACE /* ENCRYPTED_PASSWORDS * If this is defined, then passwords in the config file are assumed to * be encrypted using the system's crypt() function. This gives added * security and means that people who manage to read your config file * can't pretend to be you on IRC. */ #define ENCRYPTED_PASSWORDS /* NET_BLOCK_SIZE * Size of the block used to read() and write() data onto a socket. * Making it bigger might decrease CPU a fraction, but also means its * gonna be more likely for one to fail. */ #define NET_BLOCK_SIZE 8192 /* NET_LINGER_TIME * Maximum amount of time to allow sockets to send whatever data remains * in their output buffer before we just give up and let the dircproxy * shutdown continue */ #define NET_LINGER_TIME 5 /* DCC_BLOCK_SIZE * Size of the block we use when DCC proxying. Should never really need to * change it, as its not strictly honored anyway. */ #define DCC_BLOCK_SIZE 2048 /* NICK_GUARD_TIME * Number of seconds after being told the set nickname was rejected to wait * until we attempt to get it back again. */ #define NICK_GUARD_TIME 60 /* FALLBACK_USERNAME * Before sending username's to the server in a USER command, we strip it * of bogus characters. It shouldn't happen, but if somehow it ends up with * no other characters left, this value will be used. */ #define FALLBACK_USERNAME "user" /* FALLBACK_NICKNAME * When sending a nickname while detached, its possible that we can get * errors back from the server. To this end, we have to generate a new * nickname, because the client isn't around to do it for us. It really * will try to generate you a new one, but if all else fails we need * something to fall back on */ #define FALLBACK_NICKNAME "dircproxy" /* GLOBAL_CONFIG_FILENAME * Filename of the global configuration file. This file is for when you * want to run the dircproxy like any other daemon. * It goes under SYSCONFDIR. */ #define GLOBAL_CONFIG_FILENAME "dircproxyrc" /* USER_CONFIG_FILENAME * Loaded from the user running dircproxy's home directory. This file is * for when you want to run dircproxy as your user with your own configuration */ #define USER_CONFIG_FILENAME ".dircproxyrc" /* SYSCONFDIR * This *should* be defined by the configure script. Its the etc directory * relevant to where dircproxy is being installed to. */ #ifndef SYSCONFDIR #define SYSCONFDIR "/usr/local/etc" #endif /* SYSCONFDIR */ /* Defaults for values in the configuration file. Change the config file * instead of these */ /* DEFAULT_LISTEN_PORT * What port do we listen on for new client connections? */ #define DEFAULT_LISTEN_PORT "57000" /* DEFAULT_PID_FILE * Path to file to write the pid of the dircproxy process to. * 0 = Don't want one */ #define DEFAULT_PID_FILE 0 /* DEFAULT_CLIENT_TIMEOUT * Maxmimum amount of time (in seconds) to allow a client to take to login. * If we don't get password, nickname and username by this time then we * close their connection. */ #define DEFAULT_CLIENT_TIMEOUT 60 /* DEFAULT_CONNECT_TIMEOUT * Maxmimum amount of time (in seconds) to allow a client to choose the * server to connect to if server_autoconnect is no. This starts counting * once they've logged in. */ #define DEFAULT_CONNECT_TIMEOUT 60 /* DEFAULT_DNS_TIMEOUT * Maximum amount of time (in seconds) to allow for a DNS request. */ #define DEFAULT_DNS_TIMEOUT 20 /* DEFAULT_SERVER_PORT * What port do we connect to IRC servers on if the server string doesn't * explicitly set one */ #define DEFAULT_SERVER_PORT "6667" /* DEFAULT_SERVER_RETRY * How many seconds after disconnection or last connection attempt do we * wait before retrying again? */ #define DEFAULT_SERVER_RETRY 15 /* DEFAULT_SERVER_MAXATTEMPTS * If we are disconnected from the server, how many times should we iterate * the server list before giving up and declaring the proxied connection * dead? * 0 = iterate forever */ #define DEFAULT_SERVER_MAXATTEMPTS 0 /* DEFAULT_SERVER_MAXINITATTEMPTS * On first connection, how many times should we iterate the server list * before giving up and declaring the proxied connection dead? * 0 = iterate forever, not recommended! */ #define DEFAULT_SERVER_MAXINITATTEMPTS 5 /* DEFAULT_SERVER_KEEPALIVE * Set the SO_KEEPALIVE socket option? * 1 = Yes * 0 = No */ #define DEFAULT_SERVER_KEEPALIVE 0 /* DEFAULT_SERVER_PINGTIMEOUT * How many seconds after receiving a PING do we wait until we assume the * server is stoned? Receipt of another ping resets this timer. * 0 = don't do stoned checking */ #define DEFAULT_SERVER_PINGTIMEOUT 0 /* DEFAULT_SERVER_THROTTLE{_BYTES,_PERIOD} * What is the maximum amount of bytes we can transmit in what time period? * This is used to throttle the server connection to make sure we don't get * flooded off. The _BYTES define should be the number of bytes and the * _PERIOD define should be a time in seconds to reset the counter. * 0 (for either) = don't throttle the connection */ #define DEFAULT_SERVER_THROTTLE_BYTES 1024 #define DEFAULT_SERVER_THROTTLE_PERIOD 10 /* DEFAULT_SERVER_AUTOCONNECT * Should we automatically connect to a server on startup? * 1 = Yes * 0 = No */ #define DEFAULT_SERVER_AUTOCONNECT 1 /* DEFAULT_CHANNEL_REJOIN * If we are kicked off a channel, how many seconds do we wait before attempting * to rejoin. * -1 = Don't rejoin * 0 = Immediately */ #define DEFAULT_CHANNEL_REJOIN 15 /* DEFAULT_CHANNEL_LEAVE_ON_DETACH * Do we PART from all the channels when the user detaches? * 1 = Yes * 0 = No */ #define DEFAULT_CHANNEL_LEAVE_ON_DETACH 0 /* DEFAULT_CHANNEL_REJOIN_ON_ATTACH * If we PARTed on detach, do we automatically rejoin again on attach? * 1 = Yes * 0 = No */ #define DEFAULT_CHANNEL_REJOIN_ON_ATTACH 1 /* DEFAULT_IDLE_MAXTIME * How many seconds since last PRIVMSG/NOTICE should dircproxy reset idle * time? * 0 = never */ #define DEFAULT_IDLE_MAXTIME 0 /* DEFAULT_DISCONNECT_EXISTING * If a connecting user tries to use a proxy that is already in user, do * we disconnect that proxy? * 1 = Yes, causes problems with auto-reconnecting clients * 0 = No, disconnect the new user */ #define DEFAULT_DISCONNECT_EXISTING 0 /* DEFAULT_DISCONNECT_ON_DETACH * When the user detaches from the proxy, do we disconnect them from the * server? * 1 = Yes, they need to do explicitly make it persist * 0 = No, always persists until they explicitly quit */ #define DEFAULT_DISCONNECT_ON_DETACH 0 /* DEFAULT_INITIAL_MODES * User modes to automatically set on first server connection. * 0 = don't do this */ #define DEFAULT_INITIAL_MODES "i" /* DEFAULT_DROP_MODES * User modes to automatically drop when the client detaches. * 0 = don't do this */ #define DEFAULT_DROP_MODES "oOws" /* DEFAULT_REFUSE_MODES * User modes that cause the server connection to be dropped. * 0 = don't do this */ #define DEFAULT_REFUSE_MODES 0 /* DEFAULT_LOCAL_ADDRESS * This can be set to a domain name on the local machine that dircproxy * should bind to before connection to an irc server. * 0 = don't do this */ #define DEFAULT_LOCAL_ADDRESS 0 /* DEFAULT_AWAY_MESSAGE * If the client detaches without leaving an AWAY message, set this as the * AWAY message until it comes back. * 0 = don't do this */ #define DEFAULT_AWAY_MESSAGE "Not available, messages are logged" /* DEFAULT_QUIT_MESSAGE * QUIT message to use for a normal termination of proxy session. * 0 = dircproxy internal one */ #define DEFAULT_QUIT_MESSAGE 0 /* DEFAULT_ATTACH_MESSAGE * When the client attaches again, it will send this to each channel they * are on. If it started with "/me " it will be sent as an ACTION ctcp * instead. * 0 = don't do this */ #define DEFAULT_ATTACH_MESSAGE 0 /* DEFAULT_DETACH_MESSAGE * When the client detaches, it will send this to each channel they * are on. If it started with "/me " it will be sent as an ACTION ctcp * instead. * 0 = don't do this */ #define DEFAULT_DETACH_MESSAGE 0 /* DEFAULT_DETACH_NICKNAME * When the client detaches, we change their nickname to this. If it * contains * then that is replaced by their current nickname. * 0 = don't do this */ #define DEFAULT_DETACH_NICKNAME 0 /* DEFAULT_NICK_KEEP * Attempt to keep the nickname last set by the IRC client? * 1 = Yes * 0 = No */ #define DEFAULT_NICK_KEEP 1 /* DEFAULT_CTCP_REPLIES * Whether to reply to ctcp messages while client is detatched * 1 = Yes * 0 = No */ #define DEFAULT_CTCP_REPLIES 1 /* DEFAULT_CHAN_LOG_ENABLED * Whether to log channel text * 1 = Yes * 0 = No */ #define DEFAULT_CHAN_LOG_ENABLED 1 /* DEFAULT_CHAN_LOG_ALWAYS * Log channel text even while the client is online? * 1 = Yes * 0 = No */ #define DEFAULT_CHAN_LOG_ALWAYS 1 /* DEFAULT_CHAN_LOG_TIMESTAMP * Include a timestamp with the logged text. * 1 = Yes * 0 = No */ #define DEFAULT_CHAN_LOG_TIMESTAMP 0 /* DEFAULT_CHAN_LOG_RELATIVETIME * Do fancy relative-time timestamping. * 1 = Yes * 0 = No */ #define DEFAULT_CHAN_LOG_RELATIVETIME 1 /* DEFAULT_CHAN_LOG_MAXSIZE * Maximum number of lines a log file should be. Once they reach this size, * dircproxy will roll the log removing lines from the front. * 0 = No limit */ #define DEFAULT_CHAN_LOG_MAXSIZE 0 /* DEFAULT_CHAN_LOG_RECALL * Number of lines to automatically recall on reconnection to dircproxy. * If this is defined, then it is also used as the default size for the * /DIRCPROXY RECALL command * -1 = All lines (not recommended if always) * 0 = Don't recall any */ #define DEFAULT_CHAN_LOG_RECALL 128 /* DEFAULT_CHAN_LOG_COPYDIR * Directory to log a copy of all text received in. * 0 = Don't do this */ #define DEFAULT_CHAN_LOG_COPYDIR 0 /* DEFAULT_CHAN_LOG_PROGRAM * Default program to pass log text through. * 0 = Don't do this */ #define DEFAULT_CHAN_LOG_PROGRAM 0 /* DEFAULT_OTHER_LOG_ENABLED * Whether to log server/private messages * 1 = Yes * 0 = No */ #define DEFAULT_OTHER_LOG_ENABLED 1 /* DEFAULT_OTHER_LOG_ALWAYS * Log private messages and notices even while the client is online? * 1 = Yes * 0 = No */ #define DEFAULT_OTHER_LOG_ALWAYS 0 /* DEFAULT_OTHER_LOG_TIMESTAMP * Include a timestamp with the logged text. * 1 = Yes * 0 = No */ #define DEFAULT_OTHER_LOG_TIMESTAMP 0 /* DEFAULT_OTHER_LOG_RELATIVETIME * Do fancy relative-time timestamping. * 1 = Yes * 0 = No */ #define DEFAULT_OTHER_LOG_RELATIVETIME 1 /* DEFAULT_OTHER_LOG_MAXSIZE * Maximum number of lines a log file should be. Once they reach this size, * dircproxy will roll the log removing lines from the front. * 0 = No limit */ #define DEFAULT_OTHER_LOG_MAXSIZE 0 /* DEFAULT_OTHER_LOG_RECALL * Number of lines to automatically recall on reconnection to dircproxy. * If this is defined, then it is also used as the default size for the * /DIRCPROXY RECALL command * -1 = All lines (not recommended if always) * 0 = Don't recall any */ #define DEFAULT_OTHER_LOG_RECALL -1 /* DEFAULT_OTHER_LOG_COPYDIR * Directory to log a copy of all text received in. * 0 = Don't do this */ #define DEFAULT_OTHER_LOG_COPYDIR 0 /* DEFAULT_OTHER_LOG_PROGRAM * Default program to pass log text through. * 0 = Don't do this */ #define DEFAULT_OTHER_LOG_PROGRAM 0 /* DEFAULT_LOG_TIMEOFFSET * Different in minutes from the IRC client to the dircproxy machine. * 0 = No difference */ #define DEFAULT_LOG_TIMEOFFSET 0 /* DEFAULT_LOG_EVENTS * Bitmask of events that we can log. All is 0xffff, best to keep it at * that. Otherwise check irc_net.h for the possible list. */ #define DEFAULT_LOG_EVENTS 0xffff /* DEFAULT_DCC_PROXY_INCOMING * Whether to proxy incoming DCC requests * 1 = Yes * 0 = No */ #define DEFAULT_DCC_PROXY_INCOMING 1 /* DEFAULT_DCC_PROXY_OUTGOING * Whether to proxy outgoing DCC requests * 1 = Yes * 0 = No */ #define DEFAULT_DCC_PROXY_OUTGOING 1 /* DEFAULT_DCC_PROXY_PORTS * This MUST be left at 0, trust me */ #define DEFAULT_DCC_PROXY_PORTS 0 /* DEFAULT_DCC_PROXY_TIMEOUT * Maximum amount of time (in seconds) to wait for both sides of a DCC proxy * session to have connected. */ #define DEFAULT_DCC_PROXY_TIMEOUT 60 /* DEFAULT_DCC_PROXY_SENDREJECT * Should dircproxy send a REJECT back if it couldn't establish the proxy. * 1 = Yes * 0 = No, just cut the dcc out */ #define DEFAULT_DCC_PROXY_SENDREJECT 1 /* DEFAULT_DCC_SEND_FAST * Whether to wait for acknowledgement of data from the client before sending * any more (during a DCC Send). * 1 = Yes * 0 = No */ #define DEFAULT_DCC_SEND_FAST 0 /* DEFAULT_DCC_CAPTURE_DIRECTORY * Directory to capture DCC sends in. * 0 = Do not capture */ #define DEFAULT_DCC_CAPTURE_DIRECTORY 0 /* DEFAULT_DCC_CAPTURE_ALWAYS * Capture DCC sends even when we've got a client connected? * 1 = Yes * 0 = No */ #define DEFAULT_DCC_CAPTURE_ALWAYS 0 /* DEFAULT_DCC_CAPTURE_WITHNICK * Include the nickname at the front of the captured filename? * 1 = Yes * 0 = No */ #define DEFAULT_DCC_CAPTURE_WITHNICK 0 /* DEFAULT_DCC_CAPTURE_MAXSIZE * Maximum size of a captured file, if they reach this size then the * transfer will be refused. * 0 = No limit */ #define DEFAULT_DCC_CAPTURE_MAXSIZE 0 /* DEFAULT_DCC_TUNNEL_INCOMING * Local port that all incoming DCC connections should go through * 0 = Don't do this */ #define DEFAULT_DCC_TUNNEL_INCOMING 0 /* DEFAULT_DCC_TUNNEL_OUTGOING * Local port that all outgoing DCC connections should go through * 0 = Don't do this */ #define DEFAULT_DCC_TUNNEL_OUTGOING 0 /* DEFAULT_SWITCH_USER * Username to create server socket with * 0 = Don't do this */ #define DEFAULT_SWITCH_USER 0 /* DEFAULT_MOTD_LOGO * Display a nice dircproxy logo in the message of the day. This logo is * just fancy really, but its kinda nice to have it there imho. * 1 = Yes, display it * 0 = Don't display it */ #define DEFAULT_MOTD_LOGO 1 /* DEFAULT_MOTD_FILE * Path to file containing a custom message of the day to send to client. * If defined, its displayed between the logo and the stats. * 0 = Don't have one */ #define DEFAULT_MOTD_FILE 0 /* DEFAULT_MOTD_STATS * Display what channels you were on, and the log file sizes etc in the * message of the day when you reconnect. * 1 = Yes, display it * 0 = Don't display it */ #define DEFAULT_MOTD_STATS 1 /* DEFAULT_ALLOW_PERSIST * Whether the /DIRCPROXY PERSIST command can be used. * 1 = Enabled * 0 = Disabled */ #define DEFAULT_ALLOW_PERSIST 1 /* DEFAULT_ALLOW_JUMP * Whether the /DIRCPROXY JUMP command can be used. * 1 = Enabled * 0 = Disabled */ #define DEFAULT_ALLOW_JUMP 1 /* DEFAULT_ALLOW_JUMP_NEW * Whether the /DIRCPROXY JUMP command can be used to add a new server * 1 = Enabled * 0 = Disabled */ #define DEFAULT_ALLOW_JUMP_NEW 1 /* DEFAULT_ALLOW_HOST * Whether the /DIRCPROXY HOST command can be used. * 1 = Enabled * 0 = Disabled */ #define DEFAULT_ALLOW_HOST 1 /* DEFAULT_ALLOW_DIE * Whether the /DIRCPROXY DIE command can be used. * 1 = Enabled * 0 = Disabled */ #define DEFAULT_ALLOW_DIE 0 /* DEFAULT_ALLOW_USERS * Whether the /DIRCPROXY USERS command can be used. * 1 = Enabled * 0 = Disabled */ #define DEFAULT_ALLOW_USERS 0 /* DEFAULT_ALLOW_KILL * Whether the /DIRCPROXY KILL command can be used. * 1 = Enabled * 0 = Disabled */ #define DEFAULT_ALLOW_KILL 0 /* Global variables */ struct globalvars { long client_timeout; long connect_timeout; long dns_timeout; }; /* global variables */ extern struct globalvars g; /* functions in main.c */ extern int syscall_fail(const char *, const char *, const char *); extern int error(const char *, ...); extern int debug(const char *, ...); extern int stop(void); extern int go_daemon(void); #endif /* __DIRCPROXY_DIRCPROXY_H */ dircproxy-1.0.5/src/irc_net.c0000664000175000017500000003327707410714173011621 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * irc_net.c * - Socket to listen for new connections on * - The list of connection classes * - The list of currently active proxies * - Miscellaneous IRC functions * -- * @(#) $Id: irc_net.c,v 1.45 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "net.h" #include "dns.h" #include "timers.h" #include "sprintf.h" #include "irc_log.h" #include "irc_string.h" #include "irc_client.h" #include "irc_server.h" #include "irc_net.h" /* forward declarations */ static int _ircnet_listen(struct sockaddr_in *); static struct ircproxy *_ircnet_newircproxy(void); static int _ircnet_client_connected(struct ircproxy *); static void _ircnet_acceptclient(void *, int); static void _ircnet_freeproxy(struct ircproxy *); static void _ircnet_rejoin(struct ircproxy *, void *); /* list of connection classes */ struct ircconnclass *connclasses = 0; /* whether we are a dedicated proxy or not */ static int dedicated_proxy = 0; /* list of currently proxied connections */ static struct ircproxy *proxies = 0; /* socket we are listening for new client connections on */ static int listen_sock = -1; /* Create a socket to listen on. 0 = ok, other = error */ int ircnet_listen(const char *port) { struct sockaddr_in local_addr; local_addr.sin_family = AF_INET; local_addr.sin_addr.s_addr = INADDR_ANY; local_addr.sin_port = dns_portfromserv(port); if (!local_addr.sin_port) return -1; return _ircnet_listen(&local_addr); } /* Does the actual work of creating a listen socket. 0 = ok, other = error */ int _ircnet_listen(struct sockaddr_in *local_addr) { int this_sock; this_sock = net_socket(); if (this_sock == -1) return -1; if (local_addr) { if (bind(this_sock, (struct sockaddr *)local_addr, sizeof(struct sockaddr_in))) { syscall_fail("bind", "listen", 0); net_close(&this_sock); return -1; } } if (listen(this_sock, SOMAXCONN)) { syscall_fail("listen", 0, 0); net_close(&this_sock); return -1; } if (listen_sock != -1) { debug("Closing existing listen socket %d", listen_sock); net_close(&listen_sock); } debug("Listening on socket %d", this_sock); listen_sock = this_sock; net_hook(listen_sock, SOCK_LISTENING, 0, ACTIVITY_FUNCTION(_ircnet_acceptclient), 0); return 0; } /* Creates a new ircproxy structure */ static struct ircproxy *_ircnet_newircproxy(void) { struct ircproxy *p; p = (struct ircproxy *)malloc(sizeof(struct ircproxy)); memset(p, 0, sizeof(struct ircproxy)); return p; } /* Finishes off the creation of an ircproxy structure */ static int _ircnet_client_connected(struct ircproxy *p) { p->next = proxies; proxies = p; return ircclient_connected(p); } /* Creates a client hooked onto a socket */ int ircnet_hooksocket(int sock) { struct ircproxy *p; int len; p = _ircnet_newircproxy(); p->client_sock = sock; len = sizeof(struct sockaddr_in); if (getpeername(p->client_sock, (struct sockaddr *)&(p->client_addr), &len)) { syscall_fail("getpeername", "", 0); free(p); return -1; } p->die_on_close = 1; net_create(&(p->client_sock)); if (p->client_sock != -1) { return _ircnet_client_connected(p); } else { free(p); return -1; } } /* Accept a client. */ static void _ircnet_acceptclient(void *data, int sock) { struct ircproxy *p; int len; p = _ircnet_newircproxy(); len = sizeof(struct sockaddr_in); p->client_sock = accept(sock, (struct sockaddr *)&(p->client_addr), &len); if (p->client_sock == -1) { syscall_fail("accept", 0, 0); free(p); return; } net_create(&(p->client_sock)); if (p->client_sock != -1) { _ircnet_client_connected(p); } else { free(p); } return; } /* Fetch a proxy for a connection class if one exists */ struct ircproxy *ircnet_fetchclass(struct ircconnclass *class) { struct ircproxy *p; p = proxies; while (p) { if (!p->dead && (p->conn_class == class)) return p; p = p->next; } return 0; } /* Fetch a channel from a proxy */ struct ircchannel *ircnet_fetchchannel(struct ircproxy *p, const char *name) { struct ircchannel *c; c = p->channels; while (c) { if (!irc_strcasecmp(c->name, name)) return c; c = c->next; } return 0; } /* Add a channel to a proxy */ int ircnet_addchannel(struct ircproxy *p, const char *name) { struct ircchannel *c; if (ircnet_fetchchannel(p, name)) return 0; c = (struct ircchannel *)malloc(sizeof(struct ircchannel)); memset(c, 0, sizeof(struct ircchannel)); c->name = x_strdup(name); debug("Joined channel '%s'", c->name); if (p->channels) { struct ircchannel *cc; cc = p->channels; while (cc->next) cc = cc->next; cc->next = c; } else { p->channels = c; } /* Intialise the channel log */ irclog_init(p, c->name); /* Open the channel log */ if (p->conn_class->chan_log_enabled && p->conn_class->chan_log_always) { if (irclog_open(p, c->name)) ircclient_send_channotice(p, c->name, "(warning) Unable to log channel: %s", c->name); } return 0; } /* Remove a channel from a proxy */ int ircnet_delchannel(struct ircproxy *p, const char *name) { struct ircchannel *c, *l; l = 0; c = p->channels; debug("Parted channel '%s'", name); while (c) { if (!irc_strcasecmp(c->name, name)) { if (l) { l->next = c->next; } else { p->channels = c->next; } ircnet_freechannel(c); return 0; } else { l = c; c = c->next; } } debug(" (which didn't exist)"); return -1; } /* Got a channel mode change */ int ircnet_channel_mode(struct ircproxy *p, struct ircchannel *c, struct ircmessage *msg, int modes) { int add = 1; int param; char *ptr; if (msg->numparams < (modes + 1)) return -1; debug("Channel '%s' mode change '%s'", c->name, msg->paramstarts[modes]); ptr = msg->params[modes]; param = modes + 1; while (*ptr) { switch (*ptr) { case '+': add = 1; break; case '-': add = 0; break; /* RFC2812 modes that have a parameter */ case 'O': case 'o': case 'v': case 'b': case 'e': case 'I': case 'l': param++; break; /* Channel key */ case 'k': if (add) { if (msg->numparams >= (param + 1)) { debug("Set channel '%s' key '%s'", c->name, msg->params[param]); free(c->key); c->key = x_strdup(msg->params[param]); } else { debug("Bad mode from server, said +k without a key"); } } else if (c->key) { debug("Remove channel '%s' key"); free(c->key); c->key = 0; } param++; break; } ptr++; } return 0; } /* Free an ircchannel structure, returns the next */ struct ircchannel *ircnet_freechannel(struct ircchannel *chan) { struct ircchannel *ret; ret = chan->next; irclog_free(&(chan->log)); free(chan->name); free(chan->key); free(chan); return ret; } /* Free an ircproxy structure */ static void _ircnet_freeproxy(struct ircproxy *p) { debug("Freeing proxy"); if (p->server_status & IRC_SERVER_CONNECTED) { ircserver_send_command(p, "QUIT", ":Terminated with extreme prejudice - %s %s", PACKAGE, VERSION); ircserver_close_sock(p); } if (p->client_status & IRC_CLIENT_CONNECTED) { ircclient_send_error(p, "dircproxy going bye-bye"); ircclient_close(p); } dns_delall((void *)p); timer_delall((void *)p); free(p->client_host); free(p->nickname); free(p->setnickname); free(p->oldnickname); free(p->username); free(p->hostname); free(p->realname); free(p->servername); free(p->serverver); free(p->serverumodes); free(p->servercmodes); free(p->serverpassword); free(p->password); free(p->awaymessage); free(p->modes); if (p->channels) { struct ircchannel *c; c = p->channels; while (c) c = ircnet_freechannel(c); } if (p->squelch_modes) { struct strlist *s; s = p->squelch_modes; while (s) { struct strlist *n; n = s->next; free(s->str); free(s); s = n; } } irclog_free(&(p->other_log)); irclog_closetempdir(p); free(p); } /* Get rid of any dead proxies */ int ircnet_expunge_proxies(void) { struct ircproxy *p, *l; l = 0; p = proxies; while (p) { if (p->dead) { struct ircproxy *n; n = p->next; _ircnet_freeproxy(p); if (l) { p = l->next = n; } else { p = proxies = n; } } else { l = p; p = p->next; } } return 0; } /* Get rid of all the proxies and connection classes */ void ircnet_flush(void) { ircnet_flush_proxies(&proxies); ircnet_flush_connclasses(&connclasses); } /* Get rid of all the proxies */ void ircnet_flush_proxies(struct ircproxy **p) { while (*p) { struct ircproxy *t; t = *p; *p = (*p)->next; _ircnet_freeproxy(t); } *p = 0; } /* Get rid of all the connection classes */ void ircnet_flush_connclasses(struct ircconnclass **c) { while (*c) { struct ircconnclass *t; t = *c; *c = (*c)->next; ircnet_freeconnclass(t); } *c = 0; } /* Free a connection class structure */ void ircnet_freeconnclass(struct ircconnclass *class) { struct strlist *s; free(class->server_port); free(class->server_throttle); free(class->initial_modes); free(class->drop_modes); free(class->refuse_modes); free(class->local_address); free(class->away_message); free(class->quit_message); free(class->attach_message); free(class->detach_message); free(class->detach_nickname); free(class->chan_log_copydir); free(class->chan_log_program); free(class->other_log_copydir); free(class->other_log_program); free(class->dcc_proxy_ports); free(class->dcc_capture_directory); free(class->dcc_tunnel_incoming); free(class->dcc_tunnel_outgoing); free(class->switch_user); free(class->motd_file); free(class->orig_local_address); free(class->password); s = class->servers; while (s) { struct strlist *t; t = s; s = s->next; free(t->str); free(t); } s = class->masklist; while (s) { struct strlist *t; t = s; s = s->next; free(t->str); free(t); } s = class->channels; while (s) { struct strlist *t; t = s; s = s->next; free(t->str); free(t); } free(class); } /* hook to rejoin a channel after a kick */ static void _ircnet_rejoin(struct ircproxy *p, void *data) { struct ircchannel *c; debug("Rejoining '%s'", (char *)data); c = ircnet_fetchchannel(p, (char *)data); if (c) { if (c->key) { ircserver_send_command(p, "JOIN", "%s :%s", c->name, c->key); } else { ircserver_send_command(p, "JOIN", ":%s", c->name); } } else { ircserver_send_command(p, "JOIN", ":%s", (char *)data); } free(data); } /* Set a timer to rejoin a channel */ int ircnet_rejoin(struct ircproxy *p, const char *name) { char *str; str = x_strdup(name); if (p->conn_class->channel_rejoin == 0) { _ircnet_rejoin(p, (void *)str); } else if (p->conn_class->channel_rejoin > 0) { debug("Will rejoin '%s' in %d seconds", str, p->conn_class->channel_rejoin); timer_new((void *)p, 0, p->conn_class->channel_rejoin, TIMER_FUNCTION(_ircnet_rejoin), (void *)str); } return 0; } /* Dedicate this proxy and create a listening socket */ int ircnet_dedicate(struct ircproxy *p) { struct ircconnclass *c; if (dedicated_proxy) return -1; /* Can't dedicate if there are multiple proxies */ if ((p != proxies) || p->next) { debug("Multiple active proxies, won't dedicate"); return -1; } debug("Dedicating proxy"); if (_ircnet_listen(0)) return -1; c = connclasses; while (c) { if (c == p->conn_class) { c = c->next; } else { struct ircconnclass *t; t = c; c = c->next; ircnet_freeconnclass(t); } } connclasses = p->conn_class; connclasses->next = 0; /* Okay we're dedicated */ dedicated_proxy = 1; ircnet_announce_dedicated(p); return 0; } /* send the dedicated listening port to the user */ int ircnet_announce_dedicated(struct ircproxy *p) { struct sockaddr_in listen_addr; unsigned int port; int len; if (!IS_CLIENT_READY(p)) return -1; len = sizeof(struct sockaddr_in); if (!getsockname(listen_sock, (struct sockaddr *)&listen_addr, &len)) { port = ntohs(listen_addr.sin_port); } else { syscall_fail("getsockname", "listen_sock", 0); return -1; } ircclient_send_notice(p, "Reconnect to this session at %s:%d", p->hostname, port); return 0; } /* tell the client they can't reconnect */ int ircnet_announce_nolisten(struct ircproxy *p) { if (!IS_CLIENT_READY(p)) return -1; ircclient_send_notice(p, "You cannot reconnect to this session"); return 0; } /* tell the client whether we're dedicated or not listening */ int ircnet_announce_status(struct ircproxy *p) { if (p->die_on_close) { return ircnet_announce_nolisten(p); } else if (dedicated_proxy) { return ircnet_announce_dedicated(p); } else { return 0; } } dircproxy-1.0.5/src/irc_net.h0000664000175000017500000001445607430200156011615 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * irc_net.h * -- * @(#) $Id: irc_net.h,v 1.46 2002/02/06 10:07:42 scott Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #ifndef __DIRCPROXY_IRC_NET_H #define __DIRCPROXY_IRC_NET_H /* required includes */ #include #include #include #include #include #include "irc_prot.h" #include "stringex.h" /* a log file - there are good reasons why this isn't defined in irc_log.h */ struct logfile { int open, made; char *filename; FILE *file; FILE *copy; char *program; unsigned long nlines, maxlines; int always; int timestamp; int relativetime; }; /* a description of an authorised connction */ struct ircconnclass { char *server_port; long server_retry; long server_dnsretry; long server_maxattempts; long server_maxinitattempts; int server_keepalive; long server_pingtimeout; long *server_throttle; int server_autoconnect; long channel_rejoin; int channel_leave_on_detach; int channel_rejoin_on_attach; long idle_maxtime; int disconnect_existing; int disconnect_on_detach; char *initial_modes; char *drop_modes; char *refuse_modes; char *local_address; char *away_message; char *quit_message; char *attach_message; char *detach_message; char *detach_nickname; int nick_keep; int ctcp_replies; int chan_log_enabled; int chan_log_always; long chan_log_maxsize; long chan_log_recall; int chan_log_timestamp; int chan_log_relativetime; char *chan_log_copydir; char *chan_log_program; int other_log_enabled; int other_log_always; long other_log_maxsize; long other_log_recall; int other_log_timestamp; int other_log_relativetime; char *other_log_copydir; char *other_log_program; long log_timeoffset; int log_events; int dcc_proxy_incoming; int dcc_proxy_outgoing; int *dcc_proxy_ports; size_t dcc_proxy_ports_sz; long dcc_proxy_timeout; int dcc_proxy_sendreject; int dcc_send_fast; char *dcc_capture_directory; int dcc_capture_always; int dcc_capture_withnick; long dcc_capture_maxsize; char *dcc_tunnel_incoming; char *dcc_tunnel_outgoing; char *switch_user; int motd_logo; char *motd_file; int motd_stats; int allow_persist; int allow_jump; int allow_jump_new; int allow_host; int allow_die; int allow_users; int allow_kill; char *password; struct strlist *servers, *next_server; struct strlist *masklist; struct strlist *channels; /* Most config file options can be changed by editing the config file and HUP'ing dircproxy. One or two can be done from the /DIRCPROXY command though. Always keep the originals. */ char *orig_local_address; struct ircconnclass *next; }; /* a channel someone is on */ struct ircchannel { char *name; char *key; int inactive; int unjoined; struct logfile log; struct ircchannel *next; }; /* a proxied connection */ struct ircproxy { int dead; struct ircconnclass *conn_class; int die_on_close; time_t start; int client_sock; int client_status; struct sockaddr_in client_addr; char *client_host; int server_sock; int server_status; struct sockaddr_in server_addr; long server_attempts; char *nickname; char *setnickname; char *oldnickname; char *username; char *hostname; char *realname; char *servername; char *serverver; char *serverumodes; char *servercmodes; char *serverpassword; char *password; int allow_motd; int allow_pong; int squelch_411; int expecting_nick; struct strlist *squelch_modes; char *ctcp_userinfo; char *ctcp_finger; char *awaymessage; char *modes; struct ircchannel *channels; char *temp_logdir; struct logfile other_log; struct ircproxy *next; }; /* states a client can be in */ #define IRC_CLIENT_NONE 0x00 #define IRC_CLIENT_CONNECTED 0x01 #define IRC_CLIENT_GOTPASS 0x02 #define IRC_CLIENT_GOTNICK 0x04 #define IRC_CLIENT_GOTUSER 0x08 #define IRC_CLIENT_AUTHED 0x10 #define IRC_CLIENT_SENTWELCOME 0x20 #define IRC_CLIENT_ACTIVE 0x3d /* Can we send data to the client? */ #define IS_CLIENT_READY(_c) (((_c)->client_status & 0x1d) == 0x1d) /* states a server can be in */ #define IRC_SERVER_NONE 0x00 #define IRC_SERVER_CREATED 0x01 #define IRC_SERVER_SEEN 0x02 #define IRC_SERVER_CONNECTED 0x04 #define IRC_SERVER_INTRODUCED 0x08 #define IRC_SERVER_GOTWELCOME 0x10 #define IRC_SERVER_ACTIVE 0x1f /* Can we send data to the server? */ #define IS_SERVER_READY(_c) (((_c)->server_status & 0x0c) == 0x0c) /* types of event we can log */ #define IRC_LOG_TEXT 0x0001 #define IRC_LOG_ACTION 0x0002 #define IRC_LOG_CTCP 0x0004 #define IRC_LOG_JOIN 0x0008 #define IRC_LOG_PART 0x0010 #define IRC_LOG_KICK 0x0020 #define IRC_LOG_QUIT 0x0040 #define IRC_LOG_NICK 0x0080 #define IRC_LOG_MODE 0x0100 #define IRC_LOG_TOPIC 0x0200 #define IRC_LOG_CLIENT 0x0400 #define IRC_LOG_SERVER 0x0800 #define IRC_LOG_ERROR 0x1000 /* global variables */ extern struct ircconnclass *connclasses; /* functions */ extern int ircnet_listen(const char *); extern int ircnet_expunge_proxies(void); extern void ircnet_flush(void); extern void ircnet_flush_proxies(struct ircproxy **); extern void ircnet_flush_connclasses(struct ircconnclass **); extern void ircnet_freeconnclass(struct ircconnclass *); extern int ircnet_hooksocket(int); extern struct ircproxy *ircnet_fetchclass(struct ircconnclass *); extern struct ircchannel *ircnet_fetchchannel(struct ircproxy *, const char *); extern int ircnet_addchannel(struct ircproxy *, const char *); extern int ircnet_delchannel(struct ircproxy *, const char *); extern int ircnet_channel_mode(struct ircproxy *, struct ircchannel *, struct ircmessage *, int); extern struct ircchannel *ircnet_freechannel(struct ircchannel *); extern int ircnet_rejoin(struct ircproxy *, const char *); extern int ircnet_dedicate(struct ircproxy *); extern int ircnet_announce_dedicated(struct ircproxy *); extern int ircnet_announce_nolisten(struct ircproxy *); extern int ircnet_announce_status(struct ircproxy *); #endif /* __DIRCPROXY_IRC_NET_H */ dircproxy-1.0.5/src/irc_client.c0000664000175000017500000020160007430200370012263 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * irc_client.c * - Handling of clients connected to the proxy * - Functions to send data to the client in the correct protocol format * -- * @(#) $Id: irc_client.c,v 1.83 2002/02/06 10:10:00 scott Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #include #include #include #include #include #include #include #include #ifdef HAVE_CRYPT_H # include #else /* HAVE_CRYPT_H */ # include #endif /* HAVE_CRYPT_H */ #include "sprintf.h" #include "net.h" #include "dns.h" #include "timers.h" #include "dcc_net.h" #include "irc_log.h" #include "irc_net.h" #include "irc_prot.h" #include "irc_string.h" #include "irc_server.h" #include "irc_client.h" #include "logo.h" #include "help.h" /* forward declarations */ static void _ircclient_connected2(struct ircproxy *, void *, struct in_addr *, const char *); static void _ircclient_data(struct ircproxy *, int); static void _ircclient_error(struct ircproxy *, int, int); static int _ircclient_detach(struct ircproxy *, const char *); static int _ircclient_gotmsg(struct ircproxy *, const char *); static int _ircclient_authenticate(struct ircproxy *, const char *); static void _ircclient_resetnick(struct ircproxy *, void *); static int _ircclient_got_details(struct ircproxy *, const char *, const char *, const char *, const char *); static int _ircclient_motd(struct ircproxy *); static void _ircclient_timedout(struct ircproxy *, void *); static int _ircclient_send_dccreject(struct ircproxy *, const char *); /* New user mode bits */ #define RFC2812_MODE_W 0x04 #define RFC2812_MODE_I 0x08 /* Time/date format for strftime(3) */ #define START_TIMEDATE_FORMAT "%a, %d %b %Y %H:%M:%S %z" /* Define MIN() */ #ifndef MIN #define MIN(x, y) ((x) < (y) ? (x) : (y)) #endif /* MIN */ /* Called when a new client has connected */ int ircclient_connected(struct ircproxy *p) { ircclient_send_notice(p, "Looking up your hostname..."); dns_hostfromaddr((void *)p, 0, p->client_addr.sin_addr, DNS_FUNCTION(_ircclient_connected2)); return 0; } /* Called once a client DNS lookup has completed */ static void _ircclient_connected2(struct ircproxy *p, void *data, struct in_addr *addr, const char *name) { p->client_host = x_strdup(name); if (!p->hostname) p->hostname = x_strdup(name); ircclient_send_notice(p, "Got your hostname."); p->client_status |= IRC_CLIENT_CONNECTED; net_hook(p->client_sock, SOCK_NORMAL, (void *)p, ACTIVITY_FUNCTION(_ircclient_data), ERROR_FUNCTION(_ircclient_error)); debug("Client connected from %s", p->client_host); timer_new((void *)p, "client_auth", g.client_timeout, TIMER_FUNCTION(_ircclient_timedout), (void *)0); } /* Called when a client sends us stuff. */ static void _ircclient_data(struct ircproxy *p, int sock) { char *str; if (sock != p->client_sock) { error("Unexpected socket %d in _ircclient_data, expected %d", sock, p->client_sock); net_close(&sock); return; } str = 0; while (!p->dead && (p->client_status & IRC_CLIENT_CONNECTED) && net_gets(p->client_sock, &str, "\r\n") > 0) { debug(">> '%s'", str); _ircclient_gotmsg(p, str); free(str); } } /* Called on client disconnection or error */ static void _ircclient_error(struct ircproxy *p, int sock, int bad) { if (sock != p->client_sock) { error("Unexpected socket %d in _ircclient_error, expected %d", sock, p->client_sock); net_close(&sock); return; } if (bad) { debug("Socket error"); } else { debug("Client disconnect"); } _ircclient_detach(p, 0); } /* Called to detach an irc client */ static int _ircclient_detach(struct ircproxy *p, const char *message) { if (p->die_on_close) { debug("Killing proxy"); if (message) { ircserver_send_command(p, "QUIT", ":%s", message); } else if (p->conn_class && p->conn_class->quit_message) { ircserver_send_command(p, "QUIT", ":%s", p->conn_class->quit_message); } else { ircserver_send_command(p, "QUIT", ":Leaving IRC - %s %s", PACKAGE, VERSION); } ircserver_close_sock(p); p->conn_class = 0; ircclient_close(p); } else { debug("Detaching proxy"); if ((p->client_status == IRC_CLIENT_ACTIVE) && (p->conn_class->log_events & IRC_LOG_CLIENT)) irclog_notice(p, 0, PACKAGE, "You disconnected"); /* Drop modes */ if ((p->client_status == IRC_CLIENT_ACTIVE) && p->conn_class->drop_modes) { char *mode; mode = x_sprintf("-%s", p->conn_class->drop_modes); debug("Auto-mode-change '%s'", mode); ircclient_change_mode(p, mode); if (p->server_status == IRC_SERVER_ACTIVE) ircserver_send_command(p, "MODE", "%s %s", p->nickname, mode); free(mode); } /* Send detach message to all channels we're on */ if ((p->server_status == IRC_SERVER_ACTIVE) && (p->client_status == IRC_CLIENT_ACTIVE)) { if (p->conn_class->detach_message) { struct ircchannel *c; int slashme; char *msg; msg = p->conn_class->detach_message; if ((strlen(msg) >= 5) && !strncasecmp(msg, "/me ", 4)) { /* Starts with /me */ slashme = 1; msg += 4; } else { slashme = 0; } c = p->channels; while (c) { if (!c->inactive && !c->unjoined) { if (slashme) { ircserver_send_command(p, "PRIVMSG", "%s :\001ACTION %s\001", c->name, msg); } else { ircserver_send_command(p, "PRIVMSG", "%s :%s", c->name, msg); } } c = c->next; } } } /* Leave channels until they come back */ if ((p->server_status == IRC_SERVER_ACTIVE) && (p->client_status == IRC_CLIENT_ACTIVE)) { if (p->conn_class->channel_leave_on_detach) { struct ircchannel *c; c = p->channels; while (c) { struct ircchannel *t; t = c; c = c->next; /* Leave the channel and decide whether to delete it or rejoin */ if (!t->inactive && !t->unjoined) { ircserver_send_command(p, "PART", ":%s", t->name); if (p->conn_class->channel_rejoin_on_attach) { t->unjoined = 1; } else { ircnet_delchannel(p, t->name); } } } } } /* Set away message */ if ((p->server_status == IRC_SERVER_ACTIVE) && (p->client_status == IRC_CLIENT_ACTIVE)) { if (message) { ircserver_send_command(p, "AWAY", ":%s", message); } else if (!p->awaymessage && p->conn_class->away_message) { ircserver_send_command(p, "AWAY", ":%s", p->conn_class->away_message); } } /* Change Nickname */ if ((p->client_status == IRC_CLIENT_ACTIVE) && p->conn_class->detach_nickname) { char *nick, *ptr; nick = x_strdup(p->conn_class->detach_nickname); ptr = strchr(nick, '*'); if (ptr) { char *newnick; *(ptr++) = 0; newnick = x_sprintf("%s%s%s", nick, p->nickname, ptr); free(nick); nick = newnick; } debug("Auto-nick-change '%s'", nick); /* We need to remember what the setnickname is now so when the client comes back we can reset it again. So put it in oldnickname. */ if (p->oldnickname) free(p->oldnickname); p->oldnickname = p->setnickname; p->setnickname = 0; ircclient_change_nick(p, nick); free(nick); } /* Open other_log */ if ((p->client_status == IRC_CLIENT_ACTIVE) && p->conn_class->other_log_enabled && !p->conn_class->other_log_always) { if (irclog_open(p, p->nickname)) ircclient_send_notice(p, "(warning) Unable to log server/private " "messages"); } /* Open channel logs */ if ((p->client_status == IRC_CLIENT_ACTIVE) && p->conn_class->chan_log_enabled && !p->conn_class->chan_log_always) { struct ircchannel *c; c = p->channels; while (c) { if (irclog_open(p, c->name)) ircclient_send_notice(p, "(warning) Unable to log channel: %s", c->name); c = c->next; } } /* Close the socket */ ircclient_close(p); } return 0; } /* Called when we get an irc protocol data from a client */ static int _ircclient_gotmsg(struct ircproxy *p, const char *str) { struct ircmessage msg; if (ircprot_parsemsg(str, &msg) == -1) return -1; debug("c=%02x, s=%02x", p->client_status, p->server_status); if (!(p->client_status & IRC_CLIENT_AUTHED)) { /* Accept PASS, NICK and USER commands only until we've authenticated */ if (!irc_strcasecmp(msg.cmd, "PASS")) { if (msg.numparams >= 1) { if (p->password) free(p->password); p->password = x_strdup(msg.params[0]); p->client_status |= IRC_CLIENT_GOTPASS; } else { ircclient_send_numeric(p, 461, ":Not enough parameters"); } } else if (!irc_strcasecmp(msg.cmd, "NICK")) { if (msg.numparams >= 1) { if (!(p->client_status & IRC_CLIENT_GOTNICK) || strcmp(p->nickname, msg.params[0])) ircclient_change_nick(p, msg.params[0]); } else { ircclient_send_numeric(p, 431, ":No nickname given"); } } else if (!irc_strcasecmp(msg.cmd, "USER")) { if (msg.numparams >= 4) { if (!(p->client_status & IRC_CLIENT_GOTUSER)) _ircclient_got_details(p, msg.params[0], msg.params[1], msg.params[2], msg.params[3]); } else { ircclient_send_numeric(p, 461, ":Not enough parameters"); } } else if (!(p->client_status & IRC_CLIENT_GOTPASS)) { ircclient_send_notice(p, "Please send /QUOTE PASS to login"); } else { ircclient_send_notice(p, "Please send /QUOTE NICK and /QUOTE USER"); } } else if (!(p->client_status & IRC_CLIENT_GOTNICK)) { /* We've lost the nickname */ if (!irc_strcasecmp(msg.cmd, "NICK")) { if (msg.numparams >= 1) { ircclient_change_nick(p, msg.params[0]); } else { ircclient_send_numeric(p, 431, ":No nickname given"); } } else { ircclient_send_notice(p, "Please send a /NICK command"); } } else { /* The server MUST be active to use most of the commands. The only exception is /DIRCPROXY. */ if (p->server_status == IRC_SERVER_ACTIVE) { /* By default we squelch everything, but the else clause turns this off. Effectively it means that all handled commands are not passed to the server unless you set squelch to 0 */ int squelch = 1; if (!irc_strcasecmp(msg.cmd, "PASS")) { /* Ignore PASS */ } else if (!irc_strcasecmp(msg.cmd, "USER")) { /* Ignore USER */ } else if (!irc_strcasecmp(msg.cmd, "DIRCPROXY")) { /* Ignore DIRCPROXY (handled in a minute) */ } else if (!irc_strcasecmp(msg.cmd, "QUIT")) { /* User wants to detach */ ircnet_announce_status(p); ircclient_send_error(p, "Detached from %s %s", PACKAGE, VERSION); _ircclient_detach(p, 0); ircprot_freemsg(&msg); return 0; } else if (!irc_strcasecmp(msg.cmd, "PONG")) { /* Ignore PONG */ } else if (!irc_strcasecmp(msg.cmd, "NICK")) { /* User changing their nickname */ if (msg.numparams >= 1) { ircclient_change_nick(p, msg.params[0]); } else { ircclient_send_numeric(p, 431, ":No nickname given"); } } else if (!irc_strcasecmp(msg.cmd, "AWAY")) { /* User marking themselves as away or back */ squelch = 0; /* ircII sends an empty parameter to mark back *grr* */ if ((msg.numparams >= 1) && strlen(msg.params[0])) { free(p->awaymessage); p->awaymessage = x_strdup(msg.params[0]); } else { free(p->awaymessage); p->awaymessage = 0; } } else if (!irc_strcasecmp(msg.cmd, "MOTD")) { /* User requesting the message of the day from the server */ p->allow_motd = 1; squelch = 0; } else if (!irc_strcasecmp(msg.cmd, "PING")) { /* User requesting a ping from the server */ p->allow_pong = 1; squelch = 0; } else if (!irc_strcasecmp(msg.cmd, "PRIVMSG")) { /* All PRIVMSGs go to the server unless we fiddle */ squelch = 0; if (msg.numparams >= 2) { struct strlist *list, *s; char *str; ircprot_stripctcp(msg.params[1], &str, &list); /* Privmsgs from us get logged */ if (str && strlen(str)) { if (p->conn_class->log_events & IRC_LOG_TEXT) { struct ircchannel *c; c = ircnet_fetchchannel(p, msg.params[0]); if (c) { char *tmp; tmp = x_sprintf("%s!%s@%s", p->nickname, p->username, p->hostname); irclog_msg(p, msg.params[0], tmp, "%s", str); free(tmp); } } } free(str); /* Handle CTCP */ str = x_strdup(msg.params[1]); s = list; while (s) { struct ctcpmessage cmsg; struct strlist *n; char *unquoted; int r; n = s->next; r = ircprot_parsectcp(s->str, &cmsg); unquoted = s->str; free(s); s = n; if (r == -1) { free(unquoted); continue; } if (!strcmp(cmsg.cmd, "ACTION")) { if (p->conn_class->log_events & IRC_LOG_ACTION) { struct ircchannel *c; c = ircnet_fetchchannel(p, msg.params[0]); if (c) { char *tmp; tmp = x_sprintf("%s!%s@%s", p->nickname, p->username, p->hostname); irclog_ctcp(p, msg.params[0], tmp, "%s", cmsg.orig); free(tmp); } } } else if (!strcmp(cmsg.cmd, "DCC") && p->conn_class->dcc_proxy_outgoing) { struct sockaddr_in vis_addr; int len; /* We need our local address to do anything DCC related */ len = sizeof(struct sockaddr_in); if (getsockname(p->server_sock, (struct sockaddr *)&vis_addr, &len)) { syscall_fail("getsockname", "", 0); } else if ((cmsg.numparams >= 4) && (!irc_strcasecmp(cmsg.params[0], "CHAT") || !irc_strcasecmp(cmsg.params[0], "SEND"))) { char *tmp, *ptr, *dccmsg, *rejmsg; struct in_addr l_addr, r_addr; int l_port, r_port, t_port; char *rest = 0; int type = 0; /* Find out what type of DCC request this is */ if (!irc_strcasecmp(cmsg.params[0], "CHAT")) { type = DCC_CHAT; } else if (!irc_strcasecmp(cmsg.params[0], "SEND")) { if (p->conn_class->dcc_send_fast) { type = DCC_SEND_FAST; } else { type = DCC_SEND_SIMPLE; } } /* Check whether there's a tunnel port */ t_port = 0; if (p->conn_class->dcc_tunnel_outgoing) t_port = dns_portfromserv(p->conn_class->dcc_tunnel_outgoing); /* Eww, host order, how the hell does this even work between machines of a different byte order? */ if (!t_port) { r_addr.s_addr = strtoul(cmsg.params[2], (char **)NULL, 10); r_port = atoi(cmsg.params[3]); } else { r_addr.s_addr = INADDR_LOOPBACK; r_port = ntohs(t_port); } l_addr.s_addr = ntohl(vis_addr.sin_addr.s_addr); if (cmsg.numparams >= 5) rest = cmsg.paramstarts[4]; /* Strip out this CTCP from the message, replacing it in a moment with dccmsg */ tmp = x_sprintf("\001%s\001", unquoted); ptr = strstr(str, tmp); dccmsg = 0; /* Save this in case we need it later */ rejmsg = x_sprintf(":%s NOTICE %s :\001DCC REJECT %s %s " "(%s: unable to proxy)", msg.params[0], p->nickname, cmsg.params[0], cmsg.params[1], PACKAGE); /* Set up a dcc proxy */ if (ptr && !dccnet_new(type, p->conn_class->dcc_proxy_timeout, p->conn_class->dcc_proxy_ports, p->conn_class->dcc_proxy_ports_sz, &l_port, r_addr, r_port, 0, 0, DCCN_FUNCTION(_ircclient_send_dccreject), p, rejmsg)) { dccmsg = x_sprintf("\001DCC %s %s %lu %u%s%s\001", cmsg.params[0], cmsg.params[1], l_addr.s_addr, l_port, (rest ? " " : ""), (rest ? rest : "")); if (p->conn_class->log_events & IRC_LOG_CTCP) irclog_notice(p, msg.params[0], p->servername, "Sent DCC %s Request to %s", cmsg.params[0], msg.params[0]); } else if (ptr) { dccmsg = x_strdup(""); _ircclient_send_dccreject(p, rejmsg); } /* Don't need this now */ free(rejmsg); /* Cut out the old CTCP and replace with dccmsg */ if (ptr) { char *oldstr; *ptr = 0; ptr += strlen(tmp); oldstr = str; str = x_sprintf("%s%s%s", oldstr, dccmsg, ptr); free(oldstr); free(dccmsg); } free(tmp); } else { /* Unknown DCC */ debug("Unknown or Unimplemented DCC request - %s", cmsg.params[0]); } } else { /* Unknown CTCP */ if (p->conn_class->log_events & IRC_LOG_CTCP) irclog_notice(p, msg.params[0], p->servername, "Sent CTCP %s to %s", cmsg.cmd, msg.params[0]); } ircprot_freectcp(&cmsg); free(unquoted); } /* Send str */ if (strlen(str)) net_send(p->server_sock, ":%s PRIVMSG %s :%s\r\n", (msg.src.orig ? msg.src.orig : p->nickname), msg.params[0], str); squelch = 1; free(str); } if (p->conn_class->idle_maxtime) ircserver_resetidle(p); } else if (!irc_strcasecmp(msg.cmd, "NOTICE")) { /* Notices from us get logged */ if (msg.numparams >= 2) { char *str; ircprot_stripctcp(msg.params[1], &str, 0); if (str && strlen(str)) { if (p->conn_class->log_events & IRC_LOG_TEXT) { struct ircchannel *c; c = ircnet_fetchchannel(p, msg.params[0]); if (c) { char *tmp; tmp = x_sprintf("%s!%s@%s", p->nickname, p->username, p->hostname); irclog_notice(p, msg.params[0], tmp, "%s", str); free(tmp); } } } free(str); } if (p->conn_class->idle_maxtime) ircserver_resetidle(p); squelch = 0; } else { squelch = 0; } /* Send command up to server? (We know there is one at this point) */ if (!squelch) net_send(p->server_sock, "%s\r\n", msg.orig); } else if (irc_strcasecmp(msg.cmd, "DIRCPROXY")) { /* Command didn't (and won't be) handled. We better stick to the RFC and send a RPL_TRYAGAIN back. */ ircclient_send_numeric(p, 263, "%s :Please wait a while and try again.", msg.cmd); } /* /DIRCPROXY can be used at *any* time, if it ever sends anything to the server it has to do it explicitly (no automatic sending) and has to check there is a server there */ if (!irc_strcasecmp(msg.cmd, "DIRCPROXY")) { if (msg.numparams >= 1) { if (!irc_strcasecmp(msg.params[0], "RECALL")) { char *src, *filter; long start, lines; /* User wants to recall stuff from log files */ src = filter = 0; start = -1; lines = 0; if (msg.numparams >= 4) { src = msg.params[1]; start = atol(msg.params[2]); lines = atol(msg.params[3]); } else if (msg.numparams >= 3) { if (!irc_strcasecmp(msg.params[2], "ALL")) { src = msg.params[1]; lines = -1; } else if (strspn(msg.params[1], "0123456789") == strlen(msg.params[1])) { start = atol(msg.params[1]); lines = atol(msg.params[2]); } else { src = msg.params[1]; lines = atol(msg.params[2]); } } else if (msg.numparams >= 2) { if (!irc_strcasecmp(msg.params[1], "ALL")) { lines = -1; } else { lines = atol(msg.params[1]); } } else { ircclient_send_numeric(p, 461, ":Not enough parameters"); } if (src) { struct ircchannel *c; c = ircnet_fetchchannel(p, src); if (!c) { filter = src; src = p->nickname; } } else { src = p->nickname; } irclog_recall(p, src, start, lines, filter); } else if (p->conn_class->allow_persist && !irc_strcasecmp(msg.params[0], "PERSIST")) { /* User wants a die_on_close proxy to persist */ if (p->die_on_close) { if (p->conn_class->disconnect_on_detach) { /* Its die_on_close because of configuration, can't dedicate! */ p->die_on_close = 0; ircnet_announce_dedicated(p); } else if (!ircnet_dedicate(p)) { /* Okay, it was inetd - we can dedicate this */ p->die_on_close = 0; } else { ircclient_send_notice(p, "Could not persist"); } } else { ircnet_announce_dedicated(p); } } else if (!irc_strcasecmp(msg.params[0], "DETACH")) { /* User wants to detach and can't be bothered to use /QUIT */ ircnet_announce_status(p); ircclient_send_error(p, "Detached from %s %s", PACKAGE, VERSION); /* Optional AWAY message can be supplied */ if ((msg.numparams >= 2) && strlen(msg.paramstarts[1])) { _ircclient_detach(p, msg.paramstarts[1]); } else { _ircclient_detach(p, 0); } ircprot_freemsg(&msg); return 0; } else if (!irc_strcasecmp(msg.params[0], "QUIT")) { /* User wants to detach and end their proxy session */ if (IS_SERVER_READY(p)) { /* Optional QUIT message can be supplied */ if ((msg.numparams >= 2) && strlen(msg.paramstarts[1])) { ircserver_send_command(p, "QUIT", ":%s", msg.paramstarts[1]); } else if (p->conn_class->quit_message) { ircserver_send_command(p, "QUIT", ":%s", p->conn_class->quit_message); } else { ircserver_send_command(p, "QUIT", ":Leaving IRC - %s %s", PACKAGE, VERSION); } } ircserver_close_sock(p); p->conn_class = 0; ircclient_close(p); ircprot_freemsg(&msg); return 0; } else if (!irc_strcasecmp(msg.params[0], "MOTD")) { /* Display message of the day file */ _ircclient_motd(p); } else if (p->conn_class->allow_die && !irc_strcasecmp(msg.params[0], "DIE")) { /* User wants to kill us :( */ ircclient_send_notice(p, "I'm melting!"); stop(); } else if (p->conn_class->allow_users && !irc_strcasecmp(msg.params[0], "USERS")) { struct ircconnclass *c; struct ircproxy *cp; int i; c = connclasses; i = 0; ircclient_send_notice(p, "Connection classes:"); while (c) { cp = ircnet_fetchclass(c); if (!cp) { c = c->next; continue; } ircclient_send_notice(p, "-%s %2d. %s -> %s (%s)", (cp == p ? ">" : " "), ++i, cp->client_host ? cp->client_host : "(none)", cp->servername ? cp->servername : "(none)", cp->nickname ? cp->nickname : "no nickname"); c = c->next; } } else if (p->conn_class->allow_kill && !irc_strcasecmp(msg.params[0], "KILL")) { struct ircproxy *proxy; /* User wants to kill a user */ if (msg.numparams >= 2) { struct ircconnclass *c; struct ircproxy *cp; int i; /* Check the user list */ proxy = 0; c = connclasses; i = 0; while (c) { cp = ircnet_fetchclass(c); if (!cp) { c = c->next; continue; } if ((atoi(msg.params[1]) == ++i) || (cp->client_host && !irc_strcasecmp(msg.params[1], cp->client_host)) || (cp->servername && !irc_strcasecmp(msg.params[1], cp->servername)) || (cp->nickname && !irc_strcasecmp(msg.params[1], cp->nickname))) { proxy = cp; break; } c = c->next; } if (proxy && (proxy == p)) { ircclient_send_notice(p, "Use /DIRCPROXY QUIT to kill yourself"); } else if (proxy) { if (IS_SERVER_READY(proxy)) { ircserver_send_command(proxy, "QUIT", ":Killed by adminstrator - %s %s", PACKAGE, VERSION); } if (IS_CLIENT_READY(proxy)) { ircclient_send_error(proxy, "Killed by administrator"); } ircserver_close_sock(proxy); proxy->conn_class = 0; ircclient_close(proxy); } else { ircclient_send_numeric(p, 401, "No such user, " "use /DIRCPROXY USERS to see them"); } } else { ircclient_send_numeric(p, 461, ":Not enough parameters"); } } else if (!irc_strcasecmp(msg.params[0], "SERVERS")) { struct strlist *s; int i; s = p->conn_class->servers; i = 0; /* User wants a server list */ if (s) { ircclient_send_notice(p, "You can connect to:"); } else { ircclient_send_notice(p, "No servers"); } while (s) { ircclient_send_notice(p, "-%s %2d. %s", (s == p->conn_class->next_server ? ">" : " "), ++i, s->str); s = s->next; } } else if (p->conn_class->allow_jump && (!irc_strcasecmp(msg.params[0], "JUMP") || !irc_strcasecmp(msg.params[0], "CONNECT"))) { struct strlist *server; /* User wants to jump to a new server */ if (msg.numparams >= 2) { struct strlist *s; int i; /* Check the server list to see whether its a plain jump */ server = 0; s = p->conn_class->servers; i = 0; while (s) { if ((atoi(msg.params[1]) == ++i) || !irc_strcasecmp(msg.params[1], s->str)) { server = s; break; } s = s->next; } } else { /* User wants to jump to the next server */ server = 0; if (p->conn_class->next_server) server = p->conn_class->next_server->next; if (!server) server = p->conn_class->servers; } /* Allocate new server if jump_new */ if (!server && p->conn_class->allow_jump_new && (msg.numparams >= 2)) { debug("New server"); server = (struct strlist *)malloc(sizeof(struct strlist)); server->str = x_strdup(msg.params[1]); server->next = 0; if (p->conn_class->servers) { struct strlist *ss; ss = p->conn_class->servers; while (ss->next) ss = ss->next; ss->next = server; } else { p->conn_class->servers = server; } } else if (!server) { ircclient_send_numeric(p, 402, "No such server, " "use /DIRCPROXY SERVERS to see them"); } if (server) { debug("Jumping to %s", server->str); p->conn_class->next_server = server; ircserver_connectagain(p); /* We have no server now, so need to get out of here */ ircprot_freemsg(&msg); return 0; } } else if (p->conn_class->allow_host && !irc_strcasecmp(msg.params[0], "HOST")) { /* User wants to change their hostname */ free(p->conn_class->local_address); p->conn_class->local_address = 0; if (msg.numparams >= 2) { if (irc_strcasecmp(msg.params[1], "none")) p->conn_class->local_address = x_strdup(msg.params[1]); } else if (p->conn_class->orig_local_address) { p->conn_class->local_address = x_strdup(p->conn_class->orig_local_address); } ircserver_connectagain(p); /* We have no server now, so need to get out of here */ ircprot_freemsg(&msg); return 0; } else if (!irc_strcasecmp(msg.params[0], "STATUS")) { struct ircchannel *c; struct strlist *s; ircclient_send_notice(p, "%s %s status:", PACKAGE, VERSION); ircclient_send_notice(p, "- Nickname on server: %s", p->nickname); ircclient_send_notice(p, "- Nickname to guard: %s", p->setnickname); ircclient_send_notice(p, "- Username for server: %s", p->username); ircclient_send_notice(p, "- Hostname for server: %s", p->hostname); ircclient_send_notice(p, "- Real name for server: %s", p->realname); ircclient_send_notice(p, "-"); ircclient_send_notice(p, "- Client status: %s", IS_CLIENT_READY(p) ? "Ready" : ""); if (p->client_status != IRC_CLIENT_ACTIVE) { if (p->client_status & IRC_CLIENT_CONNECTED) ircclient_send_notice(p, "- Connected"); if (p->client_status & IRC_CLIENT_GOTPASS) ircclient_send_notice(p, "- Received password"); if (p->client_status & IRC_CLIENT_GOTNICK) ircclient_send_notice(p, "- Received nickname"); if (p->client_status & IRC_CLIENT_GOTUSER) ircclient_send_notice(p, "- Received user information"); if (p->client_status & IRC_CLIENT_AUTHED) ircclient_send_notice(p, "- Authorised"); if (p->client_status & IRC_CLIENT_SENTWELCOME) ircclient_send_notice(p, "- Welcomed"); } ircclient_send_notice(p, "-"); ircclient_send_notice(p, "- Server status: %s", IS_SERVER_READY(p) ? "Ready" : ""); if (p->server_status != IRC_SERVER_ACTIVE) { if (p->server_status & IRC_SERVER_CREATED) ircclient_send_notice(p, "- Created"); if (p->server_status & IRC_SERVER_SEEN) ircclient_send_notice(p, "- Seen"); if (p->server_status & IRC_SERVER_CONNECTED) ircclient_send_notice(p, "- Connected"); if (p->server_status & IRC_SERVER_INTRODUCED) ircclient_send_notice(p, "- Introduced ourselves"); if (p->server_status & IRC_SERVER_GOTWELCOME) ircclient_send_notice(p, "- Have been welcomed"); } ircclient_send_notice(p, "-"); ircclient_send_notice(p, "- Servers. Current marked by '->'"); s = p->conn_class->servers; while (s) { ircclient_send_notice(p, "-%s %s", (s == p->conn_class->next_server ? ">" : " "), s->str); s = s->next; } ircclient_send_notice(p, "-"); ircclient_send_notice(p, "- Channels"); c = p->channels; while (c) { ircclient_send_notice(p, "- %s%s%s%s%s%s", c->name, c->key ? " (key: " : "", c->key ? c->key : "", c->key ? ")" : "", c->inactive ? " (removed by force)" : "", c->unjoined ? " (left on detach)" : ""); c = c->next; } ircclient_send_notice(p, "-"); ircclient_send_notice(p, "- Advanced:"); ircclient_send_notice(p, "- Allow MOTD count: %d", p->allow_motd); ircclient_send_notice(p, "- Allow PONG count: %d", p->allow_pong); ircclient_send_notice(p, "- 411 Squelch count: %d", p->squelch_411); ircclient_send_notice(p, "- Expecting NICK count: %d", p->expecting_nick); if (p->squelch_modes) ircclient_send_notice(p, "- Squelching mode changes:"); s = p->squelch_modes; while (s) { ircclient_send_notice(p, "- %s", s->str); s = s->next; } } else if (!irc_strcasecmp(msg.params[0], "HELP")) { /* User needs a little help */ char **help_page; help_page = 0; if ((msg.numparams >= 2) && strlen(msg.params[1])) { if (!irc_strcasecmp(msg.params[1], "RECALL")) { help_page = help_recall; } else if (p->conn_class->allow_persist && !irc_strcasecmp(msg.params[1], "PERSIST")) { help_page = help_persist; } else if (!irc_strcasecmp(msg.params[1], "DETACH")) { help_page = help_detach; } else if (!irc_strcasecmp(msg.params[1], "QUIT")) { help_page = help_quit; } else if (!irc_strcasecmp(msg.params[1], "MOTD")) { help_page = help_motd; } else if (p->conn_class->allow_die && !irc_strcasecmp(msg.params[1], "DIE")) { help_page = help_die; } else if (!irc_strcasecmp(msg.params[1], "SERVERS")) { help_page = help_servers; } else if (p->conn_class->allow_jump && !irc_strcasecmp(msg.params[1], "JUMP")) { help_page = (p->conn_class->allow_jump_new ? help_jump_new : help_jump); } else if (p->conn_class->allow_host && !irc_strcasecmp(msg.params[1], "HOST")) { help_page = help_host; } else if (!irc_strcasecmp(msg.params[1], "STATUS")) { help_page = help_status; } else if (!irc_strcasecmp(msg.params[1], "USERS")) { help_page = help_users; } else if (!irc_strcasecmp(msg.params[1], "KILL")) { help_page = help_kill; } else if (!irc_strcasecmp(msg.params[1], "HELP")) { help_page = help_help; } else { help_page = help_index; } } else { help_page = help_index; } if (help_page) { int i; i = 0; ircclient_send_notice(p, "%s %s help", PACKAGE, VERSION); while (help_page[i]) { ircclient_send_notice(p, "- %s", help_page[i]); i++; } if (help_page == help_index) { ircclient_send_notice(p, "- HELP " "(help on /dircproxy commands)"); ircclient_send_notice(p, "- MOTD " "(show dircproxy message of the day)"); ircclient_send_notice(p, "- STATUS " "(show dircproxy status information)"); ircclient_send_notice(p, "- RECALL " "(recall text from log files)"); ircclient_send_notice(p, "- DETACH " "(detach from dircproxy)"); if (p->conn_class->allow_persist) ircclient_send_notice(p, "- PERSIST " "(keep session after detach)"); ircclient_send_notice(p, "- QUIT " "(end dircproxy session)"); if (p->conn_class->allow_die) ircclient_send_notice(p, "- DIE " "(terminate dircproxy)"); if (p->conn_class->allow_users) ircclient_send_notice(p, "- USERS " "(show users using dircproxy)"); if (p->conn_class->allow_kill) ircclient_send_notice(p, "- KILL " "(terminate a user's session)"); ircclient_send_notice(p, "- SERVERS " "(show servers list)"); if (p->conn_class->allow_jump) ircclient_send_notice(p, "- JUMP " "(jump to a different server)"); if (p->conn_class->allow_host) ircclient_send_notice(p, "- HOST " "(change your visible hostname)"); i = 0; while (help_index_end[i]) { ircclient_send_notice(p, "- %s", help_index_end[i]); i++; } } ircclient_send_notice(p, "-"); } } else { /* Invalid command */ ircclient_send_numeric(p, 421, "%s :Unknown DIRCPROXY command", msg.params[0]); } } else { ircclient_send_numeric(p, 461, ":Not enough parameters"); } } } /* Do we have enough information to authenticate them? */ if (!(p->client_status & IRC_CLIENT_AUTHED) && (p->client_status & IRC_CLIENT_GOTPASS) && (p->client_status & IRC_CLIENT_GOTNICK) && (p->client_status & IRC_CLIENT_GOTUSER)) { _ircclient_authenticate(p, p->password); free(p->password); p->password = 0; p->client_status &= ~(IRC_CLIENT_GOTPASS); } /* Do we have enough information to connect to a server? */ if (IS_CLIENT_READY(p) && !p->dead) { if (p->server_status != IRC_SERVER_ACTIVE) { if (!(p->server_status & IRC_SERVER_CREATED)) { if (p->conn_class && p->conn_class->server_autoconnect) { ircserver_connect(p); } else { ircclient_send_notice(p, "Please send /DIRCPROXY JUMP " "[:[port][:[password]]] to choose a " "server"); /* This won't delete an existing timer */ timer_new((void *)p, "client_connect", g.connect_timeout, TIMER_FUNCTION(_ircclient_timedout), (void *)1); } } else if (!IS_SERVER_READY(p)) { ircclient_send_notice(p, "Connection to server is in progress..."); } } else if (!(p->client_status & IRC_CLIENT_SENTWELCOME)) { ircclient_welcome(p); } } ircprot_freemsg(&msg); return 0; } /* Got a password */ static int _ircclient_authenticate(struct ircproxy *p, const char *password) { struct ircconnclass *cc; cc = connclasses; while (cc) { #ifdef ENCRYPTED_PASSWORDS char *cmp; cmp = crypt(password, cc->password); if (!strcmp(cc->password, cmp)) { #else if (!strcmp(cc->password, password)) { #endif if (cc->masklist) { struct strlist *m; char *ip; ip = inet_ntoa(p->client_addr.sin_addr); m = cc->masklist; while (m) { if (strcasematch(ip, m->str) || strcasematch(p->client_host, m->str)) break; m = m->next; } /* We got a matching masklist, so this one's ok */ if (m) break; } else { break; } } cc = cc->next; } if (cc) { struct ircproxy *tmp_p; tmp_p = ircnet_fetchclass(cc); if (tmp_p && (tmp_p->client_status & IRC_CLIENT_CONNECTED)) { if (tmp_p->conn_class->disconnect_existing) { debug("Already connected, disconnecting existing"); ircclient_send_error(tmp_p, "Collided with new user"); ircclient_close(tmp_p); if (tmp_p->dead) { debug("Kicked off client, and they died"); tmp_p = 0; } } else { debug("Already connected, disconnecting incoming"); ircclient_send_error(p, "Already connected"); ircclient_close(p); return -1; } } /* Check again, in case killing existing user killed the proxy */ if (tmp_p) { debug("Attaching new client to old server session"); tmp_p->client_sock = p->client_sock; tmp_p->client_status |= IRC_CLIENT_CONNECTED | IRC_CLIENT_AUTHED; tmp_p->client_addr = p->client_addr; net_hook(tmp_p->client_sock, SOCK_NORMAL, (void *)tmp_p, ACTIVITY_FUNCTION(_ircclient_data), ERROR_FUNCTION(_ircclient_error)); /* If the connecting client doesn't agree with the proxy about its nickname, then correct it. */ if (strcmp(p->nickname, tmp_p->nickname)) ircclient_send_selfcmd(p, "NICK", ":%s", tmp_p->nickname); /* If we've got to restore a different nickname, then do that now */ if (tmp_p->oldnickname && strcmp(tmp_p->oldnickname, tmp_p->nickname)) ircclient_change_nick(tmp_p, tmp_p->oldnickname); /* We don't need this anymore */ free(tmp_p->oldnickname); tmp_p->oldnickname = 0; /* Unset any away message if we set one */ if (!tmp_p->awaymessage && (tmp_p->server_status == IRC_SERVER_ACTIVE) && tmp_p->conn_class->away_message) ircserver_send_command(tmp_p, "AWAY", ""); /* Rejoin any channels we parted */ if ((tmp_p->server_status == IRC_SERVER_ACTIVE) && tmp_p->channels) { struct ircchannel *c; c = tmp_p->channels; while (c) { if (c->unjoined) { if (c->key) { ircserver_send_command(tmp_p, "JOIN", "%s :%s", c->name, c->key); } else { ircserver_send_command(tmp_p, "JOIN", ":%s", c->name); } } c = c->next; } } /* Send attach message to all channels we're on */ if (tmp_p->server_status == IRC_SERVER_ACTIVE) { if (tmp_p->conn_class->attach_message) { struct ircchannel *c; int slashme; char *msg; msg = tmp_p->conn_class->attach_message; if ((strlen(msg) >= 5) && !strncasecmp(msg, "/me ", 4)) { /* Starts with /me */ slashme = 1; msg += 4; } else { slashme = 0; } c = tmp_p->channels; while (c) { if (!c->inactive) { if (slashme) { ircserver_send_command(tmp_p, "PRIVMSG", "%s :\001ACTION %s\001", c->name, msg); } else { ircserver_send_command(tmp_p, "PRIVMSG", "%s :%s", c->name, msg); } } c = c->next; } } } if ((tmp_p->server_status == IRC_SERVER_ACTIVE) && !(tmp_p->client_status & IRC_CLIENT_SENTWELCOME)) ircclient_welcome(tmp_p); p->client_status = IRC_CLIENT_NONE; p->client_sock = -1; p->dead = 1; } else { struct strlist *s; p->conn_class = cc; p->client_status |= IRC_CLIENT_AUTHED; time(&(p->start)); if (p->conn_class->disconnect_on_detach) p->die_on_close = 1; /* Okay, they've authed for the first time, make the log directory here */ if (p->conn_class->other_log_enabled || p->conn_class->chan_log_enabled) { if (irclog_maketempdir(p)) ircclient_send_notice(p, "(warning) Unable to create log " "directory, logging disabled"); } /* Initialise the server/private message log */ irclog_init(p, ""); /* Open a log file if we're always logging */ if (p->conn_class->other_log_enabled && p->conn_class->other_log_always) { if (irclog_open(p, "")) ircclient_send_notice(p, "(warning) Unable to log server/private " "messages"); } /* Join initial channels */ s = p->conn_class->channels; while (s) { struct ircchannel *c; char *name, *key; name = x_strdup(s->str); key = strchr(name, ' '); if (key) *(key++) = 0; ircnet_addchannel(p, name); c = ircnet_fetchchannel(p, name); if (c) { c->inactive = 1; if (key) c->key = x_strdup(key); } free(name); s = s->next; } /* Set initial modes */ if (p->conn_class->initial_modes) ircclient_change_mode(p, p->conn_class->initial_modes); } return 0; } ircclient_send_numeric(p, 464, ":You are not permitted to use this proxy"); ircclient_send_error(p, "Permission Denied"); ircclient_close(p); return -1; } /* Request a nickname change */ int ircclient_change_nick(struct ircproxy *p, const char *newnick) { /* If a server is ready to accept a NICK command, send it */ if (IS_SERVER_READY(p)) { debug("Requesting nick change from '%s' to '%s'", (p->nickname ? p->nickname : ""), newnick); ircserver_send_command(p, "NICK", ":%s", newnick); } /* If we have a nickname already then the server will confirm that, otherwise we should remember it ourselves */ if (p->client_status & IRC_CLIENT_GOTNICK) { debug("Server will change it for us"); p->expecting_nick = 1; return 0; } else { int ret; /* Because we're not expecting a server confirmation, then we better do the confirm for the client ourselves */ if ((p->client_status & IRC_CLIENT_CONNECTED) && (p->client_status & IRC_CLIENT_AUTHED)) ircclient_send_selfcmd(p, "NICK", ":%s", newnick); /* Make the change in the wings */ ret = ircclient_nick_changed(p, newnick); ircclient_setnickname(p); ircclient_checknickname(p); return ret; } } /* Nickname has now definitly been changed */ int ircclient_nick_changed(struct ircproxy *p, const char *newnick) { if (p->nickname) debug("nickname WAS '%s'", p->nickname); free(p->nickname); p->nickname = x_strdup(newnick); p->client_status |= IRC_CLIENT_GOTNICK; debug("nickname NOW '%s'", p->nickname); return 0; } /* Make the current nickname the set one */ int ircclient_setnickname(struct ircproxy *p) { /* Update setnickname too */ if (p->setnickname) free(p->setnickname); p->setnickname = x_strdup(p->nickname); debug("Changed setnickname to '%s'", p->setnickname); return 0; } /* Check whether we need to restore the nickname later */ int ircclient_checknickname(struct ircproxy *p) { if (p->conn_class && p->conn_class->nick_keep && strcmp(p->nickname, p->setnickname)) timer_new((void *)p, "client_resetnick", NICK_GUARD_TIME, TIMER_FUNCTION(_ircclient_resetnick), (void *)0); return 0; } /* Change the nickname to something we generate ourselves */ int ircclient_generate_nick(struct ircproxy *p, const char *tried) { char *c, *nick; int ret; c = nick = (char *)malloc(strlen(tried) + 2); strcpy(nick, tried); c += strlen(nick) - 1; /* We add -'s until we can't, then we move back through them cycling them 0..9 then finally _ until the whole nickname is _________. Once that happens we just use 'dircproxy' and do it all over again */ if (strlen(nick) < 9) { *(++c) = '-'; *(++c) = 0; } else { while (c >= nick) { if (*c == '-') { *c = '0'; break; } else if ((*c >= '0') && (*c < '9')) { (*c)++; break; } else if (*c == '9') { *c = '_'; break; } else if (*c == '_') { c--; } else { *c = '-'; break; } } if (c < nick) { free(nick); nick = x_strdup(FALLBACK_NICKNAME); } } /* Ask the server to change the nickname */ if (IS_SERVER_READY(p)) { debug("Requesting nick change from '%s' to '%s'", (p->nickname ? p->nickname : ""), nick); ircserver_send_command(p, "NICK", ":%s", nick); } /* If we don't have a nickname yet, make the change ourselves */ if (!(p->client_status & IRC_CLIENT_GOTNICK)) { /* We know that there is no client connected, otherwise this would never have been called, so no point sending a nickname to the client. Just change it in our memory */ ret = ircclient_nick_changed(p, nick); ircclient_checknickname(p); } else { debug("Server will change it for us"); } free(nick); return 0; } /* Timer hook to restore a lost nickname */ static void _ircclient_resetnick(struct ircproxy *p, void *data) { /* We don't have a server anymore, setnickname will be restored on connection attempt */ if (!IS_SERVER_READY(p)) return; /* Is it worth doing this? */ if (!strcmp(p->nickname, p->setnickname)) return; /* Ask the server to change the nickname */ debug("Attempting to restore nickname to '%s'", p->setnickname); ircclient_change_nick(p, p->setnickname); } /* Got some details */ static int _ircclient_got_details(struct ircproxy *p, const char *newusername, const char *newmode, const char *unused, const char *newrealname) { int mode; if (!p->username) p->username = x_strdup(newusername); if (!p->realname) p->realname = x_strdup(newrealname); /* RFC2812 states that the second parameter to USER is a numeric stating what default modes to set. This disagrees with RFC1459. We follow the newer one if we can, as the old hostname/servername combo were useless and ignored anyway. */ mode = atoi(newmode); if (mode & RFC2812_MODE_W) ircclient_change_mode(p, "+w"); if (mode & RFC2812_MODE_I) ircclient_change_mode(p, "+w"); /* Okay we have the username now */ p->client_status |= IRC_CLIENT_GOTUSER; return 0; } /* Got a personal mode change */ int ircclient_change_mode(struct ircproxy *p, const char *change) { char *ptr, *str; int add = 1; ptr = str = x_strdup(change); debug("Mode change from '%s', '%s'", (p->modes ? p->modes : ""), str); while (*ptr) { switch (*ptr) { case '+': add = 1; break; case '-': add = 0; break; default: if (add) { if (!p->modes || !strchr(p->modes, *ptr)) { if (p->modes) { p->modes = (char *)realloc(p->modes, strlen(p->modes) + 2); } else { p->modes = (char *)malloc(2); p->modes[0] = 0; } p->modes[strlen(p->modes) + 1] = 0; p->modes[strlen(p->modes)] = *ptr; } } else if (p->modes) { char *pos; pos = strchr(p->modes, *ptr); if (pos) { char *tmp; tmp = p->modes; p->modes = (char *)malloc(strlen(p->modes)); *(pos++) = 0; strcpy(p->modes, tmp); strcpy(p->modes + strlen(p->modes), pos); free(tmp); if (!strlen(p->modes)) { free(p->modes); p->modes = 0; } } } } ptr++; } debug(" now '%s'", (p->modes ? p->modes : "")); free(str); return 0; } /* Close the client socket */ int ircclient_close(struct ircproxy *p) { timer_del((void *)p, "client_auth"); timer_del((void *)p, "client_connect"); net_close(&(p->client_sock)); p->client_sock = -1; p->client_status &= ~(IRC_CLIENT_CONNECTED | IRC_CLIENT_AUTHED | IRC_CLIENT_SENTWELCOME); /* No connection class, or no nick or user? Die! */ if (!p->conn_class || !(p->client_status & IRC_CLIENT_GOTNICK) || !(p->client_status & IRC_CLIENT_GOTUSER)) { if (p->server_status & IRC_SERVER_CREATED) { ircserver_send_command(p, "QUIT", ":I shouldn't really be here - %s %s", PACKAGE, VERSION); ircserver_close_sock(p); } p->dead = 1; } return p->dead; } /* send message of the day to the user */ static int _ircclient_motd(struct ircproxy *p) { FILE *motd_file; if (p->conn_class->motd_file) { motd_file = fopen(p->conn_class->motd_file, "r"); if (!motd_file) syscall_fail("fopen", p->conn_class->motd_file, 0); } else { motd_file = (FILE *)0; } /* Check whether to do anything, and send appropriate numerics */ if (!p->conn_class->motd_logo && !p->conn_class->motd_stats && !motd_file) { if (p->conn_class->motd_file) { ircclient_send_numeric(p, 422, ":MOTD File is missing"); } else { ircclient_send_numeric(p, 422, ":No MOTD"); } return 0; } else { ircclient_send_numeric(p, 375, ":- %s Message of the Day -", PACKAGE); } /* Send the pretty dircproxy logo */ if (p->conn_class->motd_logo) { char *ver; int line; line = 0; while (logo[line]) { ircclient_send_numeric(p, 372, ":- %s", logo[line]); line++; } ver = x_sprintf(verstr, VERSION); ircclient_send_numeric(p, 372, ":- %s", ver); ircclient_send_numeric(p, 372, ":-"); free(ver); } /* Send from file */ if (motd_file) { char buff[512]; while (fgets(buff, 512, motd_file)) { char *ptr; ptr = buff + strlen(buff); while ((ptr >= buff) && (!ptr || strchr(" \t\r\n", *ptr))) *(ptr--) = 0; ircclient_send_numeric(p, 372, ":- %s", buff); } ircclient_send_numeric(p, 372, ":-"); } /* Send some stats */ if (p->conn_class->motd_stats) { /* Server/private messages */ if (p->other_log.filename) { char *s; if (p->conn_class->other_log_recall == -1) { s = x_strdup(p->other_log.nlines ? "all" : "none"); } else if (p->conn_class->other_log_recall == 0) { s = x_strdup("none"); } else if (p->conn_class->other_log_recall == p->other_log.nlines) { s = x_strdup("all"); } else { s = x_sprintf("%ld", p->conn_class->other_log_recall); } ircclient_send_numeric(p, 372, ":- %ld server/private message%s " "(%s will be sent)", p->other_log.nlines, (p->other_log.nlines == 1 ? "" : "s"), s); ircclient_send_numeric(p, 372, ":-"); free(s); } /* Channels they were on */ if (p->channels) { struct ircchannel *c; c = p->channels; while (c) { if (c->inactive) { if (c->log.nlines) { ircclient_send_numeric(p, 372, ":- was on %s but removed by force", c->name); } else { ircclient_send_numeric(p, 372, ":- yet to join %s", c->name); } } else if (c->unjoined) { ircclient_send_numeric(p, 372, ":- was on %s, yet to rejoin", c->name); } else if (c->log.filename) { char *s; if (p->conn_class->chan_log_recall == -1) { s = x_strdup(p->other_log.nlines ? "all" : "none"); } else if (p->conn_class->chan_log_recall == 0) { s = x_strdup("none"); } else if (p->conn_class->chan_log_recall == c->log.nlines) { s = x_strdup("all"); } else { s = x_sprintf("%ld", MIN(c->log.nlines, p->conn_class->chan_log_recall)); } ircclient_send_numeric(p, 372, ":- %s. %ld line%s logged. " "(%s will be sent)", c->name, c->log.nlines, (c->log.nlines == 1 ? "" : "s"), s); free(s); } else { ircclient_send_numeric(p, 372, ":- %s (not logged)", c->name); } c = c->next; } ircclient_send_numeric(p, 372, ":-"); } } /* Done */ ircclient_send_numeric(p, 376, ":End of /MOTD command"); if (motd_file) fclose(motd_file); return 1; } /* send welcome headers to the user */ int ircclient_welcome(struct ircproxy *p) { char tbuf[40]; strftime(tbuf, sizeof(tbuf), START_TIMEDATE_FORMAT, localtime(&(p->start))); ircclient_send_numeric(p, 1, ":Welcome to the Internet Relay Network %s", p->nickname); ircclient_send_numeric(p, 2, ":Your host is %s running %s via %s %s", p->servername, (p->serverver ? p->serverver : "(unknown)"), PACKAGE, VERSION); ircclient_send_numeric(p, 3, ":This proxy has been running since %s", tbuf); if (p->serverver) ircclient_send_numeric(p, 4, "%s %s %s %s", p->servername, p->serverver, p->serverumodes, p->servercmodes); _ircclient_motd(p); if (p->modes) ircclient_send_selfcmd(p, "MODE", "%s +%s", p->nickname, p->modes); if (p->awaymessage) { /* Ack. There's no reason for a client to expect AWAY from a server, so we cheat and send a 306, reminding them what their away message was in the text. This might not trick the client either, but hey, I can't do anything about that. */ ircclient_send_numeric(p, 306, ":%s: %s", "You left yourself away. Your message was", p->awaymessage); } if (p->channels) { struct ircchannel *c; c = p->channels; while (c) { if (!c->inactive && !c->unjoined) { ircclient_send_selfcmd(p, "JOIN", ":%s", c->name); ircserver_send_command(p, "TOPIC", ":%s", c->name); ircserver_send_command(p, "NAMES", ":%s", c->name); if (p->conn_class->chan_log_enabled) { irclog_autorecall(p, c->name); if (!p->conn_class->chan_log_always) irclog_close(p, c->name); } } c = c->next; } } /* Recall other log file */ if (p->conn_class->other_log_enabled) { irclog_autorecall(p, p->nickname); if (!p->conn_class->other_log_always) irclog_close(p, p->nickname); } if (p->conn_class->log_events & IRC_LOG_CLIENT) irclog_notice(p, 0, PACKAGE, "You connected"); ircnet_announce_status(p); p->client_status |= IRC_CLIENT_SENTWELCOME; return 0; } /* Timer hook when something's timed out */ static void _ircclient_timedout(struct ircproxy *p, void *data) { int connect; /* These are always called after the timeout if the client's still connected, check the event they were looking for has happened */ connect = (int)data; if (connect && (p->server_status & IRC_SERVER_CREATED)) { /* Connecting to server, and a socket has been created to do it */ debug("Server has been chosen"); return; } else if (!connect && IS_CLIENT_READY(p)) { /* Authorization, and client is ready to accept data */ debug("They are authorized"); return; } /* Timeout! */ debug("Timed out"); ircclient_send_error(p, "%s Timeout", (connect ? "Connect" : "Login")); ircclient_close(p); } /* send a numeric to the user */ int ircclient_send_numeric(struct ircproxy *p, short numeric, const char *format, ...) { va_list ap; char *msg; int ret; va_start(ap, format); msg = x_vsprintf(format, ap); va_end(ap); ret = net_send(p->client_sock, ":%s %03d %s %s\r\n", (p->servername ? p->servername : PACKAGE), numeric, (p->nickname ? p->nickname : "*"), msg); debug("<- ':%s %03d %s %s'", (p->servername ? p->servername : PACKAGE), numeric, (p->nickname ? p->nickname : "*"), msg); free(msg); return ret; } /* send a notice to the user */ int ircclient_send_notice(struct ircproxy *p, const char *format, ...) { va_list ap; char *msg; int ret; va_start(ap, format); msg = x_vsprintf(format, ap); va_end(ap); ret = net_send(p->client_sock, ":%s %s %s :%s\r\n", PACKAGE, "NOTICE", (p->nickname ? p->nickname : "AUTH"), msg); debug("<- ':%s %s %s :%s'", PACKAGE, "NOTICE", (p->nickname ? p->nickname : "AUTH"), msg); free(msg); return ret; } /* send a notice to a channel */ int ircclient_send_channotice(struct ircproxy *p, const char *channel, const char *format, ...) { va_list ap; char *msg; int ret; va_start(ap, format); msg = x_vsprintf(format, ap); va_end(ap); ret = net_send(p->client_sock, ":%s %s %s :%s\r\n", (p->servername ? p->servername : PACKAGE), "NOTICE", channel, msg); debug("<- ':%s %s %s :%s'", (p->servername ? p->servername : PACKAGE), "NOTICE", channel, msg); free(msg); return ret; } /* send a command to the user from the server */ int ircclient_send_command(struct ircproxy *p, const char *command, const char *format, ...) { va_list ap; char *msg; int ret; va_start(ap, format); msg = x_vsprintf(format, ap); va_end(ap); ret = net_send(p->client_sock, ":%s %s %s\r\n", (p->servername ? p->servername : PACKAGE), command, msg); debug("<- ':%s %s %s'", (p->servername ? p->servername : PACKAGE), command, msg); free(msg); return ret; } /* send a command to the user making it look like its from them */ int ircclient_send_selfcmd(struct ircproxy *p, const char *command, const char *format, ...) { char *msg, *prefix; va_list ap; int ret; va_start(ap, format); msg = x_vsprintf(format, ap); va_end(ap); if (p->nickname && p->username && p->hostname) { prefix = x_sprintf(":%s!%s@%s ", p->nickname, p->username, p->hostname); } else if (p->nickname) { prefix = x_sprintf(":%s ", p->nickname); } else { prefix = (char *)malloc(1); prefix[0] = 0; } ret = net_send(p->client_sock, "%s%s %s\r\n", prefix, command, msg); debug("<- '%s%s %s'", prefix, command, msg); free(prefix); free(msg); return ret; } /* send an error to the user */ int ircclient_send_error(struct ircproxy *p, const char *format, ...) { char *msg, *nick, *user, *host; va_list ap; int ret; va_start(ap, format); msg = x_vsprintf(format, ap); va_end(ap); nick = p->nickname ? p->nickname : ""; user = p->username ? p->username : "user"; host = p->hostname ? p->hostname : "host"; ret = net_send(p->client_sock, "%s :%s: %s[%s@%s] (%s)\r\n", "ERROR", "Closing Link", nick, user, host, msg); debug("<- '%s :%s: %s[%s@%s] (%s)'", "ERROR", "Closing Link", nick, user, host, msg); free(msg); return ret; } /* Send a DCC reject message */ static int _ircclient_send_dccreject(struct ircproxy *p, const char *msg) { int ret = 1; if (p && p->conn_class && p->conn_class->dcc_proxy_sendreject && (p->client_status == IRC_CLIENT_ACTIVE)) { ret = net_send(p->client_sock, "%s\r\n", msg); debug("<- '%s'", msg); } return ret; } dircproxy-1.0.5/src/irc_client.h0000664000175000017500000000326607410714173012311 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * irc_client.h * -- * @(#) $Id: irc_client.h,v 1.6 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #ifndef __DIRCPROXY_IRC_CLIENT_H #define __DIRCPROXY_IRC_CLIENT_H /* required includes */ #include "irc_net.h" /* functions */ extern int ircclient_connected(struct ircproxy *); extern int ircclient_data(struct ircproxy *); extern int ircclient_change_nick(struct ircproxy *, const char *); extern int ircclient_nick_changed(struct ircproxy *, const char *); extern int ircclient_setnickname(struct ircproxy *); extern int ircclient_checknickname(struct ircproxy *); extern int ircclient_generate_nick(struct ircproxy *, const char *); extern int ircclient_change_mode(struct ircproxy *, const char *); extern int ircclient_close(struct ircproxy *); extern int ircclient_welcome(struct ircproxy *); extern int ircclient_send_numeric(struct ircproxy *, short, const char *, ...); extern int ircclient_send_notice(struct ircproxy *, const char *, ...); extern int ircclient_send_channotice(struct ircproxy *, const char *, const char *, ...); extern int ircclient_send_command(struct ircproxy *, const char *, const char *, ...); extern int ircclient_send_selfcmd(struct ircproxy *, const char *, const char *, ...); extern int ircclient_send_error(struct ircproxy *, const char *, ...); #endif /* __DIRCPROXY_IRC_CLIENT_H */ dircproxy-1.0.5/src/logo.h0000664000175000017500000000167207410714173011135 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * logo.h * -- * @(#) $Id: logo.h,v 1.3 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #ifndef __DIRCPROXY_LOGO_H #define __DIRCPROXY_LOGO_H /* static array to hold the logo */ static char *logo[] = { " _ _ w e l c o m e t o ", " __| (_)_ __ ___ _ __ _ __ _____ ___ _ ", " / _` | | '__/ __| '_ \\| '__/ _ \\ \\/ / | | |", "| (_| | | | | (__| |_) | | | (_) > <| |_| |", " \\__,_|_|_| \\___| .__/|_| \\___/_/\\_\\\\__, |", " |_| |___/ ", 0 }; /* static string to use as format for VERSION */ static char *verstr = " %s"; #endif /* __DIRCPROXY_LOGO_H */ dircproxy-1.0.5/src/help.h0000664000175000017500000001402707430200262011112 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * help.h * -- * @(#) $Id: help.h,v 1.10 2002/02/06 10:08:50 scott Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #ifndef __DIRCPROXY_HELP_H #define __DIRCPROXY_HELP_H /* help index */ static char *help_index[] = { "dircproxy can be controlled using the /DIRCPROXY command.", "This command takes one or more parameters, the first of", "which is a command, the rest of which depend on the", "command chosen.", "", "Valid commands:", 0 }; static char *help_index_end[] = { "", "For more information on a command, use /DIRCPROXY HELP", "followed by the command", 0 }; /* help help */ static char *help_help[] = { "/DIRCPROXY HELP", "displays general help on dircproxy and a list of valid", "commands.", "", "/DIRCPROXY HELP [command]", "displays specific help on the requested command.", 0 }; /* help quit */ static char *help_quit[] = { "/DIRCPROXY QUIT [quit message]", "detaches you from dircproxy, and also ends the proxied", "session to the server. This is the only way to do this.", "An optional /QUIT message may be supplied, you may need", "to prefix this with a : if it contains spaces.", 0 }; /* help detach */ static char *help_detach[] = { "/DIRCPROXY DETACH [away message]", "detaches you from dircproxy, and sets an optional away", "message. This usually has the same effect as simply", "closing your client, or using your clients /QUIT command.", "The away message may need to be prefixed with a : if it", "contains spaces", 0 }; /* help recall */ static char *help_recall[] = { "/DIRCPROXY RECALL [from] ", "/DIRCPROXY RECALL ALL", "recalls log messages from the server/private message log", "file. You can specify the number of lines to recall, and", "a starting point in the file, or you can specify ALL to", "recall all log messages", "", "/DIRCPROXY RECALL [from] lines>", "/DIRCPROXY RECALL ALL", "recalls log messages from the server/private message log", "that were sent by the nickname given. You can specify", "the number of lines to recall and an optional starting", "point (in the full log file). You may also specify ALL.", "", "/DIRCPROXY RECALL [from] ", "/DIRCPROXY RECALL ALL", "recalls log messages from the channel log specified. You", "can specify the number of lines to recall and an optional", "starting point in the file, or you can specify ALL to", "recall all log messages", 0 }; /* help persist */ static char *help_persist[] = { "/DIRCPROXY PERSIST", "for use if running dircproxy under inetd or if you have", "disconnect_on_detach set to yes in the config file.", "Tells dircproxy you want it to persist with its server", "connect and allow you to reattach later. It will tell", "you which hostname and port you should use to reconnect", "(may not be the same as the one you originally connected", "to)", "", "This command has no effect for normal proxy sessions", 0 }; /* help motd */ static char *help_motd[] = { "/DIRCPROXY MOTD", "displays the dircproxy message of the day that it gives", "you when you attach", 0 }; /* help die */ static char *help_die[] = { "/DIRCPROXY DIE", "kills the dircproxy process on the server. You won't", "be able to reconnect after you do this.", 0 }; /* help servers */ static char *help_servers[] = { "/DIRCPROXY SERVERS", "displays a list of servers that dircproxy will cycle upon", "disconnection. Current server is marked with an arrow", 0 }; /* help jump (with new) */ static char *help_jump_new[] = { "/DIRCPROXY JUMP", "disconnect from the current server and jump to the next", "server in the /DIRCPROX SERVERS list", "", "/DIRCPROXY JUMP ", "disconnect from the current server and jump to the server", "in the /DIRCPROXY SERVERS list specified by number", "", "/DIRCPROXY JUMP [:[port][:[password]]]", "disconnect from the current server and jump to the server", "specified", 0 }; /* help jump (without new) */ static char *help_jump[] = { "/DIRCPROXY JUMP", "disconnect from the current server and jump to the next", "server in the /DIRCPROX SERVERS list", "", "/DIRCPROXY JUMP ", "disconnect from the current server and jump to the server", "in the /DIRCPROXY SERVERS list specified by number", "", "/DIRCPROXY JUMP [:[port][:[password]]]", "disconnect from the current server and jump to the server", "in the /DIRCPROXY SERVERS list specified by the full", "details", 0 }; /* help host */ static char *help_host[] = { "/DIRCPROXY HOST ", "disconnect from the current server, and reconnect to it", "again with a different locally available hostname. This", "basically changes the local_address config option on the", "fly", "", "/DIRCPROXY HOST NONE", "disconnect from the current server, and reconnect to it", "again with the best available hostname.", "", "/DIRCPROXY HOST", "disconnect from the current server, and reconnect to it", "again with the hostname originally specified in the", "local_address config option (if any)", 0 }; /* help status */ static char *help_status[] = { "/DIRCPROXY STATUS", "displays dircproxy status information, great for bug", "reports!", 0 }; /* help users */ static char *help_users[] = { "/DIRCPROXY USERS", "displays list of users currently using dircproxy", 0 }; /* help kill */ static char *help_kill[] = { "/DIRCPROXY KILL ", "end the proxy session for the user listed in the", "/DIRCPROXY USERS list specified by number", "", "/DIRCPROXY KILL ", "end the proxy session for the user coming from or connecting", "to the hostname specified", "", "/DIRCPROXY KILL ", "end the proxy session for the user with the nickname specified", 0 }; #endif /* __DIRCPROXY_HELP_H */ dircproxy-1.0.5/src/irc_server.c0000664000175000017500000014550607426255445012351 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * irc_server.c * - Handling of servers connected to the proxy * - Reconnection to servers * - Functions to send data to servers in the correct protocol format * -- * @(#) $Id: irc_server.c,v 1.60 2002/01/31 14:56:37 scott Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "sprintf.h" #include "net.h" #include "dns.h" #include "timers.h" #include "dcc_net.h" #include "irc_log.h" #include "irc_net.h" #include "irc_prot.h" #include "irc_string.h" #include "irc_client.h" #include "irc_server.h" /* forward declarations */ static void _ircserver_reconnect(struct ircproxy *, void *); static void _ircserver_connect2(struct ircproxy *, void *, struct in_addr *, const char *); static void _ircserver_connect3(struct ircproxy *, void *, struct in_addr *, const char *); static void _ircserver_connected(struct ircproxy *, int); static void _ircserver_connected2(struct ircproxy *, void *, struct in_addr *, const char *); static void _ircserver_connectfailed(struct ircproxy *, int, int); static void _ircserver_data(struct ircproxy *, int); static void _ircserver_error(struct ircproxy *, int, int); static int _ircserver_gotmsg(struct ircproxy *, const char *); static int _ircserver_close(struct ircproxy *); static int _ircserver_lost(struct ircproxy *); static void _ircserver_ping(struct ircproxy *, void *); static void _ircserver_stoned(struct ircproxy *, void *); static void _ircserver_antiidle(struct ircproxy *, void *); static int _ircserver_forclient(struct ircproxy *, struct ircmessage *); static int _ircserver_send_dccreject(struct ircproxy *, const char *); /* Time/date format for strftime(3) */ #define CTCP_TIMEDATE_FORMAT "%a, %d %b %Y %H:%M:%S %z" /* hook for timer code to reconnect to a server */ static void _ircserver_reconnect(struct ircproxy *p, void *data) { debug("Reconnecting to server"); /* Choose the next server. If we have no more, choose the first again and increment attempts */ p->conn_class->next_server = p->conn_class->next_server->next; if (!p->conn_class->next_server) { p->conn_class->next_server = p->conn_class->servers; p->server_attempts++; } debug("%sAttempt %d", (p->server_status & IRC_SERVER_SEEN ? "" : "Initial "), p->server_attempts + 1); if (p->conn_class->server_maxattempts && (p->server_attempts >= p->conn_class->server_maxattempts)) { /* If we go over maximum reattempts, then give up */ if (IS_CLIENT_READY(p)) ircclient_send_notice(p, "Giving up on servers. Time to quit"); p->conn_class = 0; if (p->client_status & IRC_CLIENT_CONNECTED) { ircclient_send_error(p, "Maximum connection attempts exceeded"); ircclient_close(p); } debug("Giving up on servers, reattempted too much"); p->dead = 1; } else if (!(p->server_status & IRC_SERVER_SEEN) && p->conn_class->server_maxinitattempts && (p->server_attempts >= p->conn_class->server_maxinitattempts)) { /* Otherwise check initial attempts if its our first time */ if (IS_CLIENT_READY(p)) ircclient_send_notice(p, "Giving up on servers. Time to quit"); p->conn_class = 0; if (p->client_status & IRC_CLIENT_CONNECTED) { ircclient_send_error(p, "Maximum initial connection attempts exceeded"); ircclient_close(p); } debug("Giving up on servers, can't get initial connection"); p->dead = 1; } else { /* Attempt a new connection */ ircserver_connect(p); } } /* Called to initiate a connection to a server */ int ircserver_connect(struct ircproxy *p) { char *server; debug("Connecting to server (stage 1)"); if (timer_exists((void *)p, "server_recon")) { debug("Connection already in progress"); if (IS_CLIENT_READY(p)) ircclient_send_notice(p, "Connection already in progress..."); return 0; } server = x_strdup(p->conn_class->next_server->str); if (strchr(server, ':') != strrchr(server, ':')) { /* More than one :, second denotes password */ char *pass; pass = strrchr(server, ':'); *(pass++) = 0; if (strlen(pass)) p->serverpassword = x_strdup(pass); } if (IS_CLIENT_READY(p)) ircclient_send_notice(p, "Looking up %s...", server); /* DNS lookup the server */ dns_filladdr((void *)p, server, p->conn_class->server_port, 1, &(p->server_addr), DNS_FUNCTION(_ircserver_connect2), 0); free(server); return 0; } /* Called to initiate a connection to a server once its been looked up */ static void _ircserver_connect2(struct ircproxy *p, void *data, struct in_addr *addr, const char *host) { if (!host || !addr) { debug("DNS failure, retrying"); timer_new((void *)p, "server_recon", p->conn_class->server_retry, TIMER_FUNCTION(_ircserver_reconnect), (void *)0); free(p->serverpassword); p->serverpassword = 0; return; } debug("Resolved server"); /* Copy the found information into p */ free(p->servername); p->servername = x_strdup(host); p->server_addr.sin_addr.s_addr = addr->s_addr; if (p->conn_class->local_address) { dns_addrfromhost((void *)p, 0, p->conn_class->local_address, DNS_FUNCTION(_ircserver_connect3)); } else { _ircserver_connect3(p, 0, 0, 0); } } /* Called to initiate a connection to a server once its been looked up and the local_host has been looked up */ static void _ircserver_connect3(struct ircproxy *p, void *data, struct in_addr *addr, const char *host) { int ret; #ifdef HAVE_SETEUID int switched = 0; pid_t old_euid; #endif /* HAVE_SETEUID */ debug("Connecting to %s port %d", p->servername, ntohs(p->server_addr.sin_port)); if (IS_CLIENT_READY(p)) ircclient_send_notice(p, "Connecting to %s port %d", p->servername, ntohs(p->server_addr.sin_port)); #ifdef HAVE_SETEUID old_euid = geteuid(); /* Switch to a user */ if (p->conn_class->switch_user) { struct passwd *pwd; /* switch_user can be a username or a user id */ pwd = getpwnam(p->conn_class->switch_user); if (pwd) { debug("Switching to user '%s'", p->conn_class->switch_user); } else { uid_t uid; /* Make sure that its "0" not an invalid user if atoi returns 0 */ uid = atoi(p->conn_class->switch_user); if (uid || !strcmp(p->conn_class->switch_user, "0")) { pwd = getpwuid(uid); if (pwd) debug("Switching to user #%d", uid); } } /* Set the effective user id if we're root */ if (pwd && (getuid() == 0)) { if (!seteuid(pwd->pw_uid)) { switched = 1; } else { syscall_fail("seteuid", 0, 0); } } /* Warn if we didn't */ if (!switched) { if (IS_CLIENT_READY(p)) ircclient_send_notice(p, "(warning) Couldn't switch to username %s", p->conn_class->switch_user); } } #endif /* HAVE_SETEUID */ p->server_sock = net_socket(); #ifdef HAVE_SETEUID /* Switch back to our original euid */ if (switched) { if (seteuid(old_euid)) { /* Oh, Fuck! */ syscall_fail("seteuid", 0, 0); abort(); } } #endif /* HAVE_SETEUID */ if (p->server_sock == -1) { ret = -1; } else { if (p->conn_class->server_keepalive) net_keepalive(p->server_sock); if (p->conn_class->local_address) { if (addr) { struct sockaddr_in local_addr; memset(&local_addr, 0, sizeof(struct sockaddr_in)); local_addr.sin_family = AF_INET; local_addr.sin_addr.s_addr = addr->s_addr; if (bind(p->server_sock, (struct sockaddr *)&local_addr, sizeof(struct sockaddr_in))) { if (IS_CLIENT_READY(p)) ircclient_send_notice(p, "(warning) Couldn't use local address %s", host); } else { free(p->hostname); p->hostname = (host ? x_strdup(host) : p->conn_class->local_address); } } else { if (IS_CLIENT_READY(p)) ircclient_send_notice(p, "(warning) Couldn't find address for %s", p->conn_class->local_address); } } if (connect(p->server_sock, (struct sockaddr *)&(p->server_addr), sizeof(struct sockaddr_in)) && (errno != EINPROGRESS)) { syscall_fail("connect", p->servername, 0); net_close(&(p->server_sock)); ret = -1; } else { ret = 0; } } if (ret) { if (IS_CLIENT_READY(p)) ircclient_send_notice(p, "Connection failed: %s", strerror(errno)); debug("Connection failed: %s", strerror(errno)); net_close(&(p->server_sock)); timer_new((void *)p, "server_recon", p->conn_class->server_retry, TIMER_FUNCTION(_ircserver_reconnect), (void *)0); free(p->serverpassword); p->serverpassword = 0; } else { p->server_status |= IRC_SERVER_CREATED; net_hook(p->server_sock, SOCK_CONNECTING, (void *)p, ACTIVITY_FUNCTION(_ircserver_connected), ERROR_FUNCTION(_ircserver_connectfailed)); debug("Connection in progress"); } } /* Called when a new server has connected */ static void _ircserver_connected(struct ircproxy *p, int sock) { if (sock != p->server_sock) { error("Unexpected socket %d in _ircserver_connected, expected %d", sock, p->server_sock); net_close(&sock); return; } debug("Connection succeeded"); p->server_status |= IRC_SERVER_CONNECTED; net_hook(p->server_sock, SOCK_NORMAL, (void *)p, ACTIVITY_FUNCTION(_ircserver_data), ERROR_FUNCTION(_ircserver_error)); if (p->conn_class->server_throttle) net_throttle(p->server_sock, p->conn_class->server_throttle[0], p->conn_class->server_throttle[1]); if (IS_CLIENT_READY(p)) ircclient_send_notice(p, "Connected to server"); if (p->conn_class->log_events & IRC_LOG_SERVER) irclog_notice(p, p->nickname, PACKAGE, "Connected to server: %s", p->servername); /* Need to try and look up our local hostname now we have a socket to somewhere that will tell us */ if (!p->hostname) { struct sockaddr_in sock_addr; int len; len = sizeof(struct sockaddr_in); if (!getsockname(p->server_sock, (struct sockaddr *)&sock_addr, &len)) { dns_hostfromaddr((void *)p, 0, sock_addr.sin_addr, DNS_FUNCTION(_ircserver_connected2)); return; } else { syscall_fail("getsockname", "", 0); _ircserver_connected2(p, 0, 0, 0); } } else { _ircserver_connected2(p, 0, 0, 0); } } /* Called when a new server has connected and we have a local hostname */ static void _ircserver_connected2(struct ircproxy *p, void *data, struct in_addr *addr, const char *name) { char *username; if (!p->hostname && name) p->hostname = x_strdup(name); username = ircprot_sanitize_username(p->username); if (p->serverpassword) { ircserver_send_command(p, "PASS", ":%s", p->serverpassword); free(p->serverpassword); p->serverpassword = 0; } /* When connecting to a server, may as well try to start fresh, eh? */ if (p->setnickname && strcmp(p->nickname, p->setnickname)) { free(p->nickname); p->nickname = x_strdup(p->setnickname); } ircserver_send_command(p, "NICK", ":%s", p->nickname); ircserver_send_command(p, "USER", "%s 0 * :%s", username, p->realname); p->server_status |= IRC_SERVER_INTRODUCED; free(username); /* Begin stoned server checking */ if (p->conn_class->server_pingtimeout) { timer_new((void *)p, "server_ping", (int)(p->conn_class->server_pingtimeout / 2), TIMER_FUNCTION(_ircserver_ping), (void *)0); timer_new((void *)p, "server_stoned", p->conn_class->server_pingtimeout, TIMER_FUNCTION(_ircserver_stoned), (void *)0); } /* Begin anti-idle */ if (p->conn_class->idle_maxtime) timer_new((void *)p, "server_antiidle", p->conn_class->idle_maxtime, TIMER_FUNCTION(_ircserver_antiidle), (void *)0); } /* Called when a connection fails */ static void _ircserver_connectfailed(struct ircproxy *p, int sock, int bad) { if (sock != p->server_sock) { error("Unexpected socket %d in _ircserver_connectfailed, expected %d", sock, p->server_sock); net_close(&sock); return; } debug("Connection failed"); if (IS_CLIENT_READY(p)) ircclient_send_notice(p, "Connection failed: %s", strerror(errno)); net_close(&(p->server_sock)); p->server_status &= ~(IRC_SERVER_CREATED); timer_new((void *)p, "server_recon", p->conn_class->server_retry, TIMER_FUNCTION(_ircserver_reconnect), (void *)0); } /* Called when a server sends us stuff. */ static void _ircserver_data(struct ircproxy *p, int sock) { char *str; if (sock != p->server_sock) { error("Unexpected socket %d in _ircserver_data, expected %d", sock, p->server_sock); net_close(&sock); return; } str = 0; while (!p->dead && (p->server_status & IRC_SERVER_CONNECTED) && net_gets(p->server_sock, &str, "\r\n") > 0) { debug("<< '%s'", str); _ircserver_gotmsg(p, str); free(str); } } /* Called on server disconnection or error */ static void _ircserver_error(struct ircproxy *p, int sock, int bad) { if (sock != p->server_sock) { error("Unexpected socket %d in _ircserver_error, expected %d", sock, p->server_sock); net_close(&sock); return; } if (bad) { debug("Socket error"); } else { debug("Server disconnected"); } _ircserver_close(p); } /* Called when we get an irc protocol data from a server */ static int _ircserver_gotmsg(struct ircproxy *p, const char *str) { struct ircmessage msg; int squelch = 1; int important = 0; if (ircprot_parsemsg(str, &msg) == -1) return -1; /* Check source */ if (!msg.src.orig) { msg.src.orig = x_strdup(p->servername); msg.src.fullname = x_strdup(p->servername); msg.src.name = x_strdup(p->servername); } /* 437 is bizarre, it either means Nickname is juped or Channel is juped */ if (!irc_strcasecmp(msg.cmd, "437")) { if (msg.numparams >= 2) { if (!irc_strcasecmp(p->nickname, msg.params[1])) { /* Our nickname is Juped - make it a 433 */ free(msg.cmd); msg.cmd = x_strdup("433"); } else { /* Channel is juped - make it a 471 */ free(msg.cmd); msg.cmd = x_strdup("471"); } } } if (!irc_strcasecmp(msg.cmd, "001")) { /* Use 001 to get the servername */ if (msg.src.type & IRC_SERVER) { free(p->servername); p->servername = x_strdup(msg.src.name); } } else if (!irc_strcasecmp(msg.cmd, "002")) { /* Ignore 002 */ } else if (!irc_strcasecmp(msg.cmd, "003")) { /* Ignore 003 */ } else if (!irc_strcasecmp(msg.cmd, "004")) { /* 004 contains all the juicy info, use it */ if (msg.numparams >= 5) { free(p->servername); free(p->serverver); free(p->serverumodes); free(p->servercmodes); p->servername = x_strdup(msg.params[1]); p->serverver = x_strdup(msg.params[2]); p->serverumodes = x_strdup(msg.params[3]); p->servercmodes = x_strdup(msg.params[4]); p->server_status |= IRC_SERVER_GOTWELCOME | IRC_SERVER_SEEN; p->server_attempts = 0; if (IS_CLIENT_READY(p) && !(p->client_status & IRC_CLIENT_SENTWELCOME)) ircclient_welcome(p); } /* Also use this numeric to send everything state-related to the client. From this moment on, we assume the server is happy. */ /* Restore the user mode */ if (p->modes) ircserver_send_command(p, "MODE", "%s +%s", p->nickname, p->modes); /* Restore the away message */ if (p->awaymessage) { ircserver_send_command(p, "AWAY", ":%s", p->awaymessage); } else if (!(p->client_status & IRC_CLIENT_AUTHED) && p->conn_class->away_message) { ircserver_send_command(p, "AWAY", ":%s", p->conn_class->away_message); } /* Restore the channel list */ if (p->channels) { struct ircchannel *c; c = p->channels; while (c) { if (!c->unjoined) { if (c->key) { ircserver_send_command(p, "JOIN", "%s :%s", c->name, c->key); } else { ircserver_send_command(p, "JOIN", ":%s", c->name); } } c = c->next; } } } else if (!irc_strcasecmp(msg.cmd, "005")) { /* Ignore 005 */ } else if (!irc_strcasecmp(msg.cmd, "375")) { /* Ignore 375 unless allow_motd */ if (p->allow_motd) squelch = 0; } else if (!irc_strcasecmp(msg.cmd, "372")) { /* Ignore 372 unless allow_motd */ if (p->allow_motd) squelch = 0; } else if (!irc_strcasecmp(msg.cmd, "376")) { /* Ignore 376 unless allow_motd */ if (p->allow_motd) { squelch = 0; p->allow_motd = 0; } } else if (!irc_strcasecmp(msg.cmd, "422")) { /* Ignore 422 unless allow_motd */ if (p->allow_motd) { squelch = 0; p->allow_motd = 0; } } else if (!irc_strcasecmp(msg.cmd, "431") || !irc_strcasecmp(msg.cmd, "432") || !irc_strcasecmp(msg.cmd, "433") || !irc_strcasecmp(msg.cmd, "436") || !irc_strcasecmp(msg.cmd, "438")) { /* Our nickname got rejected. Don't update setnickname! */ if (msg.numparams >= 2) { /* Fall back on our original if we can */ if (strlen(msg.params[0]) && strcmp(msg.params[0], "*")) { if (p->client_status == IRC_CLIENT_ACTIVE) ircclient_send_selfcmd(p, "NICK", ":%s", msg.params[0]); ircclient_nick_changed(p, msg.params[0]); ircclient_checknickname(p); squelch = 0; } else { /* We don't have a nickname anymore. Don't free it, so we've still really got the old one lying around. */ p->client_status &= ~(IRC_CLIENT_GOTNICK); /* If we don't have a client connected, then we have to regenerate a new nickname ourselves... Otherwise we can just let the client do it */ if (!(p->client_status & IRC_CLIENT_CONNECTED)) { ircclient_generate_nick(p, msg.params[1]); } else { /* Have to anti-squelch this manually */ net_send(p->client_sock, "%s\r\n", msg.orig); } } } else { squelch = 0; } } else if (!irc_strcasecmp(msg.cmd, "471") || !irc_strcasecmp(msg.cmd, "473") || !irc_strcasecmp(msg.cmd, "474")) { if (msg.numparams >= 2) { /* Can't join a channel */ /* No client connected? Lets rejoin it for it */ if (p->client_status != IRC_CLIENT_ACTIVE) { struct ircchannel *chan; chan = ircnet_fetchchannel(p, msg.params[1]); if (chan) { chan->inactive = 1; ircnet_rejoin(p, chan->name); } } else { /* Let it handle it */ ircnet_delchannel(p, msg.params[1]); } squelch = 0; } } else if (!irc_strcasecmp(msg.cmd, "403") || !irc_strcasecmp(msg.cmd, "475") || !irc_strcasecmp(msg.cmd, "476") || !irc_strcasecmp(msg.cmd, "405")) { if (msg.numparams >= 2) { struct ircchannel *c; /* Can't join a channel, permanent error */ c = ircnet_fetchchannel(p, msg.params[1]); if (c) { /* No client connected? Better notify it */ if (p->client_status != IRC_CLIENT_ACTIVE) { if (p->conn_class->log_events & IRC_LOG_ERROR) { if (msg.numparams >= 3) { irclog_notice(p, p->nickname, PACKAGE, "Couldn't rejoin %s: %s (%s)", msg.params[1], msg.params[2], msg.cmd); } else { irclog_notice(p, p->nickname, PACKAGE, "Couldn't rejoin %s (%s)", msg.params[1], msg.cmd); } } /* Set it to an unjoined channel until the client comes back */ c->unjoined = 1; } else { /* Client connected, so we really can't join it - delete it */ ircnet_delchannel(p, msg.params[1]); } } squelch = 0; } } else if (!irc_strcasecmp(msg.cmd, "411")) { /* Ignore 411 if squelch_411 */ if (p->squelch_411) { p->squelch_411 = 0; } else { squelch = 0; } } else if (!irc_strcasecmp(msg.cmd, "324")) { /* Here be channel modes */ if (msg.numparams >= 2) { struct ircchannel *c; /* Set this to 1 in a minute if we need to */ squelch = 0; c = ircnet_fetchchannel(p, msg.params[1]); if (c) { if (msg.numparams >= 3) { ircnet_channel_mode(p, c, &msg, 2); } else { free(c->key); } /* Look for the channel in the squelch_modes list */ if (p->squelch_modes) { struct strlist *s, *l; l = 0; s = p->squelch_modes; while (s) { if (!irc_strcasecmp(msg.params[1], s->str)) { struct strlist *n; n = s->next; free(s->str); free(s); /* Was in the squelch list, so remove it and stop looking */ s = (l ? l->next : p->squelch_modes) = n; squelch = 1; break; } else { l = s; s = s->next; } } } } } } else if (!irc_strcasecmp(msg.cmd, "477")) { /* No channel modes for this channel */ if (msg.numparams >= 2) { struct ircchannel *c; /* Set this to 1 in a minute if we need to */ squelch = 0; c = ircnet_fetchchannel(p, msg.params[1]); if (c) { debug("No channel modes for %s", c->name); free(c->key); /* Look for the channel in the squelch_modes list */ if (p->squelch_modes) { struct strlist *s, *l; l = 0; s = p->squelch_modes; while (s) { if (!irc_strcasecmp(msg.params[1], s->str)) { struct strlist *n; n = s->next; free(s->str); free(s); /* Was in the squelch list, so remove it and stop looking */ s = (l ? l->next : p->squelch_modes) = n; squelch = 1; break; } else { l = s; s = s->next; } } } } } } else if (!irc_strcasecmp(msg.cmd, "PING")) { /* Reply to pings for the client */ if (msg.numparams == 1) { net_sendurgent(p->server_sock, "PONG :%s\r\n", msg.params[0]); debug("=> 'PONG :%s'", msg.params[0]); } else if (msg.numparams >= 2) { net_sendurgent(p->server_sock, "PONG %s :%s\r\n", msg.params[0], msg.params[1]); debug("=> 'PONG %s :%s'", msg.params[0], msg.params[1]); } /* but let it see them */ squelch = 0; } else if (!irc_strcasecmp(msg.cmd, "PONG")) { /* Use pongs to reset the server_stoned timer */ if (p->allow_pong) squelch = 0; if (p->conn_class->server_pingtimeout) { timer_del((void *)p, "server_stoned"); timer_new((void *)p, "server_stoned", p->conn_class->server_pingtimeout, TIMER_FUNCTION(_ircserver_stoned), (void *)0); p->allow_pong = 0; } } else if (!irc_strcasecmp(msg.cmd, "NICK")) { if (_ircserver_forclient(p, &msg)) { /* Server telling us our nickname */ if (msg.numparams >= 1) { if (strcmp(p->nickname, msg.params[0])) { if (IS_CLIENT_READY(p)) ircclient_send_selfcmd(p, "NICK", ":%s", msg.params[0]); ircclient_nick_changed(p, msg.params[0]); if (p->conn_class->log_events & IRC_LOG_NICK) irclog_notice(p, p->nickname, p->servername, "You changed your nickname to %s", msg.params[0]); } /* Is this as a result of a client NICK command? */ if (p->expecting_nick) { ircclient_setnickname(p); p->expecting_nick = 0; } ircclient_checknickname(p); } } else { /* Someone changing their nickname */ if (msg.numparams >= 1) { if (p->conn_class->log_events & IRC_LOG_NICK) irclog_notice(p, p->nickname, p->servername, "%s changed nickname to %s", msg.src.fullname, msg.params[0]); } squelch = 0; } } else if (!irc_strcasecmp(msg.cmd, "MODE")) { if (msg.numparams >= 2) { struct ircchannel *c; if (!irc_strcasecmp(p->nickname, msg.params[0])) { /* Personal mode change */ int param; if (p->conn_class->log_events & IRC_LOG_MODE) irclog_notice(p, p->nickname, p->servername, "Your mode was changed: %s", msg.paramstarts[1]); for (param = 1; param < msg.numparams; param++) ircclient_change_mode(p, msg.params[param]); /* Check for refuse modes */ if (p->modes && p->conn_class->refuse_modes && (strcspn(p->modes, p->conn_class->refuse_modes) != strlen(p->modes))) { char *mode; debug("Got refusal mode from server"); ircserver_send_command(p, "QUIT", ":Don't like this server - %s %s", PACKAGE, VERSION); mode = x_sprintf("-%s", p->conn_class->refuse_modes); debug("Auto-mode-change '%s'", mode); ircclient_change_mode(p, mode); free(mode); _ircserver_close(p); } } else if ((c = ircnet_fetchchannel(p, msg.params[0]))) { /* Channel mode change */ ircnet_channel_mode(p, c, &msg, 1); if (p->conn_class->log_events & IRC_LOG_MODE) irclog_notice(p, c->name, p->servername, "%s changed mode: %s", msg.src.fullname, msg.paramstarts[1]); } squelch = 0; } } else if (!irc_strcasecmp(msg.cmd, "TOPIC")) { if (msg.numparams >= 2) { struct ircchannel *c; /* Channel topic change */ c = ircnet_fetchchannel(p, msg.params[0]); if (p->conn_class->log_events & IRC_LOG_TOPIC) irclog_notice(p, c->name, p->servername, "%s changed topic: %s", msg.src.fullname, msg.paramstarts[1]); squelch = 0; } } else if (!irc_strcasecmp(msg.cmd, "JOIN")) { if (_ircserver_forclient(p, &msg)) { /* Server telling us we joined a channel */ if (msg.numparams >= 1) { struct ircchannel *c; c = ircnet_fetchchannel(p, msg.params[0]); if (c && c->inactive) { /* Must have got KICK'd or something ... */ c->inactive = 0; /* If a client is connected, tell it we just joined and give it what they missed */ if (p->client_status == IRC_CLIENT_ACTIVE) { net_send(p->client_sock, "%s\r\n", msg.orig); if (p->conn_class->chan_log_enabled) irclog_autorecall(p, msg.params[0]); } } else if (c && c->unjoined) { /* Ah, rejoined a channel we left */ c->unjoined = 0; squelch = 0; } else if (!c) { struct strlist *s; /* Orginary join */ ircnet_addchannel(p, msg.params[0]); /* Ask for the channel modes */ s = (struct strlist *)malloc(sizeof(struct strlist)); s->str = x_strdup(msg.params[0]); s->next = p->squelch_modes; p->squelch_modes = s; ircserver_send_command(p, "MODE", ":%s", msg.params[0]); squelch = 0; } else { /* Bizarre, joined a channel we thought we were already on */ squelch = 0; } if ((p->client_status != IRC_CLIENT_ACTIVE) && (p->conn_class->detach_message)) { int slashme; char *msg; msg = p->conn_class->detach_message; if ((strlen(msg) >= 5) && !strncasecmp(msg, "/me ", 4)) { /* Starts with /me */ slashme = 1; msg += 4; } else { slashme = 0; } if (slashme) { ircserver_send_command(p, "PRIVMSG", "%s :\001ACTION %s\001", c->name, msg); } else { ircserver_send_command(p, "PRIVMSG", "%s :%s", c->name, msg); } } if (p->conn_class->log_events & IRC_LOG_JOIN) irclog_notice(p, msg.params[0], p->servername, "You joined the channel"); } } else { if (msg.numparams >= 1) { if (p->conn_class->log_events & IRC_LOG_JOIN) irclog_notice(p, msg.params[0], p->servername, "%s joined the channel", msg.src.fullname); } squelch = 0; } } else if (!irc_strcasecmp(msg.cmd, "PART")) { if (_ircserver_forclient(p, &msg)) { /* Server telling us we left a channel */ if (msg.numparams >= 1) { struct ircchannel *c; if (p->conn_class->log_events & IRC_LOG_PART) irclog_notice(p, msg.params[0], p->servername, "You left the channel"); c = ircnet_fetchchannel(p, msg.params[0]); /* Ignore server PARTs for unjoined channels */ if (c && !c->unjoined) ircnet_delchannel(p, msg.params[0]); squelch = 0; } } else { if (msg.numparams >= 1) { if (p->conn_class->log_events & IRC_LOG_PART) irclog_notice(p, msg.params[0], p->servername, "%s left the channel", msg.src.fullname); } squelch = 0; } } else if (!irc_strcasecmp(msg.cmd, "KICK")) { if (msg.numparams >= 2) { if (!irc_strcasecmp(p->nickname, msg.params[1])) { /* We got kicked off a channel */ if (p->conn_class->log_events & IRC_LOG_KICK) { if (msg.numparams >= 3) { irclog_notice(p, msg.params[0], p->servername, "Kicked off by %s: %s", msg.src.fullname, msg.params[2]); } else { irclog_notice(p, msg.params[0], p->servername, "Kicked off by %s", msg.src.fullname); } } /* No client connected? Lets rejoin it for it */ if (p->client_status != IRC_CLIENT_ACTIVE) { struct ircchannel *chan; chan = ircnet_fetchchannel(p, msg.params[0]); if (chan) { chan->inactive = 1; ircnet_rejoin(p, chan->name); } } else { /* Let it handle it */ ircnet_delchannel(p, msg.params[0]); } squelch = 0; } else { squelch = 0; if (p->conn_class->log_events & IRC_LOG_KICK) { if (msg.numparams >= 3) { irclog_notice(p, msg.params[0], p->servername, "%s kicked off by %s: %s", msg.params[1], msg.src.fullname, msg.params[2]); } else { irclog_notice(p, msg.params[0], p->servername, "%s kicked off by %s", msg.params[1], msg.src.fullname); } } } } } else if (!irc_strcasecmp(msg.cmd, "QUIT")) { /* Somebody left IRC */ if (p->conn_class->log_events & IRC_LOG_QUIT) { if (msg.numparams >= 1) { irclog_notice(p, p->nickname, p->servername, "%s quit from IRC: %s", msg.src.fullname, msg.params[0]); } else { irclog_notice(p, p->nickname, p->servername, "%s quit from IRC", msg.src.fullname); } } squelch = 0; } else if (!irc_strcasecmp(msg.cmd, "ERROR")) { /* Errors are important enough to always forward to the client */ important = 1; squelch = 0; } else if (!irc_strcasecmp(msg.cmd, "PRIVMSG")) { /* All PRIVMSGs go to the client unless we fiddle */ squelch = 0; if (msg.numparams >= 2) { struct strlist *list, *s; char *str; ircprot_stripctcp(msg.params[1], &str, &list); /* Privmsgs get logged */ if (str && strlen(str)) { if (p->conn_class->log_events & IRC_LOG_TEXT) irclog_msg(p, msg.params[0], msg.src.orig, "%s", str); } free(str); /* Handle CTCP */ str = x_strdup(msg.params[1]); s = list; while (s) { struct ctcpmessage cmsg; struct strlist *n; char *unquoted; int r; n = s->next; r = ircprot_parsectcp(s->str, &cmsg); unquoted = s->str; free(s); s = n; if (r == -1) { free(unquoted); continue; } if (!strcmp(cmsg.cmd, "ACTION")) { if (p->conn_class->log_events & IRC_LOG_ACTION) irclog_ctcp(p, msg.params[0], msg.src.orig, "%s", cmsg.orig); } else if (!strcmp(cmsg.cmd, "DCC") && p->conn_class->dcc_proxy_incoming) { struct sockaddr_in vis_addr; int len; /* We need our local address to do anything DCC related */ len = sizeof(struct sockaddr_in); if ((p->client_status == IRC_CLIENT_ACTIVE) && getsockname(p->client_sock, (struct sockaddr *)&vis_addr, &len)) { syscall_fail("getsockname", "", 0); } else if ((cmsg.numparams >= 4) && (!irc_strcasecmp(cmsg.params[0], "CHAT") || !irc_strcasecmp(cmsg.params[0], "SEND"))) { char *tmp, *ptr, *dccmsg, *rejmsg; struct in_addr l_addr, r_addr; int l_port, r_port, t_port; char *capfile = 0; char *rest = 0; int type = 0; /* Find out what type of DCC request this is */ if (!irc_strcasecmp(cmsg.params[0], "CHAT")) { /* Can only proxy chats if we have a client */ if (p->client_status == IRC_CLIENT_ACTIVE) type = DCC_CHAT; } else if (!irc_strcasecmp(cmsg.params[0], "SEND")) { /* Check if we're capturing it, instead of proxying */ if (p->conn_class->dcc_capture_directory && ((p->client_status != IRC_CLIENT_ACTIVE) || p->conn_class->dcc_capture_always)) { char *file; /* Filename is after / or \ characters, this fixes any security issues we might have with it */ debug("Filename given '%s'", cmsg.params[1]); file = strrchr(cmsg.params[1], '/'); if (file) { char *ptr; file++; ptr = strrchr(file, '\\'); if (ptr) file = ptr + 1; } else { file = strrchr(cmsg.params[1], '\\'); if (file) { file++; } else { file = cmsg.params[1]; } } debug("Filtered to '%s'", file); /* Assuming we got a filename ... */ if (file && strlen(file)) { type = DCC_SEND_CAPTURE; if (p->conn_class->dcc_capture_withnick) { capfile = x_sprintf("%s/%s.%s", p->conn_class->dcc_capture_directory, msg.src.name, file); } else { capfile = x_sprintf("%s/%s", p->conn_class->dcc_capture_directory, file); } debug("Capture to '%s'", capfile); } } else if (p->client_status == IRC_CLIENT_ACTIVE) { /* Proxying - so client must be active. See whether to send it fast or normally */ if (p->conn_class->dcc_send_fast) { type = DCC_SEND_FAST; } else { type = DCC_SEND_SIMPLE; } } } /* Check whether there's a tunnel port */ t_port = 0; if (p->conn_class->dcc_tunnel_incoming) t_port = dns_portfromserv(p->conn_class->dcc_tunnel_incoming); /* Eww, host order, how the hell does this even work between machines of a different byte order? */ if (!t_port) { r_addr.s_addr = strtoul(cmsg.params[2], (char **)NULL, 10); r_port = atoi(cmsg.params[3]); } else { r_addr.s_addr = INADDR_LOOPBACK; r_port = ntohs(t_port); } l_addr.s_addr = ntohl(vis_addr.sin_addr.s_addr); if (cmsg.numparams >= 5) rest = cmsg.paramstarts[4]; /* Strip out this CTCP from the message, replacing it in a moment with dccmsg */ tmp = x_sprintf("\001%s\001", unquoted); ptr = strstr(str, tmp); dccmsg = 0; /* Save this in case we need it later */ rejmsg = x_sprintf(":%s NOTICE %s :\001DCC REJECT %s %s " "(%s: unable to proxy)\001", p->nickname, msg.src.name, cmsg.params[0], cmsg.params[1], PACKAGE); /* Set up a dcc proxy, note: type is 0 if there isn't a client active and we're not capturing it. This will send a reject back which is exactly what we want to do. */ if (ptr && type && !dccnet_new(type, p->conn_class->dcc_proxy_timeout, p->conn_class->dcc_proxy_ports, p->conn_class->dcc_proxy_ports_sz, &l_port, r_addr, r_port, capfile, p->conn_class->dcc_capture_maxsize, DCCN_FUNCTION(_ircserver_send_dccreject), p, rejmsg)) { if (capfile) { dccmsg = x_strdup(""); if (p->conn_class->log_events & IRC_LOG_CTCP) irclog_notice(p, msg.params[0], p->servername, "Captured DCC %s from %s into %s", cmsg.params[0], msg.src.fullname, capfile); } else { dccmsg = x_sprintf("\001DCC %s %s %lu %u%s%s\001", cmsg.params[0], cmsg.params[1], l_addr.s_addr, l_port, (rest ? " " : ""), (rest ? rest : "")); if (p->conn_class->log_events & IRC_LOG_CTCP) irclog_notice(p, msg.params[0], p->servername, "DCC %s Request from %s", cmsg.params[0], msg.src.fullname); } } else if (ptr) { dccmsg = x_strdup(""); _ircserver_send_dccreject(p, rejmsg); } /* Don't need this anymore */ free(rejmsg); /* Cut out the old CTCP and replace with dccmsg */ if (ptr) { char *oldstr; *ptr = 0; ptr += strlen(tmp); oldstr = str; str = x_sprintf("%s%s%s", oldstr, dccmsg, ptr); free(oldstr); free(dccmsg); } free(tmp); if (capfile) free(capfile); } else { /* Unknown DCC */ debug("Unknown or Unimplemented DCC request - %s", cmsg.params[0]); } } else if (!strcmp(cmsg.cmd, "PING") && p->conn_class->ctcp_replies && (p->client_status != IRC_CLIENT_ACTIVE)) { if (cmsg.numparams >= 1) { ircserver_send_command(p, "NOTICE", "%s :\001PING %s\001", msg.src.name, cmsg.paramstarts[0]); } else { ircserver_send_command(p, "NOTICE", "%s :\001PING\001", msg.src.name); } if (p->conn_class->log_events & IRC_LOG_CTCP) irclog_notice(p, msg.params[0], p->servername, "CTCP %s from %s", cmsg.cmd, msg.src.fullname); } else if (!strcmp(cmsg.cmd, "ECHO") && p->conn_class->ctcp_replies && (p->client_status != IRC_CLIENT_ACTIVE)) { if (cmsg.numparams >= 1) ircserver_send_command(p, "NOTICE", "%s :\001ECHO %s\001", msg.src.name, cmsg.paramstarts[0]); if (p->conn_class->log_events & IRC_LOG_CTCP) irclog_notice(p, msg.params[0], p->servername, "CTCP %s from %s", cmsg.cmd, msg.src.fullname); } else if (!strcmp(cmsg.cmd, "TIME") && p->conn_class->ctcp_replies && (p->client_status != IRC_CLIENT_ACTIVE)) { char tbuf[40]; time_t now; time(&now); strftime(tbuf, sizeof(tbuf), CTCP_TIMEDATE_FORMAT, localtime(&now)); ircserver_send_command(p, "NOTICE", "%s :\001TIME %s\001", msg.src.name, tbuf); if (p->conn_class->log_events & IRC_LOG_CTCP) irclog_notice(p, msg.params[0], p->servername, "CTCP %s from %s", cmsg.cmd, msg.src.fullname); } else if (!strcmp(cmsg.cmd, "CLIENTINFO") && p->conn_class->ctcp_replies && (p->client_status != IRC_CLIENT_ACTIVE)) { ircserver_send_command(p, "NOTICE", "%s :\001CLIENTINFO %s\001", msg.src.name, "ACTION DCC VERSION CLIENTINFO USERINFO " "FINGER PING TIME ECHO"); if (p->conn_class->log_events & IRC_LOG_CTCP) irclog_notice(p, msg.params[0], p->servername, "CTCP %s from %s", cmsg.cmd, msg.src.fullname); } else if (!strcmp(cmsg.cmd, "VERSION") && p->conn_class->ctcp_replies && (p->client_status != IRC_CLIENT_ACTIVE)) { ircserver_send_command(p, "NOTICE", "%s :\001VERSION %s %s - %s\001", msg.src.name, PACKAGE, VERSION, "http://dircproxy.sourceforge.net/"); if (p->conn_class->log_events & IRC_LOG_CTCP) irclog_notice(p, msg.params[0], p->servername, "CTCP %s from %s", cmsg.cmd, msg.src.fullname); } else if (!strcmp(cmsg.cmd, "USERINFO") && p->conn_class->ctcp_replies && (p->client_status != IRC_CLIENT_ACTIVE)) { ircserver_send_command(p, "NOTICE", "%s :\001USERINFO %s -- %s\001", msg.src.name, PACKAGE, "Saving the world from " "mutant carrots since 1899!"); if (p->conn_class->log_events & IRC_LOG_CTCP) irclog_notice(p, msg.params[0], p->servername, "CTCP %s from %s", cmsg.cmd, msg.src.fullname); } else if (!strcmp(cmsg.cmd, "FINGER") && p->conn_class->ctcp_replies && (p->client_status != IRC_CLIENT_ACTIVE)) { ircserver_send_command(p, "NOTICE", "%s :\001FINGER %s %s\001", msg.src.name, PACKAGE, "proxying for unconnected client"); if (p->conn_class->log_events & IRC_LOG_CTCP) irclog_notice(p, msg.params[0], p->servername, "CTCP %s from %s", cmsg.cmd, msg.src.fullname); } else { /* Unknown CTCP */ if (p->conn_class->log_events & IRC_LOG_CTCP) irclog_notice(p, msg.params[0], p->servername, "CTCP %s from %s", cmsg.cmd, msg.src.fullname); } ircprot_freectcp(&cmsg); free(unquoted); } /* Send str */ if (strlen(str) && (p->client_status == IRC_CLIENT_ACTIVE)) net_send(p->client_sock, ":%s PRIVMSG %s :%s\r\n", msg.src.orig, msg.params[0], str); squelch = 1; free(str); } } else if (!irc_strcasecmp(msg.cmd, "NOTICE")) { if (msg.numparams >= 1) { struct strlist *list; char *str; ircprot_stripctcp(msg.params[1], &str, &list); if (str && strlen(str)) { if (p->conn_class->log_events & IRC_LOG_TEXT) irclog_notice(p, msg.params[0], msg.src.orig, "%s", str); } free(str); if (list) { struct strlist *s; s = list; while (s) { struct ctcpmessage cmsg; struct strlist *n; int r; n = s->next; r = ircprot_parsectcp(s->str, &cmsg); free(s->str); free(s); s = n; if (r == -1) continue; if (p->conn_class->log_events & IRC_LOG_CTCP) { if (cmsg.numparams >= 1) { irclog_notice(p, msg.params[0], p->servername, "CTCP %s reply from %s: %s", cmsg.cmd, msg.src.fullname, cmsg.paramstarts[0]); } else { irclog_notice(p, msg.params[0], p->servername, "CTCP %s reply from %s", cmsg.cmd, msg.src.fullname); } } ircprot_freectcp(&cmsg); } } } /* All NOTICEs go to the client */ squelch = 0; } else { squelch = 0; } if (!squelch && ((p->client_status == IRC_CLIENT_ACTIVE) || (important && (p->client_status & IRC_CLIENT_CONNECTED)))) { net_send(p->client_sock, "%s\r\n", msg.orig); } ircprot_freemsg(&msg); return 0; } /* Close the server socket itself */ int ircserver_close_sock(struct ircproxy *p) { net_close(&(p->server_sock)); p->server_status &= ~(IRC_SERVER_CREATED | IRC_SERVER_CONNECTED | IRC_SERVER_INTRODUCED | IRC_SERVER_GOTWELCOME); /* Make sure these don't get triggered */ timer_del((void *)p, "server_ping"); timer_del((void *)p, "server_stoned"); timer_del((void *)p, "server_antiidle"); timer_del((void *)p, "server_recon"); return 0; } /* Close the connection to the server */ static int _ircserver_close(struct ircproxy *p) { ircserver_close_sock(p); if (IS_CLIENT_READY(p)) { ircclient_send_notice(p, "Lost connection to server"); _ircserver_lost(p); } if (p->conn_class->log_events & IRC_LOG_SERVER) irclog_notice(p, p->nickname, PACKAGE, "Lost connection to server: %s", p->servername); timer_new((void *)p, "server_recon", p->conn_class->server_retry, TIMER_FUNCTION(_ircserver_reconnect), (void *)0); return 0; } /* Lost the connection to the server while client is active, so send it PARTs so it doesn't get confused by later JOINs */ static int _ircserver_lost(struct ircproxy *p) { struct ircchannel *c; if (IS_CLIENT_READY(p)) { c = p->channels; while (c) { ircclient_send_selfcmd(p, "PART", ":%s", c->name); c = c->next; } } return 0; } /* Drop the connection to the server and reconnect */ int ircserver_connectagain(struct ircproxy *p) { if (IS_SERVER_READY(p)) { if (IS_CLIENT_READY(p)) { ircclient_send_notice(p, "Dropped connnection to server"); if (p->conn_class->log_events & IRC_LOG_SERVER) irclog_notice(p, p->nickname, PACKAGE, "Dropped connection to server: %s", p->servername); _ircserver_lost(p); } ircserver_send_command(p, "QUIT", ":Reconnecting to server - %s %s", PACKAGE, VERSION); } if (p->server_status & IRC_SERVER_CREATED) ircserver_close_sock(p); /* Reset seen so that we start with initattempts again */ p->server_status &= ~(IRC_SERVER_SEEN); p->server_attempts = 0; debug("Connecting again"); ircserver_connect(p); return 0; } /* hook for timer code to ping server */ static void _ircserver_ping(struct ircproxy *p, void *data) { /* Server might not be ready yet 8*/ if (IS_SERVER_READY(p)) { debug("Pinging the server"); net_sendurgent(p->server_sock, "PING :%s\r\n", p->servername); debug("=> 'PING :%s'", p->servername); } timer_new((void *)p, "server_ping", (int)(p->conn_class->server_pingtimeout / 2), TIMER_FUNCTION(_ircserver_ping), (void *)0); } /* hook for timer code to close a stoned server */ static void _ircserver_stoned(struct ircproxy *p, void *data) { /* Server is, like, stoned. Yeah man! */ if (IS_SERVER_READY(p)) { debug("Server is stoned, reconnecting"); ircserver_send_command(p, "QUIT", ":Getting off stoned server - %s %s", PACKAGE, VERSION); _ircserver_close(p); } } /* hook for timer code to send empty privmsg to prevent idling */ static void _ircserver_antiidle(struct ircproxy *p, void *data) { if (IS_SERVER_READY(p)) { debug("Sending anti-idle"); p->squelch_411 = 1; ircserver_send_command(p, "PRIVMSG", ""); } timer_new((void *)p, "server_antiidle", p->conn_class->idle_maxtime, TIMER_FUNCTION(_ircserver_antiidle), (void *)0); } /* Reset idle timer */ void ircserver_resetidle(struct ircproxy *p) { timer_del((void *)p, "server_antiidle"); timer_new((void *)p, "server_antiidle", p->conn_class->idle_maxtime, TIMER_FUNCTION(_ircserver_antiidle), (void *)0); } /* Check if a message is bound for us, and if so check our username and hostname vars are the same */ static int _ircserver_forclient(struct ircproxy *p, struct ircmessage *msg) { if (!(msg->src.type & IRC_USER)) return 0; if (irc_strcasecmp(p->nickname, msg->src.name)) return 0; if (msg->src.username) { free(p->username); p->username = x_strdup(msg->src.username); } if (msg->src.hostname) { free(p->hostname); p->hostname = x_strdup(msg->src.hostname); } return 1; } /* send a command to the server with no prefix */ int ircserver_send_command(struct ircproxy *p, const char *command, const char *format, ...) { va_list ap; char *msg; int ret; va_start(ap, format); msg = x_vsprintf(format, ap); va_end(ap); ret = net_send(p->server_sock, "%s %s\r\n", command, msg); debug("-> '%s %s'", command, msg); free(msg); return ret; } /* Send a DCC reject message */ static int _ircserver_send_dccreject(struct ircproxy *p, const char *msg) { int ret = 1; if (p && p->conn_class && p->conn_class->dcc_proxy_sendreject && (p->server_status == IRC_SERVER_ACTIVE)) { ret = net_send(p->server_sock, "%s\r\n", msg); debug("-> '%s'", msg); } return ret; } dircproxy-1.0.5/src/irc_server.h0000664000175000017500000000156207410714173012336 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * irc_server.h * -- * @(#) $Id: irc_server.h,v 1.7 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #ifndef __DIRCPROXY_IRC_SERVER_H #define __DIRCPROXY_IRC_SERVER_H /* required includes */ #include "irc_net.h" /* functions */ extern int ircserver_connect(struct ircproxy *); extern int ircserver_close_sock(struct ircproxy *); extern int ircserver_connectagain(struct ircproxy *); extern void ircserver_resetidle(struct ircproxy *); extern int ircserver_send_command(struct ircproxy *, const char *, const char *, ...); #endif /* __DIRCPROXY_IRC_SERVER_H */ dircproxy-1.0.5/src/irc_prot.c0000664000175000017500000002207507410714173012011 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * irc_prot.c * - IRC protocol message parsing * - IRC x!y@z parsing * - CTCP stripping and dequoting * - CTCP message parsing * - Username sanitisation * -- * @(#) $Id: irc_prot.c,v 1.14 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #include #include #include #include "sprintf.h" #include "stringex.h" #include "irc_prot.h" #include "irc_string.h" /* forward declarations */ static int _ircprot_parse_prefix(char *, struct ircsource *); static int _ircprot_count_params(char *); static int _ircprot_get_params(char *, char ***, char ***); static char *_ircprot_skip_spaces(char *); static char *_ircprot_ctcpdequote(const char *); /* Parse an IRC message. num of params or -1 if no command */ int ircprot_parsemsg(const char *message, struct ircmessage *msg) { char *start, *ptr; /* Copy the original message as well */ ptr = start = msg->orig = x_strdup(message); /* Begins with a prefix? */ if (*ptr == ':') { while (*ptr && (*ptr != ' ')) ptr++; msg->src.orig = (char *)malloc(ptr - start); strncpy(msg->src.orig, start + 1, ptr - start - 1); msg->src.orig[ptr - start - 1] = 0; _ircprot_parse_prefix(msg->src.orig, &(msg->src)); ptr = _ircprot_skip_spaces(ptr); } else { /* It just came from our peer */ msg->src.name = msg->src.username = msg->src.hostname = msg->src.orig = 0; msg->src.fullname = 0; msg->src.type = IRC_PEER; } /* No command? */ if (!*ptr) { free(msg->src.name); free(msg->src.username); free(msg->src.hostname); free(msg->src.fullname); free(msg->src.orig); free(msg->orig); return -1; } /* Take the command off the front */ start = ptr; while (*ptr && (*ptr != ' ')) ptr++; msg->cmd = (char *)malloc(ptr - start + 1); strncpy(msg->cmd, start, ptr - start); msg->cmd[ptr - start] = 0; ptr = _ircprot_skip_spaces(ptr); /* Now do the parameters */ msg->numparams = _ircprot_count_params(ptr); if (msg->numparams) { msg->params = (char **)malloc(sizeof(char *) * msg->numparams); msg->paramstarts = (char **)malloc(sizeof(char *) * msg->numparams); _ircprot_get_params(ptr, &(msg->params), &(msg->paramstarts)); } else { msg->params = 0; msg->paramstarts = 0; } return msg->numparams; } /* Free an IRC message */ void ircprot_freemsg(struct ircmessage *msg) { int i; for (i = 0; i < msg->numparams; i++) free(msg->params[i]); free(msg->src.name); free(msg->src.username); free(msg->src.hostname); free(msg->src.fullname); free(msg->src.orig); free(msg->cmd); free(msg->params); free(msg->paramstarts); free(msg->orig); } /* Parse a prefix from an irc message */ static int _ircprot_parse_prefix(char *prefix, struct ircsource *source) { char *str, *ptr; str = prefix; ptr = strchr(str, '!'); if (ptr) { source->type = IRC_USER; source->username = source->hostname = 0; source->name = (char *)malloc(ptr - str + 1); strncpy(source->name, str, ptr - str); source->name[ptr - str] = 0; str = ptr + 1; ptr = strchr(str, '@'); if (ptr) { source->username = (char *)malloc(ptr - str + 1); strncpy(source->username, str, ptr - str); source->username[ptr - str] = 0; str = ptr + 1; source->hostname = x_strdup(str); } else { source->type = IRC_EITHER; } } else { source->type = IRC_EITHER; source->username = source->hostname = 0; source->name = x_strdup(str); } if (source->name && source->username && source->hostname) { source->fullname = x_sprintf("%s (%s@%s)", source->name, source->username, source->hostname); } else { source->fullname = x_strdup(source->name); } return source->type; } /* Count the number of parameters in an irc message */ static int _ircprot_count_params(char *message) { char *ptr; int count; count = 0; ptr = message; while (*ptr) { count++; if (*ptr == ':') break; while (*ptr && (*ptr != ' ')) ptr++; ptr = _ircprot_skip_spaces(ptr); } return count; } /* Split an irc message into an array */ static int _ircprot_get_params(char *message, char ***params, char ***paramstarts) { char *ptr, *start; int param; param = 0; ptr = start = message; while (*ptr) { if (*ptr == ':') { (*params)[param] = x_strdup(ptr + 1); (*paramstarts)[param] = ptr + 1; break; } else { (*paramstarts)[param] = start; while (*ptr && (*ptr != ' ')) ptr++; (*params)[param] = (char *)malloc(ptr - start + 1); strncpy((*params)[param], start, ptr - start); (*params)[param][ptr - start] = 0; ptr = _ircprot_skip_spaces(ptr); param++; start = ptr; } } return param + 1; } /* Skip spaces */ static char *_ircprot_skip_spaces(char *ptr) { #ifdef OLD_RFC1459_PARAM_SPACE while (*ptr && (*ptr == ' ')) ptr++; #else /* OLD_RFC1459_PARAM_SPACE */ if (*ptr && (*ptr == ' ')) ptr++; #endif /* OLD_RFC1459_PARAM_SPACE */ return ptr; } /* Returns a new string that's the dequoted version of the old one */ static char *_ircprot_ctcpdequote(const char *msg) { char *new, *out, *in, *ret; int quote = 0; in = out = new = x_strdup(msg); while (*in) { if (quote) { if (*in == 'a') { *(out++) = '\\'; } else { *(out++) = *in; } quote = 0; } else { if (*in == '\\') { quote = 1; } else { *(out++) = *in; } } in++; } *out = 0; ret = x_strdup(new); free(new); return ret; } /* Strip embedded CTCP messages from a string, placing the new string in the * newmsg pointer and a strlist of the ctcp's that were found in the list * pointer */ void ircprot_stripctcp(const char *msg, char **newmsg, struct strlist **list) { char *copy, *in, *out, *start = 0; int ctcp = 0; if (list) *list = 0; in = out = copy = x_strdup(msg); while (*in) { if (*in == 0x01) { if (ctcp) { *(in++) = 0; out -= strlen(start); ctcp = 0; if (strlen(start + 1) && list) { struct strlist *s; s = (struct strlist *)malloc(sizeof(struct strlist)); s->str = x_strdup(start + 1); s->next = 0; if (*list) { struct strlist *ss; ss = *list; while (ss->next) ss = ss->next; ss->next = s; } else { *list = s; } } } else { /* Found start of a CTCP */ start = in; ctcp = 1; *(out++) = *(in++); } } else { *(out++) = *(in++); } } *out = 0; if (newmsg) *newmsg = x_strdup(copy); free(copy); } /* Parse an CTCP message. num of params or -1 if no command */ int ircprot_parsectcp(const char *message, struct ctcpmessage *cmsg) { char *start, *ptr; /* Copy the original message as well */ ptr = start = cmsg->orig = _ircprot_ctcpdequote(message); /* No command? */ if (!*ptr) { free(cmsg->orig); return -1; } /* Take the command off the front */ ptr += strcspn(ptr, " "); cmsg->cmd = (char *)malloc(ptr - start + 1); strncpy(cmsg->cmd, start, ptr - start); cmsg->cmd[ptr - start] = 0; irc_strupr(cmsg->cmd); /* Get the parameters */ ptr += strspn(ptr, " "); if (*ptr) { int p; start = ptr; cmsg->numparams = 0; while (*ptr) { ptr += strcspn(ptr, " "); ptr += strspn(ptr, " "); cmsg->numparams++; } cmsg->params = (char **)malloc(sizeof(char *) * cmsg->numparams); cmsg->paramstarts = (char **)malloc(sizeof(char *) * cmsg->numparams); p = 0; ptr = start; while (*ptr) { ptr += strcspn(ptr, " "); cmsg->paramstarts[p] = start; cmsg->params[p] = (char *)malloc(ptr - start + 1); strncpy(cmsg->params[p], start, ptr - start); cmsg->params[p][ptr - start] = 0; ptr += strspn(ptr, " "); start = ptr; p++; } } else { cmsg->numparams = 0; cmsg->params = 0; cmsg->paramstarts = 0; } return cmsg->numparams; } /* Free an CTCP message */ void ircprot_freectcp(struct ctcpmessage *cmsg) { int i; for (i = 0; i < cmsg->numparams; i++) free(cmsg->params[i]); free(cmsg->cmd); free(cmsg->params); free(cmsg->paramstarts); free(cmsg->orig); } /* Strip silly characters from a username */ char *ircprot_sanitize_username(const char *str) { char *ret, *out, *in; out = in = ret = x_strdup(str); while (*in) { if ((*in >= 'A') && (*in <= 'Z')) { *(out++) = *in; } else if ((*in >= 'a') && (*in <= 'z')) { *(out++) = *in; } else if ((*in >= '0') && (*in <= '9')) { *(out++) = *in; } in++; } *out = 0; if (!strlen(ret)) { free(ret); ret = x_strdup(FALLBACK_USERNAME); } return ret; } dircproxy-1.0.5/src/irc_prot.h0000664000175000017500000000275207410714173012016 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * irc_prot.h * -- * @(#) $Id: irc_prot.h,v 1.7 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #ifndef __DIRCPROXY_IRC_PROT_H #define __DIRCPROXY_IRC_PROT_H /* required includes */ #include "stringex.h" /* structure defining where a irc message came from */ struct ircsource { char *name; char *username; /* Not server */ char *hostname; /* Not server */ char *fullname; char *orig; int type; }; /* an irc message */ struct ircmessage { struct ircsource src; char *cmd; char **params; int numparams; char *orig; char **paramstarts; }; /* a ctcp message */ struct ctcpmessage { char *cmd; char **params; int numparams; char *orig; char **paramstarts; }; /* types of ircsource */ #define IRC_PEER 0x0 #define IRC_SERVER 0x1 #define IRC_USER 0x2 #define IRC_EITHER 0x3 /* functions */ extern int ircprot_parsemsg(const char *, struct ircmessage *); extern void ircprot_freemsg(struct ircmessage *); extern void ircprot_stripctcp(const char *, char **, struct strlist **); extern int ircprot_parsectcp(const char *, struct ctcpmessage *); extern void ircprot_freectcp(struct ctcpmessage *); extern char *ircprot_sanitize_username(const char *); #endif /* __DIRCPROXY_IRC_PROT_H */ dircproxy-1.0.5/src/irc_log.c0000644000175000017500000005165007537111347011611 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * irc_log.c * - Handling of log files * - Handling of log programs * - Recalling from log files * -- * @(#) $Id: irc_log.c,v 1.35.2.1 2002/09/09 12:24:07 scott Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #include #include #include #include #include #include #include #include #include #include #include #include #include "net.h" #include "sprintf.h" #include "irc_net.h" #include "irc_prot.h" #include "irc_client.h" #include "irc_string.h" #include "irc_log.h" /* forward declarations */ static void _irclog_close(struct logfile *); static struct logfile *_irclog_getlog(struct ircproxy *, const char *); static char *_irclog_read(FILE *); static void _irclog_printf(FILE *, const char *, ...); static int _irclog_write(struct logfile *, const char *, ...); static int _irclog_pipe(struct logfile *log, const char *, const char *, const char *); static int _irclog_writetext(struct ircproxy *, struct logfile *, const char *, const char *, const char *); static int _irclog_text(struct ircproxy *, const char *, const char *, const char *); static int _irclog_recall(struct ircproxy *, struct logfile *, unsigned long, unsigned long, const char *, const char *); /* Log time format for strftime(3) */ #define LOG_TIME_FORMAT "%H:%M" /* Log time/date format for strftime(3) */ #define LOG_TIMEDATE_FORMAT "%a, %d %b %Y %H:%M:%S %z" /* Define MIN() */ #ifndef MIN #define MIN(x, y) ((x) < (y) ? (x) : (y)) #endif /* MIN */ /* Create a temporary directory for log files */ int irclog_maketempdir(struct ircproxy *p) { struct passwd *pw; static unsigned int counter = 0; if (p->temp_logdir) return 0; pw = getpwuid(geteuid()); if (pw) { struct stat statinfo; char *tmpdir; tmpdir = getenv("TMPDIR"); if (!tmpdir) tmpdir = getenv("TEMP"); debug("TMPDIR = '%s'", (tmpdir ? tmpdir : "(null)")); debug("Username = '%s'", pw->pw_name); debug("PID = '%d'", getpid()); p->temp_logdir = x_sprintf("%s/%s-%s-%d-%d", (tmpdir ? tmpdir : "/tmp"), PACKAGE, pw->pw_name, getpid(), counter++); debug("temp_logdir = '%s'", p->temp_logdir); if (lstat(p->temp_logdir, &statinfo)) { if (errno != ENOENT) { syscall_fail("lstat", p->temp_logdir, 0); free(p->temp_logdir); p->temp_logdir = 0; return -1; } else if (mkdir(p->temp_logdir, 0700)) { syscall_fail("mkdir", p->temp_logdir, 0); free(p->temp_logdir); p->temp_logdir = 0; return -1; } } else if (!S_ISDIR(statinfo.st_mode)) { debug("Existed, but not directory"); free(p->temp_logdir); p->temp_logdir = 0; return -1; } } else { debug("Couldn't get username!"); return -1; } return 0; } /* Clean up temporary directory of log files */ int irclog_closetempdir(struct ircproxy *p) { if (!p->temp_logdir) return 0; debug("Freeing '%s'", p->temp_logdir); rmdir(p->temp_logdir); free(p->temp_logdir); p->temp_logdir = 0; return 0; } /* Initialise a log file, opening the copy if necessary */ int irclog_init(struct ircproxy *p, const char *to) { char *ptr, *filename, *copydir, *copyfile; struct logfile *log; log = _irclog_getlog(p, to); if (!log) return -1; if (!p->temp_logdir) return -1; /* Store the config */ if (log == &(p->other_log)) { ptr = filename = x_strdup("other"); log->maxlines = p->conn_class->other_log_maxsize; log->always = p->conn_class->other_log_always; log->timestamp = p->conn_class->other_log_timestamp; log->relativetime = p->conn_class->other_log_relativetime; log->program = (p->conn_class->other_log_program ? x_strdup(p->conn_class->other_log_program) : 0); copydir = (p->conn_class->other_log_copydir ? p->conn_class->other_log_copydir : 0); } else { ptr = filename = x_strdup(to); irc_strlwr(filename); log->maxlines = p->conn_class->chan_log_maxsize; log->always = p->conn_class->chan_log_always; log->timestamp = p->conn_class->chan_log_timestamp; log->relativetime = p->conn_class->chan_log_relativetime; log->program = (p->conn_class->chan_log_program ? x_strdup(p->conn_class->chan_log_program) : 0); copydir = (p->conn_class->chan_log_copydir ? p->conn_class->chan_log_copydir : 0); } /* Channel names are allowed to contain . and / according to the IRC protocol. These are nasty as it means someone could theoretically create a channel called #/../../etc/passwd and the program would try to unlink "/tmp/#/../../etc/passwd" = "/etc/passwd". If running as root this could be bad. So to compensate we replace '/' with ':' as thats not valid in channel names. */ while (*ptr) { switch (*ptr) { case '/': *ptr = ':'; break; } ptr++; } /* Store the filename */ if (log->filename) free(log->filename); log->filename = x_sprintf("%s/%s", p->temp_logdir, filename); log->made = 0; debug("log->filename = '%s'", log->filename); /* Work out the copy filename, and clean up */ copyfile = (copydir ? x_sprintf("%s/%s", copydir, filename) : 0); log->copy = 0; debug("copyfile = '%s'", (copyfile ? copyfile : "")); free(filename); /* Open and append to existing files (as long as they are files) */ if (copyfile) { struct stat statinfo; if (lstat(copyfile, &statinfo)) { if (errno != ENOENT) { syscall_fail("lstat", copyfile, 0); free(copyfile); copyfile = 0; } } else if (!S_ISREG(statinfo.st_mode)) { debug("File existed, but wasn't a file"); free(copyfile); copyfile = 0; } if (copyfile) { log->copy = fopen(copyfile, "a+"); if (!log->copy) syscall_fail("fopen", copyfile, 0); } free(copyfile); } /* If we opened a copy file, write to it */ if (log->copy) { char tbuf[40]; time_t now; /* Output a "logging began" line */ time(&now); strftime(tbuf, sizeof(tbuf), LOG_TIMEDATE_FORMAT, localtime(&now)); _irclog_printf(log->copy, "* Logging started %s\n", tbuf); } return 0; } /* Free up log file information */ void irclog_free(struct logfile *log) { if (!log->filename) return; if (log->open) _irclog_close(log); debug("Freeing up log file '%s'", log->filename); if (log->copy) { /* Output a "logging ended" line to the copy */ char tbuf[40]; time_t now; time(&now); strftime(tbuf, sizeof(tbuf), LOG_TIMEDATE_FORMAT, localtime(&now)); _irclog_printf(log->copy, "* Logging finished %s\n", tbuf); fclose(log->copy); log->copy = 0; } unlink(log->filename); free(log->filename); free(log->program); log->nlines = 0; log->made = 0; } /* Open a previously init'd log file. 0 = ok, -1 = error */ int irclog_open(struct ircproxy *p, const char *to) { struct logfile *log; log = _irclog_getlog(p, to); if (!log || !log->filename) return -1; if (log->open) return 0; /* Unlink first for security, then open w+ */ if (unlink(log->filename) && (errno != ENOENT)) { syscall_fail("unlink", log->filename, 0); free(log->filename); log->filename = 0; return -1; } log->file = fopen(log->filename, "w+"); if (!log->file) { syscall_fail("fopen", log->filename, 0); free(log->filename); log->filename = 0; return -1; } log->open = log->made = 1; if (chmod(log->filename, 0600)) syscall_fail("chmod", log->filename, 0); log->nlines = 0; return 0; } /* Close a log file */ void irclog_close(struct ircproxy *p, const char *to) { struct logfile *log; log = _irclog_getlog(p, to); if (!log) return; _irclog_close(log); } /* Actually close a log file */ static void _irclog_close(struct logfile *log) { if (!log->open) return; debug("Closing log file '%s'", log->filename); fclose(log->file); log->open = 0; } /* Get a log file structure out of an ircproxy */ static struct logfile *_irclog_getlog(struct ircproxy *p, const char *to) { struct ircchannel *c; if (!to) return 0; c = ircnet_fetchchannel(p, to); if (c) { return &(c->log); } else { return &(p->other_log); } } /* Read a line from the log */ static char *_irclog_read(FILE *file) { char buff[512], *line; line = 0; while (1) { if (!fgets(buff, 512, file)) { free(line); return 0; } else if (!strlen(buff)) { free(line); return 0; } else { char *ptr; if (line) { char *new; new = x_sprintf("%s%s", line, buff); free(line); line = new; } else { line = x_strdup(buff); } ptr = line + strlen(line) - 1; if (*ptr == '\n') { while ((ptr >= line) && (!ptr || strchr(" \t\r\n", *ptr))) *(ptr--) = 0; break; } } } return line; } /* Write a line to the end of a file */ static void _irclog_printf(FILE *fd, const char *format, ...) { va_list ap; char *msg; va_start(ap, format); msg = x_vsprintf(format, ap); va_end(ap); fseek(fd, 0, SEEK_END); fputs(msg, fd); fflush(fd); free(msg); } /* Write a line to the log */ static int _irclog_write(struct logfile *log, const char *format, ...) { va_list ap; char *msg; va_start(ap, format); msg = x_vsprintf(format, ap); va_end(ap); if (log->open && log->maxlines && (log->nlines >= log->maxlines)) { FILE *out; char *l; /* We can't simply add .tmp or something on the end, because there is always a possibility that might be a channel name. Besides using temporary files always looks icky to me. This "Sick Puppy" way of reading from an unlinked file sits with me much better (says a lot about me, that) */ fseek(log->file, 0, SEEK_SET); unlink(log->filename); /* This *really* shouldn't happen */ out = fopen(log->filename, "w+"); if (!out) { syscall_fail("fopen", log->filename, 0); return -1; } /* Make sure it's got the right permissions */ if (chmod(log->filename, 0600)) syscall_fail("chmod", log->filename, 0); /* Eat from the start */ while ((log->nlines >= log->maxlines) && (l = _irclog_read(log->file))) { free(l); log->nlines--; } /* Write the rest */ while ((l = _irclog_read(log->file))) { fprintf(out, "%s\n", l); free(l); } /* Close the input file, thereby *whoosh*ing it */ fclose(log->file); log->file = out; } /* Write to the log file */ if (log->open) { _irclog_printf(log->file, "%s\n", msg); log->nlines++; } /* Write to the copy too */ if (log->copy) _irclog_printf(log->copy, "%s\n", msg); free(msg); return 0; } /* Write a line through a pipe to a given program */ static int _irclog_pipe(struct logfile *log, const char *to, const char *from, const char *text) { int p[2], pid; if (!log->program) return 1; /* Prepare a pipe */ if (pipe(p)) { syscall_fail("pipe", 0, 0); return 1; } /* Do the fork() thing */ pid = fork(); if (pid == -1) { syscall_fail("fork", 0, 0); return 1; } else if (pid) { FILE *fd; /* Parent - write text to a file descriptor of the pipe */ close(p[0]); fd = fdopen(p[1], "w"); if (!fd) { syscall_fail("fdopen", 0, 0); close(p[1]); return 1; } fprintf(fd, "%s\n", text); fflush(fd); fclose(fd); } else { /* Child, copy pipe to STDIN then exec the process */ close(p[1]); if (dup2(p[0], STDIN_FILENO) != STDIN_FILENO) { syscall_fail("dup2", 0, 0); close(p[0]); return 1; } execlp(log->program, log->program, from, (to ? to : ""), 0); /* We can't get here. Well we can, it means something went wrong */ syscall_fail("execlp", log->program, 0); exit(10); } return 0; } /* Write a PRIVMSG to log file(s) */ int irclog_msg(struct ircproxy *p, const char *to, const char *nick, const char *format, ...) { char *from, *text; va_list ap; int ret; va_start(ap, format); from = x_sprintf("<%s>", nick); text = x_vsprintf(format, ap); ret = _irclog_text(p, to, from, text); free(text); free(from); va_end(ap); return ret; } /* Write a NOTICE to log file(s) */ int irclog_notice(struct ircproxy *p, const char *to, const char *nick, const char *format, ...) { char *from, *text; va_list ap; int ret; va_start(ap, format); from = x_sprintf("-%s-", nick); text = x_vsprintf(format, ap); ret = _irclog_text(p, to, from, text); free(text); free(from); va_end(ap); return ret; } /* Write a CTCP to log file(s) */ int irclog_ctcp(struct ircproxy *p, const char *to, const char *nick, const char *format, ...) { char *from, *text; va_list ap; int ret; va_start(ap, format); from = x_sprintf("[%s]", nick); text = x_vsprintf(format, ap); ret = _irclog_text(p, to, from, text); free(text); free(from); va_end(ap); return ret; } /* Write some text to a log file */ static int _irclog_writetext(struct ircproxy *p, struct logfile *log, const char *to, const char *from, const char *text) { if (log->timestamp) { time_t now; time(&now); if (p->conn_class->log_timeoffset) now -= (p->conn_class->log_timeoffset * 60); if (log->relativetime) { _irclog_write(log, "@%lu %s %s", now, from, text); } else { char tbuf[40]; strftime(tbuf, sizeof(tbuf), LOG_TIME_FORMAT, localtime(&now)); _irclog_write(log, "%s [%s] %s", from, tbuf, text); } } else { _irclog_write(log, "%s %s", from, text); } _irclog_pipe(log, to, from, text); return 0; } /* Write some text to log file(s) */ static int _irclog_text(struct ircproxy *p, const char *to, const char *from, const char *text) { if (to) { struct logfile *log; /* Write to one file */ log = _irclog_getlog(p, to); if (!log) return -1; _irclog_writetext(p, log, to, from, text); } else { struct ircchannel *c; /* Write to all files */ _irclog_writetext(p, &(p->other_log), (p->nickname ? p->nickname : ""), from, text); c = p->channels; while (c) { _irclog_writetext(p, &(c->log), c->name, from, text); c = c->next; } } return 0; } /* Called to automatically recall stuff */ int irclog_autorecall(struct ircproxy *p, const char *to) { unsigned long recall, start, lines; struct logfile *log; log = _irclog_getlog(p, to); if (!log) return -1; if (log == &(p->other_log)) { recall = p->conn_class->other_log_recall; } else { recall = p->conn_class->chan_log_recall; } /* Don't recall anything */ if (!recall) return 0; /* Recall everything */ if (recall == -1) { start = 0; } else { start = (recall > log->nlines ? 0 : log->nlines - recall); } lines = log->nlines - start; return _irclog_recall(p, log, start, lines, to, 0); } /* Called to manually recall stuff */ int irclog_recall(struct ircproxy *p, const char *to, long start, long lines, const char *from) { struct logfile *log; log = _irclog_getlog(p, to); if (!log) return -1; /* Recall everything */ if (lines == -1) { start = 0; lines = log->nlines; } /* Recall recent */ if (start == -1) start = (lines > log->nlines ? 0 : log->nlines - lines); return _irclog_recall(p, log, start, lines, to, from); } /* Called to do the recall from a log file */ static int _irclog_recall(struct ircproxy *p, struct logfile *log, unsigned long start, unsigned long lines, const char *to, const char *from) { FILE *file; int close; /* If the file isn't open, we have to open it and remember to close it later */ if (log->open) { file = log->file; close = 0; } else if (log->filename && log->made) { file = fopen(log->filename, "r"); if (!file) { ircclient_send_notice(p, "Couldn't open log file %s", log->filename); syscall_fail("fopen", log->filename, 0); return -1; } close = 1; } else { return -1; } /* Jump to the beginning */ fseek(file, 0, SEEK_SET); if (start < log->nlines) { char *l; /* Skip start lines */ while (start && (l = _irclog_read(file))) { free(l); start--; } /* Make lines sensible */ lines = MIN(lines, log->nlines - start); /* Recall lines */ while (lines && (l = _irclog_read(file))) { time_t when = 0; char *ll; /* Timestamped line for relative log creation */ ll = l; if (*l == '@') { char *ts, *rest; /* Timestamp one character in */ ts = l + 1; if (!*ts) { free(ll); continue; } /* Message continues after a space */ rest = strchr(l, ' '); if (!rest) { free(ll); continue; } /* Delete the space */ *(rest++) = 0; l = rest; /* Obtain the timestamp */ when = strtoul(ts, (char **)NULL, 10); } /* Message or Notice lines, these require a bit of parsing */ if ((*l == '<') || (*l == '-') || (*l == '[')) { char *src, *msg, lastchar; /* Source starts one character in */ src = l + 1; if (!*src) { free(ll); continue; } /* Message starts after a space and the correct closing character */ msg = strchr(l, ' '); if (*l == '<') { lastchar = '>'; } else if (*l == '[') { lastchar = ']'; } else { lastchar = '-'; } if (!msg || (*(msg - 1) != lastchar)) { free(ll); continue; } /* Delete the closing character and skip the space */ *(msg - 1) = 0; msg++; /* Do filtering */ if (from) { char *comp, *ptr; /* We just check the nickname, so strip off anything after the ! */ comp = x_strdup(src); if ((ptr = strchr(comp, '!'))) *ptr = 0; /* Check the nicknames are the same */ if (irc_strcasecmp(comp, from)) { free(comp); free(ll); continue; } free(comp); } /* If there was a timestamp on it, we either fake the old-style stuff or do the new fancy stuff */ if (when && log->timestamp) { char tbuf[40]; if (log->relativetime) { time_t now, diff; time(&now); diff = now - when; if (diff < 82800L) { /* Within 23 hours [hh:mm] */ strftime(tbuf, sizeof(tbuf), "%H:%M", localtime(&when)); } else if (diff < 518400L) { /* Within 6 days [day hh:mm] */ strftime(tbuf, sizeof(tbuf), "%a %H:%M", localtime(&when)); } else if (diff < 25920000L) { /* Within 300 days [d mon] */ strftime(tbuf, sizeof(tbuf), "%d %b", localtime(&when)); } else { /* Otherwise [d mon yyyy] */ strftime(tbuf, sizeof(tbuf), "%d %b %Y", localtime(&when)); } } else { strftime(tbuf, sizeof(tbuf), LOG_TIME_FORMAT, localtime(&when)); } /* Send the line */ if (*l == '[') { char *cmd; /* Its a CTCP, so we have to place the command before the timestamp */ cmd = msg; msg += strcspn(msg, " "); if (*msg) *(msg++) = 0; net_send(p->client_sock, ":%s PRIVMSG %s :\001%s [%s]%s%s\001\r\n", src, to, cmd, tbuf, (strlen(msg) ? " " : ""), msg); } else { net_send(p->client_sock, ":%s %s %s :[%s] %s\r\n", src, (*l == '<' ? "PRIVMSG" : "NOTICE"), to, tbuf, msg); } } else { /* Send the line */ if (*l == '[') { net_send(p->client_sock, ":%s PRIVMSG %s :\001%s\001\r\n", src, to, msg); } else { net_send(p->client_sock, ":%s %s %s :%s\r\n", src, (*l == '<' ? "PRIVMSG" : "NOTICE"), to, msg); } } } else if (strncmp(l, "* ", 2)) { /* Anything thats not a comment gets sent as a notice */ ircclient_send_notice(p, "%s", l); } free(ll); lines--; } } /* Either close, or skip back to the end */ if (close) { fclose(file); } else { fseek(file, 0, SEEK_END); } return 0; } dircproxy-1.0.5/src/irc_log.h0000664000175000017500000000255507410714173011614 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * irc_log.h * -- * @(#) $Id: irc_log.h,v 1.9 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #ifndef __DIRCPROXY_IRC_LOG_H #define __DIRCPROXY_IRC_LOG_H /* required includes */ #include #include "irc_net.h" /* functions */ extern int irclog_maketempdir(struct ircproxy *); extern int irclog_closetempdir(struct ircproxy *); extern int irclog_init(struct ircproxy *, const char *); extern void irclog_free(struct logfile *); extern int irclog_open(struct ircproxy *, const char *); extern void irclog_close(struct ircproxy *, const char *); extern int irclog_msg(struct ircproxy *, const char *, const char *, const char *, ...); extern int irclog_notice(struct ircproxy *, const char *, const char *, const char *, ...); extern int irclog_ctcp(struct ircproxy *, const char *, const char *, const char *, ...); extern int irclog_autorecall(struct ircproxy *, const char *); extern int irclog_recall(struct ircproxy *, const char *, long, long, const char *); #endif /* __DIRCPROXY_IRC_LOG_H */ dircproxy-1.0.5/src/irc_string.c0000664000175000017500000000425707410714173012335 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * irc_string.c * - Case conversion functions for IRC protocol * - Comparison and match functions for IRC protocol * -- * @(#) $Id: irc_string.c,v 1.8 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #include #include #include #include #include "match.h" #include "sprintf.h" #include "irc_string.h" /* forward declarations */ static int _irc_tolower(int); static int _irc_toupper(int); /* IRC version of tolower */ static int _irc_tolower(int c) { switch (c) { case '[': return '{'; case ']': return '}'; case '\\': return '|'; default: return tolower(c); } } /* IRC version of tolower */ static int _irc_toupper(int c) { switch (c) { case '{': return '['; case '}': return ']'; case '|': return '\\'; default: return toupper(c); } } /* Changes the case of a string to lowercase */ char *irc_strlwr(char *str) { char *c; c = str; while (*c) { *c = _irc_tolower(*c); c++; } return str; } /* Changes the case of a string to uppercase */ char *irc_strupr(char *str) { char *c; c = str; while (*c) { *c = _irc_toupper(*c); c++; } return str; } /* Compare two irc strings, ignoring case. This is done so much, I've dropped a simple version of the strcmp algorithm here rather than doing two mallocs lowercasing etc. */ int irc_strcasecmp(const char *s1, const char *s2) { while (_irc_tolower(*s1) == _irc_tolower(*s2)) { if (!*s1) return 0; s1++; s2++; } return _irc_tolower(*s1) - _irc_tolower(*s2); } /* Match an irc string against wildcards, ignoring case */ int irc_strcasematch(const char *str, const char *mask) { char *newstr, *newmask; int ret; newstr = irc_strlwr(x_strdup(str)); newmask = irc_strlwr(x_strdup(mask)); ret = strmatch(newstr, newmask); free(newstr); free(newmask); return ret; } dircproxy-1.0.5/src/irc_string.h0000664000175000017500000000133007410714173012327 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * irc_string.h * -- * @(#) $Id: irc_string.h,v 1.4 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #ifndef __DIRCPROXY_IRC_STRING_H #define __DIRCPROXY_IRC_STRING_H /* required includes */ #include "match.h" /* functions */ extern char *irc_strlwr(char *); extern char *irc_strupr(char *); extern int irc_strcasecmp(const char *, const char *); extern int irc_strcasematch(const char *, const char *); #endif /* __DIRCPROXY_STRINGEX_H */ dircproxy-1.0.5/src/dcc_net.c0000664000175000017500000002323507410714173011566 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * dcc_net.c * - Creating new DCC connections * - Connecting to DCC Senders * - The list of currently active DCC proxies * - Miscellaneous DCC functions * -- * @(#) $Id: dcc_net.c,v 1.12 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #include #include #include #include #include #include #include #include #include #include #include #include "net.h" #include "dns.h" #include "timers.h" #include "sprintf.h" #include "stringex.h" #include "dcc_chat.h" #include "dcc_send.h" #include "dcc_net.h" /* forward declarations */ static int _dccnet_listen(struct dccproxy *, int *, size_t, int *); static int _dccnet_connect(struct dccproxy *, struct in_addr, int, int *, size_t, int *); static int _dccnet_bind(int sock, int *, size_t, int *); static void _dccnet_timedout(struct dccproxy *, void *); static void _dccnet_accept(struct dccproxy *, int); static void _dccnet_free(struct dccproxy *); /* list of currently proxied connections */ static struct dccproxy *proxies = 0; /* Create a new DCC connection */ int dccnet_new(int type, long timeout, int *range, size_t range_sz, int *lport, struct in_addr addr, int port, const char *filename, long maxsize, int (*n_f)(void *, const char *), void *n_p, const char *n_msg) { struct dccproxy *p; p = (struct dccproxy *)malloc(sizeof(struct dccproxy)); memset(p, 0, sizeof(struct dccproxy)); p->type = type; /* If we're capturing, we do not need to listen for the client connecting because its not going to! */ if (p->type & DCC_SEND_CAPTURE) { /* Unlink first for security */ if (unlink(filename) && (errno != ENOENT)) { syscall_fail("unlink", filename, 0); free(p); return -1; } /* Open for writing */ p->cap_file = fopen(filename, "w"); if (!p->cap_file) { syscall_fail("fopen", filename, 0); free(p); return -1; } p->cap_filename = x_strdup(filename); p->bytes_max = maxsize * 1024; /* Connect to the sender */ if (_dccnet_connect(p, addr, port, range, range_sz, lport)) { fclose(p->cap_file); free(p->cap_filename); free(p); return -1; } } else { /* Do the connect first, because then that'll hopefully get a port, which the listen socket can also use later anyway */ if (_dccnet_connect(p, addr, port, range, range_sz, lport)) { free(p); return -1; } /* Now listen, if this fails a bind() then thats fatal */ if (_dccnet_listen(p, range, range_sz, lport)) { net_close(&(p->sender_sock)); free(p); return -1; } } p->notify_func = n_f; p->notify_data = n_p; if (n_msg) p->notify_msg = x_strdup(n_msg); p->next = proxies; proxies = p; timer_new((void *)p, "timeout", timeout, TIMER_FUNCTION(_dccnet_timedout), 0); return 0; } /* Create socket to listen on */ static int _dccnet_listen(struct dccproxy *p, int *range, size_t range_sz, int *port) { int theport; p->sendee_sock = net_socket(); if (p->sendee_sock == -1) return -1; if (_dccnet_bind(p->sendee_sock, range, range_sz, &theport)) { net_close(&(p->sendee_sock)); return -1; } if (listen(p->sendee_sock, SOMAXCONN)) { syscall_fail("listen", 0, 0); net_close(&(p->sendee_sock)); return -1; } if (port) *port = theport; debug("Listening for DCC Sendees on port %d", theport); p->sendee_status |= DCC_SENDEE_LISTENING; net_hook(p->sendee_sock, SOCK_LISTENING, (void *)p, ACTIVITY_FUNCTION(_dccnet_accept), 0); return 0; } /* Connect to remote user */ static int _dccnet_connect(struct dccproxy *p, struct in_addr addr, int port, int *range, size_t range_sz, int *bindport) { int theport; p->sender_addr.sin_family = AF_INET; p->sender_addr.sin_addr.s_addr = htonl(addr.s_addr); p->sender_addr.sin_port = htons(port); debug("Connecting to DCC Sender %s:%d", inet_ntoa(p->sender_addr.sin_addr), ntohs(p->sender_addr.sin_port)); p->sender_sock = net_socket(); if (p->sender_sock == -1) return -1; if (_dccnet_bind(p->sender_sock, range, range_sz, &theport)) { debug("Connecting to DCC Sender from random port"); } else { debug("Connecting to DCC Sender from port %d", theport); if (bindport) *bindport = theport; } if (connect(p->sender_sock, (struct sockaddr *)&(p->sender_addr), sizeof(struct sockaddr_in)) && (errno != EINPROGRESS)) { syscall_fail("connect", inet_ntoa(addr), 0); net_close(&(p->sender_sock)); return -1; } p->sender_status |= DCC_SENDER_CREATED; if (p->type & DCC_SEND) { net_hook(p->sender_sock, SOCK_CONNECTING, (void *)p, ACTIVITY_FUNCTION(dccsend_connected), ERROR_FUNCTION(dccsend_connectfailed)); } else if (p->type & DCC_CHAT) { net_hook(p->sender_sock, SOCK_CONNECTING, (void *)p, ACTIVITY_FUNCTION(dccchat_connected), ERROR_FUNCTION(dccchat_connectfailed)); } return 0; } /* Bind a dcc socket to one from the allowed range */ static int _dccnet_bind(int sock, int *range, size_t range_sz, int *port) { struct sockaddr_in local_addr; int len; local_addr.sin_family = AF_INET; local_addr.sin_addr.s_addr = INADDR_ANY; if (range) { int bound = 0; size_t i; int j; for (i = 0; i < range_sz; i += 2) { for (j = range[i]; j <= range[i + 1]; j++) { debug("Trying to bind DCC to port %d", j); local_addr.sin_port = htons(j); if (!bind(sock, (struct sockaddr *)&local_addr, sizeof(struct sockaddr_in))) { bound = 1; break; } } if (bound) break; } if (!bound) { debug("No free ports to bind DCC to"); return -1; } } else { debug("Binding DCC to random port"); local_addr.sin_port = 0; if (bind(sock, (struct sockaddr *)&local_addr, sizeof(struct sockaddr_in))) { syscall_fail("bind", "dcc_listen", 0); return -1; } } len = sizeof(struct sockaddr_in); if (getsockname(sock, (struct sockaddr *)&local_addr, &len)) { syscall_fail("getsockname", 0, 0); return -1; } if (port) *port = ntohs(local_addr.sin_port); return 0; } /* Timer hook to check if we've timed out */ static void _dccnet_timedout(struct dccproxy *p, void *data) { if ((p->sender_status == DCC_SENDER_ACTIVE) && (p->type & DCC_SEND_CAPTURE)) { debug("Capturing, and we've connected to sender"); return; } if (p->sendee_status != DCC_SENDEE_ACTIVE) { if (p->type & DCC_CHAT) { net_send(p->sender_sock, "--(%s)-- Timed out awaiting connection from " "remote peer\n", PACKAGE); } else if (p->type & DCC_SEND) { if (p->notify_func) p->notify_func(p->notify_data, p->notify_msg); } } else if (p->sender_status != DCC_SENDER_ACTIVE) { if (p->type & DCC_CHAT) { net_send(p->sendee_sock, "--(%s)-- Connection to remote peer timed out\n", PACKAGE); } else if (p->type & DCC_SEND) { if (p->sender_status & DCC_SENDER_GONE) { debug("Sender has come and gone, but sendee is connected"); return; } else { if (p->notify_func) p->notify_func(p->notify_data, p->notify_msg); } } } else { debug("They are talking"); return; } p->dead = 1; } /* Accept a sendee connection */ static void _dccnet_accept(struct dccproxy *p, int sock) { int newsock; int len; /* Accept the connection */ len = sizeof(struct sockaddr_in); newsock = accept(sock, (struct sockaddr *)&(p->sendee_addr), &len); if (newsock == -1) { syscall_fail("accept", 0, 0); p->dead = 1; return; } /* Close the listening socket and make the new socket the sendee */ net_close(&(p->sendee_sock)); p->sendee_status &= ~(DCC_SENDEE_LISTENING); p->sendee_sock = newsock; net_create(&(p->sendee_sock)); if (p->sendee_sock != -1) { p->sendee_status |= DCC_SENDEE_CONNECTED; if (p->type & DCC_SEND) { dccsend_accepted(p); } else if (p->type & DCC_CHAT) { dccchat_accepted(p); } debug("DCC Sendee connected from %s:%d", inet_ntoa(p->sendee_addr.sin_addr), ntohs(p->sendee_addr.sin_port)); } } /* Free a DCC proxy */ static void _dccnet_free(struct dccproxy *p) { debug("Freeing DCC proxy"); if (p->sender_status & DCC_SENDER_CREATED) net_close(&(p->sender_sock)); if (p->sendee_status & DCC_SENDEE_CREATED) net_close(&(p->sendee_sock)); if (p->cap_filename) { unlink(p->cap_filename); free(p->cap_filename); } if (p->cap_file) fclose(p->cap_file); free(p->notify_msg); free(p->buf); dns_delall((void *)p); timer_delall((void *)p); free(p); } /* Get rid of any dead proxies */ int dccnet_expunge_proxies(void) { struct dccproxy *p, *l; l = 0; p = proxies; while (p) { if (p->dead) { struct dccproxy *n; n = p->next; _dccnet_free(p); p = (l ? l->next : proxies) = n; } else { l = p; p = p->next; } } return 0; } /* Delete all of the proxies */ void dccnet_flush(void) { struct dccproxy *p; p = proxies; while (p) { struct dccproxy *n; n = p->next; _dccnet_free(p); p = n; } proxies = 0; } dircproxy-1.0.5/src/dcc_net.h0000664000175000017500000000442007410714173011566 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * dcc_net.h * -- * @(#) $Id: dcc_net.h,v 1.8 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #ifndef __DIRCPROXY_IRC_DCC_H #define __DIRCPROXY_IRC_DCC_H /* required includes */ #include #include #include #include /* Always included after dircproxy.h, so we can do this here. */ #ifdef HAVE_INTTYPES_H #include #else /* HAVE_INTTYPES_H */ #define uint32_t unsigned long #endif /* HAVE_INTTYPES_H */ /* a proxied dcc connection */ struct dccproxy { int dead; int type; time_t start; int sender_sock; int sender_status; struct sockaddr_in sender_addr; int sendee_sock; int sendee_status; struct sockaddr_in sendee_addr; int (*notify_func)(void *, const char *); void *notify_data; char *notify_msg; /* DCC SEND only */ uint32_t bytes_sent, bytes_ackd, bytes_rcvd; char *buf; unsigned long bufsz; /* DCC SEND (Capture) only */ char *cap_filename; FILE *cap_file; uint32_t bytes_max; struct dccproxy *next; }; /* handy defines */ #define DCCN_FUNCTION(_FUNC) ((int (*)(void *, const char *)) _FUNC) /* types of dcc proxy */ #define DCC_CHAT 0x01 #define DCC_SEND_SIMPLE 0x10 #define DCC_SEND_FAST 0x20 #define DCC_SEND_CAPTURE 0x40 #define DCC_SEND 0x70 /* states a sender can be in */ #define DCC_SENDER_NONE 0x00 #define DCC_SENDER_CREATED 0x01 #define DCC_SENDER_CONNECTED 0x02 #define DCC_SENDER_GONE 0x04 #define DCC_SENDER_ACTIVE 0x03 /* states a sendee can be in */ #define DCC_SENDEE_NONE 0x00 #define DCC_SENDEE_LISTENING 0x01 #define DCC_SENDEE_CONNECTED 0x02 #define DCC_SENDEE_ACTIVE 0x02 #define DCC_SENDEE_CREATED 0x03 /* functions */ extern int dccnet_new(int, long, int *, size_t, int *, struct in_addr, int, const char *, long, int (*)(void *, const char *), void *, const char *); extern int dccnet_expunge_proxies(void); extern void dccnet_flush(void); #endif /* __DIRCPROXY_IRC_DCC_H */ dircproxy-1.0.5/src/dcc_chat.c0000664000175000017500000000770207410714173011720 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * dcc_chat.c * - DCC chat protocol * -- * @(#) $Id: dcc_chat.c,v 1.11 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #include #include #include #include #include #include #include #include #include #include #include "sprintf.h" #include "net.h" #include "dns.h" #include "timers.h" #include "dcc_net.h" #include "dcc_chat.h" /* forward declarations */ static void _dccchat_data(struct dccproxy *, int); static void _dccchat_error(struct dccproxy *, int, int); /* Called when we've connected to the sender */ void dccchat_connected(struct dccproxy *p, int sock) { if (sock != p->sender_sock) { error("Unexpected socket %d in dccchat_connected, expected %d", sock, p->sender_sock); net_close(&sock); return; } debug("DCC Connection succeeded"); p->sender_status |= DCC_SENDER_CONNECTED; net_hook(p->sender_sock, SOCK_NORMAL, (void *)p, ACTIVITY_FUNCTION(_dccchat_data), ERROR_FUNCTION(_dccchat_error)); if (p->sendee_status != DCC_SENDEE_ACTIVE) { net_send(p->sender_sock, "--(%s)-- Awaiting connection from remote peer\n", PACKAGE); } else { net_send(p->sendee_sock, "--(%s)-- Connected to remote peer\n", PACKAGE); } } /* Called when a connection fails */ void dccchat_connectfailed(struct dccproxy *p, int sock, int bad) { if (sock != p->sender_sock) { error("Unexpected socket %d in dccchat_connectfailed, expected %d", sock, p->sender_sock); net_close(&sock); return; } if (p->sendee_status == DCC_SENDEE_ACTIVE) net_send(p->sendee_sock, "--(%s)-- Connection to remote peer failed\n", PACKAGE); debug("DCC Connection failed"); p->sender_status &= ~(DCC_SENDER_CREATED); net_close(&(p->sender_sock)); p->dead = 1; } /* Called when the sendee has been accepted */ void dccchat_accepted(struct dccproxy *p) { net_hook(p->sendee_sock, SOCK_NORMAL, (void *)p, ACTIVITY_FUNCTION(_dccchat_data), ERROR_FUNCTION(_dccchat_error)); if (p->sender_status != DCC_SENDER_ACTIVE) { net_send(p->sendee_sock, "--(%s)-- Connecting to remote peer\n", PACKAGE); } else { net_send(p->sender_sock, "--(%s)-- Remote peer connected\n", PACKAGE); } } /* Called when we get data over a DCC link */ static void _dccchat_data(struct dccproxy *p, int sock) { char *str, *dir; int to; if (sock == p->sender_sock) { dir = "}}"; to = p->sendee_sock; if (p->sendee_status != DCC_SENDEE_ACTIVE) return; } else if (sock == p->sendee_sock) { dir = "{{"; to = p->sender_sock; if (p->sender_status != DCC_SENDER_ACTIVE) return; } else { error("Unexpected socket %d in dccchat_data, expected %d or %d", sock, p->sender_sock, p->sendee_sock); net_close(&sock); return; } str = 0; while (net_gets(sock, &str, "\n") > 0) { debug("%s '%s'", dir, str); net_send(to, "%s\n", str); free(str); } } /* Called on DCC disconnection or error */ static void _dccchat_error(struct dccproxy *p, int sock, int bad) { char *who; if (sock == p->sender_sock) { who = "Sender"; p->sender_status &= ~(DCC_SENDER_CREATED); net_close(&(p->sender_sock)); } else if (sock == p->sendee_sock) { who = "Sendee"; p->sendee_status &= ~(DCC_SENDEE_CREATED); net_close(&(p->sendee_sock)); } else { error("Unexpected socket %d in dccchat_error, expected %d or %d", sock, p->sender_sock, p->sendee_sock); net_close(&sock); return; } if (bad) { debug("Socket error with %s", who); } else { debug("%s disconnected", who); } p->dead = 1; } dircproxy-1.0.5/src/dcc_chat.h0000664000175000017500000000131007410714173011712 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * dcc_chat.h * -- * @(#) $Id: dcc_chat.h,v 1.5 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #ifndef __DIRCPROXY_DCC_CHAT_H #define __DIRCPROXY_DCC_CHAT_H /* required includes */ #include "dcc_net.h" /* functions */ extern void dccchat_connected(struct dccproxy *, int); extern void dccchat_connectfailed(struct dccproxy *, int, int); extern void dccchat_accepted(struct dccproxy *); #endif /* __DIRCPROXY_DCC_CHAT_H */ dircproxy-1.0.5/src/dcc_send.c0000664000175000017500000001457107410714302011726 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * dcc_send.c * - DCC send protocol * -- * @(#) $Id: dcc_send.c,v 1.13 2001/12/21 20:17:06 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #include #include #include #include #include #include #include #include #include #include #include "sprintf.h" #include "net.h" #include "dns.h" #include "timers.h" #include "dcc_net.h" #include "dcc_send.h" /* forward declarations */ static void _dccsend_data(struct dccproxy *, int); static void _dccsend_error(struct dccproxy *, int, int); static int _dccsend_sendpacket(struct dccproxy *); /* Called when we've connected to the sender */ void dccsend_connected(struct dccproxy *p, int sock) { if (sock != p->sender_sock) { error("Unexpected socket %d in dccsend_connected, expected %d", sock, p->sender_sock); net_close(&sock); return; } debug("DCC Connection succeeded"); p->sender_status |= DCC_SENDER_CONNECTED; net_hook(p->sender_sock, SOCK_NORMAL, (void *)p, ACTIVITY_FUNCTION(_dccsend_data), ERROR_FUNCTION(_dccsend_error)); } /* Called when a connection fails */ void dccsend_connectfailed(struct dccproxy *p, int sock, int bad) { if (sock != p->sender_sock) { error("Unexpected socket %d in dccsend_connectfailed, expected %d", sock, p->sender_sock); net_close(&sock); return; } debug("DCC Connection failed"); p->sender_status &= ~(DCC_SENDER_CREATED); net_close(&(p->sender_sock)); p->dead = 1; } /* Called when the sendee has been accepted */ void dccsend_accepted(struct dccproxy *p) { net_hook(p->sendee_sock, SOCK_NORMAL, (void *)p, ACTIVITY_FUNCTION(_dccsend_data), ERROR_FUNCTION(_dccsend_error)); /* If we've already got data, we better some */ if (p->bufsz) _dccsend_sendpacket(p); } /* Called when we get data over a DCC link */ static void _dccsend_data(struct dccproxy *p, int sock) { if (sock == p->sender_sock) { int buflen, nr; /* Read the data into the buffer */ buflen = net_read(p->sender_sock, 0, 0); p->buf = (char *)realloc(p->buf, p->bufsz + buflen); nr = net_read(p->sender_sock, (void *)(p->buf + p->bufsz), buflen); /* Check we read some */ if (nr > 0) { uint32_t na; int ret; p->bufsz += nr; p->bytes_rcvd += nr; /* Acknowledge them */ na = htonl(p->bytes_rcvd); ret = net_queue(p->sender_sock, (void *)&na, sizeof(uint32_t)); if (ret) { error("Couldn't queue data in dccsend_data"); net_close(&sock); return; } } else { p->buf = (char *)realloc(p->buf, p->bufsz); } } else if (sock == p->sendee_sock) { uint32_t ack; int len; /* We should only ever get ack's back */ len = net_read(p->sendee_sock, (void *)&ack, sizeof(uint32_t)); if (len == sizeof(uint32_t)) p->bytes_ackd = ntohl(ack); } else { error("Unexpected socket %d in dccsend_data, expected %d or %d", sock, p->sender_sock, p->sendee_sock); net_close(&sock); return; } /* Receiving data is as good as trigger as any to check whether we can send more. */ if (p->bufsz && ((p->type & DCC_SEND_FAST) || (p->type & DCC_SEND_CAPTURE) || (p->bytes_ackd >= p->bytes_sent))) { /* Capturing? Just eat the buffer right here, right now */ if (p->type & DCC_SEND_CAPTURE) { /* Write it to the file */ fwrite((void *)p->buf, 1, p->bufsz, p->cap_file); /* Sent the whole thing */ p->bytes_sent += p->bufsz; p->bufsz = 0; free(p->buf); p->buf = 0; /* Check we haven't exceeded the maximum size */ if (p->bytes_max && (p->bytes_sent >= p->bytes_max)) { /* We have, kill it. It'll automatically get unlinked */ debug("Too big for my boots!"); p->dead = 1; } } else if (p->sendee_status == DCC_SENDEE_ACTIVE) { /* Send packet to the client */ _dccsend_sendpacket(p); } } } /* Called on DCC disconnection or error */ static void _dccsend_error(struct dccproxy *p, int sock, int bad) { char *who; if (sock == p->sender_sock) { who = "Sender"; p->sender_status &= ~(DCC_SENDER_CREATED); net_close(&(p->sender_sock)); /* Not necessarily bad, just means the client has gone */ if (p->bufsz && !(p->type & DCC_SEND_CAPTURE)) { p->sender_status = DCC_SENDER_GONE; } else { p->dead = 1; } } else if (sock == p->sendee_sock) { who = "Sendee"; p->sendee_status &= ~(DCC_SENDEE_CREATED); net_close(&(p->sendee_sock)); p->dead = 1; } else { error("Unexpected socket %d in dccsend_error, expected %d or %d", sock, p->sender_sock, p->sendee_sock); net_close(&sock); return; } if (bad) { debug("Socket error with %s", who); } else { debug("%s disconnected", who); /* Close the file nicely if we're capturing, so it doesn't get unlinked */ if (p->type & DCC_SEND_CAPTURE) { debug("%s closed", p->cap_filename); free(p->cap_filename); fclose(p->cap_file); p->cap_filename = 0; p->cap_file = 0; } } } /* Send a packet of buffered data to the client */ static int _dccsend_sendpacket(struct dccproxy *p) { unsigned long nr; /* If we're doing simple sends, we limit the amount we send, if doing fast just shove the whole lot to them */ if (p->type & DCC_SEND_FAST) { nr = p->bufsz; } else { nr = (p->bufsz > DCC_BLOCK_SIZE ? DCC_BLOCK_SIZE : p->bufsz); } /* Send it to the sendee */ if (nr) { int ret; ret = net_queue(p->sendee_sock, (void *)p->buf, nr); if (ret) { error("Couldn't queue data in dccsend_data"); net_close(&(p->sendee_sock)); return -1; } /* Adjust or free the buffer */ p->bytes_sent += nr; p->bufsz -= nr; if (p->bufsz) { memmove(p->buf, p->buf + nr, p->bufsz); p->buf = (char *)realloc(p->buf, p->bufsz); } else { free(p->buf); p->buf = 0; } } /* Out of buffer and the sender has gone */ if (!p->bufsz && (p->sender_status == DCC_SENDER_GONE)) p->dead = 1; return nr; } dircproxy-1.0.5/src/dcc_send.h0000664000175000017500000000131007410714173011724 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * dcc_send.h * -- * @(#) $Id: dcc_send.h,v 1.3 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #ifndef __DIRCPROXY_DCC_SEND_H #define __DIRCPROXY_DCC_SEND_H /* required includes */ #include "dcc_net.h" /* functions */ extern void dccsend_connected(struct dccproxy *, int); extern void dccsend_connectfailed(struct dccproxy *, int, int); extern void dccsend_accepted(struct dccproxy *); #endif /* __DIRCPROXY_DCC_SEND_H */ dircproxy-1.0.5/src/cfgfile.c0000664000175000017500000013332307430200156011557 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * cfgfile.c * - reading of configuration file * -- * @(#) $Id: cfgfile.c,v 1.41 2002/02/06 10:07:42 scott Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #include #include #include #include #include #include "sprintf.h" #include "irc_net.h" #include "cfgfile.h" /* forward declaration */ static int _cfg_read_bool(char **, int *); static int _cfg_read_numeric(char **, long *); static int _cfg_read_string(char **, char **); static int _cfg_read_pair(char **, long **); /* Whitespace */ #define WS " \t\r\n" /* Quick and easy "Unmatched Quote" define */ #define UNMATCHED_QUOTE { error("Unmatched quote for key '%s' " \ "at line %ld of %s", key, line, \ filename); valid = 0; break; } /* Read a config file */ int cfg_read(const char *filename, char **listen_port, char **pid_file, struct globalvars *globals) { struct ircconnclass defaults, *def, *class; int valid; long line; FILE *fd; def = &defaults; memset(globals, 0, sizeof(struct globalvars)); memset(def, 0, sizeof(struct ircconnclass)); class = 0; line = 0; valid = 1; fd = fopen(filename, "r"); if (!fd) return -1; /* Initialise globals */ globals->client_timeout = DEFAULT_CLIENT_TIMEOUT; globals->connect_timeout = DEFAULT_CONNECT_TIMEOUT; globals->dns_timeout = DEFAULT_DNS_TIMEOUT; /* Initialise using defaults */ def->server_port = x_strdup(DEFAULT_SERVER_PORT ? DEFAULT_SERVER_PORT : "0"); def->server_retry = DEFAULT_SERVER_RETRY; def->server_maxattempts = DEFAULT_SERVER_MAXATTEMPTS; def->server_maxinitattempts = DEFAULT_SERVER_MAXINITATTEMPTS; def->server_keepalive = DEFAULT_SERVER_KEEPALIVE; def->server_pingtimeout = DEFAULT_SERVER_PINGTIMEOUT; if (DEFAULT_SERVER_THROTTLE_BYTES || DEFAULT_SERVER_THROTTLE_PERIOD) { def->server_throttle = (long *)malloc(sizeof(long) * 2); def->server_throttle[0] = DEFAULT_SERVER_THROTTLE_BYTES; def->server_throttle[1] = DEFAULT_SERVER_THROTTLE_PERIOD; } def->server_autoconnect = DEFAULT_SERVER_AUTOCONNECT; def->channel_rejoin = DEFAULT_CHANNEL_REJOIN; def->channel_leave_on_detach = DEFAULT_CHANNEL_LEAVE_ON_DETACH; def->channel_rejoin_on_attach = DEFAULT_CHANNEL_REJOIN_ON_ATTACH; def->idle_maxtime = DEFAULT_IDLE_MAXTIME; def->disconnect_existing = DEFAULT_DISCONNECT_EXISTING; def->disconnect_on_detach = DEFAULT_DISCONNECT_ON_DETACH; def->initial_modes = (DEFAULT_INITIAL_MODES ? x_strdup(DEFAULT_INITIAL_MODES) : 0); def->drop_modes = (DEFAULT_DROP_MODES ? x_strdup(DEFAULT_DROP_MODES) : 0); def->refuse_modes = (DEFAULT_REFUSE_MODES ? x_strdup(DEFAULT_REFUSE_MODES) : 0); def->local_address = (DEFAULT_LOCAL_ADDRESS ? x_strdup(DEFAULT_LOCAL_ADDRESS) : 0); def->away_message = (DEFAULT_AWAY_MESSAGE ? x_strdup(DEFAULT_AWAY_MESSAGE) : 0); def->quit_message = (DEFAULT_QUIT_MESSAGE ? x_strdup(DEFAULT_QUIT_MESSAGE) : 0); def->attach_message = (DEFAULT_ATTACH_MESSAGE ? x_strdup(DEFAULT_ATTACH_MESSAGE) : 0); def->detach_message = (DEFAULT_DETACH_MESSAGE ? x_strdup(DEFAULT_DETACH_MESSAGE) : 0); def->detach_nickname = (DEFAULT_DETACH_NICKNAME ? x_strdup(DEFAULT_DETACH_NICKNAME) : 0); def->nick_keep = DEFAULT_NICK_KEEP; def->ctcp_replies = DEFAULT_CTCP_REPLIES; def->chan_log_enabled = DEFAULT_CHAN_LOG_ENABLED; def->chan_log_always = DEFAULT_CHAN_LOG_ALWAYS; def->chan_log_maxsize = DEFAULT_CHAN_LOG_MAXSIZE; def->chan_log_recall = DEFAULT_CHAN_LOG_RECALL; def->chan_log_timestamp = DEFAULT_CHAN_LOG_TIMESTAMP; def->chan_log_relativetime = DEFAULT_CHAN_LOG_RELATIVETIME; def->chan_log_copydir = (DEFAULT_CHAN_LOG_COPYDIR ? x_strdup(DEFAULT_CHAN_LOG_COPYDIR) : 0); def->chan_log_program = (DEFAULT_CHAN_LOG_PROGRAM ? x_strdup(DEFAULT_CHAN_LOG_PROGRAM) : 0); def->other_log_enabled = DEFAULT_OTHER_LOG_ENABLED; def->other_log_always = DEFAULT_OTHER_LOG_ALWAYS; def->other_log_maxsize = DEFAULT_OTHER_LOG_MAXSIZE; def->other_log_recall = DEFAULT_OTHER_LOG_RECALL; def->other_log_timestamp = DEFAULT_OTHER_LOG_TIMESTAMP; def->other_log_relativetime = DEFAULT_OTHER_LOG_RELATIVETIME; def->other_log_copydir = (DEFAULT_OTHER_LOG_COPYDIR ? x_strdup(DEFAULT_OTHER_LOG_COPYDIR) : 0); def->other_log_program = (DEFAULT_OTHER_LOG_PROGRAM ? x_strdup(DEFAULT_OTHER_LOG_PROGRAM) : 0); def->log_timeoffset = DEFAULT_LOG_TIMEOFFSET; def->log_events = DEFAULT_LOG_EVENTS; def->dcc_proxy_incoming = DEFAULT_DCC_PROXY_INCOMING; def->dcc_proxy_outgoing = DEFAULT_DCC_PROXY_OUTGOING; def->dcc_proxy_ports = 0; def->dcc_proxy_ports_sz = 0; def->dcc_proxy_timeout = DEFAULT_DCC_PROXY_TIMEOUT; def->dcc_proxy_sendreject = DEFAULT_DCC_PROXY_SENDREJECT; def->dcc_send_fast = DEFAULT_DCC_SEND_FAST; def->dcc_capture_directory = (DEFAULT_DCC_CAPTURE_DIRECTORY ? x_strdup(DEFAULT_DCC_CAPTURE_DIRECTORY) : 0); def->dcc_capture_always = DEFAULT_DCC_CAPTURE_ALWAYS; def->dcc_capture_withnick = DEFAULT_DCC_CAPTURE_WITHNICK; def->dcc_capture_maxsize = DEFAULT_DCC_CAPTURE_MAXSIZE; def->dcc_tunnel_incoming = (DEFAULT_DCC_TUNNEL_INCOMING ? x_strdup(DEFAULT_DCC_TUNNEL_INCOMING) : 0); def->dcc_tunnel_outgoing = (DEFAULT_DCC_TUNNEL_OUTGOING ? x_strdup(DEFAULT_DCC_TUNNEL_OUTGOING) : 0); def->switch_user = (DEFAULT_SWITCH_USER ? x_strdup(DEFAULT_SWITCH_USER) : 0); def->motd_logo = DEFAULT_MOTD_LOGO; def->motd_file = (DEFAULT_MOTD_FILE ? x_strdup(DEFAULT_MOTD_FILE) : 0); def->motd_stats = DEFAULT_MOTD_STATS; def->allow_persist = DEFAULT_ALLOW_PERSIST; def->allow_jump = DEFAULT_ALLOW_JUMP; def->allow_jump_new = DEFAULT_ALLOW_JUMP_NEW; def->allow_host = DEFAULT_ALLOW_HOST; def->allow_die = DEFAULT_ALLOW_DIE; def->allow_users = DEFAULT_ALLOW_USERS; def->allow_kill = DEFAULT_ALLOW_KILL; while (valid) { char buff[512], *buf; if (!fgets(buff, 512, fd)) break; line++; buf = buff; while ((buf < (buff + 512)) && strlen(buf)) { char *key; /* Skip whitespace, and ignore lines that are comments */ buf += strspn(buf, WS); if (*buf == '#') break; /* Find the end of the key, and if there isn't one, exit */ key = buf; buf += strcspn(buf, WS); if (!strlen(key)) break; /* If there isn't a newline, then we could reach the end of the buffer - so be a bit careful and ensure we don't skip past it */ if (*buf) { *(buf++) = 0; /* Close brace is only allowed when class is defined (we check here, because its a special case and has no value) */ if (!strcmp(key, "}") && !class) { error("Close brace without open at line %ld of %s", line, filename); valid = 0; break; } buf += strspn(buf, WS); } /* If we reached the end of the buffer, or a comment, that means this key has no value. Unless the key is '}' then thats bad */ if ((!*buf || (*buf == '#')) && strcmp(key, "}")) { error("Missing value for key '%s' at line %ld of %s", key, line, filename); valid = 0; break; } /* Handle the keys */ if (!class && !strcasecmp(key, "listen_port")) { /* listen_port 57000 listen_port "dircproxy" # From /etc/services ( cannot go in a connection {} ) */ char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; /* Make sure the silly programmer supplied the pointer! */ if (listen_port) { free(*listen_port); *listen_port = str; } } else if (!class && !strcasecmp(key, "pid_file")) { /* pid_file none pid_file "" # same as none pid_file "/file" pid_file "~/file" ( cannot go in a connection {} ) */ char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; if (!strcasecmp(str, "none") || !strlen(str)) { free(str); str = 0; } else if (!strncmp(str, "~/", 2)) { char *home; home = getenv("HOME"); if (home) { char *tmp; tmp = x_sprintf("%s%s", home, str + 1); free(str); str = tmp; } else { /* Best we can do */ *str = '.'; } } /* Make sure the silly programmer supplied the pointer! */ if (pid_file) { free(*pid_file); *pid_file = str; } } else if (!class && !strcasecmp(key, "client_timeout")) { /* client_timeout 60 */ _cfg_read_numeric(&buf, &globals->client_timeout); } else if (!class && !strcasecmp(key, "connect_timeout")) { /* connect_timeout 60 */ _cfg_read_numeric(&buf, &globals->connect_timeout); } else if (!class && !strcasecmp(key, "dns_timeout")) { /* dns_timeout 60 */ _cfg_read_numeric(&buf, &globals->dns_timeout); } else if (!strcasecmp(key, "server_port")) { /* server_port 6667 server_port "irc" # From /etc/services */ char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; free((class ? class : def)->server_port); (class ? class : def)->server_port = str; } else if (!strcasecmp(key, "server_retry")) { /* server_retry 15 */ _cfg_read_numeric(&buf, &(class ? class : def)->server_retry); } else if (!strcasecmp(key, "server_maxattempts")) { /* server_maxattempts 0 */ _cfg_read_numeric(&buf, &(class ? class : def)->server_maxattempts); } else if (!strcasecmp(key, "server_maxinitattempts")) { /* server_maxinitattempts 5 */ _cfg_read_numeric(&buf, &(class ? class : def)->server_maxinitattempts); } else if (!strcasecmp(key, "server_keepalive")) { /* server_keepalive yes server_keepalive no */ _cfg_read_bool(&buf, &(class ? class : def)->server_keepalive); } else if (!strcasecmp(key, "server_pingtimeout")) { /* server_pingtimeout 600 */ _cfg_read_numeric(&buf, &(class ? class : def)->server_pingtimeout); } else if (!strcasecmp(key, "server_throttle")) { /* server_throttle 0 server_throttle 512 server_throttle 1024:10 */ long *pair; _cfg_read_pair(&buf, &pair); free((class ? class : def)->server_throttle); (class ? class : def)->server_throttle = pair; } else if (!strcasecmp(key, "server_autoconnect")) { /* server_autoconnect yes server_autoconnect no */ _cfg_read_bool(&buf, &(class ? class : def)->server_autoconnect); } else if (!strcasecmp(key, "channel_rejoin")) { /* channel_rejoin 5 */ _cfg_read_numeric(&buf, &(class ? class : def)->channel_rejoin); } else if (!strcasecmp(key, "channel_leave_on_detach")) { /* channel_leave_on_detach yes channel_leave_on_detach no */ _cfg_read_bool(&buf, &(class ? class : def)->channel_leave_on_detach); } else if (!strcasecmp(key, "channel_rejoin_on_attach")) { /* channel_rejoin_on_attach yes channel_rejoin_on_attach no */ _cfg_read_bool(&buf, &(class ? class : def)->channel_rejoin_on_attach); } else if (!strcasecmp(key, "idle_maxtime")) { /* idle_maxtime 120 */ _cfg_read_numeric(&buf, &(class ? class : def)->idle_maxtime); } else if (!strcasecmp(key, "disconnect_existing_user")) { /* disconnect_existing_user yes disconnect_existing_user no */ _cfg_read_bool(&buf, &(class ? class : def)->disconnect_existing); } else if (!strcasecmp(key, "disconnect_on_detach")) { /* disconnect_on_detach yes disconnect_on_detach no */ _cfg_read_bool(&buf, &(class ? class : def)->disconnect_on_detach); } else if (!strcasecmp(key, "initial_modes")) { /* initial_modes "ow" initial_modes "" */ char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; while ((*str == '+') || (*str == '-')) { char *tmp; tmp = str; str = x_strdup(tmp + 1); free(tmp); } if (!strlen(str)) { free(str); str = 0; } free((class ? class : def)->initial_modes); (class ? class : def)->initial_modes = str; } else if (!strcasecmp(key, "drop_modes")) { /* drop_modes "ow" drop_modes "" */ char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; while ((*str == '+') || (*str == '-')) { char *tmp; tmp = str; str = x_strdup(tmp + 1); free(tmp); } if (!strlen(str)) { free(str); str = 0; } free((class ? class : def)->drop_modes); (class ? class : def)->drop_modes = str; } else if (!strcasecmp(key, "refuse_modes")) { /* refuse_modes "r" refuse_modes "" */ char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; while ((*str == '+') || (*str == '-')) { char *tmp; tmp = str; str = x_strdup(tmp + 1); free(tmp); } if (!strlen(str)) { free(str); str = 0; } free((class ? class : def)->refuse_modes); (class ? class : def)->refuse_modes = str; } else if (!strcasecmp(key, "local_address")) { /* local_address none local_address "" # same as none local_address "i.am.a.virtual.host.com" */ char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; if (!strcasecmp(str, "none") || !strlen(str)) { free(str); str = 0; } free((class ? class : def)->local_address); (class ? class : def)->local_address = str; } else if (!strcasecmp(key, "away_message")) { /* away_message none away_message "" # same as none away_message "Not available, messages are logged" */ char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; if (!strcasecmp(str, "none") || !strlen(str)) { free(str); str = 0; } free((class ? class : def)->away_message); (class ? class : def)->away_message = str; } else if (!strcasecmp(key, "quit_message")) { /* quit_message none quit_message "" # same as none quit_message "Gotta restart this thing" */ char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; if (!strcasecmp(str, "none") || !strlen(str)) { free(str); str = 0; } free((class ? class : def)->quit_message); (class ? class : def)->quit_message = str; } else if (!strcasecmp(key, "attach_message")) { /* attach_message none attach_message "" # same as none attach_message "I'm back!" attach_message "/me returns" */ char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; if (!strcasecmp(str, "none") || !strlen(str)) { free(str); str = 0; } free((class ? class : def)->attach_message); (class ? class : def)->attach_message = str; } else if (!strcasecmp(key, "detach_message")) { /* detach_message none detach_message "" # same as none detach_message "I'm gone!" detach_message "/me vanishes" */ char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; if (!strcasecmp(str, "none") || !strlen(str)) { free(str); str = 0; } free((class ? class : def)->detach_message); (class ? class : def)->detach_message = str; } else if (!strcasecmp(key, "detach_nickname")) { /* detach_nickname none detach_nickname "" # same as none detach_nickname "FooAWAY" detach_nickname "*AWAY" */ char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; if (!strcasecmp(str, "none") || !strlen(str)) { free(str); str = 0; } free((class ? class : def)->detach_nickname); (class ? class : def)->detach_nickname = str; } else if (!strcasecmp(key, "nick_keep")) { /* nick_keep yes nick_keep no */ _cfg_read_bool(&buf, &(class ? class : def)->nick_keep); } else if (!strcasecmp(key, "ctcp_replies")) { /* ctcp_replies yes ctcp_replies no */ _cfg_read_bool(&buf, &(class ? class : def)->ctcp_replies); } else if (!strcasecmp(key, "chan_log_enabled")) { /* chan_log_enabled yes chan_log_disabled no */ _cfg_read_bool(&buf, &(class ? class : def)->chan_log_enabled); } else if (!strcasecmp(key, "chan_log_always")) { /* chan_log_always yes chan_log_always no */ _cfg_read_bool(&buf, &(class ? class : def)->chan_log_always); } else if (!strcasecmp(key, "chan_log_maxsize")) { /* chan_log_maxsize 128 chan_log_maxsize 0 */ _cfg_read_numeric(&buf, &(class ? class : def)->chan_log_maxsize); } else if (!strcasecmp(key, "chan_log_recall")) { /* chan_log_recall 128 chan_log_recall 0 chan_log_recall -1 */ _cfg_read_numeric(&buf, &(class ? class : def)->chan_log_recall); } else if (!strcasecmp(key, "chan_log_timestamp")) { /* chan_log_timestamp yes chan_log_timestamp no */ _cfg_read_bool(&buf, &(class ? class : def)->chan_log_timestamp); } else if (!strcasecmp(key, "chan_log_relativetime")) { /* chan_log_relativetime yes chan_log_relativetime no */ _cfg_read_bool(&buf, &(class ? class : def)->chan_log_relativetime); } else if (!strcasecmp(key, "chan_log_copydir")) { /* chan_log_copydir none chan_log_copydir "" # same as none chan_log_copydir "/log" chan_log_copydir "~/logs" */ char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; if (!strcasecmp(str, "none") || !strlen(str)) { free(str); str = 0; } else if (!strncmp(str, "~/", 2)) { char *home; home = getenv("HOME"); if (home) { char *tmp; tmp = x_sprintf("%s%s", home, str + 1); free(str); str = tmp; } else { /* Best we can do */ *str = '.'; } } free((class ? class : def)->chan_log_copydir); (class ? class : def)->chan_log_copydir = str; } else if (!strcasecmp(key, "chan_log_program")) { /* chan_log_program none chan_log_program "" # same as none chan_log_program "/logprog" chan_log_program "~/logprog" */ char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; if (!strcasecmp(str, "none") || !strlen(str)) { free(str); str = 0; } else if (!strncmp(str, "~/", 2)) { char *home; home = getenv("HOME"); if (home) { char *tmp; tmp = x_sprintf("%s%s", home, str + 1); free(str); str = tmp; } else { /* Best we can do */ *str = '.'; } } free((class ? class : def)->chan_log_program); (class ? class : def)->chan_log_program = str; } else if (!strcasecmp(key, "other_log_enabled")) { /* other_log_enabled yes other_log_disabled no */ _cfg_read_bool(&buf, &(class ? class : def)->other_log_enabled); } else if (!strcasecmp(key, "other_log_always")) { /* other_log_always yes other_log_always no */ _cfg_read_bool(&buf, &(class ? class : def)->other_log_always); } else if (!strcasecmp(key, "other_log_maxsize")) { /* other_log_maxsize 128 other_log_maxsize 0 */ _cfg_read_numeric(&buf, &(class ? class : def)->other_log_maxsize); } else if (!strcasecmp(key, "other_log_recall")) { /* other_log_recall 128 other_log_recall 0 other_log_recall -1 */ _cfg_read_numeric(&buf, &(class ? class : def)->other_log_recall); } else if (!strcasecmp(key, "other_log_timestamp")) { /* other_log_timestamp yes other_log_timestamp no */ _cfg_read_bool(&buf, &(class ? class : def)->other_log_timestamp); } else if (!strcasecmp(key, "other_log_relativetime")) { /* other_log_relativetime yes other_log_relativetime no */ _cfg_read_bool(&buf, &(class ? class : def)->other_log_relativetime); } else if (!strcasecmp(key, "other_log_copydir")) { /* other_log_copydir none other_log_copydir "" # same as none other_log_copydir "/log" other_log_copydir "~/logs" */ char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; if (!strcasecmp(str, "none") || !strlen(str)) { free(str); str = 0; } else if (!strncmp(str, "~/", 2)) { char *home; home = getenv("HOME"); if (home) { char *tmp; tmp = x_sprintf("%s%s", home, str + 1); free(str); str = tmp; } else { /* Best we can do */ *str = '.'; } } free((class ? class : def)->other_log_copydir); (class ? class : def)->other_log_copydir = str; } else if (!strcasecmp(key, "other_log_program")) { /* other_log_program none other_log_program "" # same as none other_log_program "/logprog" other_log_program "~/logprog" */ char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; if (!strcasecmp(str, "none") || !strlen(str)) { free(str); str = 0; } else if (!strncmp(str, "~/", 2)) { char *home; home = getenv("HOME"); if (home) { char *tmp; tmp = x_sprintf("%s%s", home, str + 1); free(str); str = tmp; } else { /* Best we can do */ *str = '.'; } } free((class ? class : def)->other_log_program); (class ? class : def)->other_log_program = str; } else if (!strcasecmp(key, "log_timeoffset")) { /* log_timeoffset 0 log_timeoffset -60 log_timeoffset +60 */ _cfg_read_numeric(&buf, &(class ? class : def)->log_timeoffset); } else if (!strcasecmp(key, "log_events")) { /* log_events none log_events all log_events none,+text log_events all,-quit */ char *str, *orig; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; orig = str; while (str && strlen(str)) { char *ptr; ptr = strchr(str, ','); if (ptr) *(ptr++) = 0; str += strspn(str, WS); if (strlen(str) && !strcasecmp(str, "all")) { (class ? class : def)->log_events = 0xffff; } else if (strlen(str) && !strcasecmp(str, "none")) { (class ? class : def)->log_events = 0x0000; } else if (strlen(str)) { int add = 1; if (*str == '-') { add = 0; str++; } else if (*str == '+') { add = 1; str++; } if (strlen(str)) { int flag = 0; if (!strcasecmp(str, "text")) { flag = IRC_LOG_TEXT; } else if (!strcasecmp(str, "action")) { flag = IRC_LOG_ACTION; } else if (!strcasecmp(str, "ctcp")) { flag = IRC_LOG_CTCP; } else if (!strcasecmp(str, "join")) { flag = IRC_LOG_JOIN; } else if (!strcasecmp(str, "part")) { flag = IRC_LOG_PART; } else if (!strcasecmp(str, "kick")) { flag = IRC_LOG_KICK; } else if (!strcasecmp(str, "quit")) { flag = IRC_LOG_QUIT; } else if (!strcasecmp(str, "nick")) { flag = IRC_LOG_NICK; } else if (!strcasecmp(str, "mode")) { flag = IRC_LOG_MODE; } else if (!strcasecmp(str, "topic")) { flag = IRC_LOG_TOPIC; } else if (!strcasecmp(str, "client")) { flag = IRC_LOG_CLIENT; } else if (!strcasecmp(str, "server")) { flag = IRC_LOG_SERVER; } else if (!strcasecmp(str, "error")) { flag = IRC_LOG_ERROR; } else { error("Unknown event name '%s' in 'log_events' " "at line %ld of %s", str, line, filename); valid = 0; break; } if (add) { (class ? class : def)->log_events |= flag; } else { (class ? class : def)->log_events &= ~flag; } } else { error("Missing event name in 'log_events' at line %ld of %s", line, filename); valid = 0; break; } } else { error("Missing event name in 'log_events' at line %ld of %s", line, filename); valid = 0; break; } str = ptr; } free(orig); if (!valid) break; } else if (!strcasecmp(key, "dcc_proxy_incoming")) { /* dcc_proxy_incoming yes dcc_proxy_incoming no */ _cfg_read_bool(&buf, &(class ? class : def)->dcc_proxy_incoming); } else if (!strcasecmp(key, "dcc_proxy_outgoing")) { /* dcc_proxy_outgoing yes dcc_proxy_outgoing no */ _cfg_read_bool(&buf, &(class ? class : def)->dcc_proxy_outgoing); } else if (!strcasecmp(key, "dcc_proxy_ports")) { /* dcc_proxy_ports any dcc_proxy_ports 6667,1042-2048 */ char *str, *orig; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; if (!strcasecmp(str, "any") || !strlen(str)) { free(str); str = 0; free((class ? class : def)->dcc_proxy_ports); (class ? class : def)->dcc_proxy_ports = 0; (class ? class : def)->dcc_proxy_ports_sz = 0; } orig = str; while (str && strlen(str)) { char *ptr; ptr = strchr(str, ','); if (ptr) *(ptr++) = 0; str += strspn(str, WS); if (strlen(str)) { int lwr, upr; char *dash; dash = strchr(str, '-'); if (dash) *(dash++) = 0; lwr = atoi(str); upr = (dash ? atoi(dash) : lwr); if (lwr && upr) { int *newlist; size_t newsz; newsz = (class ? class : def)->dcc_proxy_ports_sz + 2; newlist = (int *)malloc(sizeof(int) * newsz); memcpy(newlist, (class ? class : def)->dcc_proxy_ports, sizeof(int) * (class ? class : def)->dcc_proxy_ports_sz); newlist[(class ? class : def)->dcc_proxy_ports_sz + 0] = lwr; newlist[(class ? class : def)->dcc_proxy_ports_sz + 1] = upr; free((class ? class : def)->dcc_proxy_ports); (class ? class : def)->dcc_proxy_ports = newlist; (class ? class : def)->dcc_proxy_ports_sz = newsz; } else { error("Bad port in 'dcc_proxy_ports' at line %ld of %s", line, filename); valid = 0; free(orig); break; } } else { error("Missing port range in 'dcc_proxy_ports' at line %ld of %s", line, filename); valid = 0; free(orig); break; } str = ptr; } free(orig); } else if (!strcasecmp(key, "dcc_proxy_timeout")) { /* dcc_proxy_timeout 60 */ _cfg_read_numeric(&buf, &(class ? class : def)->dcc_proxy_timeout); } else if (!strcasecmp(key, "dcc_proxy_sendreject")) { /* dcc_proxy_sendreject yes dcc_proxy_sendreject no */ _cfg_read_bool(&buf, &(class ? class : def)->dcc_proxy_sendreject); } else if (!strcasecmp(key, "dcc_send_fast")) { /* dcc_send_fast yes dcc_send_fast no */ _cfg_read_bool(&buf, &(class ? class : def)->dcc_send_fast); } else if (!strcasecmp(key, "dcc_capture_directory")) { /* dcc_capture_directory none dcc_capture_directory "" # same as none dcc_capture_directory "/tmp" dcc_capture_directory "~/caught" */ char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; if (!strcasecmp(str, "none") || !strlen(str)) { free(str); str = 0; } else if (!strncmp(str, "~/", 2)) { char *home; home = getenv("HOME"); if (home) { char *tmp; tmp = x_sprintf("%s%s", home, str + 1); free(str); str = tmp; } else { /* Best we can do */ *str = '.'; } } free((class ? class : def)->dcc_capture_directory); (class ? class : def)->dcc_capture_directory = str; } else if (!strcasecmp(key, "dcc_capture_always")) { /* dcc_capture_always yes dcc_capture_always no */ _cfg_read_bool(&buf, &(class ? class : def)->dcc_capture_always); } else if (!strcasecmp(key, "dcc_capture_withnick")) { /* dcc_capture_withnick yes dcc_capture_withnick no */ _cfg_read_bool(&buf, &(class ? class : def)->dcc_capture_withnick); } else if (!class && !strcasecmp(key, "dcc_capture_maxsize")) { /* dcc_capture_maxsize 0 dcc_capture_maxsize 1024 */ _cfg_read_numeric(&buf, &(class ? class : def)->dcc_capture_maxsize); } else if (!strcasecmp(key, "dcc_tunnel_incoming")) { /* dcc_tunnel_incoming none dcc_tunnel_incoming "" # same as none dcc_tunnel_incoming "6667" dcc_tunnel_incoming "irctunnel" # from /etc/services */ char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; if (!strcasecmp(str, "none") || !strlen(str)) { free(str); str = 0; } free((class ? class : def)->dcc_tunnel_incoming); (class ? class : def)->dcc_tunnel_incoming = str; } else if (!strcasecmp(key, "dcc_tunnel_outgoing")) { /* dcc_tunnel_outgoing none dcc_tunnel_outgoing "" # same as none dcc_tunnel_outgoing "6667" dcc_tunnel_outgoing "irctunnel" # from /etc/services */ char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; if (!strcasecmp(str, "none") || !strlen(str)) { free(str); str = 0; } free((class ? class : def)->dcc_tunnel_outgoing); (class ? class : def)->dcc_tunnel_outgoing = str; } else if (!strcasecmp(key, "switch_user")) { /* switch_user none switch_user "" # same as none switch_user 1001 switch_user "bob" */ char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; #ifdef HAVE_SETEUID if (getuid() == 0) { if (!strcasecmp(str, "none") || !strlen(str)) { free(str); str = 0; } free((class ? class : def)->switch_user); (class ? class : def)->switch_user = str; } else { error("(warning) must be run as root to use 'switch_user' " "at line %ld of %s", line, filename); free(str); } #else /* HAVE_SETEUID */ error("(warning) Your system does not support 'switch_user' " "at line %ld of %s", line, filename); free(str); #endif /* HAVE_SETEUID */ } else if (!strcasecmp(key, "motd_logo")) { /* motd_logo yes motd_logo no */ _cfg_read_bool(&buf, &(class ? class : def)->motd_logo); } else if (!strcasecmp(key, "motd_file")) { /* motd_file none motd_file "" # same as none motd_file "/file" motd_file "~/file" */ char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; if (!strcasecmp(str, "none") || !strlen(str)) { free(str); str = 0; } else if (!strncmp(str, "~/", 2)) { char *home; home = getenv("HOME"); if (home) { char *tmp; tmp = x_sprintf("%s%s", home, str + 1); free(str); str = tmp; } else { /* Best we can do */ *str = '.'; } } free((class ? class : def)->motd_file); (class ? class : def)->motd_file = str; } else if (!strcasecmp(key, "motd_stats")) { /* motd_stats yes motd_stats no */ _cfg_read_bool(&buf, &(class ? class : def)->motd_stats); } else if (!strcasecmp(key, "allow_persist")) { /* allow_persist yes allow_persist no */ _cfg_read_bool(&buf, &(class ? class : def)->allow_persist); } else if (!strcasecmp(key, "allow_jump")) { /* allow_jump yes allow_jump no */ _cfg_read_bool(&buf, &(class ? class : def)->allow_jump); } else if (!strcasecmp(key, "allow_jump_new")) { /* allow_jump_new yes allow_jump_new no */ _cfg_read_bool(&buf, &(class ? class : def)->allow_jump_new); } else if (!strcasecmp(key, "allow_host")) { /* allow_host yes allow_host no */ _cfg_read_bool(&buf, &(class ? class : def)->allow_host); } else if (!strcasecmp(key, "allow_die")) { /* allow_die yes allow_die no */ _cfg_read_bool(&buf, &(class ? class : def)->allow_die); } else if (!strcasecmp(key, "allow_users")) { /* allow_users yes allow_users no */ _cfg_read_bool(&buf, &(class ? class : def)->allow_users); } else if (!strcasecmp(key, "allow_kill")) { /* allow_kill yes allow_kill no */ _cfg_read_bool(&buf, &(class ? class : def)->allow_kill); } else if (!class && !strcasecmp(key, "connection")) { /* connection { : : } */ if (*buf != '{') { /* Connection is a bit special, because the only valid value is '{' the internals are handled elsewhere */ error("Expected open brace for key '%s' at line %ld of %s", key, line, filename); valid = 0; break; } buf++; /* Allocate memory, it'll be filled later */ class = (struct ircconnclass *)malloc(sizeof(struct ircconnclass)); memcpy(class, def, sizeof(struct ircconnclass)); class->server_port = (def->server_port ? x_strdup(def->server_port) : 0); if (def->server_throttle) { class->server_throttle = (long *)malloc(sizeof(long) * 2); memcpy(class->server_throttle, def->server_throttle, sizeof(long) * 2); } class->initial_modes = (def->initial_modes ? x_strdup(def->initial_modes) : 0); class->drop_modes = (def->drop_modes ? x_strdup(def->drop_modes) : 0); class->refuse_modes = (def->refuse_modes ? x_strdup(def->refuse_modes) : 0); class->local_address = (def->local_address ? x_strdup(def->local_address) : 0); class->away_message = (def->away_message ? x_strdup(def->away_message) : 0); class->quit_message = (def->quit_message ? x_strdup(def->quit_message) : 0); class->attach_message = (def->attach_message ? x_strdup(def->attach_message) : 0); class->detach_message = (def->detach_message ? x_strdup(def->detach_message) : 0); class->detach_nickname = (def->detach_nickname ? x_strdup(def->detach_nickname) : 0); class->chan_log_copydir = (def->chan_log_copydir ? x_strdup(def->chan_log_copydir) : 0); class->chan_log_program = (def->chan_log_program ? x_strdup(def->chan_log_program) : 0); class->other_log_copydir = (def->other_log_copydir ? x_strdup(def->other_log_copydir) : 0); class->other_log_program = (def->other_log_program ? x_strdup(def->other_log_program) : 0); if (def->dcc_proxy_ports) { class->dcc_proxy_ports = (int *)malloc(sizeof(int) * def->dcc_proxy_ports_sz); memcpy(class->dcc_proxy_ports, def->dcc_proxy_ports, sizeof(int) * def->dcc_proxy_ports_sz); } class->dcc_capture_directory = (def->dcc_capture_directory ? x_strdup(def->dcc_capture_directory) : 0); class->dcc_tunnel_incoming = (def->dcc_tunnel_incoming ? x_strdup(def->dcc_tunnel_incoming) : 0); class->dcc_tunnel_outgoing = (def->dcc_tunnel_outgoing ? x_strdup(def->dcc_tunnel_outgoing) : 0); class->switch_user = (def->switch_user ? x_strdup(def->switch_user) : 0); class->motd_file = (def->motd_file ? x_strdup(def->motd_file) : 0); } else if (class && !strcasecmp(key, "password")) { /* connection { : password "foo" : } */ char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; free(class->password); class->password = str; } else if (class && !strcasecmp(key, "server")) { /* connection { : server "irc.linux.com" server "irc.linux.com:6670" # Port other than default server "irc.linux.com:6670:foo" # Port and password server "irc.linux.com::foo" # Password and default port : } */ struct strlist *s; char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; s = (struct strlist *)malloc(sizeof(struct strlist)); s->str = str; s->next = 0; if (class->servers) { struct strlist *ss; ss = class->servers; while (ss->next) ss = ss->next; ss->next = s; } else { class->servers = s; } } else if (class && !strcasecmp(key, "from")) { /* connection { : from "static-132.myisp.com" # Static hostname from "*.myisp.com" # Masked hostname from "192.168.1.1" # Specific IP from "192.168.*" # IP range : } */ struct strlist *s; char *str; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; s = (struct strlist *)malloc(sizeof(struct strlist)); s->str = str; s->next = class->masklist; class->masklist = s; } else if (class && !strcasecmp(key, "join")) { /* connection { : join "#foo" join "#foo key,#bar" : } */ struct strlist *s; char *str, *orig; if (_cfg_read_string(&buf, &str)) UNMATCHED_QUOTE; orig = str; while (str && strlen(str)) { char *ptr; ptr = strchr(str, ','); if (ptr) *(ptr++) = 0; str += strspn(str, WS); if (strlen(str)) { s = (struct strlist *)malloc(sizeof(struct strlist)); s->str = x_strdup(str); s->next = 0; if (class->channels) { struct strlist *ss; ss = class->channels; while (ss->next) ss = ss->next; ss->next = s; } else { class->channels = s; } } else { error("Missing channel name in 'join' at line %ld of %s", line, filename); valid = 0; free(orig); break; } str = ptr; } free(orig); } else if (class && !strcmp(key, "}")) { /* No auto-connect? Then we *need* jump */ if (!class->server_autoconnect) class->allow_jump = 1; /* Check that a password and at least one server were defined */ if (!class->password) { error("Connection class defined without password " "before line %ld of %s", line, filename); valid = 0; } else if (!class->servers && (class->server_autoconnect || !class->allow_jump_new)) { error("Connection class defined without a server " "before line %ld of %s", line, filename); valid = 0; } /* Add to the list of servers if valid, otherwise free it */ if (valid) { class->orig_local_address = (class->local_address ? x_strdup(class->local_address) : 0); class->next_server = class->servers; class->next = connclasses; connclasses = class; class = 0; } else { ircnet_freeconnclass(class); class = 0; break; } } else { /* Bad key! */ error("Unknown config file key '%s' at line %ld of %s", key, line, filename); valid = 0; break; } /* Skip whitespace. The only things that can trail are comments and close braces, and we re-pass to do those */ buf += strspn(buf, WS); if (*buf && (*buf != '#') && (*buf != '}')) { error("Unexpected data at end of line %ld of %s", line, filename); valid = 0; break; } } } /* Argh, untidy stuff left around */ if (class) { ircnet_freeconnclass(class); class = 0; if (valid) { error("Unmatched open brace in %s", filename); valid = 0; } } fclose(fd); free(def->server_port); free(def->server_throttle); free(def->initial_modes); free(def->drop_modes); free(def->refuse_modes); free(def->local_address); free(def->away_message); free(def->quit_message); free(def->attach_message); free(def->detach_message); free(def->detach_nickname); free(def->chan_log_copydir); free(def->chan_log_program); free(def->other_log_copydir); free(def->other_log_program); free(def->dcc_proxy_ports); free(def->dcc_capture_directory); free(def->dcc_tunnel_incoming); free(def->dcc_tunnel_outgoing); free(def->switch_user); free(def->motd_file); return (valid ? 0 : -1); } /* Read a boolean value from config file */ static int _cfg_read_bool(char **buf, int *val) { char *ptr; ptr = *buf; *buf += strcspn(*buf, WS); *((*buf)++) = 0; if (!strcasecmp(ptr, "yes")) { *val = 1; } else if (!strcasecmp(ptr, "true")) { *val = 1; } else if (!strcasecmp(ptr, "y")) { *val = 1; } else if (!strcasecmp(ptr, "t")) { *val = 1; } else if (!strcasecmp(ptr, "no")) { *val = 0; } else if (!strcasecmp(ptr, "false")) { *val = 0; } else if (!strcasecmp(ptr, "n")) { *val = 0; } else if (!strcasecmp(ptr, "f")) { *val = 0; } else { *val = (atoi(ptr) ? 1 : 0); } return 0; } /* Read a numeric value from config file */ static int _cfg_read_numeric(char **buf, long *val) { char *ptr; ptr = *buf; *buf += strcspn(*buf, WS); *((*buf)++) = 0; *val = atol(ptr); return 0; } /* Read a string value from config file */ static int _cfg_read_string(char **buf, char **val) { char *ptr; if (**buf == '"') { ptr = ++(*buf); while (1) { *buf += strcspn(*buf, "\""); if (**buf != '"') { return -1; } else if (*(*buf - 1) == '\\') { (*buf)++; continue; } else { break; } } } else { ptr = *buf; *buf += strcspn(*buf, WS); } *((*buf)++) = 0; *val = x_strdup(ptr); return 0; } /* Read a numeric pair from config file */ static int _cfg_read_pair(char **buf, long **val) { char *ptr, *col; long ret[2]; ptr = *buf; *buf += strcspn(*buf, WS); *((*buf)++) = 0; col = strchr(ptr, ':'); if (col) { *(col++) = 0; ret[1] = atol(col); } else { ret[1] = 1; } ret[0] = atol(ptr); if (ret[0] || ret[1]) { *val = (long *)malloc(sizeof(long) * 2); memcpy(*val, ret, sizeof(long) * 2); } else { *val = 0; } return 0; } dircproxy-1.0.5/src/cfgfile.h0000664000175000017500000000106607430200156011562 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * cfgfile.h * -- * @(#) $Id: cfgfile.h,v 1.6 2002/02/06 10:07:42 scott Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #ifndef __DIRCPROXY_CFGFILE_H #define __DIRCPROXY_CFGFILE_H /* functions */ extern int cfg_read(const char *, char **, char **, struct globalvars *); #endif /* __DIRCPROXY_CFGFILE_H */ dircproxy-1.0.5/src/timers.c0000664000175000017500000000742607410714173011476 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * timers.c * - Scheduling events * -- * @(#) $Id: timers.c,v 1.8 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #include #include #include #include #include "sprintf.h" #include "timers.h" /* structure of a timer */ struct timer { char *id; time_t time; void (*function)(void *, void *); void *boundto; void *data; struct timer *next; }; /* forward declarations */ static int _timer_free(struct timer *); /* list of current timers */ static struct timer *timers = 0; /* next dynamic id */ static unsigned long nexttimer = 0; /* Check if a timer exists */ int timer_exists(void *b, const char *id) { struct timer *t; t = timers; while (t) { if ((b == t->boundto) && !strcmp(id, t->id)) return 1; t = t->next; } return 0; } /* Add a new timer */ char *timer_new(void *b, const char *id, unsigned long interval, void (*func)(void *, void *), void *data) { struct timer *t; if (id && timer_exists(b, id)) return 0; t = (struct timer *)malloc(sizeof(struct timer)); if (id) { t->id = x_strdup(id); } else { t->id = x_sprintf("timer%lu", nexttimer++); } t->time = (interval ? time(NULL) + interval : 0); t->function = func; t->boundto = b; t->data = data; t->next = timers; timers = t; debug("Timer %s will be triggered in %d seconds", t->id, (t->time ? t->time - time(NULL) : 0)); return t->id; } /* Delete a timer */ int timer_del(void *b, char *id) { struct timer *t, *l; l = 0; t = timers; while (t) { if ((b == t->boundto) && !strcmp(id, t->id)) { if (l) { l->next = t->next; } else { timers = t->next; } debug("Timer %s will not be triggered (%d on the clock)", t->id, (t->time ? t->time - time(NULL) : 0)); _timer_free(t); return 0; } else { l = t; t = t->next; } } return -1; } /* Delete all timers with a certain ircproxy class */ int timer_delall(void *b) { struct timer *t, *l; int numdone; l = 0; t = timers; numdone = 0; while (t) { if (t->boundto == b) { struct timer *n; n = t->next; debug("Timer %s will not be triggered (%d on the clock)", t->id, (t->time ? t->time - time(NULL) : 0)); _timer_free(t); if (l) { t = l->next = n; } else { t = timers = n; } numdone++; } else { l = t; t = t->next; } } return numdone; } /* Poll the timers */ int timer_poll(void) { struct timer *t, *l; time_t ctime; l = 0; t = timers; ctime = time(NULL); while (t) { if (t->time <= ctime) { void (*function)(void *, void *); struct timer *n; void *b, *data; function = t->function; b = t->boundto; data = t->data; n = t->next; debug("Timer %s triggered", t->id); _timer_free(t); if (l) { t = l->next = n; } else { t = timers = n; } if (function) function(b, data); } else { l = t; t = t->next; } } return (timers ? 1 : 0); } /* Free a timer */ static int _timer_free(struct timer *t) { free(t->id); free(t); return 0; } /* Get rid of all the proxies */ void timer_flush(void) { struct timer *t; t = timers; while (t) { struct timer *n; n = t->next; debug("Timer %s never triggered (%d on the clock)", t->id, (t->time ? t->time - time(NULL) : 0)); _timer_free(t); t = n; } timers = 0; } dircproxy-1.0.5/src/timers.h0000664000175000017500000000154607410714173011500 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * timers.h * -- * @(#) $Id: timers.h,v 1.4 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #ifndef __DIRCPROXY_TIMERS_H #define __DIRCPROXY_TIMERS_H /* handy defines */ #define TIMER_FUNCTION(_FUNC) ((void (*)(void *, void *)) _FUNC) /* functions */ extern int timer_exists(void *, const char *); extern char *timer_new(void *, const char *, unsigned long, void (*)(void *, void *), void *); extern int timer_del(void *, char *); extern int timer_delall(void *); extern int timer_poll(void); extern void timer_flush(void); #endif /* __DIRCPROXY_TIMERS_H */ dircproxy-1.0.5/src/dns.c0000664000175000017500000002272307410714173010754 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * dns.c * - non-blocking DNS lookups using callbacks * - wrappers around /etc/services lookup functions * * The non-blocking stuff is a little complex, but it means that the main * loop can continue while waiting for DNS requests to complete. Completion * of a DNS request is notified by the child death signal, so it will * interrupt the main loop to continue where you left off. * -- * @(#) $Id: dns.c,v 1.14 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #include #include #include #include #include #include #include #include #include #include #include #include #include "sprintf.h" #include "dns.h" /* Structure used to hold information about a dns child */ struct dnschild { pid_t pid; int pipe; struct in_addr addr; void (*function)(void *, void *, struct in_addr *, const char *); void *boundto; void *data; struct dnschild *next; }; /* Reply generated by a child */ struct dnsresult { int success; struct in_addr addr; char name[256]; }; /* forward declarations */ static struct dnsresult _dns_lookup(const char *, struct in_addr *); static int _dns_startrequest(void *, void (*)(void *, void *, struct in_addr *, const char *), void *, struct in_addr *, const char *); /* Children */ static struct dnschild *dnschildren = 0; /* Function that looks up DNS request */ static struct dnsresult _dns_lookup(const char *name, struct in_addr *addr) { struct dnsresult res; struct hostent *info; pid_t pid; pid = getpid(); memset(&res, 0, sizeof(struct dnsresult)); if (name) { debug("%d: Looking up IP for '%s'", pid, name); info = gethostbyname(name); } else if (addr) { debug("%d: Lookup up name for '%s'", pid, inet_ntoa(*addr)); info = gethostbyaddr((char *)addr, sizeof(struct in_addr), AF_INET); } else { info = 0; } if (info) { res.success = 1; res.addr.s_addr = *((unsigned long *) info->h_addr); if (info->h_name) { strncpy(res.name, info->h_name, 255); res.name[255] = 0; } debug("%d: Got '%s' (%s)", pid, res.name, inet_ntoa(res.addr)); } else { debug("%d: No result", pid); } return res; } /* Function that starts a non-blocking DNS request. */ static int _dns_startrequest(void *boundto, void (*function)(void *, void *, struct in_addr *, const char *), void *data, struct in_addr *addr, const char *name) { struct dnschild *child; int p[2], wp[2]; /* Pipe where the result will be placed on success */ if (pipe(p)) { syscall_fail("pipe", "p", 0); function(boundto, data, 0, 0); return -1; } /* Pipe to indicate the child can go */ if (pipe(wp)) { close(p[0]); close(p[1]); syscall_fail("pipe", "wp", 0); function(boundto, data, 0, 0); return -1; } /* Allocate and place the child on the list now, to avoid race conditions */ child = (struct dnschild *)malloc(sizeof(struct dnschild)); child->pipe = p[0]; child->function = function; child->boundto = boundto; child->addr.s_addr = (addr ? addr->s_addr : 0); child->data = data; child->next = dnschildren; dnschildren = child; /* Fork */ child->pid = fork(); if (child->pid == -1) { /* Error */ syscall_fail("fork", 0, 0); dnschildren = child->next; close(p[1]); close(p[0]); close(wp[1]); close(wp[0]); free(child); function(boundto, data, 0, 0); return -1; } else if (child->pid) { /* Parent */ debug("New DNS process started, pid %d", child->pid); close(p[1]); close(wp[0]); /* Send go signal */ write(wp[1], "go", 2); close(wp[1]); return 0; } else { struct dnsresult result; char gobuf[2]; close(p[0]); close(wp[1]); /* Use ALARM to do timeouts */ signal(SIGALRM, SIG_DFL); alarm(g.dns_timeout); /* Wait for a go signal */ read(wp[0], gobuf, 2); close(wp[0]); /* Do the lookup */ result = _dns_lookup(name, addr); if (result.success) { /* Succeded, write to our parent and die */ write(p[1], (void *)&result, sizeof(struct dnsresult)); exit(0); } else { /* Didn't succeed */ exit(1); } } } /* Called to end a DNS request. 0 = Not handled, >0 = Ok, <0 = Error */ int dns_endrequest(pid_t pid, int status) { struct dnschild *lastchild, *child; struct dnsresult result; struct in_addr *addr; char *name; size_t len; /* Check to see whether this was a DNS child */ child = dnschildren; lastchild = 0; while (child) { if (child->pid == pid) break; lastchild = child; child = child->next; } if (!child) return 0; /* Remove it from the list */ if (lastchild) { lastchild->next = child->next; } else { dnschildren = child->next; } debug("%d: Was a DNS child, getting result", pid); /* Parameters to call function with */ name = 0; addr = 0; /* Read from pipe if child returned normally */ if (WIFEXITED(status)) { if (!WEXITSTATUS(status)) { len = read(child->pipe, (void *)&result, sizeof(struct dnsresult)); if (len != sizeof(struct dnsresult)) { syscall_fail("read", 0, 0); } else if (result.success) { debug("%d: Got result", pid); addr = &(result.addr); name = result.name; } else { debug("%d: DNS lookup failed", pid); } } else { debug("%d: DNS lookup returned %d", pid, WEXITSTATUS(status)); } } else if (WIFSIGNALED(status)) { debug("%d: DNS lookup terminated with signal %d", pid, WTERMSIG(status)); } else { debug("%d: DNS lookyp terminated abnormally", pid); } /* If DNS failed, but we were looking up an IP address, fill that */ if (!addr && child->addr.s_addr) { result.addr.s_addr = child->addr.s_addr; addr = &(result.addr); } /* If DNS failed but we have an IP, fill the name in with inet_ntoa() */ if (addr && (!name || !strlen(name))) { char *ip; ip = inet_ntoa(*addr); strncpy(result.name, ip, 255); result.name[255] = 0; debug("%d: Changed name to '%s'", pid, result.name); name = result.name; } /* Call the function */ child->function(child->boundto, child->data, addr, name); /* Clean up */ close(child->pipe); free(child); return 1; } /* Kill off any children associated with an ircproxy */ int dns_delall(void *b) { struct dnschild *c, *l; int numdone; l = 0; c = dnschildren; numdone = 0; while (c) { if (c->boundto == b) { struct dnschild *n; n = c->next; debug("Killing DNS process %d", c->pid); kill(c->pid, SIGKILL); close(c->pipe); free(c); if (l) { c = l->next = n; } else { c = dnschildren = n; } } else { l = c; c = c->next; } } return numdone; } /* Kill off ALL dns children */ void dns_flush(void) { struct dnschild *c; c = dnschildren; while (c) { struct dnschild *n; n = c->next; debug("Killing DNS process %d", c->pid); kill(c->pid, SIGKILL); close(c->pipe); free(c); c = n; } dnschildren = 0; } /* Returns the IP address of a hostname */ int dns_addrfromhost(void *boundto, void *data, const char *name, void (*function)(void *, void *, struct in_addr *, const char *)) { return _dns_startrequest(boundto, function, data, 0, name); } /* Returns the hostname of an IP address */ int dns_hostfromaddr(void *boundto, void *data, struct in_addr addr, void (*function)(void *, void *, struct in_addr *, const char *)) { return _dns_startrequest(boundto, function, data, &addr, 0); } /* Fill a sockaddr_in from a hostname or hostname:port combo thing */ int dns_filladdr(void *boundto, const char *name, const char *defaultport, int allowcolon, struct sockaddr_in *result, void (*function)(void *, void *, struct in_addr *, const char *), void *data) { char *addr, *port; int ret = 0; memset(result, 0, sizeof(struct sockaddr_in)); result->sin_family = AF_INET; if (defaultport) result->sin_port = dns_portfromserv(defaultport); addr = x_strdup(name); if (allowcolon) { port = strchr(addr, ':'); if (port) { *(port++) = 0; if (strlen(port)) result->sin_port = dns_portfromserv(port); } } ret = _dns_startrequest(boundto, function, data, 0, addr); free(addr); return ret; } /* Returns a network port number for a port as a string */ int dns_portfromserv(const char *serv) { struct servent *entry; entry = getservbyname(serv, "tcp"); return (entry ? entry->s_port : htons(atoi(serv))); } /* Returns a service name for a network port number */ char *dns_servfromport(int port) { struct servent *entry; char *str; entry = getservbyport(port, "tcp"); if (entry) { str = x_strdup(entry->s_name); } else { str = x_sprintf("%d", port); } return str; } dircproxy-1.0.5/src/dns.h0000664000175000017500000000277007410714173010761 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * dns.h * -- * @(#) $Id: dns.h,v 1.6 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #ifndef __DIRCPROXY_DNS_H #define __DIRCPROXY_DNS_H /* required includes */ #include #include #include /* handy defines */ #define DNS_FUNCTION(_FUNC) ((void (*)(void *, void *, struct in_addr *, \ const char *)) _FUNC) /* functions */ extern int dns_endrequest(pid_t, int); extern int dns_delall(void *); extern void dns_flush(void); extern int dns_addrfromhost(void *, void *, const char *, void (*)(void *, void *, struct in_addr *, const char *)); extern int dns_hostfromaddr(void *, void *, struct in_addr, void (*)(void *, void *, struct in_addr *, const char *)); extern int dns_filladdr(void *, const char *, const char *, int, struct sockaddr_in *, void (*)(void *, void *, struct in_addr *, const char *), void *); extern int dns_portfromserv(const char *); extern char *dns_servfromport(int); #endif /* __DIRCPROXY_DNS_H */ dircproxy-1.0.5/src/net.c0000664000175000017500000005260707414374013010761 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * net.c * - handy functions to make/close sockets * - handy send() wrapper that uses printf() like format * - socket data buffering * - non-blocking sends * - functions to retrieve data from buffers up to delimiters (newlines?) * - main poll()/select() function * -- * @(#) $Id: net.c,v 1.15 2002/01/01 17:55:23 scott Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_POLL_H # include #else /* HAVE_POLL_H */ # ifdef HAVE_SYS_POLL_H # include # endif /* HAVE_SYS_POLL_H */ #endif /* HAVE_POLL_H */ #include "sprintf.h" #include "net.h" /* Sanity check */ #ifndef HAVE_POLL # ifndef HAVE_SELECT # error "unable to compile, no poll() or select() function" # endif /* HAVE_SELECT */ #endif /* HAVE_POLL */ /* Structure to hold a socket buffer */ struct sockbuff { void *data; size_t linelen; size_t len; int mode; struct sockbuff *next; }; /* Structure to hold the data we keep on sockets */ struct sockinfo { int sock; int closed; struct sockbuff *in_buff, *in_buff_last; struct sockbuff *out_buff, *out_buff_last; int type; void *info; void (*activity_func)(void *, int); void (*error_func)(void *, int, int); long throtbytes; long throtperiod; time_t throtlast; long throtamt; struct sockinfo *next; }; /* forward declarations */ static struct sockinfo *_net_fetch(int); static void _net_free(struct sockinfo *); static void _net_freebuffers(struct sockbuff *); static void _net_expunge(void); static int _net_buffer(struct sockinfo *, int, int, void *, int); static int _net_unbuffer(struct sockinfo *, int, void *, int); /* Types of buffer */ #define SB_IN 0x01 #define SB_OUT 0x02 #define SB_PRI 0x03 /* Modes of buffer */ #define SM_RAW 0x01 #define SM_PACK 0x02 /* Sockets */ static struct sockinfo *sockets = 0; /* Make a non-blocking socket */ int net_socket(void) { int sock, param; /* Make the socket */ sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == -1) { syscall_fail("socket", 0, 0); return -1; } /* Allow re-use of address */ param = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)¶m, sizeof(int))) { syscall_fail("setsockopt", "SO_REUSEADDR", 0); close(sock); return -1; } net_create(&sock); return sock; } /* Make a socket keep_alive */ void net_keepalive(int sock) { struct sockinfo *sockinfo; sockinfo = _net_fetch(sock); if (sockinfo) { int param; param = 1; if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)¶m, sizeof(int))) syscall_fail("setsockopt", "SO_KEEPALIVE", 0); } else { syscall_fail("net_keepalive", 0, "bad socket provided"); } } /* Create a sockinfo structure */ void net_create(int *sock) { struct sockinfo *sockinfo; int flags; /* Get socket flags */ if ((flags = fcntl(*sock, F_GETFL)) == -1) { syscall_fail("fcntl", "F_GETFL", 0); close(*sock); *sock = -1; return; } /* Add non-blocking to the flags and set them */ flags |= O_NONBLOCK; if (fcntl(*sock, F_SETFL, flags)) { syscall_fail("fcntl", "F_SETFL", 0); close(*sock); *sock = -1; return; } /* Make an information structure and add it to our lists */ sockinfo = (struct sockinfo *)malloc(sizeof(struct sockinfo)); memset(sockinfo, 0, sizeof(struct sockinfo)); sockinfo->sock = *sock; if (sockets) { struct sockinfo *ss; ss = sockets; while (ss->next) ss = ss->next; ss->next = sockinfo; } else { sockets = sockinfo; } } /* Fetch a sockinfo structure for a socket */ static struct sockinfo *_net_fetch(int sock) { struct sockinfo *s; s = sockets; while (s) { if (s->sock == sock) return s; s = s->next; } return 0; } /* Close a socket and free its data */ int net_close(int *sock) { struct sockinfo *sockinfo; sockinfo = _net_fetch(*sock); if (sockinfo) { sockinfo->closed = 1; *sock = -1; return 0; } else { syscall_fail("net_close", 0, "bad socket provided"); return -1; } } /* Free a sockinfo structure and close its socket */ static void _net_free(struct sockinfo *s) { if (s->in_buff) _net_freebuffers(s->in_buff); if (s->out_buff) _net_freebuffers(s->out_buff); close(s->sock); free(s); } /* Free a socket buffer chain */ static void _net_freebuffers(struct sockbuff *b) { while (b) { struct sockbuff *n; n = b->next; free(b->data); free(b); b = n; } } /* Close all the sockets and allow them a short time to send their data */ int net_closeall(void) { struct sockinfo *i; time_t until; int ns; debug("Shutting down all sockets"); /* Don't take any longer than this to do this work */ until = time(0) + NET_LINGER_TIME; /* Indicate all sockets as closed, release whatever throttle is upon them (to speed it up) and prevent any events from doing anything except closing the socket */ i = sockets; while (i) { i->closed = 1; i->throtbytes = i->throtamt = i->throtperiod = 0; i->throtlast = 0; i->activity_func = 0; i->error_func = 0; i = i->next; } /* Poll sockets */ ns = -1; while (time(0) < until) if (!(ns = net_poll())) break; if (ns > 0) { debug("%d sockets didn't send their data in time"); } else if (ns < 0) { debug("Unexpected error occurred, oh well"); } else { debug("All sockets cleaned up"); } return ns; } /* Free all the sockets */ int net_flush(void) { struct sockinfo *i; i = sockets; while (i) { struct sockinfo *n; n = i->next; if (!i->closed) debug("Flushing undead %01x socket %d", i->type, i->sock); _net_free(i); i = n; } sockets = 0; /* Free up the ufds buffer */ net_poll(); return 0; } /* Expunge closed sockets */ static void _net_expunge(void) { struct sockinfo *s, *l; l = 0; s = sockets; while (s) { if (s->closed && ((s->type != SOCK_NORMAL) || !s->out_buff)) { struct sockinfo *n; n = s->next; _net_free(s); if (l) { s = l->next = n; } else { s = sockets = n; } } else { l = s; s = s->next; } } } /* Amend a socket's hooks */ int net_hook(int sock, int type, void *info, void (*activity_func)(void *, int), void (*error_func)(void *, int, int)) { struct sockinfo *sockinfo; sockinfo = _net_fetch(sock); if (sockinfo) { sockinfo->type = type; sockinfo->info = info; sockinfo->activity_func = activity_func; sockinfo->error_func = error_func; return 0; } else { syscall_fail("net_hook", 0, "bad socket provided"); return -1; } } /* Amend a socket's throttle attributes */ int net_throttle(int sock, long bytes, long period) { struct sockinfo *sockinfo; sockinfo = _net_fetch(sock); if (sockinfo) { sockinfo->throtbytes = bytes; sockinfo->throtperiod = period; sockinfo->throtlast = time(0); sockinfo->throtamt = 0; return 0; } else { syscall_fail("net_throttle", 0, "bad socket provided"); return -1; } } /* Add lined data to the output socket (using formatting) */ int net_send(int sock, const char *message, ...) { struct sockinfo *sockinfo; sockinfo = _net_fetch(sock); if (sockinfo) { int ret = 0; va_list ap; char *msg; va_start(ap, message); msg = x_vsprintf(message, ap); va_end(ap); ret = _net_buffer(sockinfo, SB_OUT, SM_PACK, msg, strlen(msg)); free(msg); return ret; } else { syscall_fail("net_send", 0, "bad socket provided"); return -1; } } /* Add lined data to the priority output socket (using formatting) */ int net_sendurgent(int sock, const char *message, ...) { struct sockinfo *sockinfo; sockinfo = _net_fetch(sock); if (sockinfo) { int ret = 0; va_list ap; char *msg; va_start(ap, message); msg = x_vsprintf(message, ap); va_end(ap); ret = _net_buffer(sockinfo, SB_PRI, SM_PACK, msg, strlen(msg)); free(msg); return ret; } else { syscall_fail("net_sendurgent", 0, "bad socket provided"); return -1; } } /* Add raw data to the output socket */ int net_queue(int sock, void *data, int len) { struct sockinfo *sockinfo; sockinfo = _net_fetch(sock); if (sockinfo) { return _net_buffer(sockinfo, SB_OUT, SM_RAW, data, len); } else { syscall_fail("net_queue", 0, "bad socket provided"); return -1; } } /* Add data to a socket's buffer */ static int _net_buffer(struct sockinfo *s, int buff, int mode, void *data, int len) { struct sockbuff **l; /* Priority stuff just gets stuck on the front */ if (buff == SB_PRI) { struct sockbuff *b; b = (struct sockbuff *)malloc(sizeof(struct sockbuff)); if (!b) return -1; memset(b, 0, sizeof(struct sockbuff)); b->mode = SB_OUT; b->data = malloc(len); if (!b->data) { free(b); return -1; } memcpy(b->data, data, len); b->len = len; /* We can't put it directly on the front if there's an incomplete line buffer on the front */ if (s->out_buff && (s->out_buff->mode == SM_PACK) && (s->out_buff->linelen > s->out_buff->len)) { b->next = s->out_buff->next; s->out_buff->next = b; if (!b->next) s->out_buff_last = b; } else { b->next = s->out_buff; s->out_buff = b; if (!s->out_buff_last) s->out_buff_last = b; } return 0; } l = &(buff == SB_IN ? s->in_buff_last : s->out_buff_last); /* Check whether we can just add to the existing buffer */ if ((mode == SM_RAW) && *l && ((*l)->mode == mode)) { (*l)->data = realloc((*l)->data, (*l)->len + len); if (!(*l)->data) return -1; memcpy((*l)->data + (*l)->len, data, len); (*l)->len += len; (*l)->linelen += len; } else { struct sockbuff *b; /* Allocate new buffer */ b = (struct sockbuff *)malloc(sizeof(struct sockbuff)); if (!b) return 1; memset(b, 0, sizeof(struct sockbuff)); b->mode = mode; b->data = malloc(len); if (!b->data) { free(b); return -1; } memcpy(b->data, data, len); b->len = len; b->linelen = len; if (buff == SB_IN) { if (s->in_buff) { s->in_buff_last->next = b; } else { s->in_buff = b; } s->in_buff_last = b; } else { if (s->out_buff) { s->out_buff_last->next = b; } else { s->out_buff = b; } s->out_buff_last = b; } } return 0; } /* Get data from a socket up unto a delimiter */ int net_gets(int sock, char **dest, const char *delim) { struct sockinfo *sockinfo; sockinfo = _net_fetch(sock); if (sockinfo) { if (sockinfo->in_buff) { int bufflen, retlen, getlen; char *buff; /* Convert it into a string to make things easier */ bufflen = sockinfo->in_buff->len; buff = (char *)malloc(bufflen + 1); memcpy(buff, sockinfo->in_buff->data, bufflen); buff[bufflen] = 0; /* Find out how many characters to get and how many to return */ retlen = strcspn(buff, delim); getlen = retlen + strspn(buff + retlen, delim); free(buff); /* Make sure there was a delimiter, then get the data */ if (retlen < bufflen) { void *get; get = malloc(getlen); if (!_net_unbuffer(sockinfo, SB_IN, get, getlen)) { if (retlen) { *dest = (char *)malloc(retlen + 1); memcpy(*dest, get, retlen); (*dest)[retlen] = 0; } free(get); return retlen; } free(get); } } return 0; } else { syscall_fail("net_gets", 0, "bad socket provided"); return -1; } } /* Get an amount of data from a socket */ int net_read(int sock, void *dest, int len) { struct sockinfo *sockinfo; sockinfo = _net_fetch(sock); if (sockinfo) { if (sockinfo->in_buff) { void *get; /* Omitting len means we want to know how much data is in the buffer */ if (!len) return sockinfo->in_buff->len; get = malloc(len); if (!_net_unbuffer(sockinfo, SB_IN, get, len)) { memcpy(dest, get, len); free(get); return len; } free(get); } return 0; } else { syscall_fail("net_gets", 0, "bad socket provided"); return -1; } } /* Remove data from the front of a buffer */ static int _net_unbuffer(struct sockinfo *s, int buff, void *data, int len) { struct sockbuff *b; b = (buff == SB_IN ? s->in_buff : s->out_buff); /* Check there's enough data to unbuffer */ if (b->len < len) return -1; /* Store data if we are given a pointer to somewhere to put it */ if (data) memcpy(data, b->data, len); /* Check whether there's any data left */ b->len -= len; if (b->len) { void *tmp; /* Yes, shift it all up */ tmp = malloc(b->len); if (!tmp) return -1; memcpy(tmp, b->data + len, b->len); free(b->data); b->data = tmp; } else { struct sockbuff *n; /* No, free up this buffer and position the next one */ n = b->next; free(b->data); free(b); if (buff == SB_IN) { s->in_buff = n; if (!s->in_buff) s->in_buff_last = 0; } else { s->out_buff = n; if (!s->out_buff) s->out_buff_last = 0; } } return 0; } /* Poll sockets for activity, return number of sockets or -1 if error */ int net_poll(void) { #ifdef HAVE_POLL static struct pollfd *ufds = 0; static int m_ns = 0; #else /* HAVE_POLL */ # ifdef HAVE_SELECT fd_set readset, writeset; struct timeval timeout; int hs; # endif /* HAVE_SELECT */ #endif /* HAVE_POLL */ struct sockinfo *s; int ns, nr, sn; time_t now; char *func; #ifndef HAVE_POLL # ifdef HAVE_SELECT FD_ZERO(&readset); FD_ZERO(&writeset); hs = 0; # endif /* HAVE_SELECT */ #endif /* HAVE_POLL */ nr = ns = 0; now = time(0); /* Really close closed sockets */ _net_expunge(); /* Count the number of sockets */ s = sockets; while (s) { ns++; s = s->next; } #ifdef HAVE_POLL /* See if its changed */ if (ns != m_ns) { if (ns) { ufds = (struct pollfd *)realloc(ufds, sizeof(struct pollfd) * (ns + 1)); } else { free(ufds); ufds = 0; } m_ns = ns; } #endif /* No sockets to poll */ if (!ns) return 0; /* Fill the structures */ sn = 0; s = sockets; while (s) { /* If its been throtperiod since we last reset the counter, then reset it again. */ if (s->throtperiod && ((now - s->throtlast) >= s->throtperiod)) { s->throtlast = now; s->throtamt = 0; } #ifdef HAVE_POLL ufds[sn].fd = s->sock; ufds[sn].events = POLLIN; ufds[sn].revents = 0; #else /* HAVE_POLL */ # ifdef HAVE_SELECT hs = (hs < s->sock ? s->sock : hs); FD_SET(s->sock, &readset); # endif /* HAVE_SELECT */ #endif /* HAVE_POLL */ /* Only poll for writing if we're connecting or we're not listening and there's data to write and we're either not throttling this socket or we've sent less then the throttle (period stuff is done above) */ #ifdef HAVE_POLL if (s->type == SOCK_CONNECTING) { ufds[sn].events |= POLLOUT; } else if ((s->type != SOCK_LISTENING) && s->out_buff && (!s->throtbytes || (s->throtamt < s->throtbytes))) { ufds[sn].events |= POLLOUT; } #else /* HAVE_POLL */ # ifdef HAVE_SELECT if (s->type == SOCK_CONNECTING) { FD_SET(s->sock, &writeset); } else if ((s->type != SOCK_LISTENING) && s->out_buff && (!s->throtbytes || (s->throtamt < s->throtbytes))) { FD_SET(s->sock, &writeset); } # endif /* HAVE_SELECT */ #endif /* HAVE_POLL */ sn++; s = s->next; } #ifdef HAVE_POLL /* Do the poll itself */ nr = poll(ufds, ns, 1000); func = "poll"; #else /* HAVE_POLL */ # ifdef HAVE_SELECT /* Do the select itself */ timeout.tv_sec = 1; timeout.tv_usec = 0; nr = select(hs + 1, &readset, &writeset, 0, &timeout); func = "select"; # endif /* HAVE_SELECT */ #endif /* HAVE_POLL */ /* Check for errors or non-activity */ if (nr == -1) { if ((errno != EINTR) && (errno != EAGAIN)) { #ifdef HAVE_POLL free(ufds); ufds = 0; m_ns = 0; #endif /* HAVE_POLL */ syscall_fail(func, 0, 0); return -1; } } /* Check for activity */ sn = 0; s = sockets; while (s) { /* Make sure we don't check new sockets yet */ if (sn >= ns) break; if (!s->closed || ((s->type == SOCK_NORMAL) && s->out_buff)) { int can_read, can_write; #ifdef HAVE_POLL /* Read = any revent that isn't POLLOUT */ can_read = (ufds[sn].revents & ~POLLOUT ? 1 : 0); can_write = (ufds[sn].revents & POLLOUT ? 1 : 0); #else /* HAVE_POLL */ # ifdef HAVE_SELECT can_read = (FD_ISSET(s->sock, &readset) ? 1 : 0); can_write = (FD_ISSET(s->sock, &writeset) ? 1 : 0); # endif /* HAVE_SELECT */ #endif /* HAVE_POLL */ if (s->type == SOCK_CONNECTING) { if (can_read || can_write) { int error, len; /* If there's an error condition on the socket then the connect() failed, otherwise it worked */ len = sizeof(int); if (getsockopt(s->sock, SOL_SOCKET, SO_ERROR, (void *)&error, &len) < 0) { if (s->error_func) { s->error_func(s->info, s->sock, 1); } else { s->closed = 1; } } else if (error) { if (s->error_func) { s->error_func(s->info, s->sock, 1); } else { s->closed = 1; } } else { if (s->activity_func) { s->activity_func(s->info, s->sock); } else { s->closed = 1; } } } } else if (s->type == SOCK_LISTENING) { /* No error conditions for listening sockets */ if (can_read) { debug("Got new connection"); if (s->activity_func) s->activity_func(s->info, s->sock); } } else { /* If we can read from the socket, suck in all the data there is to keep the buffer size on the IRC server down. This can result in the call of the error function. */ if (can_read) { char buff[NET_BLOCK_SIZE]; int br, rr; br = 0; while ((rr = read(s->sock, buff, NET_BLOCK_SIZE)) > 0) { _net_buffer(s, SB_IN, SM_RAW, buff, rr); br += rr; } /* Some kind of error :( */ if (rr == -1) { if ((errno != EINTR) && (errno != EAGAIN)) { int baderror; if (errno != ECONNRESET) { syscall_fail("read", 0, 0); baderror = 1; } else { baderror = 0; } /* Make sure that it really closes */ _net_freebuffers(s->out_buff); s->out_buff = 0; if (!s->closed && s->error_func) { s->error_func(s->info, s->sock, baderror); } else { s->closed = 1; } } } /* Didn't read any bytes (socket closed) */ if (!br && (rr != -1)) { /* Make sure that it really closes */ _net_freebuffers(s->out_buff); s->out_buff = 0; if (!s->closed && s->error_func) { s->error_func(s->info, s->sock, 0); } else { s->closed = 1; } } } /* If we can write data to the socket write any that we have lying around, keeping in mind throttling of course */ if ((!s->closed || s->out_buff) && can_write) { while (s->out_buff) { int bl, wl; bl = (s->out_buff->len > NET_BLOCK_SIZE ? NET_BLOCK_SIZE : s->out_buff->len); if (s->throtbytes) { int tl; if (s->throtamt >= s->throtbytes) break; tl = s->throtbytes - s->throtamt; bl = (bl > (s->throtbytes - s->throtamt) ? (s->throtbytes - s->throtamt) : bl); } wl = write(s->sock, s->out_buff->data, bl); if (wl == -1) { /* Don't actually detect errors or closure using write, it'll poll for HUP or IN if that happens */ if ((errno != EAGAIN) && (errno != EINTR) && (errno != EPIPE)) syscall_fail("write", 0, 0); break; } else if (!wl) { /* Wrote nothing, socket is full */ break; } else { /* Get rid of that data from the buffer */ _net_unbuffer(s, SB_OUT, 0, wl); if (s->throtbytes) s->throtamt += wl; } } } /* If there's incoming data, call the activity function */ if (!s->closed && s->in_buff && s->activity_func) s->activity_func(s->info, s->sock); } } sn++; s = s->next; } return ns; } dircproxy-1.0.5/src/net.h0000664000175000017500000000245007410714173010756 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * net.h.h * -- * @(#) $Id: net.h,v 1.8 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #ifndef __DIRCPROXY_NET_H #define __DIRCPROXY_NET_H /* Socket types */ #define SOCK_NORMAL 0x00 #define SOCK_CONNECTING 0x01 #define SOCK_LISTENING 0x02 /* handy defines */ #define ACTIVITY_FUNCTION(_FUNC) ((void (*)(void *, int)) (_FUNC)) #define ERROR_FUNCTION(_FUNC) ((void (*)(void *, int, int)) (_FUNC)) /* functions */ extern int net_socket(void); extern void net_create(int *); extern void net_keepalive(int); extern int net_close(int *); extern int net_closeall(void); extern int net_flush(void); extern int net_hook(int, int, void *, void(*)(void *, int), void(*)(void *, int, int)); extern int net_throttle(int, long, long); extern int net_send(int, const char *, ...); extern int net_sendurgent(int, const char *, ...); extern int net_queue(int, void *, int); extern int net_gets(int, char **, const char *); extern int net_read(int, void *, int); extern int net_poll(void); #endif /* __DIRCPROXY_NET_H */ dircproxy-1.0.5/src/match.c0000664000175000017500000000300107410714173011250 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * match.c * - wildcard matching * * I actually figured this out and wrote it myself. Unforunately * its a lot smaller than anyone elses that I know of, which worries * me slightly :) - But it seems to work * -- * @(#) $Id: match.c,v 1.6 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #include #include #include #include "sprintf.h" #include "stringex.h" #include "match.h" /* Checks whether a string matches a wildcard string. 1 = yes, 0 = no */ int strmatch(const char *str, const char *mask) { int instar; instar = 0; while (*str) { if (*mask == '*') { instar = 1; mask++; } if ((*mask == *str) || (*mask == '?')) { if (instar && strmatch(str, mask)) return 1; } else { if (!instar) return 0; } str++; if (!instar) { mask++; if (!(*mask) && *str) return 0; } } return !(*mask && (*mask != '*')); } /* Case insentively matches against wildcards */ int strcasematch(const char *str, const char *mask) { char *newstr, *newmask; int ret; newstr = strlwr(x_strdup(str)); newmask = strlwr(x_strdup(mask)); ret = strmatch(newstr, newmask); free(newstr); free(newmask); return ret; } dircproxy-1.0.5/src/match.h0000664000175000017500000000111107410714173011255 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * match.h * -- * @(#) $Id: match.h,v 1.3 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #ifndef __DIRCPROXY_MATCH_H #define __DIRCPROXY_MATCH_H /* functions */ extern int strmatch(const char *, const char *); extern int strcasematch(const char *, const char *); #endif /* __DIRCPROXY_MATCH_H */ dircproxy-1.0.5/src/stringex.c0000664000175000017500000000145207410714173012027 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * stringex.c * - Case conversion functions * -- * @(#) $Id: stringex.c,v 1.3 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #include #include #include "stringex.h" /* Changes the case of a string to lowercase */ char *strlwr(char *str) { char *c; c = str; while (*c) { *c = tolower(*c); c++; } return str; } /* Changes the case of a string to uppercase */ char *strupr(char *str) { char *c; c = str; while (*c) { *c = toupper(*c); c++; } return str; } dircproxy-1.0.5/src/stringex.h0000664000175000017500000000122107410714173012026 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * stringex.h * -- * @(#) $Id: stringex.h,v 1.3 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #ifndef __DIRCPROXY_STRINGEX_H #define __DIRCPROXY_STRINGEX_H /* structure to hold a list of strings */ struct strlist { char *str; struct strlist *next; }; /* functions */ extern char *strlwr(char *); extern char *strupr(char *); #endif /* __DIRCPROXY_STRINGEX_H */ dircproxy-1.0.5/src/sprintf.c0000664000175000017500000003652107410714173011656 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * sprintf.c * - various ways of doing allocating sprintf() functions to void b/o * - wrapper around strdup() * -- * @(#) $Id: sprintf.c,v 1.11 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #include #include #include #include #include #include #include "stringex.h" #include "sprintf.h" /* The sprintf() version is just a wrapper around whatever vsprintf() we decide to implement. */ #ifdef DEBUG_MEMORY char *xx_sprintf(char *file, int line, const char *format, ...) { #else /* DEBUG_MEMORY */ char *x_sprintf(const char *format, ...) { #endif /* DEBUG_MEMORY */ va_list ap; char *ret; va_start(ap, format); #ifdef DEBUG_MEMORY ret = xx_vsprintf(file, line, format, ap); #else /* DEBUG_MEMORY */ ret = x_vsprintf(format, ap); #endif /* DEBUG_MEMORY */ va_end(ap); return ret; } #ifdef HAVE_VASPRINTF /* Wrap around vasprintf() which exists in BSD. We can't memdebug() this, so its disabled by configure.in if DEBUG_MEMORY is enabled. */ char *x_vsprintf(const char *format, va_list ap) { char *str; str = 0; vasprintf(&str, format, ap); return str; } #else /* HAVE_VASPRINTF */ # ifdef HAVE_VSNPRINTF /* Does vsnprintf()s until its not truncated and returns the string. We can't memdebug this, so its disabled by configure.in if DEBUG_MEMORY is enabled. */ char *x_vsprintf(const char *format, va_list ap) { int buffsz, ret; char *buff; buff = 0; buffsz = 0; do { buffsz += 64; buff = (char *)realloc(buff, buffsz + 1); ret = vsnprintf(buff, buffsz, format, ap); } while ((ret == -1) || (ret >= buffsz)); return buff; } # else /* HAVE_VSNPRINTF */ /* These routines are based on those found in the Linux Kernel. I've * rewritten them quite a bit (read completely) since then. * * Copyright (C) 1991, 1992 Linus Torvalds */ /* Makes a string representation of a number which can have different lengths, bases and precisions etc. */ #ifdef DEBUG_MEMORY static char *_x_makenum(char *file, int line, long num, int base, int minsize, int mindigits, char padchar, char signchar) { #else /* DEBUG_MEMORY */ static char *_x_makenum(long num, int base, int minsize, int mindigits, char padchar, char signchar) { #endif /* DEBUG_MEMORY */ static char *digits = "0123456789abcdefghijklmnopqrstuvwxyz"; unsigned long newstrlen; char *newstr; int i, j; if ((base < 2) || (base > 36) || (minsize < 0) || (mindigits < 0)) { return NULL; } #ifdef DEBUG_MEMORY newstr = xx_strdup(file, line, ""); #else /* DEBUG_MEMORY */ newstr = x_strdup(""); #endif /* DEBUG_MEMORY */ newstrlen = 1; if (signchar) { if (num < 0) { signchar = '-'; num = -num; } } if (signchar == ' ') { signchar = 0; } if (!num) { #ifdef DEBUG_MEMORY newstr = (char *)mem_realloc(newstr, newstrlen + 1, file, line); #else /* DEBUG_MEMORY */ newstr = (char *)realloc(newstr, newstrlen + 1); #endif /* DEBUG_MEMORY */ strcpy(newstr + newstrlen - 1, "0"); newstrlen++; } else { while (num) { #ifdef DEBUG_MEMORY newstr = (char *)mem_realloc(newstr, newstrlen + 1, file, line); #else /* DEBUG_MEMORY */ newstr = (char *)realloc(newstr, newstrlen + 1); #endif /* DEBUG_MEMORY */ newstr[newstrlen - 1] = digits[((unsigned long) num) % base]; newstr[newstrlen] = 0; newstrlen++; num = ((unsigned long) num) / base; } } if (strlen(newstr) < mindigits) { mindigits -= strlen(newstr); while (mindigits--) { #ifdef DEBUG_MEMORY newstr = (char *)mem_realloc(newstr, newstrlen + 1, file, line); #else /* DEBUG_MEMORY */ newstr = (char *)realloc(newstr, newstrlen + 1); #endif /* DEBUG_MEMORY */ strcpy(newstr + newstrlen - 1, "0"); newstrlen++; } } if (signchar && (padchar != '0')) { #ifdef DEBUG_MEMORY newstr = (char *)mem_realloc(newstr, newstrlen + 1, file, line); #else /* DEBUG_MEMORY */ newstr = (char *)realloc(newstr, newstrlen + 1); #endif /* DEBUG_MEMORY */ newstr[newstrlen - 1] = signchar; newstr[newstrlen] = 0; newstrlen++; signchar = 0; } if ((strlen(newstr) < minsize) && padchar) { minsize -= strlen(newstr); while (minsize--) { #ifdef DEBUG_MEMORY newstr = (char *)mem_realloc(newstr, newstrlen + 1, file, line); #else /* DEBUG_MEMORY */ newstr = (char *)realloc(newstr, newstrlen + 1); #endif /* DEBUG_MEMORY */ newstr[newstrlen - 1] = padchar; newstr[newstrlen] = 0; newstrlen++; } if (signchar) { newstr[strlen(newstr)-1] = signchar; signchar = 0; } } if (signchar) { #ifdef DEBUG_MEMORY newstr = (char *)mem_realloc(newstr, newstrlen + 1, file, line); #else /* DEBUG_MEMORY */ newstr = (char *)realloc(newstr, newstrlen + 1); #endif /* DEBUG_MEMORY */ newstr[newstrlen - 1] = signchar; newstr[newstrlen] = 0; newstrlen++; } i = strlen(newstr)-1; j = 0; while (i > j) { char tmpchar; tmpchar = newstr[i]; newstr[i] = newstr[j]; newstr[j] = tmpchar; i--; j++; } if ((strlen(newstr) < minsize) && !padchar) { char *tmpstr; i = minsize - strlen(newstr); #ifdef DEBUG_MEMORY tmpstr = (char *)mem_malloc(i + 1, file, line); #else /* DEBUG_MEMORY */ tmpstr = (char *)malloc(i + 1); #endif /* DEBUG_MEMORY */ tmpstr[i--] = 0; while (i >= 0) { tmpstr[i--] = ' '; } #ifdef DEBUG_MEMORY tmpstr = (char *)mem_realloc(tmpstr, strlen(tmpstr) + strlen(newstr) + 1, file, line); #else /* DEBUG_MEMORY */ tmpstr = (char *)realloc(tmpstr, strlen(tmpstr) + strlen(newstr) + 1); #endif /* DEBUG_MEMORY */ strcpy(tmpstr + strlen(tmpstr), newstr); #ifdef DEBUG_MEMORY mem_realloc(newstr, 0, file, line); #else /* DEBUG_MEMORY */ free(newstr); #endif /* DEBUG_MEMORY */ newstr = tmpstr; } return newstr; } /* Basically vasprintf, except it doesn't do floating point or pointers */ #ifdef DEBUG_MEMORY char *xx_vsprintf(char *file, int line, const char *format, va_list ap) { #else /* DEBUG_MEMORY */ char *x_vsprintf(const char *format, va_list ap) { #endif /* DEBUG_MEMORY */ char *newdest, *formatcpy, *formatpos, padding, signchar, qualifier; int width, prec, base, special, len, caps; unsigned long newdestlen; long num; #ifdef DEBUG_MEMORY newdest = xx_strdup(file, line, ""); #else /* DEBUG_MEMORY */ newdest = x_strdup(""); #endif /* DEBUG_MEMORY */ newdestlen = 1; #ifdef DEBUG_MEMORY formatpos = formatcpy = xx_strdup(file, line, format); #else /* DEBUG_MEMORY */ formatpos = formatcpy = x_strdup(format); #endif /* DEBUG_MEMORY */ while (*formatpos) { if (*formatpos == '%') { padding = signchar = ' '; qualifier = 0; width = prec = special = caps = 0; base = 10; formatpos++; while (1) { if (*formatpos == '-') { padding = 0; } else if (*formatpos == '+') { signchar = '+'; } else if (*formatpos == ' ') { signchar = (signchar == '+') ? '+' : ' '; } else if (*formatpos == '#') { special = 1; } else { break; } formatpos++; } if (*formatpos == '*') { width = va_arg(ap, int); if (width < 0) { width =- width; padding = 0; } formatpos++; } else { if (*formatpos == '0') { padding = '0'; formatpos++; } while (isdigit(*formatpos)) { width *= 10; width += (*formatpos - '0'); formatpos++; } } if (*formatpos == '.') { formatpos++; if (*formatpos == '*') { prec = abs(va_arg(ap, int)); formatpos++; } else { while (isdigit(*formatpos)) { prec *= 10; prec += (*formatpos - '0'); formatpos++; } } } if ((*formatpos == 'h') || (*formatpos == 'l')) { qualifier = *formatpos; formatpos++; } if (*formatpos == 'c') { if (padding) { while (--width > 0) { #ifdef DEBUG_MEMORY newdest = (char *)mem_realloc(newdest, newdestlen + 1, file, line); #else /* DEBUG_MEMORY */ newdest = (char *)realloc(newdest, newdestlen + 1); #endif /* DEBUG_MEMORY */ newdest[newdestlen - 1] = padding; newdest[newdestlen] = 0; newdestlen++; } } #ifdef DEBUG_MEMORY newdest = (char *)mem_realloc(newdest, newdestlen + 1, file, line); #else /* DEBUG_MEMORY */ newdest = (char *)realloc(newdest, newdestlen + 1); #endif /* DEBUG_MEMORY */ newdest[newdestlen - 1] = va_arg(ap, unsigned char); newdest[newdestlen] = 0; newdestlen++; if (!padding) { while (--width > 0) { #ifdef DEBUG_MEMORY newdest = (char *)mem_realloc(newdest, newdestlen + 1, file, line); #else /* DEBUG_MEMORY */ newdest = (char *)realloc(newdest, newdestlen + 1); #endif /* DEBUG_MEMORY */ newdest[newdestlen - 1] = padding; newdest[newdestlen] = 0; newdestlen++; } } } else if (*formatpos == 's') { char *tmpstr; #ifdef DEBUG_MEMORY tmpstr = xx_strdup(file, line, va_arg(ap, char *)); #else /* DEBUG_MEMORY */ tmpstr = x_strdup(va_arg(ap, char *)); #endif /* DEBUG_MEMORY */ len = (prec && (prec < strlen(tmpstr))) ? prec : strlen(tmpstr); if (padding) { while (--width > len) { #ifdef DEBUG_MEMORY newdest = (char *)mem_realloc(newdest, newdestlen + 1, file, line); #else /* DEBUG_MEMORY */ newdest = (char *)realloc(newdest, newdestlen + 1); #endif /* DEBUG_MEMORY */ newdest[newdestlen - 1] = padding; newdest[newdestlen] = 0; newdestlen++; } } #ifdef DEBUG_MEMORY newdest = (char *)mem_realloc(newdest, newdestlen + len, file, line); #else /* DEBUG_MEMORY */ newdest = (char *)realloc(newdest, newdestlen + len); #endif /* DEBUG_MEMORY */ strncpy(newdest + newdestlen - 1, tmpstr, len); newdestlen += len; newdest[newdestlen - 1] = 0; #ifdef DEBUG_MEMORY mem_realloc(tmpstr, 0, file, line); #else /* DEBUG_MEMORY */ free(tmpstr); #endif /* DEBUG_MEMORY */ if (!padding) { while (--width > len) { #ifdef DEBUG_MEMORY newdest = (char *)mem_realloc(newdest, newdestlen + 1, file, line); #else /* DEBUG_MEMORY */ newdest = (char *)realloc(newdest, newdestlen + 1); #endif /* DEBUG_MEMORY */ newdest[newdestlen - 1] = padding; newdest[newdestlen] = 0; newdestlen++; } } } else if (strchr("oXxdiu", *formatpos) != NULL) { char *tmpstr; if (*formatpos == 'o') { base = 8; if (signchar) { signchar = 0; } if (special) { #ifdef DEBUG_MEMORY newdest = (char *)mem_realloc(newdest, newdestlen + 1, file, line); #else /* DEBUG_MEMORY */ newdest = (char *)realloc(newdest, newdestlen + 1); #endif /* DEBUG_MEMORY */ strcpy(newdest + newdestlen - 1, "0"); newdestlen++; } } else if (*formatpos == 'X') { base = 16; caps = 1; if (signchar) { signchar = 0; } if (special) { #ifdef DEBUG_MEMORY newdest = (char *)mem_realloc(newdest, newdestlen + 1, file, line); #else /* DEBUG_MEMORY */ newdest = (char *)realloc(newdest, newdestlen + 1); #endif /* DEBUG_MEMORY */ strcpy(newdest + newdestlen - 1, "0"); newdestlen++; } } else if (*formatpos == 'x') { base = 16; if (signchar) { signchar = 0; } if (special) { #ifdef DEBUG_MEMORY newdest = (char *)mem_realloc(newdest, newdestlen + 2, file, line); #else /* DEBUG_MEMORY */ newdest = (char *)realloc(newdest, newdestlen + 2); #endif /* DEBUG_MEMORY */ strcpy(newdest + newdestlen - 1, "0x"); newdestlen += 2; } } else if (*formatpos == 'i') { if (!signchar) { signchar = ' '; } } else if (*formatpos == 'u') { if (signchar) { signchar = 0; } } if (qualifier == 'l') { num = va_arg(ap, unsigned long); } else if (qualifier == 'h') { if (signchar) { num = va_arg(ap, signed short int); } else { num = va_arg(ap, unsigned short int); } } else if (signchar) { num = va_arg(ap, signed int); } else { num = va_arg(ap, unsigned int); } #ifdef DEBUG_MEMORY tmpstr = _x_makenum(file, line, num, base, width, prec, padding, signchar); #else /* DEBUG_MEMORY */ tmpstr = _x_makenum(num, base, width, prec, padding, signchar); #endif /* DEBUG_MEMORY */ if (caps) strupr(tmpstr); #ifdef DEBUG_MEMORY newdest = (char *)mem_realloc(newdest, newdestlen + strlen(tmpstr), file, line); #else /* DEBUG_MEMORY */ newdest = (char *)realloc(newdest, newdestlen + strlen(tmpstr)); #endif /* DEBUG_MEMORY */ strcpy(newdest + newdestlen - 1, tmpstr); newdestlen += strlen(tmpstr); #ifdef DEBUG_MEMORY mem_realloc(tmpstr, 0, file, line); #else /* DEBUG_MEMORY */ free(tmpstr); #endif /* DEBUG_MEMORY */ } else if (*formatpos == '%') { #ifdef DEBUG_MEMORY newdest = (char *)mem_realloc(newdest, newdestlen + 1, file, line); #else /* DEBUG_MEMORY */ newdest = (char *)realloc(newdest, newdestlen + 1); #endif /* DEBUG_MEMORY */ newdest[newdestlen - 1] = *formatpos; newdest[newdestlen] = 0; newdestlen++; } } else { #ifdef DEBUG_MEMORY newdest = (char *)mem_realloc(newdest, newdestlen + 1, file, line); #else /* DEBUG_MEMORY */ newdest = (char *)realloc(newdest, newdestlen + 1); #endif /* DEBUG_MEMORY */ newdest[newdestlen - 1] = *formatpos; newdest[newdestlen] = 0; newdestlen++; } formatpos++; } #ifdef DEBUG_MEMORY mem_realloc(formatcpy, 0, file, line); #else /* DEBUG_MEMORY */ free(formatcpy); #endif /* DEBUG_MEMORY */ return newdest; } # endif /* HAVE_VSNPRINTF */ #endif /* HAVE_VASPRINTF */ #ifdef HAVE_STRDUP /* Wrap around strdup(). We can't memdebug() this, so its disabled by configure.in if DEBUG_MEMORY is enabled. */ char *x_strdup(const char *s) { return strdup(s); } #else /* HAVE_STRDUP */ /* Do the malloc and strcpy() ourselves so we don't annoy memdebug.c */ #ifdef DEBUG_MEMORY char *xx_strdup(char *file, int line, const char *s) { #else /* DEBUG_MEMORY */ char *x_strdup(const char *s) { #endif /* DEBUG_MEMORY */ char *ret; #ifdef DEBUG_MEMORY ret = (char *)mem_malloc(strlen(s) + 1, file, line); #else /* DEBUG_MEMORY */ ret = (char *)malloc(strlen(s) + 1); #endif /* DEBUG_MEMORY */ strcpy(ret, s); return ret; } #endif /* HAVE_STRDUP */ dircproxy-1.0.5/src/sprintf.h0000664000175000017500000000217107410714173011655 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * sprintf.h * -- * @(#) $Id: sprintf.h,v 1.7 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #ifndef __DIRCPROXY_SPRINTF_H #define __DIRCPROXY_SPRINTF_H /* required includes */ #include /* functions */ #ifdef DEBUG_MEMORY #define x_sprintf(...) xx_sprintf(__FILE__, __LINE__, __VA_ARGS__) #define x_vsprintf(FMT, LIST) xx_vsprintf(__FILE__, __LINE__, FMT, LIST) #define x_strdup(STR) xx_strdup(__FILE__, __LINE__, STR) extern char *xx_sprintf(char *, int, const char *, ...); extern char *xx_vsprintf(char *, int, const char *, va_list); extern char *xx_strdup(char *, int, const char *); #else /* DEBUG_MEMORY */ /* Not debugging memory, run normally */ extern char *x_sprintf(const char *, ...); extern char *x_vsprintf(const char *, va_list); extern char *x_strdup(const char *); #endif /* DEBUG_MEMORY */ #endif /* __DIRCPROXY_SPRINTF_H */ dircproxy-1.0.5/src/memdebug.c0000664000175000017500000002044707410714173011756 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * memdebug.c * - wrappers to memory allocation functions * - memory leak tracing * - buffer overrun detection * * The idea of these is that lots of extra memory is used to store * information about memory allocations, and to check things don't * get accidentally overrun. This is purely debug, you should * NEVER use this in a real program. * -- * @(#) $Id: memdebug.c,v 1.8 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #include #include #include /* Define MIN() */ #ifndef MIN #define MIN(x, y) ((x) < (y) ? (x) : (y)) #endif /* MIN */ /* This is the structure that goes in front of EVERY chunk or hunk of memory alloc'd. Take a good long look at how big it is, imagine your memory full of these. I think its best to only use this for debugging purposes. Okay? */ struct memstamp { unsigned short magic; unsigned long allocnum; size_t size; char *file; int line; struct memstamp *next; }; /* For statistics */ struct memcount { char *file; unsigned long count; struct memcount *next; }; /* definition of the magic number */ #define MEMMAGIC 0xDC10 /* data put before and after the memory to detect overruns */ #define MEMPREBUFF "yankydoodledandy" #define MEMPOSTBUFF "itwasacolddayinhell" /* function prototypes - don't include the .h as it'll all go *boom* */ void *mem_malloc(size_t, char *, int); void *mem_realloc(void *, size_t, char *, int); void mem_report(char *); /* variables */ static unsigned long memalloccount = 0L; static unsigned long memfreecount = 0L; static unsigned long memusage = 0L; static struct memstamp *memstamplist = NULL; static struct memcount *memcounts = 0; /* Insert a new memory stamp onto the list */ static void _mem_insert(struct memstamp *ms) { ms->next = memstamplist; memstamplist = ms; } /* Delete a memory stamp from the list */ static void _mem_delete(struct memstamp *ms) { struct memstamp *msptr; if (memstamplist != ms) { msptr = memstamplist; while (msptr->next != NULL) { if (msptr->next == ms) { msptr->next = ms->next; return; } msptr = msptr->next; } fprintf(stderr, "MEM: bugger! attempted delete of phantom stamp.\n"); } else { memstamplist = ms->next; } } /* Check for overruns */ static void _mem_checkpad(struct memstamp *ms, char *file, int line) { char *ptr; ptr = (char *)ms + sizeof(struct memstamp); if (strncmp(ptr, MEMPREBUFF, strlen(MEMPREBUFF))) { char *data; data = (char *)malloc(strlen(MEMPREBUFF) + 1); strncpy(data, ptr, strlen(MEMPREBUFF)); data[strlen(MEMPREBUFF)] = 0; fprintf(stderr, "MEM: possible underun detected by (%s/%d) " "alloc at (%s/%d).\n", file ? file : "debug code", file ? line : 0, ms->file ? ms->file : "debug code", ms->file ? ms->line : 0); fprintf(stderr, " [%s:%s]\n", MEMPREBUFF, data); free(data); } ptr = (char *)ptr + strlen(MEMPREBUFF) + ms->size; if (strncmp(ptr, MEMPOSTBUFF, strlen(MEMPOSTBUFF))) { char *data; data = (char *)malloc(strlen(MEMPOSTBUFF) + 1); strncpy(data, ptr, strlen(MEMPOSTBUFF)); data[strlen(MEMPOSTBUFF)] = 0; fprintf(stderr, "MEM: possible overun detected by (%s/%d) " "alloc at (%s/%d).\n", file ? file : "debug code", file ? line : 0, ms->file ? ms->file : "debug code", ms->file ? ms->line : 0); fprintf(stderr, " [%s:%s]\n", MEMPOSTBUFF, data); free(data); } } /* Wrapper around malloc() which adds a memstamp to the front */ void *mem_malloc(size_t size, char *file, int line) { struct memstamp *ms; struct memcount *mc; if (size > 0) { unsigned long malloc_sz; char *preptr, *postptr; malloc_sz = (sizeof(struct memstamp) + strlen(MEMPREBUFF) + size + strlen(MEMPOSTBUFF)); if (!(ms = (struct memstamp *)malloc(malloc_sz))) { fprintf(stderr, "MEM: malloc failed to alloc %lu(%lu) bytes (%s/%d)\n", (unsigned long)malloc_sz, (unsigned long)size, file ? file : "debug code", file ? line : 0); abort(); } if (file && strlen(file)) { mc = memcounts; while (mc) { if (!strcmp(mc->file, file)) { mc->count++; break; } mc = mc->next; } if (!mc) { if (!(mc = (struct memcount *)malloc(sizeof(struct memcount)))) { fprintf(stderr, "MEM: malloc failed to alloc %lu bytes (%s/%d)\n", (unsigned long)(sizeof(struct memcount)), file, line); abort(); } if (!(mc->file = (char *)malloc(strlen(file) + 1))) { fprintf(stderr, "MEM: malloc failed to alloc %lu bytes (%s/%d)\n", (unsigned long)(strlen(file) + 1), file, line); abort(); } strcpy(mc->file, file); mc->count = 1; mc->next = memcounts; memcounts = mc; } if (!(ms->file = (char *)malloc(strlen(file) + 1))) { fprintf(stderr, "MEM: malloc failed to alloc %lu bytes (%s/%d)\n", (unsigned long)(strlen(file) + 1), file, line); abort(); } strcpy(ms->file, file); ms->allocnum = memalloccount++; ms->line = line; #if 0 fprintf(stderr, "MEM: malloc of %lu bytes (%s/%d)\n", (unsigned long)size, file, line); #endif } else { ms->file = 0; ms->allocnum = 0; ms->line = 0; } ms->magic = MEMMAGIC; ms->size = size; memusage += size; _mem_insert(ms); preptr = (char *)ms; preptr += sizeof(struct memstamp); strncpy(preptr, MEMPREBUFF, strlen(MEMPREBUFF)); preptr += strlen(MEMPREBUFF); postptr = preptr; postptr += size; strncpy(postptr, MEMPOSTBUFF, strlen(MEMPOSTBUFF)); return (void *)preptr; } else { return NULL; } } /* Wrapper around realloc() which adds a memstamp to the front */ void *mem_realloc(void *ptr, size_t size, char *file, int line) { unsigned long data_off; struct memstamp *ms; void *block; if (ptr == NULL) return mem_malloc(size, file, line); data_off = sizeof(struct memstamp) + strlen(MEMPREBUFF); ms = (struct memstamp *)((char *)ptr - data_off); if (ms->magic != MEMMAGIC) { fprintf(stderr, "MEM: %s of illegal block (%s/%d)\n", (size > 0) ? "realloc" : "free", file ? file : "debug code", file ? line : 0); return NULL; } _mem_checkpad(ms, file, line); block = NULL; if (size > 0) { block = mem_malloc(size, file, line); if (size < ms->size) memcpy(block, (char *)ms + data_off, size); else memcpy(block, (char *)ms + data_off, ms->size); } if (ms->file) memfreecount++; memusage -= ms->size; _mem_delete(ms); free(ms->file); free(ms); return block; } /* Reports current memory usage and shows what was malloc()d where */ void mem_report(char *message) { struct memstamp *msptr; struct memcount *mc; msptr = memstamplist; printf("MEM:REPORT%s%s%s %lu bytes in use [%lu alloc][%lu free]\n", message ? " (" : "", message ? message : "", message ? ")" : "", memusage, memalloccount, memfreecount); mc = memcounts; while (mc) { unsigned long i, t; printf("%16s %8lu ", mc->file, mc->count); t = ((double)mc->count / (double)memalloccount) * 40; for (i = 0; i < t; i++) printf("#"); printf("\n"); mc = mc->next; } printf("\n"); while (msptr) { if (message) { int i; printf(" %s/%d - %lu bytes alloc'd [an:%lu]\n", msptr->file ? msptr->file : "debug code", msptr->file ? msptr->line : 0, (unsigned long)msptr->size, msptr->file ? msptr->allocnum : 0); printf(" ["); for (i = 0; i <= MIN(msptr->size, 70); i++) { int c; c = *((char *)msptr + sizeof(struct memstamp) + strlen(MEMPREBUFF) + i); if ((c >= 32) && (c <= 127)) { printf("%c", c); } else if (c) { printf("£"); } else { break; } } printf("]\n"); } _mem_checkpad(msptr, "report", 0); msptr = msptr->next; } } dircproxy-1.0.5/src/memdebug.h0000664000175000017500000000213307410714173011753 /* dircproxy * Copyright (C) 2002 Scott James Remnant . * All Rights Reserved. * * memdebug.h * -- * @(#) $Id: memdebug.h,v 1.4 2001/12/21 20:15:55 keybuk Exp $ * * This file is distributed according to the GNU General Public * License. For full details, read the top of 'main.c' or the * file called COPYING that was distributed with this code. */ #ifndef __DIRCPROXY_MEMDEBUG_H #define __DIRCPROXY_MEMDEBUG_H /* required includes */ #include /* replace standard functions with replacements wrapped around debug */ #ifdef DEBUG_MEMORY #undef malloc #undef calloc #undef free #undef realloc #define malloc(SIZE) mem_malloc(SIZE, __FILE__, __LINE__) #define calloc(NMEMB, SIZE) mem_malloc(NMEMB * SIZE, __FILE__, __LINE__) #define free(PTR) mem_realloc(PTR, 0, __FILE__, __LINE__) #define realloc(PTR, SIZE) mem_realloc(PTR, SIZE, __FILE__, __LINE__) #endif /* DEBUG_MEMORY */ /* functions */ extern void *mem_malloc(size_t, char *, int); extern void *mem_realloc(void *, size_t, char *, int); extern void mem_report(const char *); #endif /* __DIRCPROXY_MEMDEBUG_H */