Merged with Irssi CVS.
authorPekka Riikonen <priikone@silcnet.org>
Sun, 20 Oct 2002 12:13:28 +0000 (12:13 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sun, 20 Oct 2002 12:13:28 +0000 (12:13 +0000)
122 files changed:
CHANGES
apps/irssi/.cvsignore
apps/irssi/AUTHORS
apps/irssi/COPYING [deleted file]
apps/irssi/NEWS
apps/irssi/README
apps/irssi/README.cygwin [new file with mode: 0644]
apps/irssi/autogen.sh
apps/irssi/configure.in
apps/irssi/docs/faq.txt
apps/irssi/docs/formats.txt
apps/irssi/docs/manual.txt
apps/irssi/docs/perl.txt
apps/irssi/docs/proxy.txt
apps/irssi/docs/signals.txt
apps/irssi/docs/special_vars.txt
apps/irssi/docs/startup-HOWTO.html
apps/irssi/glib-2.0.m4_ [new file with mode: 0644]
apps/irssi/glib.m4_ [new file with mode: 0644]
apps/irssi/irssi-config.in
apps/irssi/irssi.cvs [new file with mode: 0644]
apps/irssi/irssi.spec.in
apps/irssi/src/core/Makefile.am
apps/irssi/src/core/blob.c [deleted file]
apps/irssi/src/core/blob.h [deleted file]
apps/irssi/src/core/channel-rec.h
apps/irssi/src/core/channels-setup.c
apps/irssi/src/core/channels.c
apps/irssi/src/core/channels.h
apps/irssi/src/core/chat-commands.c
apps/irssi/src/core/chat-protocols.h
apps/irssi/src/core/chatnets.c
apps/irssi/src/core/commands.c
apps/irssi/src/core/core.c
apps/irssi/src/core/expandos.c
apps/irssi/src/core/ignore.c
apps/irssi/src/core/ignore.h
apps/irssi/src/core/levels.h
apps/irssi/src/core/log.c
apps/irssi/src/core/log.h
apps/irssi/src/core/misc.c
apps/irssi/src/core/misc.h
apps/irssi/src/core/modules-load.c
apps/irssi/src/core/net-nonblock.c
apps/irssi/src/core/network-openssl.c [new file with mode: 0644]
apps/irssi/src/core/network.c
apps/irssi/src/core/network.h
apps/irssi/src/core/queries.c
apps/irssi/src/core/query-rec.h
apps/irssi/src/core/server-connect-rec.h
apps/irssi/src/core/server-setup-rec.h
apps/irssi/src/core/servers-reconnect.c
apps/irssi/src/core/servers-setup.c
apps/irssi/src/core/servers.c
apps/irssi/src/core/servers.h
apps/irssi/src/core/session.c
apps/irssi/src/core/settings.h
apps/irssi/src/core/window-item-rec.h
apps/irssi/src/fe-common/core/Makefile.am
apps/irssi/src/fe-common/core/autorun.c
apps/irssi/src/fe-common/core/chat-completion.c
apps/irssi/src/fe-common/core/chat-completion.h
apps/irssi/src/fe-common/core/completion.c
apps/irssi/src/fe-common/core/fe-channels.c
apps/irssi/src/fe-common/core/fe-common-core.c
apps/irssi/src/fe-common/core/fe-core-commands.c
apps/irssi/src/fe-common/core/fe-exec.c
apps/irssi/src/fe-common/core/fe-ignore.c
apps/irssi/src/fe-common/core/fe-log.c
apps/irssi/src/fe-common/core/fe-messages.c
apps/irssi/src/fe-common/core/fe-queries.c
apps/irssi/src/fe-common/core/fe-server.c
apps/irssi/src/fe-common/core/fe-settings.c
apps/irssi/src/fe-common/core/fe-windows.c
apps/irssi/src/fe-common/core/fe-windows.h
apps/irssi/src/fe-common/core/hilight-text.c
apps/irssi/src/fe-common/core/hilight-text.h
apps/irssi/src/fe-common/core/keyboard.c
apps/irssi/src/fe-common/core/keyboard.h
apps/irssi/src/fe-common/core/module-formats.c
apps/irssi/src/fe-common/core/module-formats.h
apps/irssi/src/fe-common/core/printtext.c
apps/irssi/src/fe-common/core/themes.c
apps/irssi/src/fe-common/core/themes.h
apps/irssi/src/fe-common/core/window-commands.c
apps/irssi/src/fe-common/core/window-items.c
apps/irssi/src/fe-common/core/windows-layout.c
apps/irssi/src/fe-text/Makefile.am
apps/irssi/src/fe-text/gui-entry.c
apps/irssi/src/fe-text/gui-readline.c
apps/irssi/src/fe-text/mainwindows-save.c [deleted file]
apps/irssi/src/fe-text/screen.c [deleted file]
apps/irssi/src/fe-text/screen.h [deleted file]
apps/irssi/src/fe-text/statusbar.c
apps/irssi/src/fe-text/term.c
apps/irssi/src/fe-text/textbuffer-view.c
apps/irssi/src/fe-text/utf8.c
apps/irssi/src/fe-text/utf8.h
apps/irssi/src/lib-config/get.c
apps/irssi/src/lib-config/iconfig.h
apps/irssi/src/perl/common/Channel.xs
apps/irssi/src/perl/common/Core.xs
apps/irssi/src/perl/common/Irssi.xs
apps/irssi/src/perl/common/module.h
apps/irssi/src/perl/common/typemap
apps/irssi/src/perl/get-signals.pl
apps/irssi/src/perl/irssi-core.pl
apps/irssi/src/perl/irssi-core.pl.h
apps/irssi/src/perl/perl-common.c
apps/irssi/src/perl/perl-common.h
apps/irssi/src/perl/perl-core.c
apps/irssi/src/perl/perl-signals-list.h
apps/irssi/src/perl/textui/TextUI.xs
apps/irssi/src/perl/ui/Themes.xs
apps/irssi/src/perl/ui/Window.xs
apps/irssi/src/silc/core/client_ops.c
apps/irssi/src/silc/core/client_ops.h
apps/irssi/src/silc/core/silc-channels.c
apps/irssi/src/silc/core/silc-channels.h
apps/irssi/src/silc/core/silc-core.c
apps/irssi/src/silc/core/silc-servers.c
apps/irssi/src/silc/core/silc-servers.h

diff --git a/CHANGES b/CHANGES
index 4b4dec2197dd4946a04a04eb06bf03fec915823d..cd1446266d7beeeac2fb34d2b5fe42d6f6edfd64 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+Sun Oct 20 14:12:24 CEST 2002  Pekka Riikonen <priikone@silcnet.org>
+
+       * Merged with irssi.org CVS.
+
 Sat Oct 19 13:32:15 CEST 2002  Pekka Riikonen <priikone@silcnet.org>
 
        * ROBODoc documented lib/silcutil/silcbuffer.h and
index bbb8ef8ff159ad4a5b530bf15bc8bd182cce3841..6b0f2e035ab0127b8aa1db7684207732a8986ef0 100644 (file)
@@ -16,6 +16,7 @@ ltmain.sh
 stamp-h
 stamp-h.in
 stamp.h
+stamp-h1
 version.h
 config.h.in
 .exrc
@@ -31,6 +32,7 @@ default-config.h
 default-theme.h
 irssi-version.h
 irssi-config
-colorless.theme
 build-stamp
 configure-stamp
+glib.m4
+glib-2.0.m4
index b82b08a3d71062a264cab6666b6e8a8a3152b4f8..093f5e94c1fe5f5c96393e7b1c5284bbce805600 100644 (file)
@@ -1 +1 @@
-Timo Sirainen, tss@iki.fi
+Timo Sirainen <cras@irssi.org>
diff --git a/apps/irssi/COPYING b/apps/irssi/COPYING
deleted file mode 100644 (file)
index 60549be..0000000
+++ /dev/null
@@ -1,340 +0,0 @@
-                   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.
-\f
-                   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.)
-\f
-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.
-\f
-  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.
-\f
-  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
-\f
-           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.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) 19yy  <name of author>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) 19yy name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 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.
index 458a96e5a43ce919b5506577ff10fd1c300cd801..ccdc0e4fc80c329c710351ca53fd85d29a9f1a0c 100644 (file)
@@ -1,3 +1,72 @@
+v0.8.4 2002-03-13  Timo Sirainen <tss@iki.fi>
+
+       * Continuing to fix my stupid mistakes...
+
+       - When a queried nick did a nick change, it might have crashed irssi
+       - read ChangeLog for some other minor changes
+
+v0.8.3 2002-03-13  Timo Sirainen <tss@iki.fi>
+
+       - Perl scripts handling channel parts/kicks/quits printed some
+         errors.
+       - Connecting to IPv6 servers without IPv4 record didn't work
+       - When queries were auto-created by you using /MSG and you had
+         /SET autoclose_query non-zero, the query was always destroyed
+         almost immediately.
+       - Fix to some stupid ircds not sending us 001 numeric, but
+         beginning from MOTD
+
+v0.8.2 2002-03-11  Timo Sirainen <tss@iki.fi>
+
+       * Changed the list of scripts distributed with irssi. Separated
+         example scripts to scripts/examples/ directory.
+
+       * Hated infobar was removed, the same info is now in topicbar in
+         empty windows. I don't think it would disturb anyone in there.
+         If you still preferred always-empty topicbars, use
+         /SBAR topic REMOVE topic_empty
+
+       + Added info_eol field to theme. If true, timestamp and server tag
+         are added to end of line, not at beginning.
+       + If -4 or -6 option is used with /SERVER, irssi now forces the
+         connection using the given protocol or fails.
+       + /SET max_wildcard_modes (default 6) - if a wildcard to /OP, /DEOP,
+         /VOICE or /DEVOICE matches more nicks than this, -yes option is
+         required. This is trying to prevent accidental massops. Setting
+         it to 0 disables this check.
+       + Supports now correctly servers which use '.' char as channel owner
+         character in /NAMES list. Also supports multiple mode chars, eg.
+         @+nick (if some server actually used it).
+       + Never ignore kick message if you get kicked from channel.
+       + Sending irssi SIGHUP now does a /RELOAD - useful if you
+         accidentally messed up something which doesn't let you do the
+         /RELOAD inside irssi (eg. /SBAR prompt DISABLE).
+       + irssi-proxy: PROXY CTCP ON|OFF - proxy clients can send this
+         command to specify that they want to handle the received CTCP
+         requests. Useful for specifying who gets to handle DCCs.
+       + Added escape_char /BIND command. The next char after that would be
+         added as-is to input line.
+       - Writing lines longers than 1024 chars to input buffer crashed
+         irssi (stupid missing sizeof() bug :)
+       - Some UTF-8 fixes
+       - Better flood protection for lines with >100 chars
+       - Control characters aren't printed as-is in topicbar (or statusbars
+         in general) anymore
+       - /OPER can be now aborted by giving empty password
+       - Netjoin messages were buggy in +channels
+       - Part message parameter for /CYCLE was never used.
+       - Don't send -autosendcmd after /UPGRADE.
+       - /SET autoclose_query - now only last received private message
+         affects when the query is closed, ie. /WHOIS requests or nick
+         changes don't reset the counter.
+       - Foreground ANSI colors weren't working
+       - Deleting one character replaced cutbuffer with that character.
+         Also ^Y leaked memory.
+       - /SCRIPT LOAD looked scripts from prefix/lib dir, not prefix/share
+         where they were actually installed.
+       - Highascii chars in replaces block in theme files could have
+         crashed irssi.
+
 v0.8.1 2002-02-17  Timo Sirainen <tss@iki.fi>
 
        * Expected bugfix release :) Worst thing was that I forgot always to
index fd05732b2bb21fcaed5d92e574fcd4f1c064d403..d6a88764ed7376b2472fbb48067665ce076e24ba 100644 (file)
@@ -111,6 +111,6 @@ See TODO file if it is already listed in there - if not send me email..
  * AUTHOR
 
  - Timo Sirainen
- - tss@iki.fi
+ - cras@irssi.org
  - cras at ircnet/opn/silc
- - #irssi at ircnet/opn, #irssi.fi at ircnet
+ - #irssi at ircnet/opn, #irssi.fi, #irssi.de and #irssi.pl at ircnet
diff --git a/apps/irssi/README.cygwin b/apps/irssi/README.cygwin
new file mode 100644 (file)
index 0000000..60409e5
--- /dev/null
@@ -0,0 +1,12 @@
+Getting perl scripting to work needs a few things:
+
+ - configure with --with-perl-staticlib
+
+ - libperl.dll is required in linking and running irssi, it's normally
+   located somewhere around /usr/lib/perl5/5.6.1/cygwin/CORE/libperl5_6_1.dll
+   copy it to eg. /usr/bin/libperl.dll
+
+ - -DUSEIMPORTLIB is needed to be defined while compiling src/perl directory.
+   It doesn't hurt to be defined everywhere, so configure irssi with:
+
+     CFLAGS='-DUSEIMPORTLIB' ./configure --with-perl-staticlib
index 791563091a22f919f76d695365e8e3195b4abcc8..a8daf65207c8da3ce9428ac61e689105134fc7fd 100755 (executable)
@@ -1,10 +1,20 @@
 #!/bin/sh
 # Run this to generate all the initial makefiles, etc.
 
+PKG_NAME="Irssi SILC"
+
 srcdir=`dirname $0`
 test -z "$srcdir" && srcdir=.
 
-PKG_NAME="Irssi SILC"
+if test ! -f $srcdir/irssi.cvs -a -f $srcdir/configure; then
+  echo
+  echo "Use ./configure instead"
+  echo
+  echo "This script should only be run if you got sources from CVS."
+  echo "If you really want to do this, say:"
+  echo "  touch irssi.cvs"
+  exit 0
+fi
 
 if test ! -f $srcdir/configure.in; then
     echo -n "**Error**: Directory \`$srcdir\' does not look like the"
@@ -27,7 +37,7 @@ cat docs/help/Makefile.am.gen|sed "s/@HELPFILES@/$files/g"|sed 's/?/\\?/g'|tr '!
 
 # .html -> .txt with lynx
 echo "Documentation: html -> txt..."
-lynx -dump -nolist docs/startup-HOWTO.html > docs/startup-HOWTO.txt
+lynx -dump -nolist docs/faq.html|perl -pe 's/^ *//; if ($_ eq "\n" && $state eq "Q") { $_ = ""; } elsif (/^([QA]):/) { $state = $1 } elsif ($_ ne "\n") { $_ = "   $_"; };' > docs/faq.txt
 
 echo "Checking auto* tools..."
 
@@ -134,3 +144,7 @@ automake --add-missing --gnu $am_opt
 #else
 #  echo Skipping configure process.
 #fi
+
+# make sure perl hashes have correct length
+find src/perl -name *.c -o -name *.xs | xargs grep -n hv_store | perl -ne 'if (/"(\w+)",\s*(\d+)/) { print unless $2 == length $1 }'
+
index e812dee82fc6da58cc8765eed9b650c41da95eaa..4333bcb4f9a174844063362c195011b621618f93 100644 (file)
@@ -7,7 +7,7 @@ if test -n "`grep '^#undef VERSION' config.h.in`"; then
 fi
 
 AM_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE(Irssi-SILC, 0.8.5+)
+AM_INIT_AUTOMAKE(Irssi-SILC, 0.8.6)
 
 AM_MAINTAINER_MODE
 
@@ -15,6 +15,7 @@ AC_ISC_POSIX
 AC_PROG_CC
 AC_PROG_CPP
 AC_STDC_HEADERS
+AC_ARG_PROGRAM
 AM_PROG_LIBTOOL
 
 AC_PATH_PROG(sedpath, sed)
@@ -110,7 +111,7 @@ if test "x$prefix" != "xNONE"; then
        perl_prefix_note=yes
 fi
 
-AC_ARG_WITH(tests,
+AC_ARG_WITH(with-glib2,
 [  --with-glib2           Use GLIB 2.0 instead of 1.2],
        if test x$withval = xyes; then
                want_glib2=yes
@@ -182,14 +183,6 @@ AC_ARG_WITH(perl,
        fi,
        want_perl=static)
 
-AC_ARG_WITH(tests,
-[  --with-tests           Run all the tests],
-       if test x$withval != xno; then
-               TEST_DIR=test
-       fi,
-       TEST_DIR=)
-AC_SUBST(TEST_DIR)
-
 AC_ARG_ENABLE(ipv6,
 [  --enable-ipv6           Enable IPv6 support],
        if test x$enableval = xyes; then
@@ -228,7 +221,7 @@ AC_CHECK_FUNC(socket, [], [
 AC_CHECK_FUNC(inet_addr, [], [
        AC_CHECK_LIB(nsl, inet_addr, [
                LIBS="$LIBS -lnsl"
-       ], -lsocket)
+       ])
 ])
 
 dnl * gcc specific options
@@ -462,7 +455,7 @@ dnl **
 if test "x$want_textui" = "xyes"; then
        AC_CHECK_CURSES
 
-       LIBS="$LIBS $CURSES_LIBS"
+       TEXTUI_LIBS="$LIBS $CURSES_LIBS"
        if test "x$has_curses" = "xtrue"; then
                        AC_CHECK_FUNC(use_default_colors, AC_DEFINE(HAVE_NCURSES_USE_DEFAULT_COLORS))
                        AC_CHECK_FUNC(idcok, AC_DEFINE(HAVE_CURSES_IDCOK))
@@ -473,19 +466,20 @@ if test "x$want_textui" = "xyes"; then
                ])
        else
                AC_CHECK_LIB(tinfo, setupterm, [
-                 LIBS="$LIBS -ltinfo"
+                 TEXTUI_LIBS="$LIBS -ltinfo"
                  want_terminfo=yes
                ], AC_CHECK_LIB(termlib, tgetent, [
-                 LIBS="$LIBS -ltermlib"
+                 TEXTUI_LIBS="$LIBS -ltermlib"
                  want_termcap=yes
                ], AC_CHECK_LIB(termcap, tgetent, [
-                 LIBS="$LIBS -ltermcap"
+                 TEXTUI_LIBS="$LIBS -ltermcap"
                  want_termcap=yes
                ], [
                  AC_ERROR(Terminfo/termcap not found - install ncurses-devel package)
                  want_textui=no
                ])))
         fi
+       AC_SUBST(TEXTUI_LIBS)
                if test "x$want_termcap" = "xyes"; then
                        AC_CHECK_FUNC(tparm,, need_tparm=yes)
        else
@@ -660,7 +654,6 @@ AM_CONDITIONAL(BUILD_TEXTUI, test "$want_textui" = "yes")
 AM_CONDITIONAL(BUILD_IRSSIBOT, test "$want_irssibot" = "yes")
 AM_CONDITIONAL(BUILD_IRSSIPROXY, test "$want_irssiproxy" = "yes")
 AM_CONDITIONAL(BUILD_PLUGINS, test "$want_plugins" = "yes")
-AM_CONDITIONAL(BUILD_SERVERTEST, test -n "$TEST_DIR")
 AM_CONDITIONAL(HAVE_PERL, test "$want_perl" != "no")
 AM_CONDITIONAL(HAVE_STATIC_PERL, test "$want_perl" = "static")
 AM_CONDITIONAL(NEED_TPARM, test "$need_tparm" = "yes")
@@ -737,7 +730,7 @@ done
 FE_COMMON_LIBS="$FE_COMMON_LIBS../fe-common/core/libfe_common_core.a"
 
 dnl ** common libraries needed by frontends
-COMMON_NOUI_LIBS="$CHAT_LIBS $CORE_LIBS $INTLLIBS"
+COMMON_NOUI_LIBS="$CHAT_LIBS $CORE_LIBS"
 COMMON_LIBS="$FE_COMMON_LIBS $COMMON_NOUI_LIBS"
 AC_SUBST(COMMON_NOUI_LIBS)
 AC_SUBST(COMMON_LIBS)
index d8825106d1e18d5cb6e5082ed0e2e9d6b78533c1..499f243bfaff722bd5ed62deb1b5359e357c6872 100644 (file)
+   FAQ
+
 Q: Why doesn't irssi display colors even when ircii etc. displays them?
-A: They force ANSI colors even if terminal doesn't support them. By default,
-   irssi uses colors only if terminfo/termcap so says. The correct way to
-   fix this would be to change your TERM environment to a value where colors
-   work, like xterm-color or color_xterm. If this doesn't help, then use the
-   evil way of /SET term_force_colors ON.
+A:  They  force  ANSI colors even if terminal doesn't support them. By
+   default,  irssi  uses  colors  only  if  terminfo/termcap so says. The
+   correct  way to fix this would be to change your TERM environment to a
+   value   where  colors  work,  like  xterm-color  or  color_xterm  (eg.
+   TERM=xterm-color  irssi).  If this doesn't help, then use the evil way
+   of /SET term_force_colors ON.
 
 Q: How do I easily write text to channel that starts with '/' character?
 A: / /text
 
-Q: Why doesn't irssi update my realname (or whatever) after I change it
-   with /SET realname and reconnect with /RECONNECT or /SERVER?
-A: Irssi is trying to be too smart. This will be fixed in future, but for
-   now you should use /DISCONNECT + /CONNECT.
+Q: Why doesn't irssi update my realname (or whatever) after I change it with
+   /SET realname and reconnect with /RECONNECT or /SERVER?
+A:  Irssi is trying to be too smart. This will be fixed in future, but
+   for now you should use /DISCONNECT and /CONNECT.
 
-Q: I connected to some server which isn't responding but now irssi tries
-   to connect back to it all the time! How can I stop it?
-A: Two ways. The "good way" to do it is with /DISCONNECT. Check the server
-   tags first with /SERVER without giving it any parameters, reconnections
-   are those that have tag starting with "recon" text. So most probably you're
-   going to do /DISCONNECT recon-1. The other way is to remove all the
-   reconnections with /RMRECONNS, easier but may remove some connections
-   you actually wanted to reconnect (if you used multiple servers..).
+Q: I connected to some server which isn't responding but now irssi tries to
+   connect back to it all the time! How can I stop it?
+A:  Two  ways.  The "good way" to do it is with /DISCONNECT. Check the
+   server  tags  first  with  /SERVER  without  giving it any parameters,
+   reconnections  are  those that have tag starting with "recon" text. So
+   most probably you're going to do /DISCONNECT recon-1. The other way is
+   to remove all the reconnections with /RMRECONNS, easier but may remove
+   some  connections  you  actually  wanted  to  reconnect  (if  you used
+   multiple servers..).
 
 Q: How do I add seconds to timestamp?
-A: "/FORMAT timestamp {timestamp %%H:%%M:%%S} " - and remember to add the
+A: /FORMAT timestamp {timestamp %%H:%%M:%%S} - and remember to add the
    trailing space :)
 
 Q: Why does irssi say "Irssi: Channel not fully synchronized yet, try again
    after a while" when I try to use /BAN etc?
-A: Possibly a bug in irssi, or ircd you're using does something that irssi
-   didn't really notice. The new code should make this happen far less often
-   than before, but one known reason for this is when irssi doesn't notice
-   that you were unable to join some channel. Currently however I don't know
-   of any such events irssi doesn't know about.
-
-   Anyway, if this does happen, do "/RAWLOG SAVE ~/rawlog" soon after joining
-   to channel, and either try to figure out yourself why irssi didn't get
-   reply to WHO request, or send the whole log to tss@iki.fi. Note that the
-   rawlog is by default only 200 lines and it may not be enough to show all
-   needed information, so you might want to do /SET rawlog_lines 1000 or so.
+A:  Possibly  a bug in irssi, or ircd you're using does something that
+   irssi  didn't  really notice. The new code should make this happen far
+   less  often  than  before, but one known reason for this is when irssi
+   doesn't  notice  that  you were unable to join some channel. Currently
+   however I don't know of any such events irssi doesn't know about.
+
+   Anyway,  if  this  does  happen,  do  /RAWLOG SAVE ~/rawlog soon after
+   joining  to  channel,  and either try to figure out yourself why irssi
+   didn't   get   reply  to  WHO  request,  or  send  the  whole  log  to
+   cras@irssi.org.  Note that the rawlog is by default only 200 lines and
+   it may not be enough to show all needed information, so you might want
+   to do /SET rawlog_lines 1000 or so.
+
+   MODE +b still works fine though.
 
 Q: Where's the GUI version?
 A: Read http://irssi.org/?page=about
 
 Q: How do I autorejoin channels after being kicked?
-A: That's evil and you shouldn't do it. If you get kicked, you should
-   stay out, at least until the channel forgot you existed :) Most channels
-   I've joined just ban you if you autorejoin after kick. If you're joined
-   to channels who kick people for fun, try changing channels or something.
-
-   Anyway, if you REALLY want to do that, and you understand that you're
-   doing evilness, you can use the autorejoin.pl script that comes with
-   irssi. You'll still need to specify the channels you wish to rejoin with
-   /SET autorejoin_channels #chan1 #chan2 ...
-
-Q: How do I announce that I'm away/back in all channels I've joined?
-   Or how do I change my nick when setting myself away/back?
-A: That's even worse than autorejoin. Who could possibly care every time you
-   come and go? Many channels will kick you for using this, and I for example
-   have added several ignores so I'd never need to see these messages. Learn
-   to use /AWAY command properly and tell it's existence to people who don't
-   know about it. /WII yournick shows your away reason much better for people
-   who actually want to know if you're there or not.
-
-   You can script these behaviours if you really wish to of course. But
-   currently there's no public scripts for either of these, and the only way
-   I'm going to add such to irssi.org is if the script contains a setting to
-   specify which specific channels the announcement is sent.
+A:  That's evil and you shouldn't do it. If you get kicked, you should
+   stay  out,  at  least  until  the  channel  forgot you existed :) Most
+   channels  I've  joined  just  ban you if you autorejoin after kick. If
+   you're  joined  to  channels  who  kick  people  for fun, try changing
+   channels or something.
+
+   Anyway,  if you REALLY want to do that, and you understand that you're
+   doing  evilness,  you can use the autorejoin.pl script that comes with
+   irssi.  You'll  still  need to specify the channels you wish to rejoin
+   with /SET autorejoin_channels #chan1 #chan2 ...
+
+Q: How do I announce that I'm away/back in all channels I've joined? Or how
+   do I change my nick when setting myself away/back?
+A:  That's  even  worse than autorejoin. Who could possibly care every
+   time  you come and go? Many channels will kick you for using this, and
+   I  for  example  have  added  several ignores so I'd never need to see
+   these  messages.  Learn  to  use  /AWAY command properly and tell it's
+   existence  to people who don't know about it. /WII yournick shows your
+   away reason much better for people who actually want to know if you're
+   there or not.
+
+   You  can  script these behaviours if you really wish to of course. But
+   currently  there's no public scripts for either of these, and the only
+   way  I'm  going  to  add such to irssi.org is if the script contains a
+   setting to specify which specific channels the announcement is sent.
+
+Q: Why does irssi autojoin on invite by default?
+A:  The  setting is /SET join_auto_chans_on_invite - it's not the same
+   as regular autojoin-on-invite, which irssi doesn't even have. The only
+   channels  that  are  joined  on  invite,  are the ones you've added to
+   config  with  /CHANNEL ADD -auto. This is very useful with +i channels
+   when  you  need  to first send an invite request to bot, or if you get
+   accidentally  kicked  from  channel,  the  kicker  can invite you back
+   immediately.
+
+   I  don't  see  any  bad  side effects with this feature, so it's ON by
+   default. I guess someone could start kicking/inviting you all the time
+   but  server  connection  shouldn't  drop  because  of  that,  and  you
+   shouldn't join channels whose operators are that evil.
+
+Q: How to make UTF-8 support work with irssi?
+A: xterm -u8, screen -U, /SET term_type utf-8
+
+Q: Will there be /DETACH-like feature?
+A:  Maybe. Detach code already is there, attach is just missing :) But
+   I don't have much interest in coding it, and screen works just fine so
+   why bother?
+
+Q: How do I run scripts automatically at startup?
+A:  Put them into ~/.irssi/scripts/autorun/ directory. Or better would
+   be  if  you  placed  them in ~/.irssi/scripts/ and created symlinks to
+   autorun   directory   (eg.   cd   ~/.irssi/scripts/autorun/  ;  ln  -s
+   ../script.pl .)
+
+Q: How do I easily edit existing topic?
+A: /TOPIC <tab>
 
+Q: How can I have /WHOIS replies to active window?
+A:  Currently there's no other way than to close the status window, or
+   at least do /WINDOW LEVEL -CRAP in it, but that would make a lot other
+   messages  show  up  in active window too. I don't have many good ideas
+   how  this  could be easily fixed inside irssi (no, kludging it to only
+   work  with  whois isn't a "fix") - it'd be possible to create a script
+   do this though but currently it doesn't exist.
index d918a26890e2c0cdd2dd733406693436a3e8bee9..0ffef08fc209469a81d982c0743ffdb7c477ae59 100644 (file)
    %p      %P              magenta (think: purple)
    %c      %C      %6      cyan            bold cyan       cyan
    %w      %W      %7      white           bold white      white
-   %n      %N              Turn off all colors and other formatting
+   %n      %N              Changes the color to "default color", removing
+                           all other coloring and formatting. %N is always
+                          the terminal's default color. %n is usually too,
+                          except in themes it changes to "previous color",
+                          ie. hello = "%Rhello%n" and "%G{hello} world"
+                          would print hello in red, and %n would turn back
+                          into %G making world green.
    %F                      Blinking on/off (think: flash)
    %U                      Underline on/off
    %8                      Reverse on/off
index 2956e18e1b23d82e67a756f7fcdb2801d471b9da..7f9b23921264c925bef3f427bb8462ac5e79ef42 100644 (file)
        after connecting to ircnet. This is useful for automatically 
        identifying yourself to NickServ, for example
 
-       /IRCNET ADD -autosendcmd "/msg NickServ identify secret" OPN
+       /IRCNET ADD -autosendcmd "/msg NickServ identify secret" freenode
 
        /IRCNET REMOVE <name>
 
            -regexp: <text> is a regular expression
            -word: <text> must match to full words
            -nick: Hilight only the nick, not the whole line
-           -color: Print the reply with <color> - see below
+           -color: Print the reply with <color>. color is in %code format
+                   (see docs/formats.txt)
            -level: Match only for <level> messages, default is
                    publics,msgs,notices,actions
            -channels: Match only in <channels>
 
        /HILIGHT without any arguments displays list of the hilights.
 
-       By default the highlighted line will be printed with white color.
-       You can change this with the -color argument. If <color> is a
+If <color> is a
        number, Irssi will treat it as a MIRC color code. You can also use
        bolds (^B), underlines (^_) etc. as <color> if you like.
 
index 59c7e57a14f5a757082aafa915b35ba3e6e369ae..cf390a745384e175ca4936719869f2fbc1ed3135 100644 (file)
@@ -91,11 +91,11 @@ Here's an example:
     }
 
     if ($data) {
-      $server->command("/MSG $data Hello!");
+      $server->command("MSG $data Hello!");
     } elsif ($witem && ($witem->{type} eq "CHANNEL" ||
                         $witem->{type} eq "QUERY")) {
       # there's query/channel active in window
-      $witem->command("/MSG ".$witem->{name}." Hello!");
+      $witem->command("MSG ".$witem->{name}." Hello!");
     } else {
       Irssi::print("Nick not given, and no active channel/query in window");
     }
@@ -673,14 +673,6 @@ Server::channels_join(channels, automatic)
   was requested by user. If channel join is "automatic", irssi doesn't
   jump to the window where the channel was joined.
 
-Channel
-Server::channel_create(name, automatic)
-  Create new channel.
-
-Channel
-channel_create(chat_type, name, automatic)
-  Create new channel with specified chat type.
-  FIXME: should this be removed? is this useful for anything?
 
 Channel::destroy()
   Destroy channel.
@@ -951,10 +943,6 @@ Ban->{}
   setby - Nick of who set the ban
   time - Timestamp when ban was set
 
-Channel
-Server::channel_create(name, automatic)
-  Create new channel.
-
 Channel::bans()
   Return a list of bans in channel.
 
index 20e51715639454d3cc9766e6ed1d1f7720141422..41875aab3beb56925105a5b387a4ae0f60e168c8 100644 (file)
@@ -19,7 +19,7 @@ You really should set some password for the proxy with:
 Then you'll need to configure the ports/ircnets the proxy listens in,
 something like:
 
-  /SET irssiproxy_ports ircnet=2777 efnet=2778 opn=2779
+  /SET irssiproxy_ports ircnet=2777 efnet=2778 freenode=2779
 
 There we have 3 different irc networks answering in 3 ports. Note that
 you'll have to make the correct /IRCNET ADD and /SERVER ADD commands to
index 9b526aef086ed20e1c2aeb0c7ab93bc0cae554e2..2bf0d9213105238597826963ed856b6ada2b618d 100644 (file)
@@ -324,10 +324,3 @@ gui-printtext.c:
 
 statusbar-items.c:
  "mail counter"
-
-SILC
-----
-
-client_ops.c:
- "mime", SERVER_REC, CHANNEL_REC, BLOB_REC, char *mime, char *enc, char *nick
- "mime-send", SERVER_REC, WI_ITEM_REC, char *data, int data_len, char *enc, char *type
index c56c452faf44bfd93b23d5fda858d3c695d36a51..7b6640effe2bb8ece0ec688c04dc826a58065537 100644 (file)
@@ -62,6 +62,7 @@ $A .. $Z is important.
    $I         channel you were last INVITEd to
    $J         client version text string
    $K         current value of CMDCHARS
+   $k         first character in CMDCHARS
    $L         current contents of the input line
    $M         modes of current channel, if any
    $N         current nickname
index 5700d9f021e132bace66bef76e39633744600264..a5c5d472b82b638d09e169886bd47a04a5edbefc 100644 (file)
@@ -2,7 +2,8 @@
 
  <h3>To new Irssi users (not to new IRC users ..)</h3>
 
- <p>Copyright (c) 2000-2002 by Timo Sirainen</p>
+ <p>Copyright (c) 2000-2002 by Timo Sirainen, release under
+    <a href="http://www.gnu.org/licenses/fdl.html">GNU FDL</a> 1.1 license.</p>
 
 
 <p>Index with some FAQ questions that are answered in the chapter:</p>
@@ -67,41 +68,41 @@ weird non-VT compatible terminal (you most probably aren't), just
 say:</p>
 
 <pre>
-     /SET term_force_colors ON
+/SET term_force_colors ON
 </pre>
 
 <p>I don't like automatic query windows, I don't like status window, I do
 like msgs window where all messages go:</p>
 
 <pre>
-     /SET autocreate_own_query OFF
-     /SET autocreate_query_level DCCMSGS
-     /SET use_status_window OFF
-     /SET use_msgs_window ON
+/SET autocreate_own_query OFF
+/SET autocreate_query_level DCCMSGS
+/SET use_status_window OFF
+/SET use_msgs_window ON
 </pre>
 
 <p>Disable automatic window closing when <code>/PART</code>ing channel or
 <code>/UNQUERY</code>ing query:</p>
 
 <pre>
-     /SET autoclose_windows OFF
-     /SET reuse_unused_windows ON
+/SET autoclose_windows OFF
+/SET reuse_unused_windows ON
 </pre>
 
 <p>Here's the settings that make irssi work exactly like ircII in window
 management (send me a note if you can think of more):</p>
 
 <pre>
-     /SET autocreate_own_query OFF
-     /SET autocreate_query_level NONE
-     /SET use_status_window OFF
-     /SET use_msgs_window OFF
-     /SET reuse_unused_windows ON
-     /SET windows_auto_renumber OFF
+/SET autocreate_own_query OFF
+/SET autocreate_query_level NONE
+/SET use_status_window OFF
+/SET use_msgs_window OFF
+/SET reuse_unused_windows ON
+/SET windows_auto_renumber OFF
 
-     /SET autostick_split_windows OFF
-     /SET autoclose_windows OFF
-     /SET print_active_channel ON
+/SET autostick_split_windows OFF
+/SET autoclose_windows OFF
+/SET print_active_channel ON
 </pre>
 
 <p>And example how to add servers:</p>
@@ -110,7 +111,7 @@ management (send me a note if you can think of more):</p>
 joining channels)</p>
 
 <pre>
-     /IRCNET ADD -autosendcmd "/^msg nickserv ident pass;wait -opn 2000" opn
+/IRCNET ADD -autosendcmd "/^msg nickserv ident pass;wait -freenode 2000" freenode
 </pre>
 
 <p>Then add some servers to different networks (ircnet is already set up 
@@ -118,24 +119,23 @@ for them), irc.kpnqwest.fi is used by default for IRCNet but if it fails,
 irc.funet.fi is tried next:</p>
 
 <pre>
-     /SERVER ADD -auto -ircnet ircnet irc.kpnqwest.fi 6667
-     /SERVER ADD -ircnet ircnet irc.funet.fi 6667
-     /SERVER ADD -auto -ircnet efnet efnet.cs.hut.fi 6667
+/SERVER ADD -auto -ircnet ircnet irc.kpnqwest.fi 6667
+/SERVER ADD -ircnet ircnet irc.funet.fi 6667
+/SERVER ADD -auto -ircnet efnet efnet.cs.hut.fi 6667
 </pre>
 
 <p>Automatically join to channels after connected to server, send op request
 to bot after joined to efnet/#irssi:</p>
 
 <pre>
-     /CHANNEL ADD -auto #irssi ircnet
-     /CHANNEL ADD -auto -bots *!*bot@host.org -botcmd "/^msg $0 op pass"
-                 #irssi efnet
+/CHANNEL ADD -auto #irssi ircnet
+/CHANNEL ADD -auto -bots *!*bot@host.org -botcmd "/^msg $0 op pass" #irssi efnet
 </pre>
 
 If you want lines containing your nick to hilight:
 
 <pre>
-     /HILIGHT nick
+/HILIGHT nick
 </pre>
 
 <h3><a id="c2">2. Basic user interface usage</a></h3>
@@ -149,10 +149,10 @@ created every time you <code>/JOIN</code> a channel or <code>/QUERY</code>
 someone. There's several ways you can change between these windows:</p>
 
 <pre>
-     Meta-1, Meta-2, .. Meta-0 - Jump directly between windows 1-10
-     Meta-q .. Meta-o          - Jump directly between windows 11-19
-     /WINDOW &lt;number&gt;          - Jump to any window with specified number
-     Ctrl-P, Ctrl-N            - Jump to previous / next window
+Meta-1, Meta-2, .. Meta-0 - Jump directly between windows 1-10
+Meta-q .. Meta-o          - Jump directly between windows 11-19
+/WINDOW &lt;number&gt;          - Jump to any window with specified number
+Ctrl-P, Ctrl-N            - Jump to previous / next window
 </pre>
 
 <p>Clearly the easiest way is to use Meta-number keys. And what is the Meta
@@ -161,21 +161,21 @@ it's probably the left Windows key. If they don't work directly, you'll need
 to set a few X resources (NOTE: these work with both xterm and rxvt):</p>   
 
 <pre>
-     XTerm*eightBitInput:   false
-     XTerm*metaSendsEscape: true
+XTerm*eightBitInput:   false
+XTerm*metaSendsEscape: true
 </pre>
 
 <p>With rxvt, you can also specify which key acts as Meta key. So if you
 want to use ALT instead of Windows key for it, use:</p>
 
 <pre>
-     rxvt*modifier: alt
+rxvt*modifier: alt
 </pre>
 
 <p>You could do this by changing the X key mappings:</p>
 
 <pre>
-    xmodmap -e "keysym Alt_L = Meta_L Alt_L"
+xmodmap -e "keysym Alt_L = Meta_L Alt_L"
 </pre>
 
 <p>And how exactly do you set these X resources? For Debian, there's
@@ -196,16 +196,16 @@ but I think they should work pretty well now :) Here's some commands
 related to them:</p>
 
 <pre>
-     /WINDOW NEW                    - Create new split window
-     /WINDOW NEW HIDE               - Create new hidden window
-     /WINDOW CLOSE                  - Close split or hidden window
+/WINDOW NEW                    - Create new split window
+/WINDOW NEW HIDE               - Create new hidden window
+/WINDOW CLOSE                  - Close split or hidden window
 
-     /WINDOW HIDE [&lt;number&gt;|&lt;name&gt;] - Make the split window hidden window
-     /WINDOW SHOW &lt;number&gt;|&lt;name&gt;   - Make the hidden window a split window
+/WINDOW HIDE [&lt;number&gt;|&lt;name&gt;] - Make the split window hidden window
+/WINDOW SHOW &lt;number&gt;|&lt;name&gt;   - Make the hidden window a split window
 
-     /WINDOW SHRINK [&lt;lines&gt;]       - Shrink the split window
-     /WINDOW GROW [&lt;lines&gt;]         - Grow the split window
-     /WINDOW BALANCE                - Balance the sizes of all split windows
+/WINDOW SHRINK [&lt;lines&gt;]       - Shrink the split window
+/WINDOW GROW [&lt;lines&gt;]         - Grow the split window
+/WINDOW BALANCE                - Balance the sizes of all split windows
 </pre>
 
 <p>By default, irssi uses "sticky windowing" for split windows. This means
@@ -214,9 +214,9 @@ split window without some effort. For example you could have following
 window layout:</p>
 
 <pre>
-     Split window 1: win#1 - Status window, win#2 - Messages window
-     Split window 2: win#3 - ircnet/#channel1, win#4 - ircnet/#channel2
-     Split window 3: win#5 - efnet/#channel1, win#6 - efnet/#channel2
+Split window 1: win#1 - Status window, win#2 - Messages window
+Split window 2: win#3 - ircnet/#channel1, win#4 - ircnet/#channel2
+Split window 3: win#5 - efnet/#channel1, win#6 - efnet/#channel2
 </pre>
 
 <p>When you are in win#1 and press ALT-6, irssi jumps to split window
@@ -229,7 +229,7 @@ split window irssi just changes to that split window. This it the way
 windows work with ircii, if you prefer it you can set it with</p>
 
 <pre>
-     /SET autostick_split_windows OFF
+/SET autostick_split_windows OFF
 </pre>
 
 <p>Each window can have multiple channels, queries and other "window
@@ -237,22 +237,22 @@ items" inside them. If you don't like windows at all, you disable
 automatic creating of them with</p>
 
 <pre>
-     /SET autocreate_windows OFF
+/SET autocreate_windows OFF
 </pre>
 
 <p>And if you keep all channels in one window, you most probably want
 the channel name printed in each line:</p>
 
 <pre>
-     /SET print_active_channel ON
+/SET print_active_channel ON
 </pre>
 
 <p>If you want to group only some channels or queries in one window,
 use</p>
 
 <pre>
-     /JOIN -window #channel
-     /QUERY -window nick
+/JOIN -window #channel
+/QUERY -window nick
 </pre>
 
 <h3><a id="c3">3. Server and channel automation</a></h3>
@@ -271,15 +271,15 @@ you're connected to some network, use <code>-autosendcmd</code> option.
 Here's some examples:</p>
 
 <pre>
-     /IRCNET ADD -autosendcmd '^msg bot invite' ircnet
-     /IRCNET ADD -autosendcmd "/^msg nickserv ident pass;wait -opn 2000" opn
+/IRCNET ADD -autosendcmd '^msg bot invite' ircnet
+/IRCNET ADD -autosendcmd "/^msg nickserv ident pass;wait -freenode 2000" freenode
 </pre>
 
 <p>After that you need to add your servers. For example:</p>
 
 <pre>
-     /SERVER ADD -auto -ircnet ircnet irc.kpnqwest.fi 6667
-     /SERVER ADD -auto -ircnet worknet irc.mycompany.com 6667 password
+/SERVER ADD -auto -ircnet ircnet irc.kpnqwest.fi 6667
+/SERVER ADD -auto -ircnet worknet irc.mycompany.com 6667 password
 </pre>
 
 <p>The <code>-auto</code> option specifies that this server is
@@ -291,9 +291,8 @@ fails.</p>
 <p>And finally channels:</p>
 
 <pre>
-     /CHANNEL ADD -auto -bots *!*bot@host.org -botcmd "/^msg $0 op pass"
-                 #irssi efnet
-     /CHANNEL ADD -auto #secret ircnet password
+/CHANNEL ADD -auto -bots *!*bot@host.org -botcmd "/^msg $0 op pass" #irssi efnet
+/CHANNEL ADD -auto #secret ircnet password
 </pre>
 
 <p><code>-bots</code> and <code>-botcmd</code> should be the only ones
@@ -313,8 +312,8 @@ queries you want. If you want to move the windows or channels around
 use commands:</p>
 
 <pre>
-     /WINDOW MOVE LEFT/RIGHT/number    - move window elsewhere
-     /WINDOW ITEM MOVE &lt;number&gt;|&lt;name&gt; - move channel/query to another window
+/WINDOW MOVE LEFT/RIGHT/number    - move window elsewhere
+/WINDOW ITEM MOVE &lt;number&gt;|&lt;name&gt; - move channel/query to another window
 </pre>
 
 <p>When everything looks the way you like, use <code>/LAYOUT SAVE</code>
@@ -338,7 +337,7 @@ pretty much all messages that don't clearly belong to some channel or
 query. Some people like it, some don't. If you want to remove it, use</p>
 
 <pre>
-     /SET use_status_window OFF
+/SET use_status_window OFF
 </pre>
 
 <p>This doesn't have any effect until you restart irssi. If you want to
@@ -349,19 +348,19 @@ messages go. By default it's disabled and query windows are created
 instead. To make all private messages go to msgs window, say:</p>
 
 <pre>
-     /SET use_msgs_window ON
-     /SET autocreate_query_level DCCMSGS  (or if you don't want queries to
-                                          dcc chats either, say NONE)
+/SET use_msgs_window ON
+/SET autocreate_query_level DCCMSGS  (or if you don't want queries to
+                                     dcc chats either, say NONE)
 </pre>
 
 <p>use_msgs_window either doesn't have any effect until restarting
 irssi. To create it immediately say:</p>
 
 <pre>
-     /WINDOW NEW HIDE     - create the window
-     /WINDOW NAME (msgs)  - name it to "(msgs)"
-     /WINDOW LEVEL MSGS   - make all private messages go to this window
-     /WINDOW MOVE 1       - move it to first window
+/WINDOW NEW HIDE     - create the window
+/WINDOW NAME (msgs)  - name it to "(msgs)"
+/WINDOW LEVEL MSGS   - make all private messages go to this window
+/WINDOW MOVE 1       - move it to first window
 </pre>
 
 <p>Note that neither use_msgs_window nor use_status_window have any
@@ -374,7 +373,7 @@ all sorts of messages with no real classification. You can get a whole
 list of levels with</p>
 
 <pre>
-     /HELP levels
+/HELP levels
 </pre>
 
 <p>Status window has message level <code>ALL -MSGS</code>, meaning that all
@@ -393,7 +392,7 @@ them to one sigle window if you really want to. That being said, here's
 how you do connect to new server without closing the old connection:</p>
 
 <pre>
-     /CONNECT irc.server.org
+/CONNECT irc.server.org
 </pre>
 
 <p>Instead of the <code>/SERVER</code> which disconnects the existing
@@ -401,13 +400,13 @@ connection. To see list of all active connections, use <code>/SERVER</code>
 without any parameters. You should see a list of something like:</p>
 
 <pre>
-     -!- IRCNet: irc.song.fi:6667 (IRCNet)
-     -!- OPN: tolkien.openprojects.net:6667 (OPN)
-     -!- RECON-1: 192.168.0.1:6667 () (02:59 left before reconnecting)
+-!- IRCNet: irc.song.fi:6667 (IRCNet)
+-!- freenode: irc.freenode.net:6667 (freenode)
+-!- RECON-1: 192.168.0.1:6667 () (02:59 left before reconnecting)
 </pre>
 
-<p>Here you see that we're connected to IRCNet and OPN networks. The
-the IRCNet at the beginning is called the "server tag" while the
+<p>Here you see that we're connected to IRCNet and freenode networks.
+The IRCNet at the beginning is called the "server tag" while the
 (IRCnet) at the end shows the IRC network. Server tag specifies unique
 tag to refer to the server, usually it's the same as the IRC network.
 When the IRC network isn't known it's some part of the server name.
@@ -423,13 +422,13 @@ successful and irssi will try to connect it again in 3 minutes.</p>
 reconnecting, use</p>
 
 <pre>
-     /DISCONNECT ircnet   - disconnect server with tag "ircnet"
-     /DISCONNECT recon-1  - stop trying to reconnect to RECON-1 server
-     /RMRECONNS           - stop all server reconnections
+/DISCONNECT ircnet   - disconnect server with tag "ircnet"
+/DISCONNECT recon-1  - stop trying to reconnect to RECON-1 server
+/RMRECONNS           - stop all server reconnections
 
-     /RECONNECT recon-1   - immediately try reconnecting back to RECON-1
-     /RECONNECT ALL       - immediately try reconnecting back to all
-                           servers in reconnection queue
+/RECONNECT recon-1   - immediately try reconnecting back to RECON-1
+/RECONNECT ALL       - immediately try reconnecting back to all
+                      servers in reconnection queue
 </pre>
 
 <p>Now that you're connected to all your servers, you'll have to know how
@@ -438,8 +437,8 @@ empty window, like status or msgs window. In it, you can specify which
 server to set active with</p>
 
 <pre>
-     /WINDOW SERVER tag    - set server "tag" active
-     Ctrl-X                - set the next server in list active
+/WINDOW SERVER tag    - set server "tag" active
+Ctrl-X                - set the next server in list active
 </pre>
 
 <p>When the server is active, you can use it normally. When there's
@@ -451,9 +450,9 @@ from.</p>
 which server it should use:</p>
 
 <pre>
-     /MSG -tag nick message
-     /JOIN -tag #channel
-     /QUERY -tag nick
+/MSG -tag nick message
+/JOIN -tag #channel
+/QUERY -tag nick
 </pre>
 
 <p><code>/MSG</code> tab completion also automatically adds the
@@ -466,22 +465,22 @@ it is automatically set active in the window. To set the window's server
 sticky use</p>
 
 <pre>
-     /WINDOW SERVER -sticky tag
+/WINDOW SERVER -sticky tag
 </pre>
 
 <p>This is useful if you wish to have multiple status or msgs windows, one
 for each server. Here's how to do them (repeat for each server)</p>
 
 <pre>
-     /WINDOW NEW HIDE
-     /WINDOW NAME (status)
-     /WINDOW LEVEL ALL -MSGS
-     /WINDOW SERVER -sticky ircnet
+/WINDOW NEW HIDE
+/WINDOW NAME (status)
+/WINDOW LEVEL ALL -MSGS
+/WINDOW SERVER -sticky ircnet
 
-     /WINDOW NEW HIDE
-     /WINDOW NAME (msgs)
-     /WINDOW LEVEL MSGS
-     /WINDOW SERVER -sticky ircnet
+/WINDOW NEW HIDE
+/WINDOW NAME (msgs)
+/WINDOW LEVEL MSGS
+/WINDOW SERVER -sticky ircnet
 </pre>
 
 <h3><a id="c7">7. /LASTLOG and jumping around in scrollback</a></h3>
@@ -490,9 +489,9 @@ for each server. Here's how to do them (repeat for each server)</p>
 scrollback buffer. Simplest usages are</p>
 
 <pre>
-     /LASTLOG word     - print all lines with "word" in them
-     /LASTLOG word 10  - print last 10 occurances of "word"
-     /LASTLOG -topics  - print all topic changes
+/LASTLOG word     - print all lines with "word" in them
+/LASTLOG word 10  - print last 10 occurances of "word"
+/LASTLOG -topics  - print all topic changes
 </pre>
 
 <p>If there's more than 1000 lines to be printed, irssi thinks that you
@@ -500,7 +499,7 @@ probably made some mistake and won't print them without <code>-force</code>
 option. If you want to save the full lastlog to file, use</p>
 
 <pre>
-     /LASTLOG -file ~/irc.log
+/LASTLOG -file ~/irc.log
 </pre>
 
 <p>With <code>-file</code> option you don't need <code>-force</code> even
@@ -524,8 +523,8 @@ END</code> command.</p>
 You can configure it with:</p>
 
 <pre>
-     /SET awaylog_level MSGS HILIGHT     - Specifies what messages to log
-     /SET awaylog_file ~/.irssi/away.log - Specifies the file to use
+/SET awaylog_level MSGS HILIGHT     - Specifies what messages to log
+/SET awaylog_file ~/.irssi/away.log - Specifies the file to use
 </pre>
 
 <p>Easiest way to start logging with Irssi is to use autologging. With it
@@ -533,7 +532,7 @@ Irssi logs all channels and private messages to specified directory.
 You can turn it on with</p>
 
 <pre>
-     /SET autolog ON
+/SET autolog ON
 </pre>
 
 <p>By default it logs pretty much everything execept CTCPS or CRAP
@@ -541,14 +540,14 @@ You can turn it on with</p>
 yourself with</p>
 
 <pre>
-     /SET autolog_level ALL -CRAP -CLIENTCRAP -CTCPS (this is the default)
+/SET autolog_level ALL -CRAP -CLIENTCRAP -CTCPS (this is the default)
 </pre>
 
 <p>By default irssi logs to ~/irclogs/&lt;servertag&gt;/&lt;target&gt;.log.
 You can change this with</p>
 
 <pre>
-     /SET autolog_path ~/irclogs/$tag/$0.log (this is the default)
+/SET autolog_path ~/irclogs/$tag/$0.log (this is the default)
 </pre>
 
 <p>The path is automatically created if it doesn't exist. $0 specifies
@@ -557,7 +556,7 @@ logs by adding date/time formats to the file name. The formats are in
 "man strftime" format. For example</p>
 
 <pre>
-     /SET autolog_path ~/irclogs/%Y/$tag/$0.%m-%d.log
+/SET autolog_path ~/irclogs/%Y/$tag/$0.%m-%d.log
 </pre>
 
 <p>For logging only some specific channels or nicks, see <code>/HELP
@@ -579,18 +578,18 @@ that would be to see what it prints in <code>cat</code>. Here's an example
 for pressing F1 key:</p>
 
 <pre>
-     [cras@hurina] ~% cat
-     ^[OP
+[cras@hurina] ~% cat
+^[OP
 </pre>
 
-<p>So in irssi you would use <code>/BIND ^[OP /ECHO F1</code> pressed. If
+<p>So in irssi you would use <code>/BIND ^[OP /ECHO F1 pressed</code>. If
 you use multiple terminals which have different bindings for the key, it
 would be better to use eg.:</p>
 
 <pre>
-     /BIND ^[OP key F1
-     /BIND ^[11~ key F1
-     /BIND F1 /ECHO F1 pressed.
+/BIND ^[OP key F1
+/BIND ^[11~ key F1
+/BIND F1 /ECHO F1 pressed.
 </pre>
 
 <h3><a id="c10">10. Proxies and IRC bouncers</a></h3>
@@ -606,13 +605,13 @@ to servers irc.dalnet and irc.efnet.org. First you'd need to setup the
 bouncer:</p>
 
 <pre>
-     /SET use_proxy ON
-     /SET proxy_address irc.bouncer.org
-     /SET proxy_port 5000
+/SET use_proxy ON
+/SET proxy_address irc.bouncer.org
+/SET proxy_port 5000
 
-     /SET proxy_password YOUR_BNC_PASSWORD_HERE
-     /SET -clear proxy_string
-     /SET proxy_string_after conn %s %d
+/SET proxy_password YOUR_BNC_PASSWORD_HERE
+/SET -clear proxy_string
+/SET proxy_string_after conn %s %d
 </pre>
 
 <p>Then you'll need to add the server connections. These are done
@@ -620,8 +619,8 @@ exactly as if you'd want to connect directly to them. Nothing special
 about them:</p>
 
 <pre>
-     /SERVER ADD -auto -ircnet dalnet irc.dal.net
-     /SERVER ADD -auto -ircnet efnet irc.efnet.org
+/SERVER ADD -auto -ircnet dalnet irc.dal.net
+/SERVER ADD -auto -ircnet efnet irc.efnet.org
 </pre>
 
 <p>With the proxy <code>/SET</code>s however, irssi now connects to those
@@ -637,9 +636,9 @@ you can just forget that your bouncer even exists.</p>
 <p>All proxies have these settings in common:</p>
 
 <pre>
-     /SET use_proxy ON
-     /SET proxy_address &lt;Proxy host address&gt;
-     /SET proxy_port &lt;Proxy port&gt;
+/SET use_proxy ON
+/SET proxy_address &lt;Proxy host address&gt;
+/SET proxy_port &lt;Proxy port&gt;
 </pre>
 
 <p><strong>HTTP proxy</strong></p>
@@ -647,31 +646,31 @@ you can just forget that your bouncer even exists.</p>
 <p>Use these settings with HTTP proxies:</p>
 
 <pre>
-     /SET -clear proxy_password
-     /EVAL SET proxy_string CONNECT %s:%d\n\n
+/SET -clear proxy_password
+/EVAL SET proxy_string CONNECT %s:%d\n\n
 </pre>
 
 <p><strong>BNC</strong></p>
 
 <pre>
-     /SET proxy_password your_pass
-     /SET -clear proxy_string
-     /SET proxy_string_after conn %s %d
+/SET proxy_password your_pass
+/SET -clear proxy_string
+/SET proxy_string_after conn %s %d
 </pre>
 
 <p><strong>dircproxy</strong></p>
 
 <p>dircproxy separates the server connections by passwords. So, if you
 for example have ircnet connection with password ircpass and
-openprojects connection with opnpass, you would do something like
+openprojects connection with freenodepass, you would do something like
 this:</p>
 
 <pre>
-     /SET -clear proxy_password
-     /SET -clear proxy_string
+/SET -clear proxy_password
+/SET -clear proxy_string
 
-     /SERVER ADD -auto -ircnet ircnet fake.ircnet 6667 ircpass
-     /SERVER ADD -auto -ircnet opn fake.opn 6667 opnpass
+/SERVER ADD -auto -ircnet ircnet fake.ircnet 6667 ircpass
+/SERVER ADD -auto -ircnet freenode fake.freenode 6667 freenodepass
 </pre>
 
 <p>The server name and port you give isn't used anywhere, so you can
@@ -685,13 +684,13 @@ connecting to different servers. You can manage this in a bit same way
 as with dircproxy, by creating fake connections:</p>
 
 <pre>
-    /SET -clear proxy_password
-    /SET -clear proxy_string
+/SET -clear proxy_password
+/SET -clear proxy_string
 
-    /IRCNET ADD -user ircnetuser ircnet
-    /SERVER ADD -auto -ircnet ircnet fake.ircnet 6667 ircpass
-    /IRCNET ADD -user opnuser opn
-    /SERVER ADD -auto -ircnet opn fake.opn 6667 opnpass
+/IRCNET ADD -user ircnetuser ircnet
+/SERVER ADD -auto -ircnet ircnet fake.ircnet 6667 ircpass
+/IRCNET ADD -user freenodeuser freenode
+/SERVER ADD -auto -ircnet freenode fake.freenode 6667 freenodepass
 </pre>
 
 <p>So, you'll specify the usernames with <code>/IRCNET ADD</code> command,
@@ -717,9 +716,9 @@ ports, like you can share ircnet in port 2777 and efnet in port 2778.</p>
 <p>Usage in proxy side:</p>
 
 <pre>
-     /LOAD proxy
-     /SET irssiproxy_password &lt;password&gt;
-     /SET irssiproxy_ports &lt;ircnet&gt;=&lt;port&gt; ... (eg. ircnet=2777 efnet=2778)
+/LOAD proxy
+/SET irssiproxy_password &lt;password&gt;
+/SET irssiproxy_ports &lt;ircnet&gt;=&lt;port&gt; ... (eg. ircnet=2777 efnet=2778)
 </pre>
 
 <p><strong>NOTE</strong>: you <strong>MUST</strong> add all the servers you
@@ -728,7 +727,7 @@ are using to server and ircnet lists with <code>/SERVER ADD</code> and
 reason, and you only use one server connection, you may simply set:</p>
 
 <pre>
-     /SET irssiproxy_ports *=2777
+/SET irssiproxy_ports *=2777
 </pre>
 
 <p>Usage in client side:</p>
@@ -737,8 +736,8 @@ reason, and you only use one server connection, you may simply set:</p>
 specified in <code>/SET irssiproxy_password</code>. For example:</p>
 
 <pre>
-     /SERVER ADD -ircnet ircnet my.irssi-proxy.org 2777 secret
-     /SERVER ADD -ircnet efnet my.irssi-proxy.org 2778 secret
+/SERVER ADD -ircnet ircnet my.irssi-proxy.org 2777 secret
+/SERVER ADD -ircnet efnet my.irssi-proxy.org 2778 secret
 </pre>
 
 <p>Irssi proxy works fine with other IRC clients as well.</p>
@@ -755,14 +754,14 @@ proxy</code> settings don't have anything to do with socks however.
 give it with:</p>
 
 <pre>
-     /SET proxy_password &lt;password&gt;
+/SET proxy_password &lt;password&gt;
 </pre>
 
 <p>Irssi's defaults for connect strings are</p>
 
 <pre>
-     /SET proxy_string CONNECT %s %d
-     /SET proxy_string_after
+/SET proxy_string CONNECT %s %d
+/SET proxy_string_after
 </pre>
 
 <p>The proxy_string is sent before NICK/USER commands, the
@@ -933,11 +932,11 @@ of them you might want to change (the default value is shown):</p>
 <p><code>/STATUSBAR</code> displays a list of statusbars:</p>
 
 <pre>
-     Name                           Type   Placement Position Visible
-     window                         window bottom    0        always
-     window_inact                   window bottom    1        inactive
-     prompt                         root   bottom    100      always
-     topic                          root   top       1        always
+Name                           Type   Placement Position Visible
+window                         window bottom    0        always
+window_inact                   window bottom    1        inactive
+prompt                         root   bottom    100      always
+topic                          root   top       1        always
 </pre>
 
 <p><code>/STATUSBAR &lt;name&gt;</code> prints the statusbar settings and
@@ -954,18 +953,18 @@ useful only with split windows, one split window is active and the rest
 are inactive. These settings can be changed with:</p>
 
 <pre>
-     STATUSBAR &lt;name&gt; TYPE window|root
-     STATUSBAR &lt;name&gt; PLACEMENT top|bottom
-     STATUSBAR &lt;name&gt; POSITION &lt;num&gt;
-     STATUSBAR &lt;name&gt; VISIBLE always|active|inactive
+/STATUSBAR &lt;name&gt; TYPE window|root
+/STATUSBAR &lt;name&gt; PLACEMENT top|bottom
+/STATUSBAR &lt;name&gt; POSITION &lt;num&gt;
+/STATUSBAR &lt;name&gt; VISIBLE always|active|inactive
 </pre>
 
 <p>When loading a new statusbar scripts, you'll need to also specify
 where you want to show it. Statusbar items can be modified with:</p>
 
 <pre>
-     STATUSBAR &lt;name&gt; ADD [-before | -after &lt;item&gt;] [-priority #] [-alignment left|right] &lt;item&gt;
-     STATUSBAR &lt;name&gt; REMOVE &lt;item&gt;
+/STATUSBAR &lt;name&gt; ADD [-before | -after &lt;item&gt;] [-priority #] [-alignment left|right] &lt;item&gt;
+/STATUSBAR &lt;name&gt; REMOVE &lt;item&gt;
 </pre>
 
 <p>The item name with statusbar scripts is usually same as the script's
diff --git a/apps/irssi/glib-2.0.m4_ b/apps/irssi/glib-2.0.m4_
new file mode 100644 (file)
index 0000000..0c1ae85
--- /dev/null
@@ -0,0 +1,212 @@
+# Configure paths for GLIB
+# Owen Taylor     1997-2001
+
+dnl AM_PATH_GLIB_2_0([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, MODULES]]]])
+dnl Test for GLIB, and define GLIB_CFLAGS and GLIB_LIBS, if gmodule, gobject or 
+dnl gthread is specified in MODULES, pass to pkg-config
+dnl
+AC_DEFUN(AM_PATH_GLIB_2_0,
+[dnl 
+dnl Get the cflags and libraries from pkg-config
+dnl
+AC_ARG_ENABLE(glibtest, [  --disable-glibtest      do not try to compile and run a test GLIB program],
+                   , enable_glibtest=yes)
+
+  pkg_config_args=glib-2.0
+  for module in . $4
+  do
+      case "$module" in
+         gmodule) 
+             pkg_config_args="$pkg_config_args gmodule-2.0"
+         ;;
+         gobject) 
+             pkg_config_args="$pkg_config_args gobject-2.0"
+         ;;
+         gthread) 
+             pkg_config_args="$pkg_config_args gthread-2.0"
+         ;;
+      esac
+  done
+
+  AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
+
+  no_glib=""
+
+  if test x$PKG_CONFIG != xno ; then
+    if $PKG_CONFIG --atleast-pkgconfig-version 0.7 ; then
+      :
+    else
+      echo *** pkg-config too old; version 0.7 or better required.
+      no_glib=yes
+      PKG_CONFIG=no
+    fi
+  else
+    no_glib=yes
+  fi
+
+  min_glib_version=ifelse([$1], ,2.0.0,$1)
+  AC_MSG_CHECKING(for GLIB - version >= $min_glib_version)
+
+  if test x$PKG_CONFIG != xno ; then
+    ## don't try to run the test against uninstalled libtool libs
+    if $PKG_CONFIG --uninstalled $pkg_config_args; then
+         echo "Will use uninstalled version of GLib found in PKG_CONFIG_PATH"
+         enable_glibtest=no
+    fi
+
+    if $PKG_CONFIG --atleast-version $min_glib_version $pkg_config_args; then
+         :
+    else
+         no_glib=yes
+    fi
+  fi
+
+  if test x"$no_glib" = x ; then
+    GLIB_GENMARSHAL=`$PKG_CONFIG --variable=glib_genmarshal glib-2.0`
+    GOBJECT_QUERY=`$PKG_CONFIG --variable=gobject_query glib-2.0`
+    GLIB_MKENUMS=`$PKG_CONFIG --variable=glib_mkenums glib-2.0`
+
+    GLIB_CFLAGS=`$PKG_CONFIG --cflags $pkg_config_args`
+    GLIB_LIBS=`$PKG_CONFIG --libs $pkg_config_args`
+    glib_config_major_version=`$PKG_CONFIG --modversion glib-2.0 | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+    glib_config_minor_version=`$PKG_CONFIG --modversion glib-2.0 | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+    glib_config_micro_version=`$PKG_CONFIG --modversion glib-2.0 | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+    if test "x$enable_glibtest" = "xyes" ; then
+      ac_save_CFLAGS="$CFLAGS"
+      ac_save_LIBS="$LIBS"
+      CFLAGS="$CFLAGS $GLIB_CFLAGS"
+      LIBS="$GLIB_LIBS $LIBS"
+dnl
+dnl Now check if the installed GLIB is sufficiently new. (Also sanity
+dnl checks the results of pkg-config to some extent)
+dnl
+      rm -f conf.glibtest
+      AC_TRY_RUN([
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int 
+main ()
+{
+  int major, minor, micro;
+  char *tmp_version;
+
+  system ("touch conf.glibtest");
+
+  /* HP/UX 9 (%@#!) writes to sscanf strings */
+  tmp_version = g_strdup("$min_glib_version");
+  if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
+     printf("%s, bad version string\n", "$min_glib_version");
+     exit(1);
+   }
+
+  if ((glib_major_version != $glib_config_major_version) ||
+      (glib_minor_version != $glib_config_minor_version) ||
+      (glib_micro_version != $glib_config_micro_version))
+    {
+      printf("\n*** 'pkg-config --modversion glib-2.0' returned %d.%d.%d, but GLIB (%d.%d.%d)\n", 
+             $glib_config_major_version, $glib_config_minor_version, $glib_config_micro_version,
+             glib_major_version, glib_minor_version, glib_micro_version);
+      printf ("*** was found! If pkg-config was correct, then it is best\n");
+      printf ("*** to remove the old version of GLib. You may also be able to fix the error\n");
+      printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n");
+      printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n");
+      printf("*** required on your system.\n");
+      printf("*** If pkg-config was wrong, set the environment variable PKG_CONFIG_PATH\n");
+      printf("*** to point to the correct configuration files\n");
+    } 
+  else if ((glib_major_version != GLIB_MAJOR_VERSION) ||
+          (glib_minor_version != GLIB_MINOR_VERSION) ||
+           (glib_micro_version != GLIB_MICRO_VERSION))
+    {
+      printf("*** GLIB header files (version %d.%d.%d) do not match\n",
+            GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION);
+      printf("*** library (version %d.%d.%d)\n",
+            glib_major_version, glib_minor_version, glib_micro_version);
+    }
+  else
+    {
+      if ((glib_major_version > major) ||
+        ((glib_major_version == major) && (glib_minor_version > minor)) ||
+        ((glib_major_version == major) && (glib_minor_version == minor) && (glib_micro_version >= micro)))
+      {
+        return 0;
+       }
+     else
+      {
+        printf("\n*** An old version of GLIB (%d.%d.%d) was found.\n",
+               glib_major_version, glib_minor_version, glib_micro_version);
+        printf("*** You need a version of GLIB newer than %d.%d.%d. The latest version of\n",
+              major, minor, micro);
+        printf("*** GLIB is always available from ftp://ftp.gtk.org.\n");
+        printf("***\n");
+        printf("*** If you have already installed a sufficiently new version, this error\n");
+        printf("*** probably means that the wrong copy of the pkg-config shell script is\n");
+        printf("*** being found. The easiest way to fix this is to remove the old version\n");
+        printf("*** of GLIB, but you can also set the PKG_CONFIG environment to point to the\n");
+        printf("*** correct copy of pkg-config. (In this case, you will have to\n");
+        printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
+        printf("*** so that the correct libraries are found at run-time))\n");
+      }
+    }
+  return 1;
+}
+],, no_glib=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
+       CFLAGS="$ac_save_CFLAGS"
+       LIBS="$ac_save_LIBS"
+     fi
+  fi
+  if test "x$no_glib" = x ; then
+     AC_MSG_RESULT(yes (version $glib_config_major_version.$glib_config_minor_version.$glib_config_micro_version))
+     ifelse([$2], , :, [$2])     
+  else
+     AC_MSG_RESULT(no)
+     if test "$PKG_CONFIG" = "no" ; then
+       echo "*** A new enough version of pkg-config was not found."
+       echo "*** See http://www.freedesktop.org/software/pkgconfig/"
+     else
+       if test -f conf.glibtest ; then
+        :
+       else
+          echo "*** Could not run GLIB test program, checking why..."
+          CFLAGS="$CFLAGS $GLIB_CFLAGS"
+          LIBS="$LIBS $GLIB_LIBS"
+          AC_TRY_LINK([
+#include <glib.h>
+#include <stdio.h>
+],      [ return ((glib_major_version) || (glib_minor_version) || (glib_micro_version)); ],
+        [ echo "*** The test program compiled, but did not run. This usually means"
+          echo "*** that the run-time linker is not finding GLIB or finding the wrong"
+          echo "*** version of GLIB. If it is not finding GLIB, you'll need to set your"
+          echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
+          echo "*** to the installed location  Also, make sure you have run ldconfig if that"
+          echo "*** is required on your system"
+         echo "***"
+          echo "*** If you have an old version installed, it is best to remove it, although"
+          echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" ],
+        [ echo "*** The test program failed to compile or link. See the file config.log for the"
+          echo "*** exact error that occured. This usually means GLIB was incorrectly installed"
+          echo "*** or that you have moved GLIB since it was installed. In the latter case, you"
+          echo "*** may want to edit the pkg-config script: $PKG_CONFIG" ])
+          CFLAGS="$ac_save_CFLAGS"
+          LIBS="$ac_save_LIBS"
+       fi
+     fi
+     GLIB_CFLAGS=""
+     GLIB_LIBS=""
+     GLIB_GENMARSHAL=""
+     GOBJECT_QUERY=""
+     GLIB_MKENUMS=""
+     ifelse([$3], , :, [$3])
+  fi
+  AC_SUBST(GLIB_CFLAGS)
+  AC_SUBST(GLIB_LIBS)
+  AC_SUBST(GLIB_GENMARSHAL)
+  AC_SUBST(GOBJECT_QUERY)
+  AC_SUBST(GLIB_MKENUMS)
+  rm -f conf.glibtest
+])
diff --git a/apps/irssi/glib.m4_ b/apps/irssi/glib.m4_
new file mode 100644 (file)
index 0000000..b8094bb
--- /dev/null
@@ -0,0 +1,196 @@
+# Configure paths for GLIB
+# Owen Taylor     97-11-3
+
+dnl AM_PATH_GLIB([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, MODULES]]]])
+dnl Test for GLIB, and define GLIB_CFLAGS and GLIB_LIBS, if "gmodule" or 
+dnl gthread is specified in MODULES, pass to glib-config
+dnl
+AC_DEFUN(AM_PATH_GLIB,
+[dnl 
+dnl Get the cflags and libraries from the glib-config script
+dnl
+AC_ARG_WITH(glib-prefix,[  --with-glib-prefix=PFX   Prefix where GLIB is installed (optional)],
+            glib_config_prefix="$withval", glib_config_prefix="")
+AC_ARG_WITH(glib-exec-prefix,[  --with-glib-exec-prefix=PFX Exec prefix where GLIB is installed (optional)],
+            glib_config_exec_prefix="$withval", glib_config_exec_prefix="")
+AC_ARG_ENABLE(glibtest, [  --disable-glibtest       Do not try to compile and run a test GLIB program],
+                   , enable_glibtest=yes)
+
+  if test x$glib_config_exec_prefix != x ; then
+     glib_config_args="$glib_config_args --exec-prefix=$glib_config_exec_prefix"
+     if test x${GLIB_CONFIG+set} != xset ; then
+        GLIB_CONFIG=$glib_config_exec_prefix/bin/glib-config
+     fi
+  fi
+  if test x$glib_config_prefix != x ; then
+     glib_config_args="$glib_config_args --prefix=$glib_config_prefix"
+     if test x${GLIB_CONFIG+set} != xset ; then
+        GLIB_CONFIG=$glib_config_prefix/bin/glib-config
+     fi
+  fi
+
+  for module in . $4
+  do
+      case "$module" in
+         gmodule) 
+             glib_config_args="$glib_config_args gmodule"
+         ;;
+         gthread) 
+             glib_config_args="$glib_config_args gthread"
+         ;;
+      esac
+  done
+
+  AC_PATH_PROG(GLIB_CONFIG, glib-config, no)
+  min_glib_version=ifelse([$1], ,0.99.7,$1)
+  AC_MSG_CHECKING(for GLIB - version >= $min_glib_version)
+  no_glib=""
+  if test "$GLIB_CONFIG" = "no" ; then
+    no_glib=yes
+  else
+    GLIB_CFLAGS=`$GLIB_CONFIG $glib_config_args --cflags`
+    GLIB_LIBS=`$GLIB_CONFIG $glib_config_args --libs`
+    glib_config_major_version=`$GLIB_CONFIG $glib_config_args --version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+    glib_config_minor_version=`$GLIB_CONFIG $glib_config_args --version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+    glib_config_micro_version=`$GLIB_CONFIG $glib_config_args --version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+    if test "x$enable_glibtest" = "xyes" ; then
+      ac_save_CFLAGS="$CFLAGS"
+      ac_save_LIBS="$LIBS"
+      CFLAGS="$CFLAGS $GLIB_CFLAGS"
+      LIBS="$GLIB_LIBS $LIBS"
+dnl
+dnl Now check if the installed GLIB is sufficiently new. (Also sanity
+dnl checks the results of glib-config to some extent
+dnl
+      rm -f conf.glibtest
+      AC_TRY_RUN([
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int 
+main ()
+{
+  int major, minor, micro;
+  char *tmp_version;
+
+  system ("touch conf.glibtest");
+
+  /* HP/UX 9 (%@#!) writes to sscanf strings */
+  tmp_version = g_strdup("$min_glib_version");
+  if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
+     printf("%s, bad version string\n", "$min_glib_version");
+     exit(1);
+   }
+
+  if ((glib_major_version != $glib_config_major_version) ||
+      (glib_minor_version != $glib_config_minor_version) ||
+      (glib_micro_version != $glib_config_micro_version))
+    {
+      printf("\n*** 'glib-config --version' returned %d.%d.%d, but GLIB (%d.%d.%d)\n", 
+             $glib_config_major_version, $glib_config_minor_version, $glib_config_micro_version,
+             glib_major_version, glib_minor_version, glib_micro_version);
+      printf ("*** was found! If glib-config was correct, then it is best\n");
+      printf ("*** to remove the old version of GLIB. You may also be able to fix the error\n");
+      printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n");
+      printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n");
+      printf("*** required on your system.\n");
+      printf("*** If glib-config was wrong, set the environment variable GLIB_CONFIG\n");
+      printf("*** to point to the correct copy of glib-config, and remove the file config.cache\n");
+      printf("*** before re-running configure\n");
+    } 
+  else if ((glib_major_version != GLIB_MAJOR_VERSION) ||
+          (glib_minor_version != GLIB_MINOR_VERSION) ||
+           (glib_micro_version != GLIB_MICRO_VERSION))
+    {
+      printf("*** GLIB header files (version %d.%d.%d) do not match\n",
+            GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION);
+      printf("*** library (version %d.%d.%d)\n",
+            glib_major_version, glib_minor_version, glib_micro_version);
+    }
+  else
+    {
+      if ((glib_major_version > major) ||
+        ((glib_major_version == major) && (glib_minor_version > minor)) ||
+        ((glib_major_version == major) && (glib_minor_version == minor) && (glib_micro_version >= micro)))
+      {
+        return 0;
+       }
+     else
+      {
+        printf("\n*** An old version of GLIB (%d.%d.%d) was found.\n",
+               glib_major_version, glib_minor_version, glib_micro_version);
+        printf("*** You need a version of GLIB newer than %d.%d.%d. The latest version of\n",
+              major, minor, micro);
+        printf("*** GLIB is always available from ftp://ftp.gtk.org.\n");
+        printf("***\n");
+        printf("*** If you have already installed a sufficiently new version, this error\n");
+        printf("*** probably means that the wrong copy of the glib-config shell script is\n");
+        printf("*** being found. The easiest way to fix this is to remove the old version\n");
+        printf("*** of GLIB, but you can also set the GLIB_CONFIG environment to point to the\n");
+        printf("*** correct copy of glib-config. (In this case, you will have to\n");
+        printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
+        printf("*** so that the correct libraries are found at run-time))\n");
+      }
+    }
+  return 1;
+}
+],, no_glib=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
+       CFLAGS="$ac_save_CFLAGS"
+       LIBS="$ac_save_LIBS"
+     fi
+  fi
+  if test "x$no_glib" = x ; then
+     AC_MSG_RESULT(yes)
+     ifelse([$2], , :, [$2])     
+  else
+     AC_MSG_RESULT(no)
+     if test "$GLIB_CONFIG" = "no" ; then
+       echo "*** The glib-config script installed by GLIB could not be found"
+       echo "*** If GLIB was installed in PREFIX, make sure PREFIX/bin is in"
+       echo "*** your path, or set the GLIB_CONFIG environment variable to the"
+       echo "*** full path to glib-config."
+     else
+       if test -f conf.glibtest ; then
+        :
+       else
+          echo "*** Could not run GLIB test program, checking why..."
+          CFLAGS="$CFLAGS $GLIB_CFLAGS"
+          LIBS="$LIBS $GLIB_LIBS"
+          AC_TRY_LINK([
+#include <glib.h>
+#include <stdio.h>
+],      [ return ((glib_major_version) || (glib_minor_version) || (glib_micro_version)); ],
+        [ echo "*** The test program compiled, but did not run. This usually means"
+          echo "*** that the run-time linker is not finding GLIB or finding the wrong"
+          echo "*** version of GLIB. If it is not finding GLIB, you'll need to set your"
+          echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
+          echo "*** to the installed location  Also, make sure you have run ldconfig if that"
+          echo "*** is required on your system"
+         echo "***"
+          echo "*** If you have an old version installed, it is best to remove it, although"
+          echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"
+          echo "***"
+          echo "*** If you have a RedHat 5.0 system, you should remove the GTK package that"
+          echo "*** came with the system with the command"
+          echo "***"
+          echo "***    rpm --erase --nodeps gtk gtk-devel" ],
+        [ echo "*** The test program failed to compile or link. See the file config.log for the"
+          echo "*** exact error that occured. This usually means GLIB was incorrectly installed"
+          echo "*** or that you have moved GLIB since it was installed. In the latter case, you"
+          echo "*** may want to edit the glib-config script: $GLIB_CONFIG" ])
+          CFLAGS="$ac_save_CFLAGS"
+          LIBS="$ac_save_LIBS"
+       fi
+     fi
+     GLIB_CFLAGS=""
+     GLIB_LIBS=""
+     ifelse([$3], , :, [$3])
+  fi
+  AC_SUBST(GLIB_CFLAGS)
+  AC_SUBST(GLIB_LIBS)
+  rm -f conf.glibtest
+])
index 3076247c7fdd86a2d4ee9bc3d36b52688d1cc65c..cd529ed06309bbdfa9f8724a6cedace189279ed8 100644 (file)
@@ -1,6 +1,9 @@
 PROG_LIBS="@PROG_LIBS@"
-PERL_LDFLAGS="@PERL_LDFLAGS@"
 COMMON_LIBS="@COMMON_LIBS@"
 
+PERL_LINK_LIBS="@PERL_LINK_LIBS@"
+PERL_FE_LINK_LIBS="@PERL_FE_LINK_LIBS@"
+PERL_LINK_FLAGS="@PERL_LINK_FLAGS@"
+
 CHAT_MODULES="@CHAT_MODULES@"
 irc_MODULES="@irc_MODULES@"
diff --git a/apps/irssi/irssi.cvs b/apps/irssi/irssi.cvs
new file mode 100644 (file)
index 0000000..e69de29
index c15069cf39a83eec444c8e60ead794dc3974ee41..d902f7868d07582a1953285d6b4743407532890d 100644 (file)
@@ -2,7 +2,7 @@
 Name:          irssi
 Version:       @VERSION@
 Release:       1
-Vendor:        Timo Sirainen <tss@iki.fi>
+Vendor:        Timo Sirainen <cras@irssi.org>
 Summary:       Irssi is a IRC client
 Copyright:     GPL
 Group:                 Applications/Communications
index 0f91a4b04c1f7341eaa221566d7b6d3f2ffca766..6a6aeef31eae3396bcdfa3a7fd1b56b24812282d 100644 (file)
@@ -32,6 +32,7 @@ libcore_a_SOURCES = \
        net-nonblock.c \
        net-sendbuffer.c \
        network.c \
+       network-openssl.c \
        nicklist.c \
        nickmatch-cache.c \
        pidwait.c \
@@ -44,8 +45,7 @@ libcore_a_SOURCES = \
        settings.c \
        signals.c \
        special-vars.c \
-       write-buffer.c \
-       blob.c
+       write-buffer.c
 
 structure_headers = \
        channel-rec.h \
@@ -55,8 +55,7 @@ structure_headers = \
        server-rec.h \
        server-setup-rec.h \
        server-connect-rec.h \
-       window-item-rec.h \
-       blob.h
+       window-item-rec.h
 
 noinst_HEADERS = \
        args.h \
diff --git a/apps/irssi/src/core/blob.c b/apps/irssi/src/core/blob.c
deleted file mode 100644 (file)
index 51fe5e5..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "common.h"
-#include "blob.h"
-#include "modules.h"
-
-void blob_fill(BLOB_REC *blob)
-{
-       blob->type = module_get_uniq_id("BLOB", 0);
-}
diff --git a/apps/irssi/src/core/blob.h b/apps/irssi/src/core/blob.h
deleted file mode 100644 (file)
index ec9e553..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef __BLOB_H__
-#define __BLOB_H__
-
-#include "modules.h"
-
-struct _BLOB_REC {
-       int type;
-       void *data;
-       guint32 octets;
-};
-
-typedef struct _BLOB_REC BLOB_REC;
-
-void blob_fill(BLOB_REC *blob);
-
-#endif
index f3ec5f8d494863e23dfb9448c0c93951eba44f8b..7b806ca440d3cea86bad0c31d572b4a208fc0c79 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "window-item-rec.h"
 
+char *name;
 char *topic;
 char *topic_by;
 time_t topic_time;
index 62d43b2c6ac0c3abf1e9c0054672fc4a55fe3bcd..a61ccb5625889aa943f4202b7eb0e1bf53f24ef9 100644 (file)
@@ -54,6 +54,8 @@ static void channel_setup_save(CHANNEL_SETUP_REC *channel)
 
 void channel_setup_create(CHANNEL_SETUP_REC *channel)
 {
+       channel->type = module_get_uniq_id("CHANNEL SETUP", 0);
+
        if (g_slist_find(setupchannels, channel) == NULL)
                setupchannels = g_slist_append(setupchannels, channel);
        channel_setup_save(channel);
index 1884c4021d86dd34585dc37e0d047c1ecba49dc8..9a92b896caac2bc2dd6692aae625c2b8ef704474 100644 (file)
@@ -35,24 +35,37 @@ static char *get_join_data(CHANNEL_REC *channel)
        return g_strdup(channel->name);
 }
 
-void channel_init(CHANNEL_REC *channel, int automatic)
+static const char *channel_get_target(WI_ITEM_REC *item)
+{
+       return ((CHANNEL_REC *) item)->name;
+}
+
+void channel_init(CHANNEL_REC *channel, SERVER_REC *server, const char *name,
+                 const char *visible_name, int automatic)
 {
        g_return_if_fail(channel != NULL);
-       g_return_if_fail(channel->name != NULL);
+       g_return_if_fail(name != NULL);
+       g_return_if_fail(server != NULL);
 
-       channels = g_slist_append(channels, channel);
-       if (channel->server != NULL) {
-               channel->server->channels =
-                       g_slist_append(channel->server->channels, channel);
-       }
+       if (visible_name == NULL)
+               visible_name = name;
 
         MODULE_DATA_INIT(channel);
        channel->type = module_get_uniq_id_str("WINDOW ITEM TYPE", "CHANNEL");
         channel->destroy = (void (*) (WI_ITEM_REC *)) channel_destroy;
-        channel->mode = g_strdup("");
-       channel->createtime = time(NULL);
+       channel->get_target = channel_get_target;
         channel->get_join_data = get_join_data;
 
+       channel->chat_type = server->chat_type;
+       channel->server = server;
+       channel->name = g_strdup(name);
+       channel->visible_name = g_strdup(visible_name);
+       channel->mode = g_strdup("");
+       channel->createtime = time(NULL);
+
+       channels = g_slist_append(channels, channel);
+       server->channels = g_slist_append(server->channels, channel);
+
        signal_emit("channel created", 2, channel, GINT_TO_POINTER(automatic));
 }
 
@@ -64,8 +77,9 @@ void channel_destroy(CHANNEL_REC *channel)
        channel->destroying = TRUE;
 
        channels = g_slist_remove(channels, channel);
-       if (!channel->server->disconnected)
-               channel->server->channels = g_slist_remove(channel->server->channels, channel);
+       channel->server->channels =
+               g_slist_remove(channel->server->channels, channel);
+
        signal_emit("channel destroyed", 1, channel);
 
         MODULE_DATA_DEINIT(channel);
@@ -116,6 +130,26 @@ CHANNEL_REC *channel_find(SERVER_REC *server, const char *name)
                                   (void *) name);
 }
 
+void channel_change_name(CHANNEL_REC *channel, const char *name)
+{
+       g_return_if_fail(IS_CHANNEL(channel));
+
+       g_free(channel->name);
+       channel->name = g_strdup(name);
+
+       signal_emit("channel name changed", 1, channel);
+}
+
+void channel_change_visible_name(CHANNEL_REC *channel, const char *name)
+{
+       g_return_if_fail(IS_CHANNEL(channel));
+
+       g_free(channel->visible_name);
+       channel->visible_name = g_strdup(name);
+
+       signal_emit("window item name changed", 1, channel);
+}
+
 static CHANNEL_REC *channel_find_servers(GSList *servers, const char *name)
 {
        return gslist_foreach_find(servers,
index 98b75ee0cf392a4f3185965e516350f1701ed26d..0839d69bea4c60d582e2f5ecc39b12ae771ce34a 100644 (file)
@@ -19,12 +19,16 @@ struct _CHANNEL_REC {
 extern GSList *channels;
 
 /* Create new channel record */
-void channel_init(CHANNEL_REC *channel, int automatic);
+void channel_init(CHANNEL_REC *channel, SERVER_REC *server, const char *name,
+                 const char *visible_name, int automatic);
 void channel_destroy(CHANNEL_REC *channel);
 
 /* find channel by name, if `server' is NULL, search from all servers */
 CHANNEL_REC *channel_find(SERVER_REC *server, const char *name);
 
+void channel_change_name(CHANNEL_REC *channel, const char *name);
+void channel_change_visible_name(CHANNEL_REC *channel, const char *name);
+
 /* Send the auto send command to channel */
 void channel_send_autocommands(CHANNEL_REC *channel);
 
index 933cc3f578aa3c1d877459d63abf3de96abfc42c..aff0d8b77ad446bc0258772ac5868b9751aa241b 100644 (file)
@@ -69,7 +69,7 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr,
                g_hash_table_lookup(optlist, proto->chatnet);
        conn = server_create_conn(proto != NULL ? proto->id : -1, addr,
                                  atoi(portstr), chatnet, password, nick);
-        if (proto == NULL)
+       if (proto == NULL)
                proto = chat_protocol_find_id(conn->chat_type);
 
        if (proto->not_initialized) {
@@ -80,17 +80,24 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr,
                return NULL;
        }
 
+       if (strchr(addr, '/') != NULL)
+               conn->unix_socket = TRUE;
+
        if (g_hash_table_lookup(optlist, "6") != NULL)
                conn->family = AF_INET6;
        else if (g_hash_table_lookup(optlist, "4") != NULL)
                conn->family = AF_INET;
 
+       if(g_hash_table_lookup(optlist, "ssl") != NULL)
+               conn->use_ssl = TRUE;
+
        if (g_hash_table_lookup(optlist, "!") != NULL)
                conn->no_autojoin_channels = TRUE;
 
        if (g_hash_table_lookup(optlist, "noproxy") != NULL)
                 g_free_and_null(conn->proxy);
 
+
        *rawlog_file = g_strdup(g_hash_table_lookup(optlist, "rawlog"));
 
         host = g_hash_table_lookup(optlist, "host");
@@ -105,7 +112,7 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr,
         return conn;
 }
 
-/* SYNTAX: CONNECT [-4 | -6] [-ircnet <ircnet>] [-host <hostname>]
+/* SYNTAX: CONNECT [-4 | -6] [-ssl] [-ircnet <ircnet>] [-host <hostname>]
                    <address>|<chatnet> [<port> [<password> [<nick>]]] */
 static void cmd_connect(const char *data)
 {
@@ -115,7 +122,7 @@ static void cmd_connect(const char *data)
 
        conn = get_server_connect(data, NULL, &rawlog_file);
        if (conn != NULL) {
-               server = CHAT_PROTOCOL(conn)->server_connect(conn);
+               server = server_connect(conn);
                 server_connect_unref(conn);
 
                if (server != NULL && rawlog_file != NULL)
@@ -206,7 +213,7 @@ static void sig_default_command_server(const char *data, SERVER_REC *server,
         signal_emit("command server connect", 3, data, server, item);
 }
 
-/* SYNTAX: SERVER [-4 | -6] [-ircnet <ircnet>] [-host <hostname>]
+/* SYNTAX: SERVER [-4 | -6] [-ssl] [-ircnet <ircnet>] [-host <hostname>]
                   [+]<address>|<chatnet> [<port> [<password> [<nick>]]] */
 static void cmd_server_connect(const char *data, SERVER_REC *server)
 {
@@ -221,7 +228,7 @@ static void cmd_server_connect(const char *data, SERVER_REC *server)
        if (conn != NULL) {
                if (!plus_addr)
                        update_reconnection(conn, server);
-               server = CHAT_PROTOCOL(conn)->server_connect(conn);
+               server = server_connect(conn);
                server_connect_unref(conn);
 
                if (server != NULL && rawlog_file != NULL)
@@ -242,8 +249,11 @@ static void cmd_disconnect(const char *data, SERVER_REC *server)
        if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &tag, &msg))
                return;
 
-       if (*tag != '\0' && strcmp(tag, "*") != 0)
+       if (*tag != '\0' && strcmp(tag, "*") != 0) {
                server = server_find_tag(tag);
+               if (server == NULL)
+                       server = server_find_lookup_tag(tag);
+       }
        if (server == NULL) cmd_param_error(CMDERR_NOT_CONNECTED);
 
        if (*msg == '\0') msg = (char *) settings_get_str("quit_message");
@@ -344,9 +354,8 @@ static void cmd_msg(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
 
                target_type = IS_CHANNEL(item) ?
                        SEND_TARGET_CHANNEL : SEND_TARGET_NICK;
-               target = item->name;
-       }
-       else if (g_hash_table_lookup(optlist, "channel") != NULL)
+               target = (char *) window_item_get_target(item);
+       } else if (g_hash_table_lookup(optlist, "channel") != NULL)
                 target_type = SEND_TARGET_CHANNEL;
        else if (g_hash_table_lookup(optlist, "nick") != NULL)
                target_type = SEND_TARGET_NICK;
@@ -434,7 +443,7 @@ void chat_commands_init(void)
 
         signal_add("default command server", (SIGNAL_FUNC) sig_default_command_server);
 
-       command_set_options("connect", "4 6 !! +host noproxy -rawlog");
+       command_set_options("connect", "4 6 !! ssl +host noproxy -rawlog");
        command_set_options("join", "invite");
        command_set_options("msg", "channel nick");
 }
index ad8c64ba6f7905e083ef4cd08226f1ac0a351961..8b7dc170fb11e93b0fdcbf7070ed9d98d55e801c 100644 (file)
@@ -17,8 +17,10 @@ struct _CHAT_PROTOCOL_REC {
        SERVER_CONNECT_REC *(*create_server_connect) (void);
         void (*destroy_server_connect) (SERVER_CONNECT_REC *);
 
-        SERVER_REC *(*server_connect) (SERVER_CONNECT_REC *);
-        CHANNEL_REC *(*channel_create) (SERVER_REC *, const char *, int);
+        SERVER_REC *(*server_init_connect) (SERVER_CONNECT_REC *);
+        void (*server_connect) (SERVER_REC *);
+       CHANNEL_REC *(*channel_create) (SERVER_REC *, const char *,
+                                       const char *, int);
         QUERY_REC *(*query_create) (const char *, const char *, int);
 };
 
index 502d11d7fbc1f1dde72c203eed90552aef4e202d..f7b0ec627ce2d06dbb77fbf014b6f445b6cce179 100644 (file)
@@ -118,8 +118,7 @@ static void sig_connected(SERVER_REC *server)
 
        g_return_if_fail(IS_SERVER(server));
 
-       if (server->connrec->chatnet == NULL ||
-           server->session_reconnect)
+       if (server->connrec->chatnet == NULL || server->session_reconnect)
                return;
 
        rec = chatnet_find(server->connrec->chatnet);
index 96a740088015aab24d271e97d8fb1858cf6defcc..0669ddedda51a6915b15243682ace08e5e3151e3 100644 (file)
@@ -497,13 +497,17 @@ static char *cmd_get_quoted_param(char **data)
        quote = **data; (*data)++;
 
        pos = *data;
-       while (**data != '\0' && **data != quote) {
+       while (**data != '\0' && (**data != quote || (*data)[1] != ' ')) {
                if (**data == '\\' && (*data)[1] != '\0')
                         g_memmove(*data, (*data)+1, strlen(*data));
                (*data)++;
        }
 
-       if (**data != '\0') *(*data)++ = '\0';
+       if (**data == quote) {
+               *(*data)++ = '\0';
+               if (**data == ' ')
+                       (*data)++;
+       }
 
        return pos;
 }
@@ -653,11 +657,12 @@ typedef struct {
         GHashTable *options;
 } CMD_TEMP_REC;
 
-static char *get_optional_channel(WI_ITEM_REC *active_item, char **data,
-                                 int require_name)
+static const char *
+get_optional_channel(WI_ITEM_REC *active_item, char **data, int require_name)
 {
         CHANNEL_REC *chanrec;
-       char *tmp, *origtmp, *channel, *ret;
+       const char *ret;
+       char *tmp, *origtmp, *channel;
 
        if (active_item == NULL) {
                 /* no active channel in window, channel required */
@@ -670,10 +675,10 @@ static char *get_optional_channel(WI_ITEM_REC *active_item, char **data,
        if (strcmp(channel, "*") == 0 && !require_name) {
                 /* "*" means active channel */
                cmd_get_param(data);
-               ret = active_item->name;
+               ret = window_item_get_target(active_item);
        } else if (!server_ischannel(active_item->server, channel)) {
                 /* we don't have channel parameter - use active channel */
-               ret = active_item->name;
+               ret = window_item_get_target(active_item);
        } else {
                /* Find the channel first and use it's name if found.
                   This allows automatic !channel -> !XXXXXchannel replaces. */
@@ -730,7 +735,7 @@ int cmd_get_params(const char *data, gpointer *free_me, int count, ...)
                        /* optional channel as first parameter */
                        require_name = (count & PARAM_FLAG_OPTCHAN_NAME) ==
                                PARAM_FLAG_OPTCHAN_NAME;
-                       arg = get_optional_channel(item, &datad, require_name);
+                       arg = (char *) get_optional_channel(item, &datad, require_name);
 
                        str = (char **) va_arg(args, char **);
                        if (str != NULL) *str = arg;
@@ -911,13 +916,8 @@ static void event_command(const char *line, SERVER_REC *server, void *item)
 
        g_return_if_fail(line != NULL);
 
-       if (*line == '\0') {
-               /* empty line, forget it. */
-                signal_stop();
-               return;
-       }
-
-       cmdchar = strchr(settings_get_str("cmdchars"), *line);
+       cmdchar = *line == '\0' ? NULL :
+               strchr(settings_get_str("cmdchars"), *line);
        if (cmdchar != NULL && line[1] == ' ') {
                /* "/ text" = same as sending "text" to active channel. */
                line += 2;
index 0deb5090f6b8ce73eec8947bd138f8768becc7ac..b4e6d6e0627f9607eb01ffb00d5e3410476cc07b 100644 (file)
@@ -159,6 +159,7 @@ void core_init_paths(int argc, char *argv[])
                { "home", 0, POPT_ARG_STRING, NULL, 0, "Irssi home dir location (~/.irssi)", "PATH" },
                { NULL, '\0', 0, NULL }
        };
+       const char *home;
        char *str;
        int n, len;
 
@@ -191,11 +192,15 @@ void core_init_paths(int argc, char *argv[])
 
        args_register(options);
 
-        if (irssi_dir == NULL)
-               irssi_dir = g_strdup_printf(IRSSI_DIR_FULL, get_home_dir());
+       if (irssi_dir == NULL) {
+               home = g_get_home_dir();
+               if (home == NULL)
+                       home = ".";
+
+               irssi_dir = g_strdup_printf(IRSSI_DIR_FULL, home);
+       }
        if (irssi_config_file == NULL)
-               irssi_config_file = g_strdup_printf("%s/"IRSSI_HOME_CONFIG, 
-                                                   irssi_dir);
+               irssi_config_file = g_strdup_printf("%s/"IRSSI_HOME_CONFIG, irssi_dir);
 
        session_set_binary(argv[0]);
 }
index 2830d6771bd0651ec40713271cd8bba040852e0d..8f97836a69ee3e1555a2d8f67023b18d78ddc21b 100644 (file)
@@ -318,6 +318,17 @@ static char *expando_cmdchars(SERVER_REC *server, void *item, int *free_ret)
        return (char *) settings_get_str("cmdchars");
 }
 
+/* first CMDCHAR */
+static char *expando_cmdchar(SERVER_REC *server, void *item, int *free_ret)
+{
+       char str[2] = { 0, 0 };
+
+       str[0] = *settings_get_str("cmdchars");
+
+       *free_ret = TRUE;
+       return g_strdup(str);
+}
+
 /* modes of current channel, if any */
 static char *expando_chanmode(SERVER_REC *server, void *item, int *free_ret)
 {
@@ -358,7 +369,8 @@ static char *expando_serverversion(SERVER_REC *server, void *item, int *free_ret
 /* target of current input (channel or QUERY nickname) */
 static char *expando_target(SERVER_REC *server, void *item, int *free_ret)
 {
-       return item == NULL ? "" : ((WI_ITEM_REC *) item)->name;
+       return item == NULL ? "" :
+               (char *) window_item_get_target((WI_ITEM_REC *) item);
 }
 
 /* client release date (in YYYYMMDD format) */
@@ -461,6 +473,12 @@ static char *expando_chatnet(SERVER_REC *server, void *item, int *free_ret)
        return server == NULL ? "" : server->connrec->chatnet;
 }
 
+/* visible_name of current window item */
+static char *expando_itemname(SERVER_REC *server, void *item, int *free_ret)
+{
+       return item == NULL ? "" : ((WI_ITEM_REC *) item)->visible_name;
+}
+
 static void sig_message_public(SERVER_REC *server, const char *msg,
                               const char *nick, const char *address,
                               const char *target)
@@ -578,12 +596,15 @@ void expandos_init(void)
                       "", EXPANDO_NEVER, NULL);
        expando_create("K", expando_cmdchars,
                       "setup changed", EXPANDO_ARG_NONE, NULL);
+       expando_create("k", expando_cmdchar,
+                      "setup changed", EXPANDO_ARG_NONE, NULL);
        expando_create("M", expando_chanmode,
                       "window changed", EXPANDO_ARG_NONE,
                       "window item changed", EXPANDO_ARG_WINDOW,
                       "channel mode changed", EXPANDO_ARG_WINDOW_ITEM, NULL);
        expando_create("N", expando_nick,
                       "window changed", EXPANDO_ARG_NONE,
+                      "window connect changed", EXPANDO_ARG_WINDOW,
                       "window server changed", EXPANDO_ARG_WINDOW,
                        "server nick changed", EXPANDO_ARG_SERVER, NULL);
        expando_create("O", expando_statusoper,
@@ -611,6 +632,7 @@ void expandos_init(void)
        expando_create("W", expando_workdir, NULL);
        expando_create("Y", expando_realname,
                       "window changed", EXPANDO_ARG_NONE,
+                      "window connect changed", EXPANDO_ARG_WINDOW,
                       "window server changed", EXPANDO_ARG_WINDOW, NULL);
        expando_create("Z", expando_time,
                       "time changed", EXPANDO_ARG_NONE, NULL);
@@ -630,10 +652,17 @@ void expandos_init(void)
                       "query address changed", EXPANDO_ARG_WINDOW_ITEM, NULL);
        expando_create("tag", expando_servertag,
                       "window changed", EXPANDO_ARG_NONE,
+                      "window connect changed", EXPANDO_ARG_WINDOW,
                       "window server changed", EXPANDO_ARG_WINDOW, NULL);
        expando_create("chatnet", expando_chatnet,
                       "window changed", EXPANDO_ARG_NONE,
+                      "window connect changed", EXPANDO_ARG_WINDOW,
                       "window server changed", EXPANDO_ARG_WINDOW, NULL);
+       expando_create("itemname", expando_itemname,
+                      "window changed", EXPANDO_ARG_NONE,
+                      "window item changed", EXPANDO_ARG_WINDOW,
+                      "window item name changed", EXPANDO_ARG_WINDOW_ITEM,
+                      NULL);
 
        read_settings();
 
index cebbc3b060926ef800d527fb8aa71b02d566206b..99986dd27ce979c488d97b63dd873a85a5cab8ba 100644 (file)
@@ -264,7 +264,7 @@ static void ignore_set_config(IGNORE_REC *rec)
        CONFIG_NODE *node;
        char *levelstr;
 
-       if (rec->level == 0 || rec->unignore_time > 0)
+       if (rec->level == 0)
                return;
 
        node = iconfig_node_traverse("(ignores", TRUE);
@@ -281,6 +281,9 @@ static void ignore_set_config(IGNORE_REC *rec)
        if (rec->regexp) iconfig_node_set_bool(node, "regexp", TRUE);
        if (rec->fullword) iconfig_node_set_bool(node, "fullword", TRUE);
        if (rec->replies) iconfig_node_set_bool(node, "replies", TRUE);
+       if (rec->unignore_time != 0)
+               iconfig_node_set_int(node, "unignore_time", rec->unignore_time);
+       iconfig_node_set_str(node, "servertag", rec->servertag);
 
        if (rec->channels != NULL && *rec->channels != NULL) {
                node = config_node_section(node, "channels", NODE_TYPE_LIST);
@@ -297,9 +300,6 @@ static int ignore_index(IGNORE_REC *find)
        for (tmp = ignores; tmp != NULL; tmp = tmp->next) {
                IGNORE_REC *rec = tmp->data;
 
-               if (rec->servertag != NULL)
-                       continue;
-
                if (rec == find)
                        return index;
                index++;
@@ -319,6 +319,7 @@ static void ignore_remove_config(IGNORE_REC *rec)
 static void ignore_init_rec(IGNORE_REC *rec)
 {
 #ifdef HAVE_REGEX_H
+       if (rec->regexp_compiled) regfree(&rec->preg);
        rec->regexp_compiled = !rec->regexp || rec->pattern == NULL ? FALSE :
                regcomp(&rec->preg, rec->pattern,
                        REG_EXTENDED|REG_ICASE|REG_NOSUB) == 0;
@@ -368,6 +369,7 @@ void ignore_update_rec(IGNORE_REC *rec)
                ignores = g_slist_append(ignores, rec);
                ignore_set_config(rec);
 
+                ignore_init_rec(rec);
                signal_emit("ignore changed", 1, rec);
                nickmatch_rebuild(nickmatch);
        }
@@ -424,6 +426,8 @@ static void read_ignores(void)
                rec->regexp = config_node_get_bool(node, "regexp", FALSE);
                rec->fullword = config_node_get_bool(node, "fullword", FALSE);
                rec->replies = config_node_get_bool(node, "replies", FALSE);
+               rec->unignore_time = config_node_get_int(node, "unignore_time", 0);
+               rec->servertag = g_strdup(config_node_get_str(node, "servertag", 0));
 
                node = config_node_section(node, "channels", -1);
                if (node != NULL) rec->channels = config_node_get_list(node);
index 4056062e0c49214373a6b7787a4753be648be26d..4abfaca528bfad5ab9ad8862fec466c52824e3d0 100644 (file)
@@ -5,7 +5,9 @@
 #  include <regex.h>
 #endif
 
-typedef struct {
+typedef struct _IGNORE_REC IGNORE_REC;
+
+struct _IGNORE_REC {
        int level; /* ignore these levels */
        char *mask; /* nick mask */
        char *servertag; /* this is for autoignoring */
@@ -22,7 +24,7 @@ typedef struct {
        unsigned int regexp_compiled:1; /* should always be TRUE, unless regexp is invalid */
        regex_t preg;
 #endif
-} IGNORE_REC;
+};
 
 extern GSList *ignores;
 
index 2d7288f70cfe0fc52fd0a5dcdd409ca519b07210..dec7afe74c05274f31d8ff7f368394ba235ecdb7 100644 (file)
@@ -7,35 +7,37 @@
    needed..). */
 
 /* Message levels */
-#define MSGLEVEL_CRAP         0x0000001
-#define MSGLEVEL_MSGS         0x0000002
-#define MSGLEVEL_PUBLIC       0x0000004
-#define MSGLEVEL_NOTICES      0x0000008
-#define MSGLEVEL_SNOTES       0x0000010
-#define MSGLEVEL_CTCPS        0x0000020
-#define MSGLEVEL_ACTIONS      0x0000040
-#define MSGLEVEL_JOINS        0x0000080
-#define MSGLEVEL_PARTS        0x0000100
-#define MSGLEVEL_QUITS        0x0000200
-#define MSGLEVEL_KICKS        0x0000400
-#define MSGLEVEL_MODES        0x0000800
-#define MSGLEVEL_TOPICS       0x0001000
-#define MSGLEVEL_WALLOPS      0x0002000
-#define MSGLEVEL_INVITES      0x0004000
-#define MSGLEVEL_NICKS        0x0008000
-#define MSGLEVEL_DCC          0x0010000
-#define MSGLEVEL_DCCMSGS      0x0020000
-#define MSGLEVEL_CLIENTNOTICE 0x0040000
-#define MSGLEVEL_CLIENTCRAP   0x0080000
-#define MSGLEVEL_CLIENTERROR  0x0100000
-#define MSGLEVEL_HILIGHT      0x0200000
+enum {
+       MSGLEVEL_CRAP         = 0x0000001,
+       MSGLEVEL_MSGS         = 0x0000002,
+       MSGLEVEL_PUBLIC       = 0x0000004,
+       MSGLEVEL_NOTICES      = 0x0000008,
+       MSGLEVEL_SNOTES       = 0x0000010,
+       MSGLEVEL_CTCPS        = 0x0000020,
+       MSGLEVEL_ACTIONS      = 0x0000040,
+       MSGLEVEL_JOINS        = 0x0000080,
+       MSGLEVEL_PARTS        = 0x0000100,
+       MSGLEVEL_QUITS        = 0x0000200,
+       MSGLEVEL_KICKS        = 0x0000400,
+       MSGLEVEL_MODES        = 0x0000800,
+       MSGLEVEL_TOPICS       = 0x0001000,
+       MSGLEVEL_WALLOPS      = 0x0002000,
+       MSGLEVEL_INVITES      = 0x0004000,
+       MSGLEVEL_NICKS        = 0x0008000,
+       MSGLEVEL_DCC          = 0x0010000,
+       MSGLEVEL_DCCMSGS      = 0x0020000,
+       MSGLEVEL_CLIENTNOTICE = 0x0040000,
+       MSGLEVEL_CLIENTCRAP   = 0x0080000,
+       MSGLEVEL_CLIENTERROR  = 0x0100000,
+       MSGLEVEL_HILIGHT      = 0x0200000,
 
-#define MSGLEVEL_ALL          0x03fffff
+       MSGLEVEL_ALL          = 0x03fffff,
 
-#define MSGLEVEL_NOHILIGHT    0x1000000 /* Don't highlight this message */
-#define MSGLEVEL_NO_ACT       0x2000000 /* Don't trigger channel activity */
-#define MSGLEVEL_NEVER        0x4000000 /* never ignore / never log */
-#define MSGLEVEL_LASTLOG      0x8000000 /* never ignore / never log */
+       MSGLEVEL_NOHILIGHT    = 0x1000000, /* Don't highlight this message */
+       MSGLEVEL_NO_ACT       = 0x2000000, /* Don't trigger channel activity */
+       MSGLEVEL_NEVER        = 0x4000000, /* never ignore / never log */
+       MSGLEVEL_LASTLOG      = 0x8000000 /* never ignore / never log */
+};
 
 int level_get(const char *level);
 int level2bits(const char *level);
index 9a131f9680d5f573e13132a668e7f8f0233fe227..e17f5c568686f6bb2d2030de8bde46379e8e7acb 100644 (file)
@@ -100,6 +100,8 @@ static char *log_filename(LOG_REC *log)
 
 int log_start_logging(LOG_REC *log)
 {
+       char *dir;
+
        g_return_val_if_fail(log != NULL, FALSE);
 
        if (log->handle != -1)
@@ -108,6 +110,16 @@ int log_start_logging(LOG_REC *log)
        /* Append/create log file */
        g_free_not_null(log->real_fname);
        log->real_fname = log_filename(log);
+
+       if (log->real_fname != NULL &&
+           strcmp(log->real_fname, log->fname) != 0) {
+               /* path may contain variables (%time, $vars),
+                  make sure the directory is created */
+               dir = g_dirname(log->real_fname);
+               mkpath(dir, LOG_DIR_CREATE_MODE);
+               g_free(dir);
+       }
+
        log->handle = log->real_fname == NULL ? -1 :
                open(log->real_fname, O_WRONLY | O_APPEND | O_CREAT,
                     log_file_create_mode);
@@ -165,7 +177,7 @@ void log_stop_logging(LOG_REC *log)
 
 static void log_rotate_check(LOG_REC *log)
 {
-       char *new_fname, *dir;
+       char *new_fname;
 
        g_return_if_fail(log != NULL);
 
@@ -178,10 +190,6 @@ static void log_rotate_check(LOG_REC *log)
                log_stop_logging(log);
                signal_emit("log rotated", 1, log);
 
-               dir = g_dirname(new_fname);
-               mkpath(dir, LOG_DIR_CREATE_MODE);
-               g_free(dir);
-
                log_start_logging(log);
        }
        g_free(new_fname);
index 6ada7c65b0de325bc2a9f7f0efb5874fb093650b..da97fb2c341f60940c480729292e37892e974dec 100644 (file)
@@ -10,13 +10,16 @@ enum {
 
 typedef char *(*COLORIZE_FUNC)(const char *str);
 
-typedef struct {
+typedef struct _LOG_REC LOG_REC;
+typedef struct _LOG_ITEM_REC LOG_ITEM_REC;
+
+struct _LOG_ITEM_REC {
        int type;
         char *name;
        char *servertag;
-} LOG_ITEM_REC;
+};
 
-typedef struct {
+struct _LOG_REC {
        char *fname; /* file name, in strftime() format */
        char *real_fname; /* the current expanded file name */
        int handle; /* file handle */
@@ -31,7 +34,7 @@ typedef struct {
        unsigned int autoopen:1; /* automatically start logging at startup */
        unsigned int failed:1; /* opening log failed last time */
        unsigned int temp:1; /* don't save this to config file */
-} LOG_REC;
+};
 
 extern GSList *logs;
 
index e030a5147b9e744b42f84a4f6109d7c3b6a9b208..886c40f1bbbffa0170b6c85ffd4790f83ac3b451 100644 (file)
@@ -26,7 +26,6 @@
 #ifdef HAVE_REGEX_H
 #  include <regex.h>
 #endif
-#include <pwd.h>
 
 typedef struct {
        int condition;
@@ -449,25 +448,20 @@ int mkpath(const char *path, int mode)
        return 0;
 }
 
-/* Get home directory */
-const char *get_home_dir(void)
-{
-       struct passwd *pw = getpwuid(getuid());
-       if (!pw) {
-        if (g_getenv("HOME"))
-          return g_getenv("HOME");
-        else
-          return ".";
-       }
-       return pw->pw_dir;
-}
-
 /* convert ~/ to $HOME */
 char *convert_home(const char *path)
 {
-       return *path == '~' && (*(path+1) == '/' || *(path+1) == '\0') ?
-               g_strconcat((char *)get_home_dir(), path+1, NULL) :
-               g_strdup(path);
+       const char *home;
+
+       if (*path == '~' && (*(path+1) == '/' || *(path+1) == '\0')) {
+               home = g_get_home_dir();
+               if (home == NULL)
+                       home = ".";
+
+               return g_strconcat(home, path+1, NULL);
+       } else {
+               return g_strdup(path);
+       }
 }
 
 int g_istr_equal(gconstpointer v, gconstpointer v2)
@@ -784,3 +778,19 @@ int expand_escape(const char **data)
                return strtol(digit, NULL, 8);
        }
 }
+
+/* Escape all '"', "'" and '\' chars with '\' */
+char *escape_string(const char *str)
+{
+       char *ret, *p;
+
+       p = ret = g_malloc(strlen(str)*2+1);
+       while (*str != '\0') {
+               if (*str == '"' || *str == '\'' || *str == '\\')
+                       *p++ = '\\';
+               *p++ = *str++;
+       }
+       *p = '\0';
+
+       return ret;
+}
index a321bdfca8187c515e9164e1e9fb8bd4ec3e097f..b9002c1ce200952bf0e4f043e03c6d2905b56cdc 100644 (file)
@@ -61,10 +61,6 @@ int regexp_match(const char *str, const char *regexp);
 
 /* Create the directory and all it's parent directories */
 int mkpath(const char *path, int mode);
-
-/* Get home directory */
-const char *get_home_dir(void);
-
 /* convert ~/ to $HOME */
 char *convert_home(const char *path);
 
@@ -109,4 +105,7 @@ GSList *columns_sort_list(GSList *list, int rows);
    one after '\'. Returns the expanded character or -1 if error. */
 int expand_escape(const char **data);
 
+/* Escape all '"', "'" and '\' chars with '\' */
+char *escape_string(const char *str);
+
 #endif
index 69bdecdf07c61780b4f93eeb3dc401c1b2812b20..7b90d802940a106cb9f70c4b6577531c16f32f61 100644 (file)
@@ -367,6 +367,15 @@ static void module_file_deinit_gmodule(MODULE_FILE_REC *file)
        g_module_close(file->gmodule);
 }
 
+#else /* !HAVE_GMODULE - modules are not supported */
+
+int module_load(const char *path, char **prefixes)
+{
+        return FALSE;
+}
+
+#endif
+
 void module_file_unload(MODULE_FILE_REC *file)
 {
        MODULE_REC *root;
@@ -377,8 +386,10 @@ void module_file_unload(MODULE_FILE_REC *file)
         if (file->initialized)
                signal_emit("module unloaded", 2, file->root, file);
 
+#ifdef HAVE_GMODULE
        if (file->gmodule != NULL)
                 module_file_deinit_gmodule(file);
+#endif
 
        g_free(file->name);
        g_free(file->defined_module_name);
@@ -402,16 +413,3 @@ void module_unload(MODULE_REC *module)
         g_free(module->name);
        g_free(module);
 }
-
-#else /* !HAVE_GMODULE - modules are not supported */
-
-int module_load(const char *path, char **prefixes)
-{
-        return FALSE;
-}
-
-void module_unload(MODULE_REC *module)
-{
-}
-
-#endif
index 7392f429136d8c704dfbf5cbf958f4efb01d20f3..6af87a96fac464da4be0e2bff820605772ea01d4 100644 (file)
@@ -186,7 +186,7 @@ static void simple_readpipe(SIMPLE_THREAD_REC *rec, GIOChannel *pipe)
 {
        RESOLVED_IP_REC iprec;
        GIOChannel *handle;
-        IPADDR *ip;
+       IPADDR *ip;
 
        g_return_if_fail(rec != NULL);
 
diff --git a/apps/irssi/src/core/network-openssl.c b/apps/irssi/src/core/network-openssl.c
new file mode 100644 (file)
index 0000000..b9b7b4a
--- /dev/null
@@ -0,0 +1,305 @@
+/*
+ network-ssl.c : SSL support
+
+    Copyright (C) 2002 vjt
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "module.h"
+#include "network.h"
+
+#ifdef HAVE_OPENSSL
+
+#include <openssl/crypto.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+/* ssl read */
+GIOError irssi_ssl_read(GIOChannel *, gchar *, guint, guint *);
+/* ssl write */
+GIOError irssi_ssl_write(GIOChannel *, gchar *, guint, guint*);
+/* ssl seek */
+GIOError irssi_ssl_seek(GIOChannel *, gint, GSeekType);
+/* ssl close */
+void irssi_ssl_close(GIOChannel *);
+#if GLIB_MAJOR_VERSION < 2
+/* ssl create watch */
+guint irssi_ssl_create_watch(GIOChannel *, gint, GIOCondition, GIOFunc, gpointer, GDestroyNotify);
+#else
+GSource *irssi_ssl_create_watch(GIOChannel *, GIOCondition);
+#endif
+/* ssl free */
+void irssi_ssl_free(GIOChannel *);
+
+/* ssl i/o channel object */
+typedef struct
+{
+       GIOChannel pad;
+       gint fd;
+       GIOChannel *giochan;
+       SSL *ssl;
+       X509 *cert;
+} GIOSSLChannel;
+       
+/* ssl function pointers */
+GIOFuncs irssi_ssl_channel_funcs =
+{
+       irssi_ssl_read,
+       irssi_ssl_write,
+       irssi_ssl_seek,
+       irssi_ssl_close,
+       irssi_ssl_create_watch,
+       irssi_ssl_free
+};
+
+SSL_CTX *ssl_ctx = NULL;
+
+#ifdef G_CAN_INLINE
+G_INLINE_FUNC
+#endif
+gint ssl_errno(gint e)
+{
+       switch(e)
+       {
+               case EINVAL:
+                       return G_IO_ERROR_INVAL;
+               case EINTR:
+               case EAGAIN:
+                       return G_IO_ERROR_AGAIN;
+               default:
+                       return G_IO_ERROR_INVAL;
+       }
+       /*UNREACH*/
+       return -1;
+}
+
+gboolean irssi_ssl_cert_step(GIOSSLChannel *chan)
+{
+       gint err;
+       switch(err = SSL_do_handshake(chan->ssl))
+       {
+               case 1:
+                       if(!(chan->cert = SSL_get_peer_certificate(chan->ssl)))
+                       {
+                               g_warning("SSL server supplied no certificate");
+                               return G_IO_ERROR_INVAL;
+                       }
+                       return G_IO_ERROR_NONE;
+               default:
+                       if(SSL_get_error(chan->ssl, err) == SSL_ERROR_WANT_READ)
+                               return G_IO_ERROR_AGAIN;
+                       return ssl_errno(errno);
+       }
+       /*UNREACH*/
+       return -1;
+}
+
+GIOError irssi_ssl_read(GIOChannel *handle, gchar *buf, guint len, guint *ret)
+{
+       GIOSSLChannel *chan = (GIOSSLChannel *)handle;
+       gint err;
+       
+       if(chan->cert == NULL)
+       {
+               gint cert_err = irssi_ssl_cert_step(chan);
+               if(cert_err != G_IO_ERROR_NONE)
+                       return cert_err;
+       }
+       
+       err = SSL_read(chan->ssl, buf, len);
+       if(err < 0)
+       {
+               *ret = 0;
+               if(SSL_get_error(chan->ssl, err) == SSL_ERROR_WANT_READ)
+                       return G_IO_ERROR_AGAIN;
+               return ssl_errno(errno);
+       }
+       else
+       {
+               *ret = err;
+               return G_IO_ERROR_NONE;
+       }
+       /*UNREACH*/
+       return -1;
+}
+
+GIOError irssi_ssl_write(GIOChannel *handle, gchar *buf, guint len, guint *ret)
+{
+       GIOSSLChannel *chan = (GIOSSLChannel *)handle;
+       gint err;
+
+       if(chan->cert == NULL)
+       {
+               gint cert_err = irssi_ssl_cert_step(chan);
+               if(cert_err != G_IO_ERROR_NONE)
+                       return cert_err;
+       }
+       
+
+       err = SSL_write(chan->ssl, (const char *)buf, len);
+       if(err < 0)
+       {
+               *ret = 0;
+               if(SSL_get_error(chan->ssl, err) == SSL_ERROR_WANT_READ)
+                       return G_IO_ERROR_AGAIN;
+               return ssl_errno(errno);
+       }
+       else
+       {
+               *ret = err;
+               return G_IO_ERROR_NONE;
+       }
+       /*UNREACH*/
+       return -1;
+}
+
+GIOError irssi_ssl_seek(GIOChannel *handle, gint offset, GSeekType type)
+{
+       GIOSSLChannel *chan = (GIOSSLChannel *)handle;
+       GIOError e;
+       e = g_io_channel_seek(chan->giochan, offset, type);
+       return (e == G_IO_ERROR_NONE) ? G_IO_ERROR_NONE : G_IO_ERROR_INVAL;
+}
+
+void irssi_ssl_close(GIOChannel *handle)
+{
+       GIOSSLChannel *chan = (GIOSSLChannel *)handle;
+       g_io_channel_close(chan->giochan);
+}
+
+#if GLIB_MAJOR_VERSION < 2
+guint irssi_ssl_create_watch(GIOChannel *handle, gint priority, GIOCondition cond,
+                            GIOFunc func, gpointer data, GDestroyNotify notify)
+{
+       GIOSSLChannel *chan = (GIOSSLChannel *)handle;
+
+       return chan->giochan->funcs->io_add_watch(handle, priority, cond, func, data, notify);
+}
+#else
+GSource *irssi_ssl_create_watch(GIOChannel *handle, GIOCondition cond)
+{
+       GIOSSLChannel *chan = (GIOSSLChannel *)handle;
+
+       return chan->giochan->funcs->io_create_watch(handle, cond);
+}
+#endif
+
+void irssi_ssl_free(GIOChannel *handle)
+{
+       GIOSSLChannel *chan = (GIOSSLChannel *)handle;
+       g_io_channel_unref(chan->giochan);
+       SSL_free(chan->ssl);
+       g_free(chan);
+}
+
+gboolean irssi_ssl_init(void)
+{
+       SSL_library_init();
+       SSL_load_error_strings();
+       
+       ssl_ctx = SSL_CTX_new(SSLv23_client_method());
+       if(!ssl_ctx)
+       {
+               g_error("Initialization of the SSL library failed");
+               return FALSE;
+       }
+
+       return TRUE;
+
+}
+
+GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle)
+{
+       GIOSSLChannel *chan;
+       GIOChannel *gchan;
+       int err, fd;
+       SSL *ssl;
+       X509 *cert = NULL;
+
+       g_return_val_if_fail(handle != NULL, NULL);
+       
+       if(!ssl_ctx && !irssi_ssl_init())
+               return NULL;
+
+       if(!(fd = g_io_channel_unix_get_fd(handle)))
+               return NULL;
+
+       if(!(ssl = SSL_new(ssl_ctx)))
+       {
+               g_warning("Failed to allocate SSL structure");
+               return NULL;
+       }
+
+       if(!(err = SSL_set_fd(ssl, fd)))
+       {
+               g_warning("Failed to associate socket to SSL stream");
+               return NULL;
+       }
+
+       if((err = SSL_connect(ssl)) <= 0)
+       {
+               switch(err = SSL_get_error(ssl, err))
+               {
+                       case SSL_ERROR_SYSCALL:
+                               if(errno == EINTR || errno == EAGAIN)
+                       case SSL_ERROR_WANT_READ:
+                       case SSL_ERROR_WANT_WRITE:
+                                       break;
+                       default:
+                                       return NULL;
+               }
+       }
+       else if(!(cert = SSL_get_peer_certificate(ssl)))
+       {
+               g_warning("SSL server supplied no certificate");
+               return NULL;
+       }
+       else
+               X509_free(cert);
+
+       chan = g_new0(GIOSSLChannel, 1);
+       chan->fd = fd;
+       chan->giochan = handle;
+       chan->ssl = ssl;
+       chan->cert = cert;
+       g_io_channel_ref(handle);
+
+       gchan = (GIOChannel *)chan;
+       gchan->funcs = &irssi_ssl_channel_funcs;
+       g_io_channel_init(gchan);
+       
+       return gchan;
+}
+
+GIOChannel *net_connect_ip_ssl(IPADDR *ip, int port, IPADDR *my_ip)
+{
+       GIOChannel *gret = net_connect_ip(ip, port, my_ip);
+       gret = irssi_ssl_get_iochannel(gret);
+       return gret;
+}
+
+#else /* HAVE_OPENSSL */
+
+GIOChannel *net_connect_ip_ssl(IPADDR *ip, int port, IPADDR *my_ip)
+{
+       g_warning("Connection failed: SSL support not enabled in this build.");
+       errno = ENOSYS;
+       return NULL;
+}
+
+#endif /* ! HAVE_OPENSSL */
index e53b01897b4938ddfe1ea3e092165160a26e9428..6b2ceab4c50ea3fa6ebb2b141a884656044b38a7 100644 (file)
@@ -21,6 +21,8 @@
 #include "module.h"
 #include "network.h"
 
+#include <sys/un.h>
+
 #ifndef INADDR_NONE
 #  define INADDR_NONE INADDR_BROADCAST
 #endif
@@ -217,7 +219,42 @@ GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip)
        if (ret < 0 && WSAGetLastError() != WSAEWOULDBLOCK)
 #endif
        {
+               int old_errno = errno;
                close(handle);
+               errno = old_errno;
+               return NULL;
+       }
+
+       return g_io_channel_new(handle);
+}
+
+/* Connect to named UNIX socket */
+GIOChannel *net_connect_unix(const char *path)
+{
+       struct sockaddr_un sa;
+       int handle, ret;
+
+       /* create the socket */
+       handle = socket(PF_UNIX, SOCK_STREAM, 0);
+       if (handle == -1)
+               return NULL;
+
+       /* set socket options */
+#ifndef WIN32
+       fcntl(handle, F_SETFL, O_NONBLOCK);
+#endif
+
+       /* connect */
+       memset(&sa, 0, sizeof(sa));
+       sa.sun_family = AF_UNIX;
+       strncpy(sa.sun_path, path, sizeof(sa.sun_path)-1);
+       sa.sun_path[sizeof(sa.sun_path)-1] = '\0';
+
+       ret = connect(handle, (struct sockaddr *) &sa, sizeof(sa));
+       if (ret < 0 && errno != EINPROGRESS) {
+               int old_errno = errno;
+               close(handle);
+               errno = old_errno;
                return NULL;
        }
 
@@ -472,12 +509,16 @@ int net_ip2host(IPADDR *ip, char *host)
 #else
        unsigned long ip4;
 
-       ip4 = ntohl(ip->ip.s_addr);
-       g_snprintf(host, MAX_IP_LEN, "%lu.%lu.%lu.%lu",
-                  (ip4 & 0xff000000UL) >> 24,
-                  (ip4 & 0x00ff0000) >> 16,
-                  (ip4 & 0x0000ff00) >> 8,
-                  (ip4 & 0x000000ff));
+       if (ip->family != AF_INET) {
+               strcpy(host, "0.0.0.0");
+       } else {
+               ip4 = ntohl(ip->ip.s_addr);
+               g_snprintf(host, MAX_IP_LEN, "%lu.%lu.%lu.%lu",
+                          (ip4 & 0xff000000UL) >> 24,
+                          (ip4 & 0x00ff0000) >> 16,
+                          (ip4 & 0x0000ff00) >> 8,
+                          (ip4 & 0x000000ff));
+       }
 #endif
        return 0;
 }
@@ -486,15 +527,16 @@ int net_host2ip(const char *host, IPADDR *ip)
 {
        unsigned long addr;
 
-#ifdef HAVE_IPV6
        if (strchr(host, ':') != NULL) {
                /* IPv6 */
                ip->family = AF_INET6;
+#ifdef HAVE_IPV6
                if (inet_pton(AF_INET6, host, &ip->ip) == 0)
                        return -1;
-       } else
+#else
+               ip->ip.s_addr = 0;
 #endif
-       {
+       } else {
                /* IPv4 */
                ip->family = AF_INET;
 #ifdef HAVE_INET_ATON
index 4c25740f5c1c774f09294a9a19e045a53d6f529c..c6b08f9fe48d6cb830a5089c27de217c245b19c7 100644 (file)
@@ -44,8 +44,12 @@ int net_ip_compare(IPADDR *ip1, IPADDR *ip2);
 
 /* Connect to socket */
 GIOChannel *net_connect(const char *addr, int port, IPADDR *my_ip);
+/* Connect to socket with ip address and SSL*/
+GIOChannel *net_connect_ip_ssl(IPADDR *ip, int port, IPADDR *my_ip);
 /* Connect to socket with ip address */
 GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip);
+/* Connect to named UNIX socket */
+GIOChannel *net_connect_unix(const char *path);
 /* Disconnect socket */
 void net_disconnect(GIOChannel *handle);
 /* Try to let the other side close the connection, if it still isn't
index 8ae994a285e6dcc051d76d794e2e3cd1fcc253b5..799a6320309263e682f0095ee8f1d1a39d4dd0c6 100644 (file)
 
 GSList *queries;
 
+static const char *query_get_target(WI_ITEM_REC *item)
+{
+       return ((QUERY_REC *) item)->name;
+}
+
 void query_init(QUERY_REC *query, int automatic)
 {
        g_return_if_fail(query != NULL);
@@ -37,8 +42,10 @@ void query_init(QUERY_REC *query, int automatic)
         MODULE_DATA_INIT(query);
        query->type = module_get_uniq_id_str("WINDOW ITEM TYPE", "QUERY");
         query->destroy = (void (*) (WI_ITEM_REC *)) query_destroy;
+       query->get_target = query_get_target;
        query->createtime = time(NULL);
        query->last_unread_msg = time(NULL);
+       query->visible_name = g_strdup(query->name);
 
        if (query->server_tag != NULL) {
                query->server = server_find_tag(query->server_tag);
@@ -69,6 +76,7 @@ void query_destroy(QUERY_REC *query)
        g_free_not_null(query->hilight_color);
         g_free_not_null(query->server_tag);
         g_free_not_null(query->address);
+       g_free(query->visible_name);
        g_free(query->name);
 
         query->type = 0;
@@ -124,6 +132,10 @@ void query_change_nick(QUERY_REC *query, const char *nick)
 
         oldnick = query->name;
        query->name = g_strdup(nick);
+
+       g_free(query->visible_name);
+       query->visible_name = g_strdup(nick);
+
        signal_emit("query nick changed", 2, query, oldnick);
        signal_emit("window item name changed", 1, query);
         g_free(oldnick);
index fc08d2effe3851aece47ec3c50ee328702df7e2c..ddb85ba417479e84e09541a495f138ce74e05b15 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "window-item-rec.h"
 
+char *name;
 char *address;
 char *server_tag;
 time_t last_unread_msg;
index a59880e4f4fef4e3b5428156dd752ddd57baaccd..ce1e48a4fd3459b095c7b1ba535a9ec1c23ee8d3 100644 (file)
@@ -23,8 +23,12 @@ char *nick;
 char *username;
 char *realname;
 
+GIOChannel *connect_handle; /* connect using this handle */
+
 /* when reconnecting, the old server status */
 unsigned int reconnection:1; /* we're trying to reconnect */
 unsigned int no_autojoin_channels:1; /* don't autojoin any channels */
+unsigned int unix_socket:1; /* Connect using named unix socket */
+unsigned int use_ssl:1; /* this connection uses SSL */
 char *channels;
 char *away_reason;
index f94ec9aed6dcccf17b6d2e90844e61b8414e35e8..d04fa1fea9112500e25f2e75967c384bf4480046 100644 (file)
@@ -18,5 +18,6 @@ unsigned int no_proxy:1;
 unsigned int last_failed:1; /* if last connection attempt failed */
 unsigned int banned:1; /* if we're banned from this server */
 unsigned int dns_error:1; /* DNS said the host doesn't exist */
+unsigned int use_ssl:1; /* this connection uses SSL */
 
 GHashTable *module_data;
index 86d900a6ebdcc35aa9cae219394a278399eeffe9..cc053150dc012ee7ae27bd6befdee133bd6ec229 100644 (file)
@@ -44,6 +44,17 @@ void reconnect_save_status(SERVER_CONNECT_REC *conn, SERVER_REC *server)
        conn->away_reason = !server->usermode_away ? NULL :
                g_strdup(server->away_reason);
 
+       if (!server->connected) {
+               /* default to channels/usermode from connect record
+                  since server isn't fully connected yet */
+               g_free_not_null(conn->channels);
+               conn->channels = server->connrec->no_autojoin_channels ? NULL :
+                       g_strdup(server->connrec->channels);
+
+               g_free_not_null(conn->channels);
+               conn->channels = g_strdup(server->connrec->channels);
+       }
+
        signal_emit("server reconnect save status", 2, conn, server);
 }
 
@@ -99,7 +110,7 @@ static int server_reconnect_timeout(void)
                        conn = rec->conn;
                        server_connect_ref(conn);
                        server_reconnect_destroy(rec);
-                       CHAT_PROTOCOL(conn)->server_connect(conn);
+                       server_connect(conn);
                        server_connect_unref(conn);
                }
        }
@@ -164,6 +175,8 @@ server_connect_copy_skeleton(SERVER_CONNECT_REC *src, int connect_info)
        dest->away_reason = g_strdup(src->away_reason);
         dest->no_autojoin_channels = src->no_autojoin_channels;
 
+       dest->use_ssl = src->use_ssl;
+
        return dest;
 }
 
@@ -208,8 +221,8 @@ static void sig_reconnect(SERVER_REC *server)
                sserver->last_connect = server->connect_time == 0 ?
                        time(NULL) : server->connect_time;
                sserver->last_failed = !server->connected;
-               if (server->banned) sserver->banned = TRUE;
-                if (server->dns_error) sserver->dns_error = TRUE;
+               sserver->banned = server->banned;
+                sserver->dns_error = server->dns_error;
        }
 
        if (sserver == NULL || conn->chatnet == NULL) {
@@ -329,36 +342,50 @@ static void reconnect_all(void)
        while (list != NULL) {
                conn = list->data;
 
-               CHAT_PROTOCOL(conn)->server_connect(conn);
+               server_connect(conn);
                 server_connect_unref(conn);
                 list = g_slist_remove(list, conn);
        }
 }
 
-/* SYNTAX: RECONNECT <tag> */
+/* SYNTAX: RECONNECT <tag> [<quit message>] */
 static void cmd_reconnect(const char *data, SERVER_REC *server)
 {
        SERVER_CONNECT_REC *conn;
        RECONNECT_REC *rec;
-       int tag;
+       char *tag, *msg;
+       void *free_arg;
+       int tagnum;
+
+       if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &tag, &msg))
+               return;
+
+       if (*tag != '\0' && strcmp(tag, "*") != 0)
+               server = server_find_tag(tag);
 
-       if (*data == '\0' && server != NULL) {
-               /* reconnect back to same server */
+       if (server != NULL) {
+               /* reconnect connected server */
                conn = server_connect_copy_skeleton(server->connrec, TRUE);
 
                if (server->connected)
                        reconnect_save_status(conn, server);
-               signal_emit("command disconnect", 2, "* Reconnecting", server);
+
+               msg = g_strconcat("* ", *msg == '\0' ?
+                                 "Reconnecting" : msg, NULL);
+               signal_emit("command disconnect", 2, msg, server);
+               g_free(msg);
 
                conn->reconnection = TRUE;
-               CHAT_PROTOCOL(conn)->server_connect(conn);
+               server_connect(conn);
                server_connect_unref(conn);
+               cmd_params_free(free_arg);
                 return;
        }
 
-       if (g_strcasecmp(data, "all") == 0) {
+       if (g_strcasecmp(tag, "all") == 0) {
                /* reconnect all servers in reconnect queue */
                 reconnect_all();
+               cmd_params_free(free_arg);
                 return;
        }
 
@@ -371,20 +398,21 @@ static void cmd_reconnect(const char *data, SERVER_REC *server)
                if (g_strncasecmp(data, "RECON-", 6) == 0)
                        data += 6;
 
-               tag = atoi(data);
-               rec = tag <= 0 ? NULL : reconnect_find_tag(tag);
+               tagnum = atoi(tag);
+               rec = tagnum <= 0 ? NULL : reconnect_find_tag(tagnum);
+       }
 
-               if (rec == NULL) {
-                       signal_emit("server reconnect not found", 1, data);
-                        return;
-               }
+       if (rec == NULL) {
+               signal_emit("server reconnect not found", 1, data);
+       } else {
+               conn = rec->conn;
+               server_connect_ref(conn);
+               server_reconnect_destroy(rec);
+               server_connect(conn);
+               server_connect_unref(conn);
        }
 
-       conn = rec->conn;
-       server_connect_ref(conn);
-       server_reconnect_destroy(rec);
-       CHAT_PROTOCOL(conn)->server_connect(conn);
-       server_connect_unref(conn);
+       cmd_params_free(free_arg);
 }
 
 static void cmd_disconnect(const char *data, SERVER_REC *server)
@@ -423,7 +451,7 @@ static void read_settings(void)
 
 void servers_reconnect_init(void)
 {
-       settings_add_int("server", "server_reconnect_time", 3000);
+       settings_add_int("server", "server_reconnect_time", 300);
 
        reconnects = NULL;
        last_reconnect_tag = 0;
index d16f93a7fd4bee3ecf9681968dcd67369f128b55..6bdafb80747f06de055e176080fb844c4646cfe6 100644 (file)
@@ -163,6 +163,8 @@ static void server_setup_fill_server(SERVER_CONNECT_REC *conn,
                 conn->family = sserver->family;
        if (sserver->port > 0 && conn->port <= 0)
                conn->port = sserver->port;
+       conn->use_ssl = sserver->use_ssl;
+
        server_setup_fill_reconn(conn, sserver);
 
        signal_emit("server setup fill server", 2, conn, sserver);
@@ -391,6 +393,7 @@ static SERVER_SETUP_REC *server_setup_read(CONFIG_NODE *node)
                (g_strcasecmp(family, "inet") == 0 ? AF_INET : 0);
        rec->address = g_strdup(server);
        rec->password = g_strdup(config_node_get_str(node, "password", NULL));
+       rec->use_ssl = config_node_get_bool(node, "use_ssl", FALSE);
        rec->port = port;
        rec->autoconnect = config_node_get_bool(node, "autoconnect", FALSE);
        rec->no_proxy = config_node_get_bool(node, "no_proxy", FALSE);
@@ -420,6 +423,7 @@ static void server_setup_save(SERVER_SETUP_REC *rec)
 
        iconfig_node_set_int(node, "port", rec->port);
        iconfig_node_set_str(node, "password", rec->password);
+       iconfig_node_set_bool(node, "use_ssl", rec->use_ssl);
        iconfig_node_set_str(node, "own_host", rec->own_host);
 
        iconfig_node_set_str(node, "family",
index 1e5c0b8487c70fb482dbdf83b80452911c38fcf1..92a6e5ac7b3c65d2b5ab3e20b865ca6d31124cf4 100644 (file)
@@ -110,6 +110,7 @@ static char *server_create_tag(SERVER_CONNECT_REC *conn)
                server_create_address_tag(conn->address);
 
        if (conn->tag != NULL && server_find_tag(conn->tag) == NULL &&
+            server_find_lookup_tag(conn->tag) == NULL &&
            strncmp(conn->tag, tag, strlen(tag)) == 0) {
                /* use the existing tag if it begins with the same ID -
                   this is useful when you have several connections to
@@ -123,8 +124,13 @@ static char *server_create_tag(SERVER_CONNECT_REC *conn)
 
        /* then just append numbers after tag until unused is found.. */
        str = g_string_new(tag);
-       for (num = 2; server_find_tag(str->str) != NULL; num++)
+
+       num = 2;
+       while (server_find_tag(str->str) != NULL ||
+              server_find_lookup_tag(str->str) != NULL) {
                g_string_sprintf(str, "%s%d", tag, num);
+               num++;
+       }
        g_free(tag);
 
        tag = str->str;
@@ -161,16 +167,52 @@ static void server_connect_callback_init(SERVER_REC *server, GIOChannel *handle)
        server_connect_finished(server);
 }
 
-static void server_connect_callback_readpipe(SERVER_REC *server)
+static void server_real_connect(SERVER_REC *server, IPADDR *ip,
+                               const char *unix_socket)
 {
-       SERVER_CONNECT_REC *conn;
-       RESOLVED_IP_REC iprec;
        GIOChannel *handle;
-        IPADDR *ip, *own_ip;
-       const char *errormsg;
+        IPADDR *own_ip;
         int port;
 
-       g_return_if_fail(IS_SERVER(server));
+       g_return_if_fail(ip != NULL || unix_socket != NULL);
+
+       signal_emit("server connecting", 2, server, ip);
+
+       if (ip != NULL) {
+               own_ip = ip == NULL ? NULL :
+                       (IPADDR_IS_V6(ip) ? server->connrec->own_ip6 :
+                        server->connrec->own_ip4);
+               port = server->connrec->proxy != NULL ?
+                       server->connrec->proxy_port : server->connrec->port;
+               handle = server->connrec->use_ssl ?
+                       net_connect_ip_ssl(ip, port, own_ip) :
+                       net_connect_ip(ip, port, own_ip);
+       } else {
+               handle = net_connect_unix(unix_socket);
+       }
+
+       if (handle == NULL) {
+               /* failed */
+               if (server->connrec->use_ssl && errno == ENOSYS)
+                       server->no_reconnect = TRUE;
+
+               server->connection_lost = TRUE;
+               server_connect_failed(server, g_strerror(errno));
+       } else {
+               server->handle = net_sendbuffer_create(handle, 0);
+               server->connect_tag =
+                       g_input_add(handle, G_INPUT_WRITE | G_INPUT_READ,
+                                   (GInputFunction)
+                                   server_connect_callback_init,
+                                   server);
+       }
+}
+
+static void server_connect_callback_readpipe(SERVER_REC *server)
+{
+       RESOLVED_IP_REC iprec;
+        IPADDR *ip;
+       const char *errormsg;
 
        g_source_remove(server->connect_tag);
        server->connect_tag = -1;
@@ -204,33 +246,18 @@ static void server_connect_callback_readpipe(SERVER_REC *server)
                        &iprec.ip6 : &iprec.ip4;
        }
 
-        conn = server->connrec;
-       port = conn->proxy != NULL ? conn->proxy_port : conn->port;
-       own_ip = ip == NULL ? NULL :
-               (IPADDR_IS_V6(ip) ? conn->own_ip6 : conn->own_ip4);
-
-       handle = NULL;
        if (ip != NULL) {
-               signal_emit("server connecting", 2, server, ip);
-                if (server->handle == NULL)
-                       handle = net_connect_ip(ip, port, own_ip);
-               else
-                        handle = net_sendbuffer_handle(server->handle);
-       }
-
-       if (handle == NULL) {
-               /* failed */
-               if (ip == NULL && (iprec.error == 0 ||
-                                  net_hosterror_notfound(iprec.error))) {
-                       /* IP wasn't found for the host, don't try to reconnect
-                          back to this server */
+               /* host lookup ok */
+               server_real_connect(server, ip, NULL);
+               errormsg = NULL;
+       } else {
+               if (iprec.error == 0 || net_hosterror_notfound(iprec.error)) {
+                       /* IP wasn't found for the host, don't try to
+                          reconnect back to this server */
                        server->dns_error = TRUE;
                }
 
-               if (ip != NULL) {
-                       /* connect() failed */
-                       errormsg = g_strerror(errno);
-               } else if (iprec.error == 0) {
+               if (iprec.error == 0) {
                        /* forced IPv4 or IPv6 address but it wasn't found */
                        errormsg = server->connrec->family == AF_INET ?
                                "IPv4 address not found for host" :
@@ -240,18 +267,24 @@ static void server_connect_callback_readpipe(SERVER_REC *server)
                        errormsg = iprec.errorstr != NULL ? iprec.errorstr :
                                "Host lookup failed";
                }
+
                server->connection_lost = TRUE;
                server_connect_failed(server, errormsg);
-               g_free_not_null(iprec.errorstr);
-               return;
        }
 
-        if (server->handle == NULL)
-               server->handle = net_sendbuffer_create(handle, 0);
-       server->connect_tag =
-               g_input_add(handle, G_INPUT_WRITE | G_INPUT_READ,
-                           (GInputFunction) server_connect_callback_init,
-                           server);
+       g_free(iprec.errorstr);
+}
+
+SERVER_REC *server_connect(SERVER_CONNECT_REC *conn)
+{
+       CHAT_PROTOCOL_REC *proto;
+       SERVER_REC *server;
+
+       proto = CHAT_PROTOCOL(conn);
+       server = proto->server_init_connect(conn);
+       proto->server_connect(server);
+
+       return server;
 }
 
 /* initializes server record but doesn't start connecting */
@@ -270,18 +303,19 @@ void server_connect_init(SERVER_REC *server)
                g_free_not_null(server->connrec->username);
 
                str = g_get_user_name();
-               if (*str == '\0') str = "-";
+               if (*str == '\0') str = "unknown";
                server->connrec->username = g_strdup(str);
        }
        if (server->connrec->realname == NULL || *server->connrec->realname == '\0') {
                g_free_not_null(server->connrec->realname);
 
                str = g_get_real_name();
-               if (*str == '\0') str = "-";
+               if (*str == '\0') str = server->connrec->username;
                server->connrec->realname = g_strdup(str);
        }
 
        server->tag = server_create_tag(server->connrec);
+       server->connect_tag = -1;
 }
 
 /* starts connecting to server */
@@ -291,48 +325,63 @@ int server_start_connect(SERVER_REC *server)
         int fd[2];
 
        g_return_val_if_fail(server != NULL, FALSE);
-       if (server->connrec->port <= 0) return FALSE;
-
-       server_connect_init(server);
-
-       if (pipe(fd) != 0) {
-               g_warning("server_connect(): pipe() failed.");
-                g_free(server->tag);
-               g_free(server->nick);
+       if (!server->connrec->unix_socket && server->connrec->port <= 0)
                return FALSE;
-       }
 
-        server->connect_pipe[0] = g_io_channel_unix_new(fd[0]);
-       server->connect_pipe[1] = g_io_channel_unix_new(fd[1]);
-
-       connect_address = server->connrec->proxy != NULL ?
-               server->connrec->proxy : server->connrec->address;
-       server->connect_pid =
-               net_gethostbyname_nonblock(connect_address,
-                                          server->connect_pipe[1]);
-       server->connect_tag =
-               g_input_add(server->connect_pipe[0], G_INPUT_READ,
-                           (GInputFunction) server_connect_callback_readpipe,
-                           server);
        server->rawlog = rawlog_create();
 
-       lookup_servers = g_slist_append(lookup_servers, server);
+       if (server->connrec->connect_handle != NULL) {
+               /* already connected */
+               GIOChannel *handle = server->connrec->connect_handle;
+
+               server->connrec->connect_handle = NULL;
+               server->handle = net_sendbuffer_create(handle, 0);
+               server_connect_finished(server);
+       } else if (server->connrec->unix_socket) {
+               /* connect with unix socket */
+               server_real_connect(server, NULL, server->connrec->address);
+       } else {
+               /* resolve host name */
+               if (pipe(fd) != 0) {
+                       g_warning("server_connect(): pipe() failed.");
+                       g_free(server->tag);
+                       g_free(server->nick);
+                       return FALSE;
+               }
+
+               server->connect_pipe[0] = g_io_channel_unix_new(fd[0]);
+               server->connect_pipe[1] = g_io_channel_unix_new(fd[1]);
+
+               connect_address = server->connrec->proxy != NULL ?
+                       server->connrec->proxy : server->connrec->address;
+               server->connect_pid =
+                       net_gethostbyname_nonblock(connect_address,
+                                                  server->connect_pipe[1]);
+               server->connect_tag =
+                       g_input_add(server->connect_pipe[0], G_INPUT_READ,
+                                   (GInputFunction)
+                                   server_connect_callback_readpipe,
+                                   server);
 
-       signal_emit("server looking", 1, server);
+               lookup_servers = g_slist_append(lookup_servers, server);
+
+               signal_emit("server looking", 1, server);
+       }
        return TRUE;
 }
 
 static int server_remove_channels(SERVER_REC *server)
 {
-       GSList *tmp;
+       GSList *tmp, *next;
        int found;
 
        g_return_val_if_fail(server != NULL, FALSE);
 
        found = FALSE;
-       for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
+       for (tmp = server->channels; tmp != NULL; tmp = next) {
                CHANNEL_REC *channel = tmp->data;
 
+               next = tmp->next;
                channel_destroy(channel);
                found = TRUE;
        }
@@ -440,6 +489,16 @@ SERVER_REC *server_find_tag(const char *tag)
                        return server;
        }
 
+       return NULL;
+}
+
+SERVER_REC *server_find_lookup_tag(const char *tag)
+{
+       GSList *tmp;
+
+       g_return_val_if_fail(tag != NULL, NULL);
+       if (*tag == '\0') return NULL;
+
        for (tmp = lookup_servers; tmp != NULL; tmp = tmp->next) {
                SERVER_REC *server = tmp->data;
 
@@ -486,6 +545,9 @@ void server_connect_unref(SERVER_CONNECT_REC *conn)
 
         CHAT_PROTOCOL(conn)->destroy_server_connect(conn);
 
+       if (conn->connect_handle != NULL)
+               net_disconnect(conn->connect_handle);
+
        g_free_not_null(conn->proxy);
        g_free_not_null(conn->proxy_string);
        g_free_not_null(conn->proxy_string_after);
index dddde2634525986ad85e4b437304a638c3b4c0ce..d6afbdf57c4f27b51e0458da6c5c06273988585a 100644 (file)
@@ -46,6 +46,7 @@ void server_ref(SERVER_REC *server);
 int server_unref(SERVER_REC *server);
 
 SERVER_REC *server_find_tag(const char *tag);
+SERVER_REC *server_find_lookup_tag(const char *tag);
 SERVER_REC *server_find_chatnet(const char *chatnet);
 
 /* starts connecting to server */
@@ -53,6 +54,8 @@ int server_start_connect(SERVER_REC *server);
 void server_connect_ref(SERVER_CONNECT_REC *conn);
 void server_connect_unref(SERVER_CONNECT_REC *conn);
 
+SERVER_REC *server_connect(SERVER_CONNECT_REC *conn);
+
 /* initializes server record but doesn't start connecting */
 void server_connect_init(SERVER_REC *server);
 /* Connection to server finished, fill the rest of the fields */
index b541913489385e674326e0e3426a55fc8c966a46..004cd4f737022110f4f837ce969d44cded2913cb 100644 (file)
@@ -146,6 +146,7 @@ static void session_save_channel(CHANNEL_REC *channel, CONFIG_REC *config,
        node = config_node_section(node, NULL, NODE_TYPE_BLOCK);
 
        config_node_set_str(config, node, "name", channel->name);
+       config_node_set_str(config, node, "visible_name", channel->visible_name);
        config_node_set_str(config, node, "topic", channel->topic);
        config_node_set_str(config, node, "topic_by", channel->topic_by);
        config_node_set_int(config, node, "topic_time", channel->topic_time);
@@ -181,6 +182,8 @@ static void session_save_server(SERVER_REC *server, CONFIG_REC *config,
        config_node_set_str(config, node, "password", server->connrec->password);
        config_node_set_str(config, node, "nick", server->nick);
 
+       config_node_set_bool(config, node, "use_ssl", server->connrec->use_ssl);
+
        handle = g_io_channel_unix_get_fd(net_sendbuffer_handle(server->handle));
        config_node_set_int(config, node, "handle", handle);
 
@@ -215,13 +218,14 @@ static void session_restore_channel_nicks(CHANNEL_REC *channel,
 static void session_restore_channel(SERVER_REC *server, CONFIG_NODE *node)
 {
         CHANNEL_REC *channel;
-       const char *name;
+       const char *name, *visible_name;
 
        name = config_node_get_str(node, "name", NULL);
        if (name == NULL)
                return;
 
-       channel = CHAT_PROTOCOL(server)->channel_create(server, name, TRUE);
+       visible_name = config_node_get_str(node, "visible_name", NULL);
+       channel = CHAT_PROTOCOL(server)->channel_create(server, name, visible_name, TRUE);
        channel->topic = g_strdup(config_node_get_str(node, "topic", NULL));
        channel->topic_by = g_strdup(config_node_get_str(node, "topic_by", NULL));
        channel->topic_time = config_node_get_int(node, "topic_time", 0);
@@ -274,12 +278,13 @@ static void session_restore_server(CONFIG_NODE *node)
                                  chatnet, password, nick);
        if (conn != NULL) {
                conn->reconnection = TRUE;
+               conn->connect_handle = g_io_channel_unix_new(handle);
 
-               server = proto->server_connect(conn);
-                server->handle = net_sendbuffer_create(g_io_channel_unix_new(handle), 0);
+               server = proto->server_init_connect(conn);
                server->session_reconnect = TRUE;
-
                signal_emit("session restore server", 2, server, node);
+
+               proto->server_connect(server);
        }
 }
 
index e0df975a185807e459a39ebbaeb2c6ac3e024a62..fdff38015e798ef3ed3e243ef9898ef180b2072d 100644 (file)
@@ -19,7 +19,6 @@ typedef struct {
 #define iconfig_get_str(a, b, c) config_get_str(mainconfig, a, b, c)
 #define iconfig_get_int(a, b, c) config_get_int(mainconfig, a, b, c)
 #define iconfig_get_bool(a, b, c) config_get_bool(mainconfig, a, b, c)
-#define iconfig_list_find(a, b, c, d) config_list_find(mainconfig, a, b, c, d)
 
 #define iconfig_set_str(a, b, c) config_set_str(mainconfig, a, b, c)
 #define iconfig_set_int(a, b, c) config_set_int(mainconfig, a, b, c)
index eeb465f4743aa7d4078358f0626fcca8a773b3f5..d7b6f7dbfc8e5bae851376eccab6bd3b685e625f 100644 (file)
@@ -6,7 +6,7 @@ GHashTable *module_data;
 
 void *window;
 STRUCT_SERVER_REC *server;
-char *name;
+char *visible_name;
 
 time_t createtime;
 int data_level;
@@ -14,4 +14,8 @@ char *hilight_color;
 
 void (*destroy)(WI_ITEM_REC *item);
 
+const char *(*get_target)(WI_ITEM_REC *item);
+#define window_item_get_target(item) \
+       ((item)->get_target(item))
+
 #undef STRUCT_SERVER_REC
index d97433a371f72aa8620c06365ce9960fc24e3e6f..920e261148ff796253ef25fc319a720a813b4b4d 100644 (file)
@@ -47,6 +47,7 @@ noinst_HEADERS = \
        completion.h \
        fe-channels.h \
        fe-common-core.h \
+       fe-core-commands.h \
        fe-exec.h \
        fe-messages.h \
        fe-queries.h \
index 9c1050db313cdb123a9bd1814676f64dea7f5d49..77513a0ded525b18513d0594c83156611f4b9e3a 100644 (file)
@@ -44,7 +44,7 @@ void autorun_startup(void)
                recvlen = read(f, tmpbuf, sizeof(tmpbuf));
 
                ret = line_split(tmpbuf, recvlen, &str, &buffer);
-               if (ret > 0) {
+               if (ret > 0 && *str != '#') {
                        eval_special_string(str, "",
                                            active_win->active_server,
                                            active_win->active);
index df5525eb4ad08765f979c893e8b99e2f8967b188..f64dca65f8a242d439fff0ce7107bd87d505ac0b 100644 (file)
@@ -23,6 +23,7 @@
 #include "commands.h"
 #include "misc.h"
 #include "levels.h"
+#include "lib-config/iconfig.h"
 #include "settings.h"
 
 #include "chatnets.h"
@@ -34,6 +35,7 @@
 #include "nicklist.h"
 
 #include "completion.h"
+#include "chat-completion.h"
 #include "window-items.h"
 
 static int keep_privates_count, keep_publics_count;
@@ -317,7 +319,7 @@ static GList *completion_msg(SERVER_REC *win_server,
        for (tmp = servers; tmp != NULL; tmp = tmp->next) {
                SERVER_REC *rec = tmp->data;
 
-               if (rec == win_server)
+               if (servers->next == NULL && rec == win_server)
                        newprefix = g_strdup(prefix);
                else {
                        newprefix = prefix == NULL ?
@@ -484,6 +486,32 @@ static GList *completion_joinlist(GList *list1, GList *list2)
        return list1;
 }
 
+GList *completion_get_servertags(const char *word)
+{
+       GList *list;
+       GSList *tmp;
+       int len;
+
+       g_return_val_if_fail(word != NULL, NULL);
+
+       len = strlen(word);
+       list = NULL;
+
+       for (tmp = servers; tmp != NULL; tmp = tmp->next) {
+               SERVER_REC *rec = tmp->data;
+
+               if (g_strncasecmp(rec->tag, word, len) == 0) {
+                       if (rec == active_win->active_server)
+                               list = g_list_prepend(list, g_strdup(rec->tag));
+                       else
+                               list = g_list_append(list, g_strdup(rec->tag));
+               }
+
+       }
+
+       return list;
+}
+
 GList *completion_get_channels(SERVER_REC *server, const char *word)
 {
        GList *list;
@@ -491,7 +519,6 @@ GList *completion_get_channels(SERVER_REC *server, const char *word)
        int len;
 
        g_return_val_if_fail(word != NULL, NULL);
-       g_return_val_if_fail(*word != '\0', NULL);
 
        len = strlen(word);
        list = NULL;
@@ -501,7 +528,9 @@ GList *completion_get_channels(SERVER_REC *server, const char *word)
        for (; tmp != NULL; tmp = tmp->next) {
                CHANNEL_REC *rec = tmp->data;
 
-               if (g_strncasecmp(rec->name, word, len) == 0)
+               if (g_strncasecmp(rec->visible_name, word, len) == 0)
+                       list = g_list_append(list, g_strdup(rec->visible_name));
+               else if (g_strncasecmp(rec->name, word, len) == 0)
                        list = g_list_append(list, g_strdup(rec->name));
        }
 
@@ -518,6 +547,36 @@ GList *completion_get_channels(SERVER_REC *server, const char *word)
        return list;
 }
 
+GList *completion_get_aliases(const char *word)
+{
+       CONFIG_NODE *node;
+       GList *list;
+       GSList *tmp;
+       int len;
+
+       g_return_val_if_fail(word != NULL, NULL);
+
+       len = strlen(word);
+       list = NULL;
+
+       /* get the list of all aliases */
+       node = iconfig_node_traverse("aliases", FALSE);
+       tmp = node == NULL ? NULL : config_node_first(node->value);
+       for (; tmp != NULL; tmp = config_node_next(tmp)) {
+               node = tmp->data;
+
+               if (node->type != NODE_TYPE_KEY)
+                       continue;
+
+               if (len != 0 && g_strncasecmp(node->key, word, len) != 0)
+                       continue;
+
+               list = g_list_append(list, g_strdup(node->key));
+       }
+       
+       return list;
+}
+
 static void complete_window_nicks(GList **list, WINDOW_REC *window,
                                   const char *word, const char *linestart)
 {
@@ -739,6 +798,17 @@ static void sig_complete_connect(GList **list, WINDOW_REC *window,
        if (*list != NULL) signal_stop();
 }
 
+static void sig_complete_tag(GList **list, WINDOW_REC *window,
+                            const char *word, const char *line,
+                            int *want_space)
+{
+       g_return_if_fail(list != NULL);
+       g_return_if_fail(word != NULL);
+
+       *list = completion_get_servertags(word);
+       if (*list != NULL) signal_stop();
+}
+
 static void sig_complete_topic(GList **list, WINDOW_REC *window,
                               const char *word, const char *line,
                               int *want_space)
@@ -757,6 +827,59 @@ static void sig_complete_topic(GList **list, WINDOW_REC *window,
        }
 }
 
+static void sig_complete_away(GList **list, WINDOW_REC *window,
+                              const char *word, const char *line,
+                              int *want_space)
+{
+       const char *reason;
+
+       g_return_if_fail(list != NULL);
+       g_return_if_fail(word != NULL);
+
+        *want_space = FALSE;
+
+       if (*word == '\0' && window->active_server != NULL) {
+               reason = SERVER(window->active_server)->away_reason;
+               if (reason != NULL) {
+                       *list = g_list_append(NULL, g_strdup(reason));
+                       signal_stop();
+               }
+       }
+}
+
+static void sig_complete_unalias(GList **list, WINDOW_REC *window,
+                               const char *word, const char *line,
+                               int *want_space)
+{
+       g_return_if_fail(list != NULL);
+       g_return_if_fail(word != NULL);
+
+       *list = completion_get_aliases(word);
+       if (*list != NULL) signal_stop();
+}
+
+static void sig_complete_alias(GList **list, WINDOW_REC *window,
+                               const char *word, const char *line,
+                               int *want_space)
+{
+       const char *definition;
+       
+       g_return_if_fail(list != NULL);
+       g_return_if_fail(word != NULL);
+       g_return_if_fail(line != NULL);
+
+       if (*line != '\0') {
+               if ((definition = alias_find(line)) != NULL) {
+                       *list = g_list_append(NULL, g_strdup(definition));
+                       signal_stop();
+               }
+       } else {        
+               *list = completion_get_aliases(word);
+               if (*list != NULL) signal_stop();
+       }
+}
+
+
 static void sig_complete_channel(GList **list, WINDOW_REC *window,
                                 const char *word, const char *line,
                                 int *want_space)
@@ -768,6 +891,17 @@ static void sig_complete_channel(GList **list, WINDOW_REC *window,
        if (*list != NULL) signal_stop();
 }
 
+static void sig_complete_server(GList **list, WINDOW_REC *window,
+                               const char *word, const char *line,
+                               int *want_space)
+{
+       g_return_if_fail(list != NULL);
+       g_return_if_fail(word != NULL);
+
+       *list = completion_get_servers(word);
+       if (*list != NULL) signal_stop();
+}
+
 /* expand \n, \t and \\ */
 static char *expand_escapes(const char *line, SERVER_REC *server,
                            WI_ITEM_REC *item)
@@ -842,10 +976,18 @@ static char *auto_complete(CHANNEL_REC *channel, const char *line)
 
 static void event_text(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
 {
-       char *line, *str;
+       char *line, *str, *target;
 
        g_return_if_fail(data != NULL);
-       if (item == NULL) return;
+
+       if (item == NULL)
+               return;
+
+       if (*data == '\0') {
+               /* empty line, forget it. */
+                signal_stop();
+               return;
+       }
 
        line = settings_get_bool("expand_escapes") ?
                expand_escapes(data, server, item) : g_strdup(data);
@@ -859,9 +1001,14 @@ static void event_text(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
                }
        }
 
-       str = g_strdup_printf(IS_CHANNEL(item) ? "-channel %s %s" :
-                             IS_QUERY(item) ? "-nick %s %s" : "%s %s",
-                             item->name, line);
+       /* the nick is quoted in case it contains '-' character. also
+          spaces should work too now :) The nick is also escaped in case
+          it contains '\' characters */
+       target = escape_string(window_item_get_target(item));
+       str = g_strdup_printf(IS_CHANNEL(item) ? "-channel \"%s\" %s" :
+                             IS_QUERY(item) ? "-nick \"%s\" %s" : "%s %s",
+                             target, line);
+       g_free(target);
 
        signal_emit("command msg", 3, str, server, item);
 
@@ -917,10 +1064,11 @@ void chat_completion_init(void)
        settings_add_bool("completion", "completion_auto", FALSE);
        settings_add_int("completion", "completion_keep_publics", 50);
        settings_add_int("completion", "completion_keep_privates", 10);
-       settings_add_bool("completion", "expand_escapes", FALSE);
        settings_add_bool("completion", "completion_nicks_lowercase", FALSE);
        settings_add_bool("completion", "completion_strict", FALSE);
 
+       settings_add_bool("lookandfeel", "expand_escapes", FALSE);
+
        read_settings();
        signal_add("complete word", (SIGNAL_FUNC) sig_complete_word);
        signal_add("complete command msg", (SIGNAL_FUNC) sig_complete_msg);
@@ -931,8 +1079,15 @@ void chat_completion_init(void)
        signal_add("complete erase command action", (SIGNAL_FUNC) sig_erase_complete_msg);
        signal_add("complete command connect", (SIGNAL_FUNC) sig_complete_connect);
        signal_add("complete command server", (SIGNAL_FUNC) sig_complete_connect);
+       signal_add("complete command disconnect", (SIGNAL_FUNC) sig_complete_tag);
+       signal_add("complete command reconnect", (SIGNAL_FUNC) sig_complete_tag);
        signal_add("complete command topic", (SIGNAL_FUNC) sig_complete_topic);
+       signal_add("complete command away", (SIGNAL_FUNC) sig_complete_away);
+       signal_add("complete command unalias", (SIGNAL_FUNC) sig_complete_unalias);
+       signal_add("complete command alias", (SIGNAL_FUNC) sig_complete_alias);
        signal_add("complete command window item move", (SIGNAL_FUNC) sig_complete_channel);
+       signal_add("complete command server add", (SIGNAL_FUNC) sig_complete_server);
+       signal_add("complete command server remove", (SIGNAL_FUNC) sig_complete_server);
        signal_add("message public", (SIGNAL_FUNC) sig_message_public);
        signal_add("message join", (SIGNAL_FUNC) sig_message_join);
        signal_add("message private", (SIGNAL_FUNC) sig_message_private);
@@ -960,8 +1115,15 @@ void chat_completion_deinit(void)
        signal_remove("complete erase command action", (SIGNAL_FUNC) sig_erase_complete_msg);
        signal_remove("complete command connect", (SIGNAL_FUNC) sig_complete_connect);
        signal_remove("complete command server", (SIGNAL_FUNC) sig_complete_connect);
+       signal_remove("complete command disconnect", (SIGNAL_FUNC) sig_complete_tag);
+       signal_remove("complete command reconnect", (SIGNAL_FUNC) sig_complete_tag);
        signal_remove("complete command topic", (SIGNAL_FUNC) sig_complete_topic);
+       signal_remove("complete command away", (SIGNAL_FUNC) sig_complete_away);
+       signal_remove("complete command unalias", (SIGNAL_FUNC) sig_complete_unalias);
+       signal_remove("complete command alias", (SIGNAL_FUNC) sig_complete_alias);
        signal_remove("complete command window item move", (SIGNAL_FUNC) sig_complete_channel);
+       signal_remove("complete command server add", (SIGNAL_FUNC) sig_complete_server);
+       signal_remove("complete command server remove", (SIGNAL_FUNC) sig_complete_server);
        signal_remove("message public", (SIGNAL_FUNC) sig_message_public);
        signal_remove("message join", (SIGNAL_FUNC) sig_message_join);
        signal_remove("message private", (SIGNAL_FUNC) sig_message_private);
index 3cb70ca59ed1aa38580f2f599bcf2451c0564a93..ff6098b15761fa7adbfc715650ee788909b60b09 100644 (file)
@@ -1,6 +1,12 @@
 #ifndef __CHAT_COMPLETION_H
 #define __CHAT_COMPLETION_H
 
+GList *completion_get_chatnets(const char *word);
+GList *completion_get_servers(const char *word);
+GList *completion_get_servertags(const char *word);
+GList *completion_get_channels(SERVER_REC *server, const char *word);
+GList *completion_get_aliases(const char *word);
+
 void completion_last_message_add(const char *nick);
 void completion_last_message_remove(const char *nick);
 void completion_last_message_rename(const char *oldnick, const char *newnick);
index 99046b9f3e073178ca084eb91c0cd860063eb0c4..7a9c9ad3f14669cfa9be3ca882b08f3551f6497c 100644 (file)
 */
 
 #include "module.h"
+#include "module-formats.h"
 #include "signals.h"
 #include "commands.h"
+#include "levels.h"
 #include "misc.h"
 #include "lib-config/iconfig.h"
 #include "settings.h"
 
 #include "completion.h"
-
-#define wordreplace_find(word) \
-       iconfig_list_find("replaces", "text", word, "replace")
-
-#define completion_find(completion) \
-       iconfig_list_find("completions", "short", completion, "long")
+#include "printtext.h"
 
 static GList *complist; /* list of commands we're currently completing */
 static char *last_line;
@@ -46,6 +43,24 @@ static int last_want_space, last_line_pos;
 void chat_completion_init(void);
 void chat_completion_deinit(void);
 
+static const char *completion_find(const char *key, int automatic)
+{
+       CONFIG_NODE *node;
+
+       node = iconfig_node_traverse("completions", FALSE);
+       if (node == NULL || node->type != NODE_TYPE_BLOCK)
+               return NULL;
+
+       node = config_node_section(node, key, -1);
+       if (node == NULL)
+               return NULL;
+
+       if (automatic && !config_node_get_bool(node, "auto", FALSE))
+               return NULL;
+
+       return config_node_get_str(node, "value", NULL);
+}
+
 /* Return whole word at specified position in string */
 char *get_word_at(const char *str, int pos, char **startpos)
 {
@@ -85,7 +100,7 @@ char *auto_word_complete(const char *line, int *pos)
        g_string_erase(result, startpos, strlen(word));
 
        /* check for words in autocompletion list */
-       replace = wordreplace_find(word);
+       replace = completion_find(word, TRUE);
        if (replace == NULL) {
                ret = NULL;
                g_string_free(result, TRUE);
@@ -569,7 +584,7 @@ static void sig_complete_word(GList **list, WINDOW_REC *window,
        g_return_if_fail(linestart != NULL);
 
        /* check against "completion words" list */
-       newword = completion_find(word);
+       newword = completion_find(word, FALSE);
        if (newword != NULL) {
                *list = g_list_append(*list, g_strdup(newword));
 
@@ -577,6 +592,16 @@ static void sig_complete_word(GList **list, WINDOW_REC *window,
                return;
        }
 
+       if (*linestart != '\0' && (*word == '/' || *word == '~')) {
+               /* quite likely filename completion */
+               *list = g_list_concat(*list, filename_complete(word, NULL));
+               if (*list != NULL) {
+                       *want_space = FALSE;
+                       signal_stop();
+                       return;
+               }
+       }
+
        /* command completion? */
        cmdchars = settings_get_str("cmdchars");
        if (*word != '\0' && *linestart == '\0' && strchr(cmdchars, *word)) {
@@ -734,6 +759,79 @@ static void sig_complete_command(GList **list, WINDOW_REC *window,
        if (*list != NULL) signal_stop();
 }
 
+static void cmd_completion(const char *data)
+{
+       GHashTable *optlist;
+       CONFIG_NODE *node;
+       GSList *tmp;
+       char *key, *value;
+       void *free_arg;
+       int len;
+
+       if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS |
+                           PARAM_FLAG_GETREST,
+                           "completion", &optlist, &key, &value))
+               return;
+
+       node = iconfig_node_traverse("completions", *value != '\0');
+       if (node != NULL && node->type != NODE_TYPE_BLOCK) {
+               /* FIXME: remove after 0.8.5 */
+               iconfig_node_remove(mainconfig->mainnode, node);
+               node = iconfig_node_traverse("completions", *value != '\0');
+       }
+
+       if (node == NULL || (node->value == NULL && *value == '\0')) {
+               printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
+                           TXT_NO_COMPLETIONS);
+               cmd_params_free(free_arg);
+               return;
+       }
+
+       if (g_hash_table_lookup(optlist, "delete") != NULL && *key != '\0') {
+               printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
+                           TXT_COMPLETION_REMOVED, key);
+
+               iconfig_set_str("completions", key, NULL);
+               signal_emit("completion removed", 1, key);
+       } else if (*key != '\0' && *value != '\0') {
+               int automatic = g_hash_table_lookup(optlist, "auto") != NULL;
+
+               node = config_node_section(node, key, NODE_TYPE_BLOCK);
+               iconfig_node_set_str(node, "value", value);
+               if (automatic)
+                       iconfig_node_set_bool(node, "auto", TRUE);
+               else
+                       iconfig_node_set_str(node, "auto", NULL);
+
+               printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP,
+                           TXT_COMPLETION_LINE,
+                           key, value, automatic ? "yes" : "no");
+
+               signal_emit("completion added", 1, key);
+       } else {
+               printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP,
+                           TXT_COMPLETION_HEADER);
+
+               len = strlen(key);
+               for (tmp = node->value; tmp != NULL; tmp = tmp->next) {
+                       node = tmp->data;
+
+                       if (len == 0 ||
+                           g_strncasecmp(node->key, key, len) == 0) {
+                               printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP,
+                                           TXT_COMPLETION_LINE, node->key,
+                                           config_node_get_str(node, "value", ""),
+                                           config_node_get_bool(node, "auto", FALSE) ? "yes" : "no");
+                       }
+               }
+
+               printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP,
+                           TXT_COMPLETION_FOOTER);
+       }
+
+       cmd_params_free(free_arg);
+}
+
 void completion_init(void)
 {
        complist = NULL;
@@ -741,6 +839,8 @@ void completion_init(void)
 
        chat_completion_init();
 
+       command_bind("completion", NULL, (SIGNAL_FUNC) cmd_completion);
+
        signal_add_first("complete word", (SIGNAL_FUNC) sig_complete_word);
        signal_add_first("complete erase", (SIGNAL_FUNC) sig_complete_erase);
        signal_add("complete command set", (SIGNAL_FUNC) sig_complete_set);
@@ -752,6 +852,8 @@ void completion_init(void)
        signal_add("complete command rawlog open", (SIGNAL_FUNC) sig_complete_filename);
        signal_add("complete command rawlog save", (SIGNAL_FUNC) sig_complete_filename);
        signal_add("complete command help", (SIGNAL_FUNC) sig_complete_command);
+
+       command_set_options("completion", "auto delete");
 }
 
 void completion_deinit(void)
@@ -760,6 +862,8 @@ void completion_deinit(void)
 
        chat_completion_deinit();
 
+       command_unbind("completion", (SIGNAL_FUNC) cmd_completion);
+
        signal_remove("complete word", (SIGNAL_FUNC) sig_complete_word);
        signal_remove("complete erase", (SIGNAL_FUNC) sig_complete_erase);
        signal_remove("complete command set", (SIGNAL_FUNC) sig_complete_set);
@@ -772,5 +876,3 @@ void completion_deinit(void)
        signal_remove("complete command rawlog save", (SIGNAL_FUNC) sig_complete_filename);
        signal_remove("complete command help", (SIGNAL_FUNC) sig_complete_command);
 }
-
-
index 27ad4365c0923831a163cdcdc97586bd1e2a19ab..4ce5abeb2f5701b51c6c9ae327359cd4496e5ac7 100644 (file)
@@ -70,7 +70,7 @@ static void signal_channel_destroyed(CHANNEL_REC *channel)
            !channel->server->disconnected) {
                /* kicked out from channel */
                window_bind_add(window, channel->server->tag,
-                               channel->name);
+                               channel->visible_name);
        } else if (!channel->joined || channel->left)
                window_auto_destroy(window);
 }
@@ -96,12 +96,20 @@ static void signal_window_item_changed(WINDOW_REC *window, WI_ITEM_REC *item)
        if (item == NULL) return;
 
        if (g_slist_length(window->items) > 1 && IS_CHANNEL(item)) {
-               printformat(item->server, item->name, MSGLEVEL_CLIENTNOTICE,
-                           TXT_TALKING_IN, item->name);
+               printformat(item->server, item->visible_name,
+                           MSGLEVEL_CLIENTNOTICE,
+                           TXT_TALKING_IN, item->visible_name);
                 signal_stop();
        }
 }
 
+static void sig_channel_joined(CHANNEL_REC *channel)
+{
+       if (settings_get_bool("show_names_on_join") &&
+           !channel->session_rejoin)
+               fe_channels_nicklist(channel, CHANNEL_NICKLIST_FLAG_ALL);
+}
+
 static void cmd_wjoin_pre(const char *data)
 {
        GHashTable *optlist;
@@ -172,7 +180,8 @@ static void cmd_channel_list_joined(void)
        /* print active channel */
        channel = CHANNEL(active_win->active);
        if (channel != NULL)
-               printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_CURRENT_CHANNEL, channel->name);
+               printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
+                           TXT_CURRENT_CHANNEL, channel->visible_name);
 
        /* print list of all channels, their modes, server tags and nicks */
        printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_CHANLIST_HEADER);
@@ -189,7 +198,8 @@ static void cmd_channel_list_joined(void)
 
                if (nicks->len > 1) g_string_truncate(nicks, nicks->len-1);
                printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_CHANLIST_LINE,
-                           channel->name, channel->mode, channel->server->tag, nicks->str);
+                           channel->visible_name, channel->mode,
+                           channel->server->tag, nicks->str);
 
                g_slist_free(nicklist);
                g_string_free(nicks, TRUE);
@@ -326,13 +336,13 @@ static void display_sorted_nicks(CHANNEL_REC *channel, GSList *nicklist)
        int *columns, cols, rows, last_col_rows, col, row, max_width;
         int item_extra, linebuf_size, formatnum;
 
-       window = window_find_closest(channel->server, channel->name,
+       window = window_find_closest(channel->server, channel->visible_name,
                                     MSGLEVEL_CLIENTCRAP);
         max_width = window->width;
 
         /* get the length of item extra stuff ("[ ] ") */
        format = format_get_text(MODULE_NAME, NULL,
-                                channel->server, channel->name,
+                                channel->server, channel->visible_name,
                                 TXT_NAMES_NICK, " ", "");
        stripped = strip_codes(format);
        item_extra = strlen(stripped);
@@ -344,7 +354,7 @@ static void display_sorted_nicks(CHANNEL_REC *channel, GSList *nicklist)
                max_width = settings_get_int("names_max_width");
 
         /* remove width of the timestamp from max_width */
-       format_create_dest(&dest, channel->server, channel->name,
+       format_create_dest(&dest, channel->server, channel->visible_name,
                           MSGLEVEL_CLIENTCRAP, NULL);
        format = format_get_line_start(current_theme, &dest, time(NULL));
        if (format != NULL) {
@@ -356,8 +366,9 @@ static void display_sorted_nicks(CHANNEL_REC *channel, GSList *nicklist)
 
         /* remove width of the prefix from max_width */
        prefix_format = format_get_text(MODULE_NAME, NULL,
-                                       channel->server, channel->name,
-                                       TXT_NAMES_PREFIX, channel->name);
+                                       channel->server, channel->visible_name,
+                                       TXT_NAMES_PREFIX,
+                                       channel->visible_name);
        if (prefix_format != NULL) {
                stripped = strip_codes(prefix_format);
                max_width -= strlen(stripped);
@@ -410,13 +421,14 @@ static void display_sorted_nicks(CHANNEL_REC *channel, GSList *nicklist)
                        rec->voice ? TXT_NAMES_NICK_VOICE :
                         TXT_NAMES_NICK;
                format = format_get_text(MODULE_NAME, NULL,
-                                        channel->server, channel->name,
+                                        channel->server,
+                                        channel->visible_name,
                                         formatnum, nickmode, linebuf);
                g_string_append(str, format);
                g_free(format);
 
                if (++col == cols) {
-                       printtext(channel->server, channel->name,
+                       printtext(channel->server, channel->visible_name,
                                  MSGLEVEL_CLIENTCRAP, "%s", str->str);
                        g_string_truncate(str, 0);
                        if (prefix_format != NULL)
@@ -429,7 +441,7 @@ static void display_sorted_nicks(CHANNEL_REC *channel, GSList *nicklist)
        }
 
        if (str->len > strlen(prefix_format)) {
-               printtext(channel->server, channel->name,
+               printtext(channel->server, channel->visible_name,
                          MSGLEVEL_CLIENTCRAP, "%s", str->str);
        }
 
@@ -480,15 +492,17 @@ void fe_channels_nicklist(CHANNEL_REC *channel, int flags)
 
        /* display the nicks */
         if ((flags & CHANNEL_NICKLIST_FLAG_COUNT) == 0) {
-               printformat(channel->server, channel->name,
-                           MSGLEVEL_CLIENTCRAP, TXT_NAMES, channel->name, nicks, ops, halfops, voices, normal);
+               printformat(channel->server, channel->visible_name,
+                           MSGLEVEL_CLIENTCRAP, TXT_NAMES,
+                           channel->visible_name,
+                           nicks, ops, halfops, voices, normal);
                display_sorted_nicks(channel, sorted);
        }
        g_slist_free(sorted);
 
-       printformat(channel->server, channel->name,
+       printformat(channel->server, channel->visible_name,
                    MSGLEVEL_CLIENTNOTICE, TXT_ENDOFNAMES,
-                   channel->name, nicks, ops, halfops, voices, normal);
+                   channel->visible_name, nicks, ops, halfops, voices, normal);
 }
 
 /* SYNTAX: NAMES [-count | -ops -halfops -voices -normal] [<channels> | **] */
@@ -513,7 +527,7 @@ static void cmd_names(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
                if (!IS_CHANNEL(item))
                         cmd_param_error(CMDERR_NOT_JOINED);
 
-               channel = item->name;
+               channel = CHANNEL(item)->name;
        }
 
        flags = 0;
@@ -594,6 +608,7 @@ static void cmd_cycle(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
 void fe_channels_init(void)
 {
        settings_add_bool("lookandfeel", "autoclose_windows", TRUE);
+       settings_add_bool("lookandfeel", "show_names_on_join", TRUE);
        settings_add_int("lookandfeel", "names_max_columns", 6);
        settings_add_int("lookandfeel", "names_max_width", 0);
 
@@ -601,6 +616,7 @@ void fe_channels_init(void)
        signal_add("channel destroyed", (SIGNAL_FUNC) signal_channel_destroyed);
        signal_add_last("window item changed", (SIGNAL_FUNC) signal_window_item_changed);
        signal_add_last("server disconnected", (SIGNAL_FUNC) sig_disconnected);
+       signal_add_last("channel joined", (SIGNAL_FUNC) sig_channel_joined);
 
        command_bind_first("join", NULL, (SIGNAL_FUNC) cmd_wjoin_pre);
        command_bind("join", NULL, (SIGNAL_FUNC) cmd_join);
@@ -623,6 +639,7 @@ void fe_channels_deinit(void)
        signal_remove("channel destroyed", (SIGNAL_FUNC) signal_channel_destroyed);
        signal_remove("window item changed", (SIGNAL_FUNC) signal_window_item_changed);
        signal_remove("server disconnected", (SIGNAL_FUNC) sig_disconnected);
+       signal_remove("channel joined", (SIGNAL_FUNC) sig_channel_joined);
 
        command_unbind("join", (SIGNAL_FUNC) cmd_wjoin_pre);
        command_unbind("join", (SIGNAL_FUNC) cmd_join);
index 94e18fc1f1c9c611ca4f858f075710d4004ce322..32f405ace2c2a7370d47fb2bbcd355600bf7ee29 100644 (file)
@@ -31,6 +31,7 @@
 #include "servers-setup.h"
 
 #include "autorun.h"
+#include "fe-core-commands.h"
 #include "fe-queries.h"
 #include "hilight-text.h"
 #include "command-history.h"
@@ -91,9 +92,6 @@ void fe_settings_deinit(void);
 void window_commands_init(void);
 void window_commands_deinit(void);
 
-void fe_core_commands_init(void);
-void fe_core_commands_deinit(void);
-
 static void print_version(void)
 {
        printf(PACKAGE" " IRSSI_VERSION" (%d %04d)\n",
@@ -276,6 +274,8 @@ void glog_func(const char *log_domain, GLogLevelFlags log_level,
        }
 }
 
+#define MSGS_WINDOW_LEVELS (MSGLEVEL_MSGS|MSGLEVEL_ACTIONS|MSGLEVEL_DCCMSGS)
+
 static void create_windows(void)
 {
        WINDOW_REC *window;
@@ -289,14 +289,14 @@ static void create_windows(void)
                window_set_name(window, "(status)");
                window_set_level(window, MSGLEVEL_ALL ^
                                 (settings_get_bool("use_msgs_window") ?
-                                 (MSGLEVEL_MSGS|MSGLEVEL_DCCMSGS) : 0));
+                                 MSGS_WINDOW_LEVELS : 0));
                 window_set_immortal(window, TRUE);
        }
 
        if (settings_get_bool("use_msgs_window")) {
                window = window_create(NULL, TRUE);
                window_set_name(window, "(msgs)");
-               window_set_level(window, MSGLEVEL_MSGS|MSGLEVEL_DCCMSGS);
+               window_set_level(window, MSGS_WINDOW_LEVELS);
                 window_set_immortal(window, TRUE);
        }
 
index d50b23e501bb5d54194bcf64945b43a5d6363d10..b599c8109cbbb79d2c25367f41bd8375957356a5 100644 (file)
@@ -50,11 +50,12 @@ static int ret_texts[] = {
        TXT_NOT_GOOD_IDEA
 };
 
+int command_hide_output;
+
 /* keep the whole command line here temporarily. we need it in
    "default command" event handler, but there we don't know if the start of
    the line had one or two command chars, and which one.. */
 static const char *current_cmdline;
-static int hide_output;
 
 static GTimeVal time_command_last, time_command_now;
 static int last_command_cmd, command_cmd;
@@ -198,12 +199,6 @@ static void event_command(const char *data)
 {
        const char *cmdchar;
 
-       if (*data == '\0') {
-               /* empty line, forget it. */
-                signal_stop();
-               return;
-       }
-
        /* save current command line */
        current_cmdline = data;
 
@@ -212,13 +207,15 @@ static void event_command(const char *data)
        last_command_cmd = command_cmd;
 
        g_get_current_time(&time_command_now);
-       command_cmd = strchr(settings_get_str("cmdchars"), *data) != NULL;
+       command_cmd = *data != '\0' &&
+               strchr(settings_get_str("cmdchars"), *data) != NULL;
 
        /* /^command hides the output of the command */
-       cmdchar = strchr(settings_get_str("cmdchars"), *data);
+       cmdchar = *data == '\0' ? NULL :
+               strchr(settings_get_str("cmdchars"), *data);
        if (cmdchar != NULL && (data[1] == '^' ||
                                (data[1] == *cmdchar && data[2] == '^'))) {
-                hide_output = TRUE;
+                command_hide_output = TRUE;
                signal_add_first("print starting", (SIGNAL_FUNC) sig_stop);
                signal_add_first("print format", (SIGNAL_FUNC) sig_stop);
                signal_add_first("print text", (SIGNAL_FUNC) sig_stop);
@@ -227,8 +224,8 @@ static void event_command(const char *data)
 
 static void event_command_last(const char *data)
 {
-       if (hide_output) {
-               hide_output = FALSE;
+       if (command_hide_output) {
+               command_hide_output = FALSE;
                signal_remove("print starting", (SIGNAL_FUNC) sig_stop);
                signal_remove("print format", (SIGNAL_FUNC) sig_stop);
                signal_remove("print text", (SIGNAL_FUNC) sig_stop);
@@ -318,7 +315,7 @@ static void event_list_subcommands(const char *command)
 
 void fe_core_commands_init(void)
 {
-       hide_output = FALSE;
+       command_hide_output = FALSE;
 
        command_cmd = FALSE;
        memset(&time_command_now, 0, sizeof(GTimeVal));
index 88df56aeeb10c3f781dd38d491dee05ff50850bc..68ff1c437ac6ebbad8b52e22dd1a81f14ce7f6bc 100644 (file)
@@ -54,10 +54,15 @@ static void exec_wi_destroy(EXEC_WI_REC *rec)
                window_item_destroy((WI_ITEM_REC *) rec);
 
        MODULE_DATA_DEINIT(rec);
-       g_free(rec->name);
+       g_free(rec->visible_name);
         g_free(rec);
 }
 
+static const char *exec_get_target(WI_ITEM_REC *item)
+{
+       return ((EXEC_WI_REC *) item)->visible_name;
+}
+
 static EXEC_WI_REC *exec_wi_create(WINDOW_REC *window, PROCESS_REC *rec)
 {
        EXEC_WI_REC *item;
@@ -68,7 +73,8 @@ static EXEC_WI_REC *exec_wi_create(WINDOW_REC *window, PROCESS_REC *rec)
        item = g_new0(EXEC_WI_REC, 1);
        item->type = module_get_uniq_id_str("WINDOW ITEM TYPE", "EXEC");
         item->destroy = (void (*) (WI_ITEM_REC *)) exec_wi_destroy;
-       item->name = rec->name != NULL ? g_strdup(rec->name) :
+       item->get_target = exec_get_target;
+       item->visible_name = rec->name != NULL ? g_strdup(rec->name) :
                g_strdup_printf("%%%d", rec->id);
 
        item->createtime = time(NULL);
@@ -411,7 +417,7 @@ static void handle_exec(const char *args, GHashTable *optlist,
                 /* redirect output to active channel/query */
                if (item == NULL)
                        cmd_return_error(CMDERR_NOT_JOINED);
-               target = item->name;
+               target = (char *) window_item_get_target(item);
                target_channel = IS_CHANNEL(item);
                target_nick = IS_QUERY(item);
        } else if (g_hash_table_lookup(optlist, "msg") != NULL) {
@@ -589,7 +595,7 @@ static void sig_exec_input(PROCESS_REC *rec, const char *text)
                            3, str, server, item);
                 g_free(str);
        } else if (rec->target_item != NULL) {
-               printtext(NULL, rec->target_item->name,
+               printtext(NULL, rec->target_item->visible_name,
                          rec->level, "%s", text);
        } else {
                printtext_window(rec->target_win, rec->level, "%s", text);
@@ -612,7 +618,8 @@ static void sig_window_destroyed(WINDOW_REC *window)
 
 static void event_text(const char *data, SERVER_REC *server, EXEC_WI_REC *item)
 {
-       if (!IS_EXEC_WI(item)) return;
+       if (!IS_EXEC_WI(item))
+               return;
 
        net_sendbuffer_send(item->process->out, data, strlen(data));
        net_sendbuffer_send(item->process->out, "\n", 1);
index 55a882664abbf586ada3cdb948aadf673556a2a4..4621ab2628ece9ede9a6a2e85e560434238eb403 100644 (file)
@@ -53,25 +53,31 @@ static void ignore_print(int index, IGNORE_REC *rec)
        levels = bits2level(rec->level);
 
        options = g_string_new(NULL);
-       if (rec->exception) g_string_sprintfa(options, "-except ");
+       if (rec->exception) g_string_append(options, "-except ");
        if (rec->regexp) {
-               g_string_sprintfa(options, "-regexp ");
+               g_string_append(options, "-regexp ");
 #ifdef HAVE_REGEX_H
                if (!rec->regexp_compiled)
-                       g_string_sprintfa(options, "[INVALID!] ");
+                       g_string_append(options, "[INVALID!] ");
 #endif
        }
-       if (rec->fullword) g_string_sprintfa(options, "-full ");
-       if (rec->replies) g_string_sprintfa(options, "-replies ");
+       if (rec->fullword) g_string_append(options, "-full ");
+       if (rec->replies) g_string_append(options, "-replies ");
        if (rec->pattern != NULL)
                g_string_sprintfa(options, "-pattern %s ", rec->pattern);
 
        if (options->len > 1) g_string_truncate(options, options->len-1);
 
-       printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP,
-                   TXT_IGNORE_LINE, index,
-                   key != NULL ? key : "",
-                   levels != NULL ? levels : "", options->str);
+       if (index >= 0) {
+               printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP,
+                           TXT_IGNORE_LINE, index, key != NULL ? key : "",
+                           levels != NULL ? levels : "", options->str);
+       } else {
+               printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP,
+                           options->len > 0 ? TXT_IGNORED_OPTIONS : TXT_IGNORED,
+                           key != NULL ? key : "",
+                           levels != NULL ? levels : "", options->str);
+       }
        g_string_free(options, TRUE);
         g_free(key);
        g_free(levels);
@@ -134,7 +140,7 @@ static void cmd_ignore(const char *data)
        channels = (chanarg == NULL || *chanarg == '\0') ? NULL :
                g_strsplit(replace_chars(chanarg, ',', ' '), " ", -1);
 
-       rec = ignore_find(NULL, mask, channels);
+       rec = patternarg != NULL ? NULL: ignore_find(NULL, mask, channels);
        new_ignore = rec == NULL;
 
        if (rec == NULL) {
@@ -221,14 +227,7 @@ static void cmd_unignore(const char *data)
 
 static void sig_ignore_created(IGNORE_REC *rec)
 {
-       char *key, *levels;
-
-       key = ignore_get_key(rec);
-       levels = bits2level(rec->level);
-       printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
-                   TXT_IGNORED, key, levels);
-       g_free(key);
-       g_free(levels);
+        ignore_print(-1, rec);
 }
 
 static void sig_ignore_destroyed(IGNORE_REC *rec)
index bebff7f587bec2d96be823139c4d414d2a4b3862..215d4a52f8b32cd4f44ecd975be236e2d318210f 100644 (file)
@@ -475,12 +475,13 @@ static void log_single_line(WINDOW_REC *window, const char *server_tag,
        char **targets, **tmp;
        LOG_REC *log;
 
-       /* save to log created with /WINDOW LOG */
-       ltoa(windownum, window->refnum);
-       log = logs_find_item(LOG_ITEM_WINDOW_REFNUM,
-                            windownum, NULL, NULL);
-       if (log != NULL) {
-               log_write_rec(log, text, level);
+       if (window != NULL) {
+               /* save to log created with /WINDOW LOG */
+               ltoa(windownum, window->refnum);
+               log = logs_find_item(LOG_ITEM_WINDOW_REFNUM,
+                                    windownum, NULL, NULL);
+               if (log != NULL)
+                       log_write_rec(log, text, level);
        }
 
        if (target == NULL)
@@ -591,11 +592,11 @@ static int sig_autoremove(void)
        return 1;
 }
 
-static void sig_window_item_destroy(WINDOW_REC *window, WI_ITEM_REC *item)
+static void sig_window_item_remove(WINDOW_REC *window, WI_ITEM_REC *item)
 {
        LOG_REC *log;
 
-       log = logs_find_item(LOG_ITEM_TARGET, item->name,
+       log = logs_find_item(LOG_ITEM_TARGET, item->visible_name,
                             item->server == NULL ? NULL :
                             item->server->tag, NULL);
        if (log != NULL && log->temp)
@@ -709,7 +710,7 @@ void fe_log_init(void)
        command_bind("window log", NULL, (SIGNAL_FUNC) cmd_window_log);
        command_bind("window logfile", NULL, (SIGNAL_FUNC) cmd_window_logfile);
        signal_add_first("print text", (SIGNAL_FUNC) sig_printtext);
-       signal_add("window item destroy", (SIGNAL_FUNC) sig_window_item_destroy);
+       signal_add("window item remove", (SIGNAL_FUNC) sig_window_item_remove);
        signal_add("window refnum changed", (SIGNAL_FUNC) sig_window_refnum_changed);
        signal_add("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
        signal_add("log locked", (SIGNAL_FUNC) sig_log_locked);
@@ -738,7 +739,7 @@ void fe_log_deinit(void)
        command_unbind("window log", (SIGNAL_FUNC) cmd_window_log);
        command_unbind("window logfile", (SIGNAL_FUNC) cmd_window_logfile);
        signal_remove("print text", (SIGNAL_FUNC) sig_printtext);
-       signal_remove("window item destroy", (SIGNAL_FUNC) sig_window_item_destroy);
+       signal_remove("window item remove", (SIGNAL_FUNC) sig_window_item_remove);
        signal_remove("window refnum changed", (SIGNAL_FUNC) sig_window_refnum_changed);
        signal_remove("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
        signal_remove("log locked", (SIGNAL_FUNC) sig_log_locked);
index 44c9fb35f635c4929c7ecd6c77788aed28d90028..e210c2a2d156101e53adc30dee660797419e33f5 100644 (file)
@@ -227,14 +227,19 @@ static void sig_message_private(SERVER_REC *server, const char *msg,
        g_free_not_null(freemsg);
 }
 
-static void print_own_channel_message(SERVER_REC *server, CHANNEL_REC *channel,
-                                     const char *target, const char *msg)
+static void sig_message_own_public(SERVER_REC *server, const char *msg,
+                                  const char *target)
 {
        WINDOW_REC *window;
+       CHANNEL_REC *channel;
        const char *nickmode;
         char *freemsg = NULL;
        int print_channel;
 
+       channel = channel_find(server, target);
+       if (channel != NULL)
+               target = channel->visible_name;
+
        nickmode = channel_get_nickmode(channel, server->nick);
 
        window = channel == NULL ? NULL :
@@ -261,18 +266,6 @@ static void print_own_channel_message(SERVER_REC *server, CHANNEL_REC *channel,
        g_free_not_null(freemsg);
 }
 
-static void sig_message_own_public(SERVER_REC *server, const char *msg,
-                                  const char *target)
-{
-       CHANNEL_REC *channel;
-
-       g_return_if_fail(server != NULL);
-       g_return_if_fail(msg != NULL);
-
-       channel = channel_find(server, target);
-       print_own_channel_message(server, channel, target, msg);
-}
-
 static void sig_message_own_private(SERVER_REC *server, const char *msg,
                                    const char *target, const char *origtarget)
 {
@@ -347,7 +340,7 @@ static void sig_message_quit(SERVER_REC *server, const char *nick,
                if (!nicklist_find(rec, nick))
                        continue;
 
-               if (ignore_check(server, nick, address, rec->name,
+               if (ignore_check(server, nick, address, rec->visible_name,
                                 reason, MSGLEVEL_QUITS)) {
                        count++;
                        continue;
@@ -355,17 +348,18 @@ static void sig_message_quit(SERVER_REC *server, const char *nick,
 
                if (print_channel == NULL ||
                    active_win->active == (WI_ITEM_REC *) rec)
-                       print_channel = rec->name;
+                       print_channel = rec->visible_name;
 
                if (once)
-                       g_string_sprintfa(chans, "%s,", rec->name);
+                       g_string_sprintfa(chans, "%s,", rec->visible_name);
                else {
                        window = window_item_window((WI_ITEM_REC *) rec);
                        if (g_slist_find(windows, window) == NULL) {
                                windows = g_slist_append(windows, window);
-                               printformat(server, rec->name, MSGLEVEL_QUITS,
+                               printformat(server, rec->visible_name,
+                                           MSGLEVEL_QUITS,
                                            TXT_QUIT, nick, address, reason,
-                                           rec->name);
+                                           rec->visible_name);
                        }
                }
                count++;
@@ -441,8 +435,8 @@ static void print_nick_change(SERVER_REC *server, const char *newnick,
                        continue;
 
                windows = g_slist_append(windows, window);
-               print_nick_change_channel(server, channel->name, newnick,
-                                         oldnick, address, ownnick);
+               print_nick_change_channel(server, channel->visible_name,
+                                         newnick, oldnick, address, ownnick);
                msgprint = TRUE;
        }
 
index 93f1304014c805088abbb128aa9780a172f45b03..8345d52f06b79adcd8f4bd7edd158e2249e83b5a 100644 (file)
@@ -30,6 +30,7 @@
 #include "servers.h"
 #include "queries.h"
 
+#include "fe-core-commands.h"
 #include "fe-windows.h"
 #include "window-items.h"
 #include "printtext.h"
@@ -46,7 +47,8 @@ QUERY_REC *privmsg_get_query(SERVER_REC *server, const char *nick,
         g_return_val_if_fail(nick != NULL, NULL);
 
        query = query_find(server, nick);
-       if (query == NULL && (querycreate_level & level) != 0 &&
+       if (query == NULL && !command_hide_output &&
+           (querycreate_level & level) != 0 &&
            (!own || settings_get_bool("autocreate_own_query"))) {
                query = CHAT_PROTOCOL(server)->
                        query_create(server->tag, nick, TRUE);
@@ -192,23 +194,29 @@ static void cmd_window_server(const char *data)
 static void cmd_unquery(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
 {
        QUERY_REC *query;
+       char *nick;
+       void *free_arg;
 
        g_return_if_fail(data != NULL);
 
-       if (*data == '\0') {
+       if (!cmd_get_params(data, &free_arg, 1, &nick))
+               return;
+
+       if (*nick == '\0') {
                /* remove current query */
                query = QUERY(item);
-               if (query == NULL) return;
        } else {
-               query = query_find(server, data);
+               query = query_find(server, nick);
                if (query == NULL) {
                        printformat(server, NULL, MSGLEVEL_CLIENTERROR,
-                                   TXT_NO_QUERY, data);
-                       return;
+                                   TXT_NO_QUERY, nick);
                }
        }
 
-       query_destroy(query);
+       if (query != NULL)
+               query_destroy(query);
+
+       cmd_params_free(free_arg);
 }
 
 /* SYNTAX: QUERY [-window] [-<server tag>] <nick> [<message>] */
index d8f9d13725960836612abdc6a46ca48c2befaaa6..06f46777c58a78b6d7ef257dc26927d65b07b1bc 100644 (file)
@@ -144,6 +144,9 @@ static void cmd_server_add(const char *data)
         else if (g_hash_table_lookup(optlist, "4"))
                rec->family = AF_INET;
 
+       if (g_hash_table_lookup(optlist, "ssl"))
+               rec->use_ssl = TRUE;
+
        if (g_hash_table_lookup(optlist, "auto")) rec->autoconnect = TRUE;
        if (g_hash_table_lookup(optlist, "noauto")) rec->autoconnect = FALSE;
        if (g_hash_table_lookup(optlist, "proxy")) rec->no_proxy = FALSE;
@@ -238,9 +241,12 @@ static void sig_server_connecting(SERVER_REC *server, IPADDR *ip)
        char ipaddr[MAX_IP_LEN];
 
        g_return_if_fail(server != NULL);
-       g_return_if_fail(ip != NULL);
 
-       net_ip2host(ip, ipaddr);
+       if (ip == NULL)
+               ipaddr[0] = '\0';
+       else
+               net_ip2host(ip, ipaddr);
+
        printformat(server, NULL, MSGLEVEL_CLIENTNOTICE, TXT_CONNECTING,
                    server->connrec->address, ipaddr, server->connrec->port);
 }
@@ -324,7 +330,7 @@ void fe_server_init(void)
        command_bind("server connect", NULL, (SIGNAL_FUNC) cmd_server_connect);
        command_bind("server add", NULL, (SIGNAL_FUNC) cmd_server_add);
        command_bind("server remove", NULL, (SIGNAL_FUNC) cmd_server_remove);
-       command_set_options("server add", "4 6 auto noauto proxy noproxy -host -port");
+       command_set_options("server add", "4 6 ssl auto noauto proxy noproxy -host -port");
 
        signal_add("server looking", (SIGNAL_FUNC) sig_server_looking);
        signal_add("server connecting", (SIGNAL_FUNC) sig_server_connecting);
index 70bc5cc3238a8e59e3534aaafb3ec98ff0788771..7fb512e8446172150bad00929e60478e0b626497 100644 (file)
@@ -66,7 +66,7 @@ static void set_boolean(const char *key, const char *value)
                printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_NOT_TOGGLE);
 }
 
-/* SYNTAX: SET [-clear] [<key> [<value>]] */
+/* SYNTAX: SET [-clear | -default] [<key> [<value>]] */
 static void cmd_set(char *data)
 {
         GHashTable *optlist;
@@ -74,13 +74,14 @@ static void cmd_set(char *data)
        const char *last_section;
        char *key, *value;
        void *free_arg;
-       int found, clear;
+       int found, clear, set_default;
 
        if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST | PARAM_FLAG_OPTIONS,
                            "set", &optlist, &key, &value))
                return;
 
        clear = g_hash_table_lookup(optlist, "clear") != NULL;
+       set_default = g_hash_table_lookup(optlist, "default") != NULL;
 
        last_section = ""; found = 0;
        sets = settings_get_sorted();
@@ -98,20 +99,26 @@ static void cmd_set(char *data)
                        last_section = rec->section;
                }
 
-               if (clear || *value != '\0') {
+               if (clear || set_default || *value != '\0') {
                        /* change the setting */
                        switch (rec->type) {
                        case SETTING_TYPE_BOOLEAN:
                                 if (clear)
                                        settings_set_bool(key, FALSE);
-                                else
+                               else if (set_default)
+                                       settings_set_bool(key, GPOINTER_TO_INT(rec->def));
+                               else
                                        set_boolean(key, value);
                                break;
                        case SETTING_TYPE_INT:
-                               settings_set_int(key, clear ? 0 : atoi(value));
+                               settings_set_int(key, clear ? 0 :
+                                                set_default ? GPOINTER_TO_INT(rec->def) :
+                                                atoi(value));
                                break;
                        case SETTING_TYPE_STRING:
-                               settings_set_str(key, clear ? "" : value);
+                               settings_set_str(key, clear ? "" :
+                                                set_default ? rec->def :
+                                                value);
                                break;
                        }
                        signal_emit("setup changed", 0);
@@ -240,10 +247,17 @@ static void cmd_alias(const char *data)
 /* SYNTAX: UNALIAS <alias> */
 static void cmd_unalias(const char *data)
 {
+       char *alias;
+       void *free_arg;
+
        g_return_if_fail(data != NULL);
-       if (*data == '\0') cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS);
 
-       alias_remove(data);
+       if (!cmd_get_params(data, &free_arg, 1, &alias))
+               return;
+       if (*alias == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
+
+       alias_remove(alias);
+        cmd_params_free(free_arg);
 }
 
 /* SYNTAX: RELOAD [<file>] */
@@ -327,7 +341,7 @@ void fe_settings_init(void)
        command_bind("unalias", NULL, (SIGNAL_FUNC) cmd_unalias);
        command_bind("reload", NULL, (SIGNAL_FUNC) cmd_reload);
        command_bind("save", NULL, (SIGNAL_FUNC) cmd_save);
-       command_set_options("set", "clear");
+       command_set_options("set", "clear default");
 
         signal_add("settings errors", (SIGNAL_FUNC) sig_settings_errors);
 }
index af8e4297e9fe3fe5b1f2b9061b4df521cbf461b2..24a32a51e7ab0fa4f94d661d832da2e6d49e3d9a 100644 (file)
@@ -161,11 +161,30 @@ void window_set_active(WINDOW_REC *window)
 
 void window_change_server(WINDOW_REC *window, void *server)
 {
+       SERVER_REC *active, *connect;
+
        if (server != NULL && SERVER(server)->disconnected)
                return;
 
-       window->active_server = server;
-       signal_emit("window server changed", 2, window, server);
+       if (server == NULL) {
+               active = connect = NULL;
+       } else if (g_slist_find(servers, server) != NULL) {
+               active = server;
+               connect = NULL;
+       } else {
+               active = NULL;
+               connect = server;
+       }
+
+       if (window->connect_server != connect) {
+               window->connect_server = connect;
+               signal_emit("window connect changed", 2, window, connect);
+       }
+
+       if (window->active_server != active) {
+               window->active_server = active;
+               signal_emit("window server changed", 2, window, active);
+       } 
 }
 
 void window_set_refnum(WINDOW_REC *window, int refnum)
@@ -232,12 +251,12 @@ void window_set_immortal(WINDOW_REC *window, int immortal)
 }
 
 /* return active item's name, or if none is active, window's name */
-char *window_get_active_name(WINDOW_REC *window)
+const char *window_get_active_name(WINDOW_REC *window)
 {
        g_return_val_if_fail(window != NULL, NULL);
 
        if (window->active != NULL)
-               return window->active->name;
+               return window->active->visible_name;
 
        return window->name;
 }
@@ -489,7 +508,7 @@ void window_bind_remove_unsticky(WINDOW_REC *window)
        }
 }
 
-static void sig_server_looking(SERVER_REC *server)
+static void sig_server_connected(SERVER_REC *server)
 {
        GSList *tmp;
 
@@ -519,7 +538,8 @@ static void sig_server_disconnected(SERVER_REC *server)
        for (tmp = windows; tmp != NULL; tmp = tmp->next) {
                WINDOW_REC *rec = tmp->data;
 
-               if (rec->active_server == server) {
+               if (rec->active_server == server ||
+                   rec->connect_server == server) {
                        window_change_server(rec, rec->servertag != NULL ?
                                             NULL : new_server);
                }
@@ -609,7 +629,8 @@ void windows_init(void)
        settings_add_str("lookandfeel", "window_default_level", "NONE");
 
        read_settings();
-       signal_add("server looking", (SIGNAL_FUNC) sig_server_looking);
+       signal_add("server looking", (SIGNAL_FUNC) sig_server_connected);
+       signal_add("server connected", (SIGNAL_FUNC) sig_server_connected);
        signal_add("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
        signal_add("server connect failed", (SIGNAL_FUNC) sig_server_disconnected);
        signal_add("setup changed", (SIGNAL_FUNC) read_settings);
@@ -620,7 +641,8 @@ void windows_deinit(void)
        if (daytag != -1) g_source_remove(daytag);
        if (daycheck == 1) signal_remove("print text", (SIGNAL_FUNC) sig_print_text);
 
-       signal_remove("server looking", (SIGNAL_FUNC) sig_server_looking);
+       signal_remove("server looking", (SIGNAL_FUNC) sig_server_connected);
+       signal_remove("server connected", (SIGNAL_FUNC) sig_server_connected);
        signal_remove("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
        signal_remove("server connect failed", (SIGNAL_FUNC) sig_server_disconnected);
        signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
index 9173459fd6ab2c0e0749bf409f1731898e74974d..58c316ef115963b6113af3667f1a05e6efbef6a0 100644 (file)
@@ -26,6 +26,7 @@ struct _WINDOW_REC {
        GSList *items;
        WI_ITEM_REC *active;
        SERVER_REC *active_server;
+       SERVER_REC *connect_server;
         char *servertag; /* active_server must be either NULL or have this tag (unless there's items in this window) */
 
        int level; /* message level */
@@ -69,7 +70,7 @@ void window_set_level(WINDOW_REC *window, int level);
 void window_set_immortal(WINDOW_REC *window, int immortal);
 
 /* return active item's name, or if none is active, window's name */
-char *window_get_active_name(WINDOW_REC *window);
+const char *window_get_active_name(WINDOW_REC *window);
 
 WINDOW_REC *window_find_level(void *server, int level);
 WINDOW_REC *window_find_closest(void *server, const char *name, int level);
index 4d5466e288065fd048a74b27e2065269975fdb30..9749504b4afa107f49800622a98216375346f552 100644 (file)
@@ -112,12 +112,38 @@ static void hilights_destroy_all(void)
        hilights = NULL;
 }
 
-static void hilight_remove(HILIGHT_REC *rec)
+static void hilight_init_rec(HILIGHT_REC *rec)
+{
+#ifdef HAVE_REGEX_H
+       if (rec->regexp_compiled) regfree(&rec->preg);
+       rec->regexp_compiled = !rec->regexp ? FALSE :
+               regcomp(&rec->preg, rec->text, REG_EXTENDED|REG_ICASE) == 0;
+#endif
+}
+
+void hilight_create(HILIGHT_REC *rec)
+{
+       if (g_slist_find(hilights, rec) != NULL) {
+               hilights = g_slist_remove(hilights, rec);
+               hilight_remove_config(rec);
+       }
+
+       hilights = g_slist_append(hilights, rec);
+       hilight_add_config(rec);
+
+       hilight_init_rec(rec);
+
+       signal_emit("hilight created", 1, rec);
+}
+
+void hilight_remove(HILIGHT_REC *rec)
 {
        g_return_if_fail(rec != NULL);
 
        hilight_remove_config(rec);
        hilights = g_slist_remove(hilights, rec);
+
+       signal_emit("hilight destroyed", 1, rec);
        hilight_destroy(rec);
 }
 
@@ -435,11 +461,7 @@ static void read_hilight_config(void)
                rec->fullword = config_node_get_bool(node, "fullword", FALSE);
                rec->regexp = config_node_get_bool(node, "regexp", FALSE);
 
-#ifdef HAVE_REGEX_H
-               rec->regexp_compiled = !rec->regexp ? FALSE :
-                       regcomp(&rec->preg, rec->text,
-                               REG_EXTENDED|REG_ICASE) == 0;
-#endif
+               hilight_init_rec(rec);
 
                node = config_node_section(node, "channels", -1);
                if (node != NULL) rec->channels = config_node_get_list(node);
@@ -451,6 +473,32 @@ static void read_hilight_config(void)
 static void hilight_print(int index, HILIGHT_REC *rec)
 {
        char *chans, *levelstr;
+       GString *options;
+
+       options = g_string_new(NULL);
+       if (!rec->nick || !rec->word) {
+               if (rec->nick) g_string_append(options, "-nick ");
+               if (rec->word) g_string_append(options, "-word ");
+       }
+
+       if (rec->nickmask) g_string_append(options, "-nickmask ");
+       if (rec->fullword) g_string_append(options, "-fullword ");
+       if (rec->regexp) {
+               g_string_append(options, "-regexp ");
+#ifdef HAVE_REGEX_H
+               if (!rec->regexp_compiled)
+                       g_string_append(options, "[INVALID!] ");
+#endif
+       }
+
+       if (options->len > 1) g_string_truncate(options, options->len-1);
+
+       if (rec->priority != 0)
+               g_string_sprintfa(options, "-priority %d ", rec->priority);
+       if (rec->color != NULL)
+               g_string_sprintfa(options, "-color %s ", rec->color);
+       if (rec->act_color != NULL)
+               g_string_sprintfa(options, "-actcolor %s ", rec->act_color);
 
        chans = rec->channels == NULL ? NULL :
                g_strjoinv(",", rec->channels);
@@ -460,11 +508,10 @@ static void hilight_print(int index, HILIGHT_REC *rec)
                    TXT_HILIGHT_LINE, index, rec->text,
                    chans != NULL ? chans : "",
                    levelstr != NULL ? levelstr : "",
-                   rec->nickmask ? " -mask" : "",
-                   rec->fullword ? " -full" : "",
-                   rec->regexp ? " -regexp" : "");
+                   options->str);
        g_free_not_null(chans);
        g_free_not_null(levelstr);
+       g_string_free(options, TRUE);
 }
 
 static void cmd_hilight_show(void)
@@ -527,9 +574,6 @@ static void cmd_hilight(const char *data)
                rec->channels = channels;
        } else {
                g_strfreev(channels);
-
-                hilight_remove_config(rec);
-               hilights = g_slist_remove(hilights, rec);
        }
 
        rec->level = (levelarg == NULL || *levelarg == '\0') ? 0 :
@@ -564,15 +608,7 @@ static void cmd_hilight(const char *data)
                        rec->act_color = g_strdup(actcolorarg);
        }
 
-#ifdef HAVE_REGEX_H
-       if (rec->regexp_compiled)
-               regfree(&rec->preg);
-       rec->regexp_compiled = !rec->regexp ? FALSE :
-               regcomp(&rec->preg, rec->text, REG_EXTENDED|REG_ICASE) == 0;
-#endif
-
-       hilights = g_slist_append(hilights, rec);
-       hilight_add_config(rec);
+       hilight_create(rec);
 
        hilight_print(g_slist_index(hilights, rec)+1, rec);
         cmd_params_free(free_arg);
index 92093bb126a8cc2df53ffb008e2715d104d8aecd..6e5107374ebc98ab268a504177e2ad0859927218 100644 (file)
@@ -5,7 +5,9 @@
 #  include <regex.h>
 #endif
 
-typedef struct {
+typedef struct _HILIGHT_REC HILIGHT_REC;
+
+struct _HILIGHT_REC {
        char *text;
 
        char **channels; /* if non-NULL, check the text only from these channels */
@@ -25,7 +27,7 @@ typedef struct {
        unsigned int regexp_compiled:1; /* should always be TRUE, unless regexp is invalid */
        regex_t preg;
 #endif
-} HILIGHT_REC;
+};
 
 extern GSList *hilights;
 
@@ -38,6 +40,9 @@ char *hilight_match_nick(SERVER_REC *server, const char *channel,
                         const char *nick, const char *address,
                         int level, const char *msg);
 
+void hilight_create(HILIGHT_REC *rec);
+void hilight_remove(HILIGHT_REC *rec);
+
 void hilight_text_init(void);
 void hilight_text_deinit(void);
 
index fb1d89fec0f47ac6ee44f4749e3978987978f552..9bbb218aa47cb0b589a9b9522d3ed7c92e668147 100644 (file)
@@ -388,6 +388,8 @@ static void key_configure_destroy(KEY_REC *rec)
        rec->info->keys = g_slist_remove(rec->info->keys, rec);
        g_hash_table_remove(keys, rec->key);
 
+       signal_emit("key destroyed", 1, rec);
+
        if (!key_config_frozen)
                 key_states_rescan();
 
@@ -421,6 +423,8 @@ static void key_configure_create(const char *id, const char *key,
        info->keys = g_slist_append(info->keys, rec);
        g_hash_table_insert(keys, rec->key, rec);
 
+       signal_emit("key created", 1, rec);
+
        if (!key_config_frozen)
                 key_states_rescan();
 }
index c508d53b810b3ac3d4b64e4535b50b1be9b9077b..eff8966a37d6c2f770b77ac8beec8bad8fa2ac93 100644 (file)
@@ -4,20 +4,22 @@
 #include "signals.h"
 
 typedef struct _KEYBOARD_REC KEYBOARD_REC;
+typedef struct _KEYINFO_REC KEYINFO_REC;
+typedef struct _KEY_REC KEY_REC;
 
-typedef struct {
+struct _KEYINFO_REC {
        char *id;
        char *description;
 
        GSList *keys, *default_keys;
-} KEYINFO_REC;
+};
 
-typedef struct {
+struct _KEY_REC {
        KEYINFO_REC *info;
 
        char *key;
        char *data;
-} KEY_REC;
+};
 
 extern GSList *keyinfos;
 
index 223eb3accfa50b070578696ebf06d815f93631ed..2d4f02e1a33f0026165a497505f0d51df943c6bf 100644 (file)
@@ -153,7 +153,7 @@ FORMAT_REC fecommon_core_formats[] = {
        { NULL, "Highlighting", 0 },
 
        { "hilight_header", "%#Highlights:", 0 },
-       { "hilight_line", "%#$[-4]0 $1 $2 $3$4$5", 7, { 1, 0, 0, 0, 0, 0, 0 } },
+       { "hilight_line", "%#$[-4]0 $1 $2 $3$4", 5, { 1, 0, 0, 0, 0 } },
        { "hilight_footer", "", 0 },
        { "hilight_not_found", "Highlight not found: $0", 1, { 0 } },
        { "hilight_removed", "Highlight removed: $0", 1, { 0 } },
@@ -234,6 +234,7 @@ FORMAT_REC fecommon_core_formats[] = {
        { NULL, "Ignores", 0 },
 
        { "ignored", "Ignoring {hilight $1} from {nick $0}", 2, { 0, 0 } },
+       { "ignored_options", "Ignoring {hilight $1} from {nick $0} {comment $2}", 3, { 0, 0, 0 } },
        { "unignored", "Unignored {nick $0}", 1, { 0 } },
        { "ignore_not_found", "{nick $0} is not being ignored", 1, { 0 } },
        { "ignore_no_ignores", "There are no ignores", 0 },
@@ -263,6 +264,11 @@ FORMAT_REC fecommon_core_formats[] = {
        { "set_not_boolean", "Setting {hilight $0} isn't boolean, use /SET", 1, { 0 } },
        { "translation_not_found", "Error opening translation table file $0: $1", 2, { 0, 0 } },
        { "translation_file_error", "Error parsing translation table file $0", 1, { 0 } },
+       { "no_completions", "There's no completions", 0 },
+       { "completion_removed", "Removed completion $0", 1, { 0 } },
+       { "completion_header", "%#Key        Value                                    Auto", 0 },
+       { "completion_line", "%#$[10]0 $[!40]1 $2", 3, { 0, 0, 0 } },
+       { "completion_footer", "", 0 },
 
        { NULL, NULL, 0 }
 };
index e4d744613754fde7cf7cfcac2a98f102006a7f52..7cd46bab956fc53b772a32fd1808dfaf4af2a6cf 100644 (file)
@@ -201,6 +201,7 @@ enum {
        TXT_FILL_12,
 
        TXT_IGNORED,
+       TXT_IGNORED_OPTIONS,
        TXT_UNIGNORED,
        TXT_IGNORE_NOT_FOUND,
        TXT_IGNORE_NO_IGNORES,
@@ -228,7 +229,12 @@ enum {
         TXT_SET_UNKNOWN,
        TXT_SET_NOT_BOOLEAN,
        TXT_TRANSLATION_NOT_FOUND,
-        TXT_TRANSLATION_FILE_ERROR
+       TXT_TRANSLATION_FILE_ERROR,
+       TXT_NO_COMPLETIONS,
+        TXT_COMPLETION_REMOVED,
+       TXT_COMPLETION_HEADER,
+        TXT_COMPLETION_LINE,
+       TXT_COMPLETION_FOOTER
 };
 
 extern FORMAT_REC fecommon_core_formats[];
index dbd52343a500e1b369bd1c4622d682fb64515059..e32b5943258336f16af8acda5cbf8cbcf615b6f7 100644 (file)
@@ -70,7 +70,7 @@ void printformat_module_dest_args(const char *module, TEXT_DEST_REC *dest,
 
        str = format_get_text_theme_charargs(theme, module, dest,
                                             formatnum, arglist);
-       if (*str != '\0') print_line(dest, str);
+       if (str != NULL && *str != '\0') print_line(dest, str);
        g_free(str);
 }
 
index ec4a994af44a1f450b6df1822c22d0625098b2d1..baa1d3e599d112d554dee9dfbf571801d6b8efb2 100644 (file)
@@ -50,6 +50,7 @@ THEME_REC *theme_create(const char *path, const char *name)
        g_return_val_if_fail(name != NULL, NULL);
 
        rec = g_new0(THEME_REC, 1);
+       rec->refcount = 1;
        rec->path = g_strdup(path);
        rec->name = g_strdup(name);
        rec->abstracts = g_hash_table_new((GHashFunc) g_str_hash,
@@ -83,12 +84,8 @@ static void theme_module_destroy(const char *key, MODULE_THEME_REC *rec)
        g_free(rec);
 }
 
-void theme_destroy(THEME_REC *rec)
+static void theme_real_destroy(THEME_REC *rec)
 {
-       themes = g_slist_remove(themes, rec);
-
-       signal_emit("theme destroyed", 1, rec);
-
        g_hash_table_foreach(rec->abstracts, (GHFunc) theme_abstract_destroy, NULL);
        g_hash_table_destroy(rec->abstracts);
        g_hash_table_foreach(rec->modules, (GHFunc) theme_module_destroy, NULL);
@@ -102,6 +99,20 @@ void theme_destroy(THEME_REC *rec)
        g_free(rec);
 }
 
+static void theme_unref(THEME_REC *rec)
+{
+       if (--rec->refcount == 0)
+               theme_real_destroy(rec);
+}
+
+void theme_destroy(THEME_REC *rec)
+{
+       themes = g_slist_remove(themes, rec);
+       signal_emit("theme destroyed", 1, rec);
+
+       theme_unref(rec);
+}
+
 static char *theme_replace_expand(THEME_REC *theme, int index,
                                  char default_fg, char default_bg,
                                  char *last_fg, char *last_bg,
@@ -242,10 +253,11 @@ static int data_is_empty(const char **data)
 {
        /* since we don't know the real argument list, assume there's always
           an argument in them */
-       char *arglist[] = {
+       static char *arglist[] = {
                "x", "x", "x", "x", "x", "x","x", "x", "x", "x",
                NULL
        };
+       SERVER_REC *server;
        const char *p;
        char *ret;
         int free_ret, empty;
@@ -266,8 +278,12 @@ static int data_is_empty(const char **data)
 
        /* variable - check if it's empty */
         p++;
-       ret = parse_special((char **) &p,
-                           active_win == NULL ? NULL : active_win->active_server,
+
+       server = active_win == NULL ? NULL :
+               active_win->active_server != NULL ?
+               active_win->active_server : active_win->connect_server;
+
+       ret = parse_special((char **) &p, server,
                            active_win == NULL ? NULL : active_win->active,
                            arglist, &free_ret, NULL, 0);
         p++;
@@ -1207,10 +1223,20 @@ static void read_settings(void)
 
 static void themes_read(void)
 {
+       GSList *refs;
        char *fname;
 
-       while (themes != NULL)
-               theme_destroy(themes->data);
+       /* increase every theme's refcount, and destroy them. this way if
+          we want to use the theme before it's reloaded we don't crash. */
+       refs = NULL;
+       while (themes != NULL) {
+               THEME_REC *theme = themes->data;
+
+               refs = g_slist_prepend(refs, theme);
+
+               theme->refcount++;
+               theme_destroy(theme);
+       }
 
        /* first there's default theme.. */
        current_theme = theme_load("default");
@@ -1223,7 +1249,12 @@ static void themes_read(void)
        }
 
         window_themes_update();
-        change_theme(settings_get_str("theme"), FALSE);
+       change_theme(settings_get_str("theme"), FALSE);
+
+       while (refs != NULL) {
+               theme_unref(refs->data);
+               refs = g_slist_remove(refs, refs->data);
+       }
 }
 
 void themes_init(void)
index 3ef7cb924348a8a32be64477845a1d172dfb4afe..0a809b950acc3c27bfa07c9865b00ad7d48c3690 100644 (file)
@@ -11,6 +11,8 @@ typedef struct {
 } MODULE_THEME_REC;
 
 typedef struct {
+       int refcount;
+
        char *path;
        char *name;
         time_t last_modify;
index bbe495aa611a5b992a36f8d0f155d2deeee7db70..a8f3bb1066bd2835023e03842e73572d858c2f85 100644 (file)
@@ -64,7 +64,8 @@ static void window_print_items(WINDOW_REC *win)
                type = module_find_id_str("WINDOW ITEM TYPE", item->type);
                printformat_window(win, MSGLEVEL_CLIENTCRAP,
                                   TXT_WINDOW_INFO_ITEM,
-                                  type == NULL ? "??" : type, item->name,
+                                  type == NULL ? "??" : type,
+                                  item->visible_name,
                                   item->server == NULL ? "" :
                                   item->server->tag);
        }
@@ -279,6 +280,8 @@ static WINDOW_REC *window_highest_activity(WINDOW_REC *window)
 static void cmd_window_goto(const char *data)
 {
        WINDOW_REC *window;
+       char *target;
+       void *free_arg;
 
        g_return_if_fail(data != NULL);
 
@@ -287,13 +290,18 @@ static void cmd_window_goto(const char *data)
                return;
        }
 
-       if (g_strcasecmp(data, "active") == 0)
+       if (!cmd_get_params(data, &free_arg, 1, &target))
+               return;
+
+       if (g_strcasecmp(target, "active") == 0)
                 window = window_highest_activity(active_win);
        else
-                window = window_find_item(active_win->active_server, data);
+                window = window_find_item(active_win->active_server, target);
 
        if (window != NULL)
                window_set_active(window);
+
+       cmd_params_free(free_arg);
 }
 
 /* SYNTAX: WINDOW NEXT */
@@ -392,6 +400,8 @@ static void cmd_window_server(const char *data)
        if (*tag == '\0')
                cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
        server = server_find_tag(tag);
+       if (server == NULL)
+               server = server_find_lookup_tag(tag);
 
        if (g_hash_table_lookup(optlist, "unsticky") != NULL &&
            active_win->servertag != NULL) {
@@ -616,17 +626,10 @@ static void cmd_window_move_next(void)
         window_refnums_move_right(active_win);
 }
 
-/* SYNTAX: WINDOW MOVE <number>|<direction> */
-static void cmd_window_move(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
+static void active_window_move_to(int new_refnum)
 {
-       int new_refnum, refnum;
-
-       if (!is_numeric(data, 0)) {
-               command_runsub("window move", data, server, item);
-                return;
-       }
+       int refnum;
 
-       new_refnum = atoi(data);
        if (new_refnum > active_win->refnum) {
                for (;;) {
                        refnum = window_refnum_next(active_win->refnum, FALSE);
@@ -646,6 +649,29 @@ static void cmd_window_move(const char *data, SERVER_REC *server, WI_ITEM_REC *i
        }
 }
 
+/* SYNTAX: WINDOW MOVE FIRST */
+static void cmd_window_move_first(void)
+{
+       active_window_move_to(1);
+}
+
+/* SYNTAX: WINDOW MOVE LAST */
+static void cmd_window_move_last(void)
+{
+       active_window_move_to(windows_refnum_last());
+}
+
+/* SYNTAX: WINDOW MOVE <number>|<direction> */
+static void cmd_window_move(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
+{
+       if (!is_numeric(data, 0)) {
+               command_runsub("window move", data, server, item);
+                return;
+       }
+
+       active_window_move_to(atoi(data));
+}
+
 /* SYNTAX: WINDOW LIST */
 static void cmd_window_list(void)
 {
@@ -660,7 +686,7 @@ static void cmd_window_list(void)
                levelstr = bits2level(rec->level);
                printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_WINDOWLIST_LINE,
                            rec->refnum, rec->name == NULL ? "" : rec->name,
-                           rec->active == NULL ? "" : rec->active->name,
+                           rec->active == NULL ? "" : rec->active->visible_name,
                            rec->active_server == NULL ? "" : ((SERVER_REC *) rec->active_server)->tag,
                            levelstr);
                g_free(levelstr);
@@ -737,7 +763,8 @@ static void cmd_foreach_window(const char *data)
                 list = g_slist_remove(list, list->data);
        }
 
-        active_win = old;
+       if (g_slist_find(windows, old) != NULL)
+               active_win = old;
 }
 
 void window_commands_init(void)
@@ -765,6 +792,8 @@ void window_commands_init(void)
        command_bind("window move", NULL, (SIGNAL_FUNC) cmd_window_move);
        command_bind("window move prev", NULL, (SIGNAL_FUNC) cmd_window_move_prev);
        command_bind("window move next", NULL, (SIGNAL_FUNC) cmd_window_move_next);
+       command_bind("window move first", NULL, (SIGNAL_FUNC) cmd_window_move_first);
+       command_bind("window move last", NULL, (SIGNAL_FUNC) cmd_window_move_last);
        command_bind("window list", NULL, (SIGNAL_FUNC) cmd_window_list);
        command_bind("window theme", NULL, (SIGNAL_FUNC) cmd_window_theme);
        command_bind("layout", NULL, (SIGNAL_FUNC) cmd_layout);
@@ -804,6 +833,8 @@ void window_commands_deinit(void)
        command_unbind("window move", (SIGNAL_FUNC) cmd_window_move);
        command_unbind("window move prev", (SIGNAL_FUNC) cmd_window_move_prev);
        command_unbind("window move next", (SIGNAL_FUNC) cmd_window_move_next);
+       command_unbind("window move first", (SIGNAL_FUNC) cmd_window_move_first);
+       command_unbind("window move last", (SIGNAL_FUNC) cmd_window_move_last);
        command_unbind("window list", (SIGNAL_FUNC) cmd_window_list);
        command_unbind("window theme", (SIGNAL_FUNC) cmd_window_theme);
        command_unbind("layout", (SIGNAL_FUNC) cmd_layout);
index e53e5a1d1ee273ddc06fb61390c979df21584edc..ce4b57e0f781c1415c25039bc2c3f5745d26817b 100644 (file)
@@ -23,6 +23,7 @@
 #include "modules.h"
 #include "signals.h"
 #include "servers.h"
+#include "channels.h"
 #include "settings.h"
 
 #include "levels.h"
@@ -195,15 +196,23 @@ void window_item_next(WINDOW_REC *window)
 WI_ITEM_REC *window_item_find_window(WINDOW_REC *window,
                                      void *server, const char *name)
 {
+       CHANNEL_REC *channel;
        GSList *tmp;
 
        for (tmp = window->items; tmp != NULL; tmp = tmp->next) {
                WI_ITEM_REC *rec = tmp->data;
 
                if ((server == NULL || rec->server == server) &&
-                   g_strcasecmp(name, rec->name) == 0) return rec;
+                   g_strcasecmp(name, rec->visible_name) == 0)
+                       return rec;
        }
 
+       /* try with channel name too, it's not necessarily
+          same as visible_name (!channels) */
+       channel = channel_find(server, name);
+       if (channel != NULL && window_item_window(channel) == window)
+               return (WI_ITEM_REC *) channel;
+
        return NULL;
 }
 
@@ -259,7 +268,7 @@ void window_item_create(WI_ITEM_REC *item, int automatic)
                 /* is item bound to this window? */
                if (item->server != NULL) {
                        bind = window_bind_find(rec, item->server->tag,
-                                               item->name);
+                                               item->visible_name);
                        if (bind != NULL) {
                                 if (!bind->sticky)
                                        window_bind_destroy(rec, bind);
@@ -316,8 +325,9 @@ static void signal_window_item_changed(WINDOW_REC *window, WI_ITEM_REC *item)
        if (g_slist_length(window->items) > 1) {
                /* default to printing "talking with ...",
                   you can override it it you wish */
-               printformat(item->server, item->name, MSGLEVEL_CLIENTNOTICE,
-                           TXT_TALKING_WITH, item->name);
+               printformat(item->server, item->visible_name,
+                           MSGLEVEL_CLIENTNOTICE,
+                           TXT_TALKING_WITH, item->visible_name);
        }
 }
 
index a19b2942485661324203a783f456ce52d8827e1d..9429c00ae6236d78e3a116f621e0b915bdcb8c35 100644 (file)
@@ -136,6 +136,7 @@ static void sig_layout_save_item(WINDOW_REC *window, WI_ITEM_REC *item,
                                 CONFIG_NODE *node)
 {
        CONFIG_NODE *subnode;
+        CHAT_PROTOCOL_REC *proto;
        const char *type;
 
        type = module_find_id_str("WINDOW ITEM TYPE", item->type);
@@ -145,9 +146,11 @@ static void sig_layout_save_item(WINDOW_REC *window, WI_ITEM_REC *item,
        subnode = config_node_section(node, NULL, NODE_TYPE_BLOCK);
 
        iconfig_node_set_str(subnode, "type", type);
-       type = chat_protocol_find_id(item->chat_type)->name;
-       iconfig_node_set_str(subnode, "chat_type", type);
-       iconfig_node_set_str(subnode, "name", item->name);
+       proto = item->chat_type == 0 ? NULL :
+               chat_protocol_find_id(item->chat_type);
+       if (proto != NULL)
+               iconfig_node_set_str(subnode, "chat_type", proto->name);
+       iconfig_node_set_str(subnode, "name", item->visible_name);
 
        if (item->server != NULL)
                iconfig_node_set_str(subnode, "tag", item->server->tag);
index b6a005a228ff1eeaff8d5c3a6558bcf87217b5bb..d1d51c46de88483dc528fb4b05e92c4f13fffbe8 100644 (file)
@@ -23,6 +23,7 @@ silc_LDADD = \
        @PERL_FE_LINK_LIBS@ \
        @PERL_LINK_FLAGS@ \
        @PROG_LIBS@     \
+       @TEXTUI_LIBS@   \
        -L../../../lib -lsilcclient
 silc_LDFLAGS = -export-dynamic
 
index e7e5fcc5f12ba92e003902aa57b4bd92244b0f29..f6bfb27dc8c7dae032fa4c785012e6efa3a938f6 100644 (file)
@@ -104,7 +104,11 @@ static void gui_entry_draw_from(GUI_ENTRY_REC *entry, int pos)
 
        p = entry->scrstart + pos < entry->text_len ?
                entry->text + entry->scrstart + pos : empty_str;
-       for (; *p != '\0' && xpos < end_xpos; p++, xpos++) {
+       for (; *p != '\0'; p++) {
+               xpos += utf8_width(*p);
+               if (xpos > end_xpos)
+                       break;
+
                if (entry->hidden)
                         term_addch(root_window, ' ');
                else if (*p >= 32 && (entry->utf8 || (*p & 127) >= 32))
index c23b42c79d245ca753bfac0e62731d591112d875..1cabfac72b634e77e804139e1619e97cc7b97600 100644 (file)
@@ -162,6 +162,12 @@ void handle_key(unichar key)
                str[utf16_char_to_utf8(key, str)] = '\0';
        }
 
+       if (strcmp(str, "^") == 0) {
+               /* change it as ^^ */
+               str[1] = '^';
+               str[2] = '\0';
+       }
+
        if (escape_next_key || !key_pressed(keyboard, str)) {
                /* key wasn't used for anything, print it */
                 escape_next_key = FALSE;
@@ -175,14 +181,10 @@ static void key_send_line(void)
         char *str, *add_history;
 
        str = gui_entry_get_text(active_entry);
-       if (str == NULL || (*str == '\0' && redir == NULL)) {
-                g_free(str);
-               return;
-       }
 
        /* we can't use gui_entry_get_text() later, since the entry might
           have been destroyed after we get back */
-       add_history = g_strdup(str);
+       add_history = *str == '\0' ? NULL : g_strdup(str);
        history = command_history_current(active_win);
 
        translate_output(str);
@@ -481,43 +483,98 @@ static void key_active_window(void)
        signal_emit("command window goto", 3, "active", active_win->active_server, active_win->active);
 }
 
+static SERVER_REC *get_prev_server(SERVER_REC *current)
+{
+       int pos;
+
+       if (current == NULL) {
+               return servers != NULL ? g_slist_last(servers)->data :
+                       lookup_servers != NULL ?
+                       g_slist_last(lookup_servers)->data : NULL;
+       }
+
+       /* connect2 -> connect1 -> server2 -> server1 -> connect2 -> .. */
+
+       pos = g_slist_index(servers, current);
+       if (pos != -1) {
+               if (pos > 0)
+                       return g_slist_nth(servers, pos-1)->data;
+               if (lookup_servers != NULL)
+                       return g_slist_last(lookup_servers)->data;
+               return g_slist_last(servers)->data;
+       }
+
+       pos = g_slist_index(lookup_servers, current);
+       g_assert(pos >= 0);
+
+       if (pos > 0)
+               return g_slist_nth(lookup_servers, pos-1)->data;
+       if (servers != NULL)
+               return g_slist_last(servers)->data;
+       return g_slist_last(lookup_servers)->data;
+}
+
+static SERVER_REC *get_next_server(SERVER_REC *current)
+{
+       GSList *pos;
+
+       if (current == NULL) {
+               return servers != NULL ? servers->data :
+                       lookup_servers != NULL ? lookup_servers->data : NULL;
+       }
+
+       /* server1 -> server2 -> connect1 -> connect2 -> server1 -> .. */
+
+       pos = g_slist_find(servers, current);
+       if (pos != NULL) {
+               if (pos->next != NULL)
+                       return pos->next->data;
+               if (lookup_servers != NULL)
+                       return lookup_servers->data;
+               return servers->data;
+       }
+
+       pos = g_slist_find(lookup_servers, current);
+       g_assert(pos != NULL);
+
+       if (pos->next != NULL)
+               return pos->next->data;
+       if (servers != NULL)
+               return servers->data;
+       return lookup_servers->data;
+}
+
 static void key_previous_window_item(void)
 {
        SERVER_REC *server;
-       GSList *pos;
 
-       if (active_win->items != NULL)
-               signal_emit("command window item prev", 3, "", active_win->active_server, active_win->active);
-       else if (servers != NULL) {
+       if (active_win->items != NULL) {
+               signal_emit("command window item prev", 3, "",
+                           active_win->active_server, active_win->active);
+       } else if (servers != NULL || lookup_servers != NULL) {
                /* change server */
-               if (active_win->active_server == NULL)
-                       server = servers->data;
-               else {
-                       pos = g_slist_find(servers, active_win->active_server);
-                       server = pos->next != NULL ? pos->next->data : servers->data;
-               }
-               signal_emit("command window server", 3, server->tag, active_win->active_server, active_win->active);
+               server = active_win->active_server;
+               if (server == NULL)
+                       server = active_win->connect_server;
+               server = get_prev_server(server);
+               signal_emit("command window server", 3, server->tag,
+                           active_win->active_server, active_win->active);
        }
 }
 
 static void key_next_window_item(void)
 {
        SERVER_REC *server;
-       int index;
 
        if (active_win->items != NULL) {
                signal_emit("command window item next", 3, "",
                            active_win->active_server, active_win->active);
-       }
-       else if (servers != NULL) {
+       } else if (servers != NULL || lookup_servers != NULL) {
                /* change server */
-               if (active_win->active_server == NULL)
-                       server = servers->data;
-               else {
-                       index = g_slist_index(servers, active_win->active_server);
-                       server = index > 0 ? g_slist_nth(servers, index-1)->data :
-                               g_slist_last(servers)->data;
-               }
+               server = active_win->active_server;
+               if (server == NULL)
+                       server = active_win->connect_server;
+               server = get_next_server(server);
                signal_emit("command window server", 3, server->tag,
                            active_win->active_server, active_win->active);
        }
@@ -647,7 +704,7 @@ void gui_readline_init(void)
        key_bind("backspace", "", "backspace", NULL, (SIGNAL_FUNC) key_backspace);
        key_bind("delete_character", "", "delete", NULL, (SIGNAL_FUNC) key_delete_character);
        key_bind("delete_character", NULL, "^D", NULL, (SIGNAL_FUNC) key_delete_character);
-       key_bind("delete_next_word", "", NULL, NULL, (SIGNAL_FUNC) key_delete_next_word);
+       key_bind("delete_next_word", "meta-d", NULL, NULL, (SIGNAL_FUNC) key_delete_next_word);
        key_bind("delete_previous_word", "meta-backspace", NULL, NULL, (SIGNAL_FUNC) key_delete_previous_word);
        key_bind("delete_to_previous_space", "", "^W", NULL, (SIGNAL_FUNC) key_delete_to_previous_space);
        key_bind("delete_to_next_space", "", "", NULL, (SIGNAL_FUNC) key_delete_to_next_space);
diff --git a/apps/irssi/src/fe-text/mainwindows-save.c b/apps/irssi/src/fe-text/mainwindows-save.c
deleted file mode 100644 (file)
index 113037b..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- mainwindows-save.c : irssi
-
-    Copyright (C) 2001 Timo Sirainen
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include "module.h"
-#include "signals.h"
-#include "misc.h"
-#include "lib-config/iconfig.h"
-#include "settings.h"
-
-#include "mainwindows.h"
-#include "gui-windows.h"
-
-static void main_window_save(MAIN_WINDOW_REC *window, CONFIG_NODE *node)
-{
-       GSList *tmp;
-       GString *str;
-        char num[MAX_INT_STRLEN];
-
-        ltoa(num, window->active->refnum);
-       node = config_node_section(node, num, NODE_TYPE_BLOCK);
-
-       iconfig_node_set_int(node, "first_line", window->first_line);
-       iconfig_node_set_int(node, "lines", window->height);
-
-       str = g_string_new(NULL);
-       for (tmp = window->sticky_windows; tmp != NULL; tmp = tmp->next) {
-                WINDOW_REC *rec = tmp->data;
-                g_string_sprintfa(str, "%d ", rec->refnum);
-       }
-       if (str->len > 1) {
-               g_string_truncate(str, str->len-1);
-               iconfig_node_set_str(node, "sticky", str->str);
-       }
-        g_string_free(str, TRUE);
-}
-
-static void sig_windows_saved(void)
-{
-       CONFIG_NODE *node;
-
-       iconfig_set_str(NULL, "mainwindows", NULL);
-       node = iconfig_node_traverse("mainwindows", TRUE);
-
-       g_slist_foreach(mainwindows, (GFunc) main_window_save, node);
-}
-
-static int window_node_cmp(CONFIG_NODE *n1, CONFIG_NODE *n2)
-{
-       return config_node_get_int(n1, "first_line", 0) <
-               config_node_get_int(n2, "first_line", 0) ? -1 : 1;
-}
-
-static GSList *read_sorted_windows(CONFIG_NODE *node)
-{
-       GSList *tmp, *output;
-
-        output = NULL;
-       for (tmp = node->value; tmp != NULL; tmp = tmp->next) {
-               output = g_slist_insert_sorted(output, tmp->data,
-                                              (GCompareFunc) window_node_cmp);
-       }
-
-        return output;
-}
-
-static void restore_sticky_windows(CONFIG_NODE *node,
-                                  MAIN_WINDOW_REC *mainwindow)
-{
-        WINDOW_REC *window;
-        char **sticky_list, **sticky;
-
-       sticky_list = g_strsplit(config_node_get_str(node, "sticky", ""), " ", -1);
-       for (sticky = sticky_list; *sticky != NULL; sticky++) {
-               window = window_find_refnum(atoi(*sticky));
-               if (window != NULL) {
-                       mainwindow->sticky_windows =
-                               g_slist_append(mainwindow->sticky_windows,
-                                              window);
-               }
-       }
-       g_strfreev(sticky_list);
-}
-
-static WINDOW_REC *window_find_hidden(void)
-{
-       GSList *tmp;
-
-       for (tmp = windows; tmp != NULL; tmp = tmp->next) {
-               WINDOW_REC *rec = tmp->data;
-
-               if (!is_window_visible(rec))
-                        return rec;
-       }
-
-        return NULL;
-}
-
-static void sig_windows_restored(void)
-{
-        MAIN_WINDOW_REC *mainwindow, *lowerwin;
-        WINDOW_REC *window;
-       CONFIG_NODE *node;
-       GSList *tmp, *tmp2, *sorted_windows, *sorted_config;
-        int count, newsize;
-
-       node = iconfig_node_traverse("mainwindows", FALSE);
-       if (node == NULL) return;
-
-       /* create all windows, shrink the lower windows to minimum size */
-        lowerwin = mainwindows->data;
-       count = g_slist_length(node->value);
-       while (count > 1) {
-               window = window_find_hidden();
-               if (window == NULL)
-                       break;
-
-               mainwindow = mainwindow_create();
-               if (mainwindow == NULL)
-                       break;
-
-               mainwindow->active = window;
-               WINDOW_GUI(window)->parent = mainwindow;
-
-               active_mainwin = NULL;
-               window_set_active(window);
-
-                if (lowerwin->height > WINDOW_MIN_SIZE)
-                       mainwindow_set_size(lowerwin, WINDOW_MIN_SIZE);
-               count--;
-
-               lowerwin = mainwindow;
-       }
-
-        sorted_config = read_sorted_windows(node);
-       sorted_windows = mainwindows_get_sorted(FALSE);
-       for (tmp = sorted_windows, tmp2 = sorted_config;
-            tmp != NULL && tmp2 != NULL;
-            tmp = tmp->next, tmp2 = tmp2->next) {
-               MAIN_WINDOW_REC *mainwindow = tmp->data;
-                CONFIG_NODE *node = tmp2->data;
-
-                window = window_find_refnum(atoi(node->key));
-               if (window == NULL) {
-                       mainwindow_destroy(mainwindow);
-                        continue;
-               }
-
-               if (is_window_visible(window)) {
-                        active_mainwin = WINDOW_GUI(window)->parent;
-                       window_set_active(window_find_hidden());
-               }
-
-               active_mainwin = mainwindow;
-               window_set_active(window);
-
-               restore_sticky_windows(node, mainwindow);
-
-               newsize = config_node_get_int(node, "lines", 0);
-               if (newsize > 0)
-                        mainwindow_set_size(mainwindow, newsize);
-       }
-       g_slist_free(sorted_windows);
-       g_slist_free(sorted_config);
-
-        irssi_redraw();
-}
-
-void mainwindows_save_init(void)
-{
-       signal_add("windows saved", (SIGNAL_FUNC) sig_windows_saved);
-       signal_add("windows restored", (SIGNAL_FUNC) sig_windows_restored);
-}
-
-void mainwindows_save_deinit(void)
-{
-       signal_remove("windows saved", (SIGNAL_FUNC) sig_windows_saved);
-       signal_remove("windows restored", (SIGNAL_FUNC) sig_windows_restored);
-}
diff --git a/apps/irssi/src/fe-text/screen.c b/apps/irssi/src/fe-text/screen.c
deleted file mode 100644 (file)
index 3657a23..0000000
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- screen.c : irssi
-
-    Copyright (C) 1999-2000 Timo Sirainen
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include "module.h"
-#include "signals.h"
-#include "misc.h"
-#include "settings.h"
-
-#include "screen.h"
-#include "gui-readline.h"
-#include "mainwindows.h"
-
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-#include <signal.h>
-
-#ifndef COLOR_PAIRS
-#define COLOR_PAIRS 64
-#endif
-
-#define MIN_SCREEN_WIDTH 20
-
-static int scrx, scry;
-static int use_colors;
-static int freeze_refresh;
-static int resized;
-
-static int init_screen_int(void);
-static void deinit_screen_int(void);
-
-#ifdef SIGWINCH
-static void sig_winch(int p)
-{
-       resized = TRUE;
-}
-#endif
-
-static void screen_resize(void)
-{
-#if defined (TIOCGWINSZ) && defined (HAVE_CURSES_RESIZETERM)
-       struct winsize ws;
-
-       /* Get new window size */
-       if (ioctl(0, TIOCGWINSZ, &ws) < 0)
-               return;
-
-       if (ws.ws_row == LINES && ws.ws_col == COLS) {
-               /* Same size, abort. */
-               return;
-       }
-
-       if (ws.ws_col < MIN_SCREEN_WIDTH)
-               ws.ws_col = MIN_SCREEN_WIDTH;
-
-       /* Resize curses terminal */
-       resizeterm(ws.ws_row, ws.ws_col);
-#else
-       deinit_screen_int();
-       init_screen_int();
-       mainwindows_recreate();
-#endif
-
-       mainwindows_resize(COLS, LINES);
-}
-
-void screen_check_resizes(void)
-{
-       if (!resized)
-               return;
-       screen_resize();
-       resized = FALSE;
-}
-
-static void read_signals(void)
-{
-#ifndef WIN32
-       int signals[] = {
-               SIGHUP, SIGINT, SIGQUIT, SIGTERM,
-               SIGALRM, SIGUSR1, SIGUSR2
-       };
-       char *signames[] = {
-               "hup", "int", "quit", "term",
-               "alrm", "usr1", "usr2"
-       };
-
-       const char *ignores;
-       struct sigaction act;
-        int n;
-
-       ignores = settings_get_str("ignore_signals");
-
-       sigemptyset (&act.sa_mask);
-       act.sa_flags = 0;
-
-       for (n = 0; n < sizeof(signals)/sizeof(signals[0]); n++) {
-               act.sa_handler = find_substr(ignores, signames[n]) ?
-                       SIG_IGN : SIG_DFL;
-               sigaction(signals[n], &act, NULL);
-       }
-#endif
-}
-
-static void read_settings(void)
-{
-       int old_colors = use_colors;
-
-       use_colors = settings_get_bool("colors");
-       read_signals();
-       if (use_colors && !has_colors())
-               use_colors = FALSE;
-
-       if (use_colors != old_colors)
-               irssi_redraw();
-}
-
-static int init_curses(void)
-{
-       char ansi_tab[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
-       int num;
-#ifndef WIN32
-       struct sigaction act;
-#endif
-
-       if (!initscr())
-               return FALSE;
-
-       if (COLS < MIN_SCREEN_WIDTH)
-               COLS = MIN_SCREEN_WIDTH;
-
-#ifdef SIGWINCH
-       sigemptyset (&act.sa_mask);
-       act.sa_flags = 0;
-       act.sa_handler = sig_winch;
-       sigaction(SIGWINCH, &act, NULL);
-#endif
-       raw(); noecho(); idlok(stdscr, 1);
-#ifdef HAVE_CURSES_IDCOK
-       idcok(stdscr, 1);
-#endif
-       intrflush(stdscr, FALSE); nodelay(stdscr, TRUE);
-
-       if (has_colors())
-               start_color();
-       else if (use_colors)
-                use_colors = FALSE;
-
-#ifdef HAVE_NCURSES_USE_DEFAULT_COLORS
-       /* this lets us to use the "default" background color for colors <= 7 so
-          background pixmaps etc. show up right */
-       use_default_colors();
-
-       for (num = 1; num < COLOR_PAIRS; num++)
-               init_pair(num, ansi_tab[num & 7], num <= 7 ? -1 : ansi_tab[num >> 3]);
-
-       init_pair(63, 0, -1); /* hm.. not THAT good idea, but probably more
-                                people want dark grey than white on white.. */
-#else
-       for (num = 1; num < COLOR_PAIRS; num++)
-               init_pair(num, ansi_tab[num & 7], ansi_tab[num >> 3]);
-       init_pair(63, 0, 0);
-#endif
-
-       clear();
-       return TRUE;
-}
-
-static int init_screen_int(void)
-{
-       use_colors = settings_get_bool("colors");
-       read_signals();
-
-       scrx = scry = 0;
-       freeze_refresh = 0;
-
-       return init_curses();
-}
-
-static void deinit_screen_int(void)
-{
-       endwin();
-}
-
-/* Initialize screen, detect screen length */
-int init_screen(void)
-{
-       settings_add_bool("lookandfeel", "colors", TRUE);
-       settings_add_str("misc", "ignore_signals", "");
-       signal_add("setup changed", (SIGNAL_FUNC) read_settings);
-
-       return init_screen_int();
-}
-
-/* Deinitialize screen */
-void deinit_screen(void)
-{
-        deinit_screen_int();
-       signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
-}
-
-void set_color(WINDOW *window, int col)
-{
-       int attr;
-
-       if (!use_colors)
-               attr = (col & 0x70) ? A_REVERSE : 0;
-       else if (col & ATTR_COLOR8)
-                attr = (A_DIM | COLOR_PAIR(63));
-       else if ((col & 0x77) == 0)
-               attr = A_NORMAL;
-       else
-               attr = (COLOR_PAIR((col&7) + (col&0x70)/2));
-
-       if (col & 0x08) attr |= A_BOLD;
-       if (col & 0x80) attr |= A_BLINK;
-
-       if (col & ATTR_UNDERLINE) attr |= A_UNDERLINE;
-       if (col & ATTR_REVERSE) attr |= A_REVERSE;
-
-       wattrset(window, attr);
-}
-
-void set_bg(WINDOW *window, int col)
-{
-       int attr;
-
-       if (!use_colors)
-               attr = (col & 0x70) ? A_REVERSE : 0;
-       else {
-               attr = (col == 8) ?
-                       (A_DIM | COLOR_PAIR(63)) :
-                       (COLOR_PAIR((col&7) + (col&0x70)/2));
-       }
-
-       if (col & 0x08) attr |= A_BOLD;
-       if (col & 0x80) attr |= A_BLINK;
-
-       wbkgdset(window, ' ' | attr);
-}
-
-void move_cursor(int y, int x)
-{
-       scry = y;
-       scrx = x;
-}
-
-void screen_refresh_freeze(void)
-{
-       freeze_refresh++;
-}
-
-void screen_refresh_thaw(void)
-{
-       if (freeze_refresh > 0) {
-               freeze_refresh--;
-               if (freeze_refresh == 0) screen_refresh(NULL);
-       }
-}
-
-void screen_refresh(WINDOW *window)
-{
-       if (window != NULL)
-               wnoutrefresh(window);
-       if (freeze_refresh == 0) {
-               move(scry, scrx);
-               wnoutrefresh(stdscr);
-               doupdate();
-       }
-}
diff --git a/apps/irssi/src/fe-text/screen.h b/apps/irssi/src/fe-text/screen.h
deleted file mode 100644 (file)
index 9e6143f..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef __SCREEN_H
-#define __SCREEN_H
-
-#if defined(USE_NCURSES) && !defined(RENAMED_NCURSES)
-#  include <ncurses.h>
-#else
-#  include <curses.h>
-#endif
-
-/* Some curseses include term.h, which #defines some things breaking irssi */
-#undef lines
-#undef key_backspace
-#undef tab
-
-#define ATTR_UNDERLINE 0x100
-#define ATTR_COLOR8    0x200
-#define ATTR_REVERSE   0x400
-
-/* XXX I hope this could be integrated into BX.
- * XXX Well, this should be done via libc,
- *     but FreeBSD libc support is quite LAME.
- *     Macro below are copied from lynx.
- *
- *                             clive@FreeBSD.org
- */
-#ifdef WANT_BIG5
-/* XXX I didn't check the encoding range of big5+. This is standard big5. */
-#define is_big5_los(lo) (((char)0x40<=lo)&&(lo<=(char)0x7E))   /* standard */
-#define is_big5_lox(lo) (((char)0x80<=lo)&&(lo<=(char)0xFE))   /* extended */
-#define is_big5_hi(hi)  (((char)0x81<=hi)&&(hi<=(char)0xFE))
-#define is_big5(hi,lo) is_big5_hi(hi) && (is_big5_los(lo) || is_big5_lox(lo))
-#endif
-
-void screen_check_resizes(void);
-
-int init_screen(void); /* Initialize screen, detect screen length */
-void deinit_screen(void); /* Deinitialize screen */
-
-void set_color(WINDOW *window, int col);
-void set_bg(WINDOW *window, int col);
-
-void move_cursor(int y, int x);
-
-void screen_refresh_freeze(void);
-void screen_refresh_thaw(void);
-void screen_refresh(WINDOW *window);
-
-#endif
index ef62037914b4f2726822f3dc5c358c05b1278206..689e4f9b3416137ec0a643e42e6410954acf83f8 100644 (file)
@@ -699,8 +699,9 @@ void statusbar_item_default_handler(SBAR_ITEM_REC *item, int get_size_only,
                server = NULL;
                 wiitem = NULL;
        } else {
-               server = active_win->active_server;
-                wiitem = active_win->active;
+               server = active_win->active_server != NULL ?
+                       active_win->active_server : active_win->connect_server;
+               wiitem = active_win->active;
        }
 
        /* expand templates */
index 03004b10a9e741dfe6812f8482a88991e49a96e1..a36e68fac142ec7187d0e2b3e699d1b9245d63e9 100644 (file)
@@ -27,7 +27,6 @@
 #include "mainwindows.h"
 
 #ifdef HAVE_NL_LANGINFO
-#  include <locale.h>
 #  include <langinfo.h>
 #endif
 
@@ -155,7 +154,6 @@ void term_common_init(void)
         read_settings();
 
 #if defined (HAVE_NL_LANGINFO) && defined(CODESET)
-        setlocale(LC_CTYPE, "");
        if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0) {
                term_type = TERM_TYPE_UTF8;
                term_set_input_type(TERM_TYPE_UTF8);
index da69734e6e6e2e1a27dd7299b69fe9ef75862969..77b21a2e512c00f470db5ff0fd55616454137b85 100644 (file)
@@ -152,8 +152,10 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
        LINE_CACHE_SUB_REC *sub;
        GSList *lines;
         unsigned char cmd;
-       const unsigned char *ptr, *last_space_ptr;
+       const unsigned char *ptr, *next_ptr, *last_space_ptr;
        int xpos, pos, indent_pos, last_space, last_color, color, linecount;
+       int char_len;
+       unichar chr;
 
        g_return_val_if_fail(line->text != NULL, NULL);
 
@@ -196,7 +198,24 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
                        continue;
                }
 
-               if (xpos == view->width && sub != NULL &&
+               if (!view->utf8) {
+                       next_ptr = ptr+1;
+                       char_len = 1;
+               } else {
+                       char_len = 1;
+                       while (ptr[char_len] != '\0' && char_len < 6)
+                               char_len++;
+
+                       next_ptr = ptr;
+                       chr = get_utf8_char(&next_ptr, char_len);
+                       if (chr < 0)
+                               char_len = 1;
+                       else
+                               char_len = utf8_width(chr);
+                       next_ptr++;
+               }
+
+               if (xpos + char_len > view->width && sub != NULL &&
                    (last_space <= indent_pos || last_space <= 10) &&
                    view->longword_noindent) {
                         /* long word, remove the indentation from this line */
@@ -204,7 +223,7 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
                         sub->indent = 0;
                }
 
-               if (xpos == view->width) {
+               if (xpos + char_len > view->width) {
                        xpos = indent_func == NULL ? indent_pos :
                                indent_func(view, line, -1);
 
@@ -232,15 +251,14 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
                        continue;
                }
 
-               if (view->utf8)
-                       get_utf8_char(&ptr, 6);
-
-               xpos++;
-               if (*ptr++ == ' ') {
-                       last_space = xpos-1;
+               if (*ptr == ' ') {
+                       last_space = xpos;
                        last_space_ptr = ptr;
                        last_color = color;
                }
+
+               xpos += char_len;
+               ptr = next_ptr;
        }
 
        rec = g_malloc(sizeof(LINE_CACHE_REC)-sizeof(LINE_CACHE_SUB_REC) +
@@ -309,9 +327,9 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
 {
         INDENT_FUNC indent_func;
        LINE_CACHE_REC *cache;
-        const unsigned char *text, *text_newline;
+        const unsigned char *text, *end, *text_newline;
        unsigned char *tmp;
-       int xpos, color, drawcount, first, need_move, need_clrtoeol;
+       int xpos, color, drawcount, first, need_move, need_clrtoeol, char_width;
 
        if (view->dirty) /* don't bother drawing anything - redraw is coming */
                 return 0;
@@ -343,13 +361,14 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
                        if (subline > 0) {
                                 /* continuing previous line - indent it */
                                indent_func = cache->lines[subline-1].indent_func;
-                               xpos = indent_func != NULL ?
-                                       indent_func(view, line, ypos) :
-                                       cache->lines[subline-1].indent;
+                               if (indent_func == NULL)
+                                       xpos = cache->lines[subline-1].indent;
                                 color = cache->lines[subline-1].color;
+                       } else {
+                               indent_func = NULL;
                        }
 
-                       if (xpos == 0)
+                       if (xpos == 0 && indent_func == NULL)
                                 need_clrtoeol = TRUE;
                        else {
                                /* line was indented - need to clear the
@@ -357,6 +376,9 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
                                term_set_color(view->window, ATTR_RESET);
                                term_move(view->window, 0, ypos);
                                term_clrtoeol(view->window);
+
+                               if (indent_func != NULL)
+                                       xpos = indent_func(view, line, ypos);
                        }
 
                        if (need_move || xpos > 0)
@@ -397,11 +419,16 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
                        continue;
                }
 
-               if (xpos < term_width) {
-                       const unsigned char *end = text;
-                       if (view->utf8)
-                               get_utf8_char(&end, 6);
+               end = text;
+               if (view->utf8) {
+                       unichar chr = get_utf8_char(&end, 6);
+                       char_width = utf8_width(chr);
+               } else {
+                       char_width = 1;
+               }
 
+               xpos += char_width;
+               if (xpos <= term_width) {
                        if (*text >= 32 &&
                            (end != text || (*text & 127) >= 32)) {
                                for (; text < end; text++)
@@ -415,7 +442,6 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
                        }
                }
                text++;
-               xpos++;
        }
 
        if (need_clrtoeol && xpos < term_width) {
index 2d72fe2bf8fb23516dce54f47c5e22eeb57261f4..4049991db524c3f5d4d464382d97b3369c6cb1d2 100644 (file)
@@ -7,6 +7,10 @@
  * Copyright (C) 1999 Tom Tromey
  * Copyright (C) 2000 Red Hat, Inc.
  *
+ * UTF-8 width tables based on locale data from GNU libc by
+ *
+ * Copyright (C) 1991-2002 Free Software Foundation, Inc.
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
@@ -175,3 +179,73 @@ void utf16_to_utf8(const unichar *str, char *out)
        }
        *out = '\0';
 }
+
+static const unichar wcc[] = {
+       0x0, 0x300, 0x34F, 0x360, 0x363, 0x483, 0x487, 0x488, 0x48A, 0x591,
+       0x5A2, 0x5A3, 0x5BA, 0x5BB, 0x5BE, 0x5BF, 0x5C0, 0x5C1, 0x5C3, 0x5C4,
+       0x5C5, 0x64B, 0x656, 0x670, 0x671, 0x6D6, 0x6E5, 0x6E7, 0x6E9, 0x6EA,
+       0x6EE, 0x70F, 0x710, 0x711, 0x712, 0x730, 0x74B, 0x7A6, 0x7B1, 0x901,
+       0x903, 0x93C, 0x93D, 0x941, 0x949, 0x94D, 0x94E, 0x951, 0x955, 0x962,
+       0x964, 0x981, 0x982, 0x9BC, 0x9BD, 0x9C1, 0x9C5, 0x9CD, 0x9CE, 0x9E2,
+       0x9E4, 0xA02, 0xA03, 0xA3C, 0xA3D, 0xA41, 0xA43, 0xA47, 0xA49, 0xA4B,
+       0xA4E, 0xA70, 0xA72, 0xA81, 0xA83, 0xABC, 0xABD, 0xAC1, 0xAC6, 0xAC7,
+       0xAC9, 0xACD, 0xACE, 0xB01, 0xB02, 0xB3C, 0xB3D, 0xB3F, 0xB40, 0xB41,
+       0xB44, 0xB4D, 0xB4E, 0xB56, 0xB57, 0xB82, 0xB83, 0xBC0, 0xBC1, 0xBCD,
+       0xBCE, 0xC3E, 0xC41, 0xC46, 0xC49, 0xC4A, 0xC4E, 0xC55, 0xC57, 0xCBF,
+       0xCC0, 0xCC6, 0xCC7, 0xCCC, 0xCCE, 0xD41, 0xD44, 0xD4D, 0xD4E, 0xDCA,
+       0xDCB, 0xDD2, 0xDD5, 0xDD6, 0xDD7, 0xE31, 0xE32, 0xE34, 0xE3B, 0xE47,
+       0xE4F, 0xEB1, 0xEB2, 0xEB4, 0xEBA, 0xEBB, 0xEBD, 0xEC8, 0xECE, 0xF18,
+       0xF1A, 0xF35, 0xF36, 0xF37, 0xF38, 0xF39, 0xF3A, 0xF71, 0xF7F, 0xF80,
+       0xF85, 0xF86, 0xF88, 0xF90, 0xF98, 0xF99, 0xFBD, 0xFC6, 0xFC7, 0x102D,
+       0x1031, 0x1032, 0x1033, 0x1036, 0x1038, 0x1039, 0x103A, 0x1058, 0x105A,
+       0x1100, 0x1160, 0x17B7, 0x17BE, 0x17C6, 0x17C7, 0x17C9, 0x17D4, 0x180B,
+       0x180F, 0x18A9, 0x18AA, 0x200B, 0x2010, 0x202A, 0x202F, 0x206A, 0x2070,
+       0x20D0, 0x20E4, 0x2E80, 0x3008, 0x300C, 0x3014, 0x3016, 0x3018, 0x301C,
+       0x302A, 0x3030, 0x303F, 0x3041, 0x3095, 0x3099, 0x309B, 0xA4C7, 0xAC00,
+       0xD7A4, 0xF8F0, 0xF900, 0xFA2E, 0xFB1E, 0xFB1F, 0xFE20, 0xFE24, 0xFE30,
+       0xFE6C, 0xFEFF, 0xFF00, 0xFF01, 0xFF5F, 0xFFE0, 0xFFE7, 0xFFF9, 0xFFFC,
+#if 1
+       0x1D167, 0x1D16A, 0x1D173, 0x1D183, 0x1D185, 0x1D18C, 0x1D1AA, 0x1D1AE,
+       0x20000, 0x2A6D7, 0x2F800, 0x2FA1E, 0xE0001, 0xE0002, 0xE0020, 0xE0080
+#endif
+};
+
+static const int wccnum = sizeof(wcc) / sizeof(wcc[0]) - 1;
+
+static const char wws[] = {
+       1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+       1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+       1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+       1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+       1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+       1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+       1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+       1, 2, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 1, 2,
+       1, 2, 1, 2, 0, 2, 1, 2, 1, 0, 2, 1, 2, 1, 0, 2, 1, 0, 1, 0, 1, 2, 1, 0,
+       1, 2, 1, 2, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 1, 2, 1, 0, 1, 0, 1, -1
+};
+
+int utf8_width(unichar c)
+{
+       int p, q, r;
+       unichar d;
+
+       if (c < wcc[1])
+               return 1;
+
+       p = 0;
+       q = wccnum;
+
+       while (p < q - 1) {
+               r = (p + q)/2;
+               d = wcc[r];
+               if (d < c)
+                       p = r;
+               else if (d > c)
+                       q = r;
+               else
+                       return wws[r];
+       }
+
+       return wws[p];
+}
index efc6af082c0a83c24a6445325eae0c7443f8cfca..64c0e347e110f7aeebc7b8a2e763b7830b922917 100644 (file)
@@ -18,4 +18,7 @@ int utf16_char_to_utf8(unichar c, char *outbuf);
    Make sure out is at least 6 x length of str. */
 void utf16_to_utf8(const unichar *str, char *out);
 
+/* Returns width for character (0-2). */
+int utf8_width(unichar c);
+
 #endif
index e4c5cf07fba7d8fa6e09d0b97a9bb18178a2aac5..2df0cc901a6690e98db2ae306f563191fc5b55e7 100644 (file)
@@ -171,46 +171,6 @@ int config_get_bool(CONFIG_REC *rec, const char *section, const char *key, int d
         return i_toupper(*str) == 'T' || i_toupper(*str) == 'Y';
 }
 
-/* Return value of key `value_key' from list item where `key' is `value' */
-const char *config_list_find(CONFIG_REC *rec, const char *section, const char *key, const char *value, const char *value_key)
-{
-       CONFIG_NODE *node;
-
-       node = config_list_find_node(rec, section, key, value, value_key);
-       return node != NULL && node->type == NODE_TYPE_KEY ?
-               node->value : NULL;
-}
-
-/* Like config_list_find(), but return node instead of it's value */
-CONFIG_NODE *config_list_find_node(CONFIG_REC *rec, const char *section, const char *key, const char *value, const char *value_key)
-{
-       CONFIG_NODE *node, *keynode;
-       GSList *tmp;
-
-       g_return_val_if_fail(rec != NULL, NULL);
-       g_return_val_if_fail(key != NULL, NULL);
-       g_return_val_if_fail(value_key != NULL, NULL);
-
-       node = config_node_traverse(rec, section, FALSE);
-       if (node == NULL || !is_node_list(node)) return NULL;
-
-       for (tmp = node->value; tmp != NULL; tmp = tmp->next) {
-               node = tmp->data;
-
-               if (node->type != NODE_TYPE_BLOCK)
-                       continue;
-
-               /* key matches value? */
-               keynode = config_node_find(node, key);
-               if (keynode == NULL || keynode->type != NODE_TYPE_KEY ||
-                   g_strcasecmp(keynode->value, value) != 0) continue;
-
-               return config_node_find(node, value_key);
-       }
-
-       return NULL;
-}
-
 char *config_node_get_str(CONFIG_NODE *parent, const char *key, const char *def)
 {
        CONFIG_NODE *node;
index 7ef8d7919176ba7a4928ff2c8505e279036dfbe8..3d6072d118ac25291062d1bbc9ae3f351b36128c 100644 (file)
@@ -93,10 +93,6 @@ char *config_get_str(CONFIG_REC *rec, const char *section, const char *key, cons
 int config_get_int(CONFIG_REC *rec, const char *section, const char *key, int def);
 int config_get_bool(CONFIG_REC *rec, const char *section, const char *key, int def);
 
-/* Return value of key `value_key' from list item where `key' is `value' */
-const char *config_list_find(CONFIG_REC *rec, const char *section, const char *key, const char *value, const char *value_key);
-/* Like config_list_find(), but return node instead of it's value */
-CONFIG_NODE *config_list_find_node(CONFIG_REC *rec, const char *section, const char *key, const char *value, const char *value_key);
 /* Returns n'th node from list. */
 CONFIG_NODE *config_node_nth(CONFIG_NODE *node, int index);
 /* Returns index for given key */
index f425dc2bc347adb6975f5edd25afc44645d6aa5e..0692a7ccc5642f78af2c33ae6c1a8f095bd9b7bf 100644 (file)
@@ -42,14 +42,6 @@ channels_join(server, channels, automatic)
 CODE:
        server->channels_join(server, channels, automatic);
 
-Irssi::Channel
-channel_create(server, name, automatic)
-       Irssi::Server server
-       char *name
-       int automatic
-CODE:
-       CHAT_PROTOCOL(server)->channel_create(server, name, automatic);
-
 Irssi::Channel
 channel_find(server, name)
        Irssi::Server server
index 129b208118289eaf0691138354b0cc179cc295b4..c3fd41ba91bf45b44ddc9660e7ad9c943520aed8 100644 (file)
@@ -1,5 +1,6 @@
 #include "module.h"
 #include "irssi-version.h"
+#include "core.h"
 
 #define DEFAULT_COMMAND_CATEGORY "Perl scripts' commands"
 
@@ -556,6 +557,55 @@ CODE:
 OUTPUT:
         RETVAL
 
+int
+get_gui()
+CODE:
+       RETVAL = irssi_gui;
+OUTPUT:
+       RETVAL
+
+int
+IRSSI_GUI_NONE()
+CODE:
+       RETVAL = IRSSI_GUI_NONE;
+OUTPUT:
+       RETVAL
+
+int
+IRSSI_GUI_TEXT()
+CODE:
+       RETVAL = IRSSI_GUI_TEXT;
+OUTPUT:
+       RETVAL
+
+int
+IRSSI_GUI_GTK()
+CODE:
+       RETVAL = IRSSI_GUI_GTK;
+OUTPUT:
+       RETVAL
+
+int
+IRSSI_GUI_GNOME()
+CODE:
+       RETVAL = IRSSI_GUI_GNOME;
+OUTPUT:
+       RETVAL
+
+int
+IRSSI_GUI_QT()
+CODE:
+       RETVAL = IRSSI_GUI_QT;
+OUTPUT:
+       RETVAL
+
+int
+IRSSI_GUI_KDE()
+CODE:
+       RETVAL = IRSSI_GUI_KDE;
+OUTPUT:
+       RETVAL
+
 #*******************************
 MODULE = Irssi::Core   PACKAGE = Irssi::Server
 #*******************************
index c84918e82e6a94efaff8c1f80863cc9bbfc2f93e..67d5e96cda6911a2985635918cedb75b10ebc7f7 100644 (file)
@@ -31,4 +31,3 @@ BOOT:
        irssi_boot(Rawlog);
        irssi_boot(Server);
        irssi_boot(Settings);
-       irssi_boot(Blob);
index aa1cce47896b7445cf47b7ce33e97427935fbe2a..5456f6300414a57f9932ed1237c98a647244e37f 100644 (file)
@@ -22,7 +22,6 @@
 #include "channels.h"
 #include "queries.h"
 #include "nicklist.h"
-#include "blob.h"
 
 #include "perl/perl-core.h"
 #include "perl/perl-common.h"
@@ -43,4 +42,3 @@ typedef RECONNECT_REC *Irssi__Reconnect;
 typedef CHANNEL_REC *Irssi__Channel;
 typedef QUERY_REC *Irssi__Query;
 typedef NICK_REC *Irssi__Nick;
-typedef BLOB_REC *Irssi__Blob;
index 41bcd4c581499ffcdab43543c5e59f40d490758f..5b7e0c32836c268e2529778964bb955eeef2c347 100644 (file)
@@ -13,7 +13,6 @@ Irssi::Logitem        T_PlainObj
 Irssi::Rawlog          T_PlainObj
 Irssi::Module          T_PlainObj
 Irssi::Windowitem      T_IrssiObj
-Irssi::Blob            T_PlainObj
 
 INPUT
 
index 7cd97614ffa26d62b4f47127c42359574a128343..df4667cef659928322144880390ae42e363ee74f 100755 (executable)
@@ -51,9 +51,6 @@ while (<STDIN>) {
        s/WINDOW_REC[^,]*/Irssi::UI::Window/g;
        s/WI_ITEM_REC[^,]*/iobject/g;
 
-       # silc
-       s/BLOB_REC[^,]*/siobject/g;
-
        s/([\w\*:]+)(,|$)/"\1"\2/g;
        print "    { \"$signal\", { $_, NULL } },\n";
 }
index 31fbe484e86dd4d1f6b2b5c8f1867c28a81d595b..11aa0f6f50275cf51ec50629c6927dacb8ae7a80 100644 (file)
@@ -6,14 +6,15 @@
 # %%s : must be second - use Irssi; use Irssi::Irc; etc..
 package Irssi::Core;
 
-use Symbol qw(delete_package);
+use Symbol;
 
 sub is_static {
   return %d;
 }
 
 sub destroy {
-  delete_package($_[0]);
+  eval { $_[0]->UNLOAD() if $_[0]->can('UNLOAD'); };
+  Symbol::delete_package($_[0]);
 }
 
 sub eval_data {
@@ -29,8 +30,10 @@ sub eval_data {
   }
   die $@ if $@;
 
-  eval {$package->handler;};
+  my $ret;
+  eval { $ret = $package->handler; };
   die $@ if $@;
+  return $ret;
 }
 
 sub eval_file {
index 3e4ec9a8bc858fa079a62e28d8fbca3f334506d6..9c4dd606f8d0160a286d26e2efca4398f3499d5e 100644 (file)
@@ -7,14 +7,15 @@ const char *irssi_core_code =
 "# %%s : must be second - use Irssi; use Irssi::Irc; etc..\n"
 "package Irssi::Core;\n"
 "\n"
-"use Symbol qw(delete_package);\n"
+"use Symbol;\n"
 "\n"
 "sub is_static {\n"
 "  return %d;\n"
 "}\n"
 "\n"
 "sub destroy {\n"
-"  delete_package($_[0]);\n"
+"  eval { $_[0]->UNLOAD() if $_[0]->can('UNLOAD'); };\n"
+"  Symbol::delete_package($_[0]);\n"
 "}\n"
 "\n"
 "sub eval_data {\n"
@@ -30,8 +31,10 @@ const char *irssi_core_code =
 "  }\n"
 "  die $@ if $@;\n"
 "\n"
-"  eval {$package->handler;};\n"
+"  my $ret;\n"
+"  eval { $ret = $package->handler; };\n"
 "  die $@ if $@;\n"
+"  return $ret;\n"
 "}\n"
 "\n"
 "sub eval_file {\n"
index 0113bdf3155069948788482d18165b10d6876cd9..cad117fcdd1e8abe06aa4ea56c57a8bbbf81d70f 100644 (file)
@@ -39,7 +39,6 @@
 #include "channels.h"
 #include "queries.h"
 #include "nicklist.h"
-#include "blob.h"
 
 #include "perl-common.h"
 
@@ -220,22 +219,16 @@ char *perl_get_use_list(void)
         return ret;
 }
 
-void irssi_callXS(void (*subaddr)(CV* cv), CV *cv, SV **mark)
+void irssi_callXS(void (*subaddr)(pTHX_ CV* cv), CV *cv, SV **mark)
 {
        dSP;
 
        PUSHMARK(mark);
-       (*subaddr)(cv);
+       (*subaddr)(aTHX_ cv);
 
        PUTBACK;
 }
 
-static void perl_blob_fill_hash(HV *hv, BLOB_REC *blob)
-{
-       hv_store(hv, "octets", 6, newSViv(blob->octets), 0);
-       hv_store(hv, "data", 4, newSVpv(blob->data, blob->octets), 0);
-}
-
 void perl_chatnet_fill_hash(HV *hv, CHATNET_REC *chatnet)
 {
        char *type, *chat_type;
@@ -333,7 +326,7 @@ void perl_window_item_fill_hash(HV *hv, WI_ITEM_REC *item)
        if (item->server != NULL) {
                hv_store(hv, "server", 6, iobject_bless(item->server), 0);
        }
-       hv_store(hv, "name", 4, new_pv(item->name), 0);
+       hv_store(hv, "visible_name", 12, new_pv(item->visible_name), 0);
 
        hv_store(hv, "createtime", 10, newSViv(item->createtime), 0);
        hv_store(hv, "data_level", 10, newSViv(item->data_level), 0);
@@ -350,6 +343,7 @@ void perl_channel_fill_hash(HV *hv, CHANNEL_REC *channel)
         if (channel->ownnick != NULL)
                hv_store(hv, "ownnick", 7, iobject_bless(channel->ownnick), 0);
 
+       hv_store(hv, "name", 4, new_pv(channel->name), 0);
        hv_store(hv, "topic", 5, new_pv(channel->topic), 0);
        hv_store(hv, "topic_by", 8, new_pv(channel->topic_by), 0);
        hv_store(hv, "topic_time", 10, newSViv(channel->topic_time), 0);
@@ -376,6 +370,7 @@ void perl_query_fill_hash(HV *hv, QUERY_REC *query)
 
        perl_window_item_fill_hash(hv, (WI_ITEM_REC *) query);
 
+       hv_store(hv, "name", 4, new_pv(query->name), 0);
        hv_store(hv, "last_unread_msg", 15, newSViv(query->last_unread_msg), 0);
        hv_store(hv, "address", 7, new_pv(query->address), 0);
        hv_store(hv, "server_tag", 10, new_pv(query->server_tag), 0);
@@ -425,8 +420,10 @@ static void perl_ignore_fill_hash(HV *hv, IGNORE_REC *ignore)
        hv_store(hv, "mask", 4, new_pv(ignore->mask), 0);
        hv_store(hv, "servertag", 9, new_pv(ignore->servertag), 0);
        av = newAV();
-       for (tmp = ignore->channels; *tmp != NULL; tmp++) {
-               av_push(av, new_pv(*tmp));
+       if (ignore->channels != NULL) {
+               for (tmp = ignore->channels; *tmp != NULL; tmp++) {
+                       av_push(av, new_pv(*tmp));
+               }
        }
        hv_store(hv, "channels", 8, newRV_noinc((SV*)av), 0);
        hv_store(hv, "pattern", 7, new_pv(ignore->pattern), 0);
@@ -631,10 +628,6 @@ void perl_common_start(void)
        plain_stashes = g_hash_table_new((GHashFunc) g_str_hash,
                                         (GCompareFunc) g_str_equal);
         irssi_add_plains(core_plains);
-       irssi_add_object(module_get_uniq_id("BLOB", 0), 0,
-                       "Irssi::Blob",
-                       (PERL_OBJECT_FUNC) perl_blob_fill_hash);
-
 
         use_protocols = NULL;
        g_slist_foreach(chat_protocols, (GFunc) perl_register_protocol, NULL);
index 9fa85f07824fc10c8d21ae2d0b5844d5f1283fc4..cef0036ff12f2b9c35cad3985660208ef8894ce5 100644 (file)
@@ -32,6 +32,14 @@ SV *perl_func_sv_inc(SV *func, const char *package);
 extern STRLEN PL_na;
 #endif
 
+#ifndef pTHX_
+#  define pTHX_
+#endif
+
+#ifndef aTHX_
+#  define aTHX_
+#endif
+
 #define iobject_bless(object) \
        ((object) == NULL ? &PL_sv_undef : \
        irssi_bless_iobject((object)->type, (object)->chat_type, object))
@@ -57,10 +65,10 @@ void irssi_add_plains(PLAIN_OBJECT_INIT_REC *objects);
 char *perl_get_use_list(void);
 
 #define irssi_boot(x) { \
-       extern void boot_Irssi__##x(CV *cv); \
+       extern void boot_Irssi__##x(pTHX_ CV *cv); \
        irssi_callXS(boot_Irssi__##x, cv, mark); \
        }
-void irssi_callXS(void (*subaddr)(CV* cv), CV *cv, SV **mark);
+void irssi_callXS(void (*subaddr)(pTHX_ CV* cv), CV *cv, SV **mark);
 
 void perl_common_start(void);
 void perl_common_stop(void);
index accd5ef478aa1957ab7f974614c2dc635b5b72a5..2d300289cd60b8ebe237c2ce42ea0aba123c2647 100644 (file)
@@ -84,7 +84,7 @@ static void perl_script_destroy(PERL_SCRIPT_REC *script)
         g_free(script);
 }
 
-extern void boot_DynaLoader(CV* cv);
+extern void boot_DynaLoader(pTHX_ CV* cv);
 
 #if PERL_STATIC_LIBS == 1
 extern void boot_Irssi(CV *cv);
@@ -101,7 +101,7 @@ XS(boot_Irssi_Core)
 }
 #endif
 
-static void xs_init(void)
+static void xs_init(pTHX)
 {
        dXSUB_SYS;
 
@@ -216,6 +216,7 @@ static int perl_script_eval(PERL_SCRIPT_REC *script)
        dSP;
        char *error;
        int retcount;
+       SV *ret;
 
        ENTER;
        SAVETMPS;
@@ -234,19 +235,19 @@ static int perl_script_eval(PERL_SCRIPT_REC *script)
 
         error = NULL;
        if (SvTRUE(ERRSV)) {
-                error = SvPV(ERRSV, PL_na);
-       } else if (retcount > 0) {
-               error = POPp;
-       }
+               error = SvPV(ERRSV, PL_na);
 
-       if (error != NULL) {
-               if (*error == '\0')
-                       error = NULL;
-               else {
-                        error = g_strdup(error);
+               if (error != NULL) {
+                       error = g_strdup(error);
                        signal_emit("script error", 2, script, error);
-                        g_free(error);
+                       g_free(error);
                }
+       } else if (retcount > 0) {
+               /* if script returns 0, it means the script wanted to die
+                  immediately without any error message */
+               ret = POPs;
+               if (ret != &PL_sv_undef && SvIOK(ret) && SvIV(ret) == 0)
+                       error = "";
        }
 
        PUTBACK;
index f541511c29135825380523a0a2ec8516c1e190e9..05003c0fb2885e25e606e8f0d196d50c60e1efe1 100644 (file)
@@ -175,8 +175,6 @@ static PERL_SIGNAL_ARGS_REC perl_signal_args[] =
     { "message dcc", { "siobject", "string", NULL } },
     { "message dcc action", { "siobject", "string", NULL } },
     { "message dcc ctcp", { "siobject", "string", "string", NULL } },
-    { "mime", { "iobject", "iobject", "siobject", "string", "string", "string", NULL } },
-    { "mime-send", { "iobject", "iobject", "string", "int", "string", "string", NULL } },
 
     { NULL }
 };
index 8d49ac4499a7612a1c5516d068b2a440740603fb..4e7db7b23ef9318092ee89b1ca7d67f1a391b6a8 100644 (file)
@@ -69,6 +69,8 @@ static void perl_statusbar_item_fill_hash(HV *hv, SBAR_ITEM_REC *item)
        hv_store(hv, "max_size", 8, newSViv(item->max_size), 0);
        hv_store(hv, "xpos", 4, newSViv(item->xpos), 0);
        hv_store(hv, "size", 4, newSViv(item->size), 0);
+       if (item->bar->parent_window != NULL)
+               hv_store(hv, "window", 6, plain_bless(item->bar->parent_window->active, "Irssi::UI::Window"), 0);
 }
 
 static PLAIN_OBJECT_INIT_REC textui_plains[] = {
index 64a0567686e67de6940adfecf429fd32ee5daf66..7f1c5277f14470e74be46f9fd68316b93828001f 100644 (file)
@@ -195,7 +195,7 @@ PREINIT:
        char *arglist[MAX_FORMAT_PARAMS+1];
        int n;
 CODE:
-       format_create_dest(&dest, item->server, item->name, level, NULL);
+       format_create_dest(&dest, item->server, item->visible_name, level, NULL);
        memset(arglist, 0, sizeof(arglist));
        for (n = 3; n < items && n < MAX_FORMAT_PARAMS+3; n++) {
                arglist[n-3] = SvPV(ST(n), PL_na);
index cadff1abdf5bfc82e09a59fb72d844f4b2f11763..89d874ee7cb88a8bdbb9e160fa828a3f31f998e7 100644 (file)
@@ -225,6 +225,10 @@ window_activity(window, data_level, hilight_color=NULL)
 char *
 window_get_active_name(window)
        Irssi::UI::Window window
+CODE:
+       RETVAL = (char *) window_get_active_name(window);
+OUTPUT:
+       RETVAL
 
 Irssi::Windowitem
 window_item_find(window, server, name)
@@ -246,7 +250,7 @@ print(item, str, level=MSGLEVEL_CLIENTNOTICE)
        int level
        char *str
 CODE:
-       printtext_string(item->server, item->name, level, str);
+       printtext_string(item->server, item->visible_name, level, str);
 
 Irssi::UI::Window
 window_create(item, automatic)
index 297272ef8902e27d32022d9216326aa3cebd56d0..484c2e492b0998f829631526befd4362394ca09b 100644 (file)
@@ -39,7 +39,6 @@
 #include "fe-common/silc/module-formats.h"
 
 #include "core.h"
-#include "blob.h"
 
 static void 
 silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
@@ -111,20 +110,6 @@ void silc_say_error(char *msg, ...)
   va_end(va);
 }
 
-void silc_emit_mime_sig(SILC_SERVER_REC *server, SILC_CHANNEL_REC *channel,
-                       const char *data, SilcUInt32 data_len,
-                       const char *encoding, const char *type,
-                       const char *nick)
-{
-  BLOB_REC blob;
-
-  blob_fill(&blob);
-  blob.octets = data_len;
-  blob.data = (char *)data;
-
-  signal_emit("mime", 6, server, channel, &blob, encoding, type, nick);
-}
-
 /* Message for a channel. The `sender' is the nickname of the sender 
    received in the packet. The `channel_name' is the name of the channel. */
 
@@ -172,10 +157,6 @@ void silc_channel_message(SilcClient client, SilcClientConnection conn,
        !strstr(type, "text/vnd")) {
       /* It is something textual, display it */
       message = (const unsigned char *)data;
-    } else {
-      silc_emit_mime_sig(server, chanrec, data, data_len, 
-                        enc, type, nick->nick);
-      message = NULL;
     }
   }
 
@@ -254,10 +235,6 @@ void silc_private_message(SilcClient client, SilcClientConnection conn,
        !strstr(type, "text/vnd")) {
       /* It is something textual, display it */
       message = (const unsigned char *)data;
-    } else {
-      silc_emit_mime_sig(server, NULL, data, data_len, 
-                        enc, type, sender->nickname);
-      message = NULL;
     }
   }
 
@@ -1010,8 +987,6 @@ static void silc_client_join_get_users(SilcClient client,
                       MSGLEVEL_CRAP, SILCTXT_CHANNEL_TOPIC,
                       channel->channel_name, chanrec->topic);
 
-  fe_channels_nicklist(CHANNEL(chanrec), CHANNEL_NICKLIST_FLAG_ALL);
-
   if (founder) {
     if (founder == conn->local_entry)
       printformat_module("fe-common/silc", 
@@ -1329,7 +1304,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
 
       chanrec = silc_channel_find(server, channel);
       if (!chanrec)
-       chanrec = silc_channel_create(server, channel, TRUE);
+       chanrec = silc_channel_create(server, channel, channel, TRUE);
 
       if (topic) {
        g_free_not_null(chanrec->topic);
@@ -2185,10 +2160,10 @@ void silc_failure(SilcClient client, SilcClientConnection conn,
    desired (application may start it later by calling the function
    silc_client_perform_key_agreement). */
 
-int silc_key_agreement(SilcClient client, SilcClientConnection conn,
-                      SilcClientEntry client_entry, const char *hostname,
-                      SilcUInt16 port, SilcKeyAgreementCallback *completion,
-                      void **context)
+bool silc_key_agreement(SilcClient client, SilcClientConnection conn,
+                       SilcClientEntry client_entry, const char *hostname,
+                       SilcUInt16 port, SilcKeyAgreementCallback *completion,
+                       void **context)
 {
   char portstr[12];
 
index 9fbf84bcaff5bcb1397676ccd1f2fbfa933df88b..68e2b09eeff3d43bc56ab049d400c3ad0718cac7 100644 (file)
@@ -58,10 +58,10 @@ void silc_get_auth_method(SilcClient client, SilcClientConnection conn,
                          SilcGetAuthMeth completion, void *context);
 void silc_failure(SilcClient client, SilcClientConnection conn, 
                  SilcProtocol protocol, void *failure);
-int silc_key_agreement(SilcClient client, SilcClientConnection conn,
-                      SilcClientEntry client_entry, const char *hostname,
-                      SilcUInt16 port, SilcKeyAgreementCallback *completion,
-                      void **context);
+bool silc_key_agreement(SilcClient client, SilcClientConnection conn,
+                       SilcClientEntry client_entry, const char *hostname,
+                       SilcUInt16 port, SilcKeyAgreementCallback *completion,
+                       void **context);
 void silc_ftp(SilcClient client, SilcClientConnection conn,
              SilcClientEntry client_entry, SilcUInt32 session_id,
              const char *hostname, SilcUInt16 port);
index 8c03fcdbab705a08d08e77dbb19c7ae3b30c6524..04dd65d7af83b9108228ffb67044ba7a1f9d569b 100644 (file)
@@ -31,7 +31,6 @@
 #include "rawlog.h"
 #include "misc.h"
 #include "settings.h"
-#include "blob.h"
 
 #include "channels-setup.h"
 
 
 #include "silc-commands.h"
 
-void sig_mime(SILC_SERVER_REC *server, SILC_CHANNEL_REC *channel,
-             BLOB_REC *blob, const char *enc, const char *type,
-             const char *nick)
-{
-  if (!(IS_SILC_SERVER(server)))
-    return;
-  
-  printformat_module("fe-common/silc", server, 
-                    channel == NULL ? NULL : channel->name,
-                    MSGLEVEL_CRAP, SILCTXT_MESSAGE_DATA,
-                    nick == NULL ? "[<unknown>]" : nick, type);
-}
-
 SILC_CHANNEL_REC *silc_channel_create(SILC_SERVER_REC *server,
-                                     const char *name, int automatic)
+                                     const char *name,
+                                     const char *visible_name,
+                                     int automatic)
 {
   SILC_CHANNEL_REC *rec;
 
@@ -69,10 +57,8 @@ SILC_CHANNEL_REC *silc_channel_create(SILC_SERVER_REC *server,
 
   rec = g_new0(SILC_CHANNEL_REC, 1);
   rec->chat_type = SILC_PROTOCOL;
-  rec->name = g_strdup(name);
-  rec->server = server;
-
-  channel_init((CHANNEL_REC *) rec, automatic);
+  channel_init((CHANNEL_REC *)rec, (SERVER_REC *)server, name, name,
+              automatic);
   return rec;
 }
 
@@ -158,7 +144,7 @@ static void command_part(const char *data, SILC_SERVER_REC *server,
   if (!strcmp(data, "*") || *data == '\0') {
     if (!IS_SILC_CHANNEL(item))
       cmd_return_error(CMDERR_NOT_JOINED);
-    data = item->name;
+    data = item->visible_name;
   }
 
   chanrec = silc_channel_find(server, data);
@@ -209,7 +195,7 @@ static void command_me(const char *data, SILC_SERVER_REC *server,
   if (argc < 2)
     cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS);
 
-  chanrec = silc_channel_find(server, item->name);
+  chanrec = silc_channel_find(server, item->visible_name);
   if (chanrec == NULL) 
     cmd_return_error(CMDERR_CHAN_NOT_FOUND);
 
@@ -334,7 +320,7 @@ static void command_notice(const char *data, SILC_SERVER_REC *server,
   if (argc < 2)
     cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS);
 
-  chanrec = silc_channel_find(server, item->name);
+  chanrec = silc_channel_find(server, item->visible_name);
   if (chanrec == NULL) 
     cmd_return_error(CMDERR_CHAN_NOT_FOUND);
 
@@ -990,7 +976,6 @@ void silc_channels_init(void)
   signal_add("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed);
   signal_add("server connected", (SIGNAL_FUNC) sig_connected);
   signal_add("server quit", (SIGNAL_FUNC) sig_server_quit);
-  signal_add("mime", (SIGNAL_FUNC) sig_mime);
 
   command_bind_silc("part", MODULE_NAME, (SIGNAL_FUNC) command_part);
   command_bind_silc("me", MODULE_NAME, (SIGNAL_FUNC) command_me);
@@ -1008,7 +993,6 @@ void silc_channels_deinit(void)
   signal_remove("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed);
   signal_remove("server connected", (SIGNAL_FUNC) sig_connected);
   signal_remove("server quit", (SIGNAL_FUNC) sig_server_quit);
-  signal_remove("mime", (SIGNAL_FUNC) sig_mime);
 
   command_unbind("part", (SIGNAL_FUNC) command_part);
   command_unbind("me", (SIGNAL_FUNC) command_me);
index b572712c4b8c0cf30d5e8445262424ba544643bb..769621148bea1af85bb9e7af92ac5581c7cd2532 100644 (file)
@@ -28,7 +28,9 @@ void silc_channels_deinit(void);
 
 /* Create new SILC channel record */
 SILC_CHANNEL_REC *silc_channel_create(SILC_SERVER_REC *server,
-                                     const char *name, int automatic);
+                                     const char *name,
+                                     const char *visible_name,
+                                     int automatic);
 SILC_CHANNEL_REC *silc_channel_find_entry(SILC_SERVER_REC *server,
                                          SilcChannelEntry entry);
 
index 9039a5dc5faa6f5b45eb0621c66632cdcf820306..e7725f3c35db54fbe65644102e41c1eed8e945d5 100644 (file)
@@ -444,9 +444,10 @@ void silc_core_init(void)
   rec->create_channel_setup = create_channel_setup;
   rec->create_server_connect = create_server_connect;
   rec->destroy_server_connect = destroy_server_connect;
-  rec->server_connect = (SERVER_REC *(*) (SERVER_CONNECT_REC *))
-    silc_server_connect; 
-  rec->channel_create = (CHANNEL_REC *(*) (SERVER_REC *, const char *, int))
+  rec->server_init_connect = silc_server_init_connect; 
+  rec->server_connect = silc_server_connect;
+  rec->channel_create = (CHANNEL_REC *(*) (SERVER_REC *, const char *, 
+                                          const char *, int))
     silc_channel_create;
   rec->query_create = (QUERY_REC *(*) (const char *, const char *, int))
     silc_query_create;
index dd900ce7426b623dd475ad2233153b1d36d6aa37..c3e4932fa7b2288d087c5b7ae82bd57e0d1f90b3 100644 (file)
@@ -323,33 +323,37 @@ static void sig_disconnected(SILC_SERVER_REC *server)
   }
 }
 
-SILC_SERVER_REC *silc_server_connect(SILC_SERVER_CONNECT_REC *conn){
+SERVER_REC *silc_server_init_connect(SERVER_CONNECT_REC *conn)
+{
   SILC_SERVER_REC *server;
 
   g_return_val_if_fail(IS_SILC_SERVER_CONNECT(conn), NULL);
   if (conn->address == NULL || *conn->address == '\0') 
     return NULL;
   if (conn->nick == NULL || *conn->nick == '\0') {
-    printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, 
-             "Cannot connect: nickname is not set");
+    silc_say_error("Cannot connect: nickname is not set");
     return NULL;
   }
 
   server = g_new0(SILC_SERVER_REC, 1);
   server->chat_type = SILC_PROTOCOL;
-  server->connrec = conn;
+  server->connrec = (SILC_SERVER_CONNECT_REC *)conn;
+  server_connect_ref(conn);
+
   if (server->connrec->port <= 0) 
     server->connrec->port = 706;
 
-  server_connect_ref(SERVER_CONNECT(conn));
+  server_connect_init((SERVER_REC *)server);
+  return (SERVER_REC *)server;
+}
 
-  if (!server_start_connect((SERVER_REC *) server)) {
-    server_connect_unref(SERVER_CONNECT(conn));
+void silc_server_connect(SERVER_REC *server)
+{
+  if (!server_start_connect(server)) {
+    server_connect_unref(server->connrec);
     g_free(server);
-    return NULL;
+    return;
   }
-
-  return server;
 }
 
 /* Return a string of all channels in server in server->channels_join() 
@@ -476,7 +480,7 @@ static void command_self(const char *data, SILC_SERVER_REC *server,
 
   if (IS_SILC_CHANNEL(item)) {
     SILC_CHANNEL_REC *chanrec;
-    chanrec = silc_channel_find(server, item->name);
+    chanrec = silc_channel_find(server, item->visible_name);
     if (chanrec)
       server->conn->current_channel = chanrec->entry;
   }
index 7b319766ee7cfbac09381fc600591e62a1540e56..bf3f3b7066722009fe2b0b6ff863c249083ed325 100644 (file)
@@ -59,7 +59,8 @@ typedef struct {
   SilcUInt32 umode;
 } SILC_SERVER_REC;
 
-SILC_SERVER_REC *silc_server_connect(SILC_SERVER_CONNECT_REC *conn);
+SERVER_REC *silc_server_init_connect(SERVER_CONNECT_REC *conn);
+void silc_server_connect(SERVER_REC *server);
 
 /* Return a string of all channels in server in server->channels_join() 
    format */