Changeset 4f6097e


Ignore:
Timestamp:
Jun 22, 2013, 9:49:49 PM (12 years ago)
Author:
Anders Kaseorg <andersk@mit.edu>
Parents:
96d80e9 (diff), 7f86e3d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:
Merge 7f86e3dd695e4807d0fdd87af08792a3c204e746 into 96d80e9b4aa667605b9c786b0272e1ab04dfbe9b
Files:
36 added
41 deleted
94 edited
1 moved

Legend:

Unmodified
Added
Removed
  • .gitignore

    rf93cc34 r1c22155  
    22*.o
    33*.par
    4 *~
    5 .#*
    6 .*.swp
    74.deps
     5/bin/
    86META.yml
     7MYMETA.yml
    98Makefile
    109Makefile.in
    1110Makefile.old
    1211TAGS
    13 \#*#
    1412aclocal.m4
    1513autom4te.cache
    16 barnowl.bin
    17 tester.bin
    18 zcrypt
     14barnowl
    1915blib
    2016config.cache
    2117config.h
    2218config.h.in
     19config.h.in~
    2320config.log
    2421config.status
     
    2623core
    2724depcomp
     25gmarshal_funcs.c
     26gmarshal_funcs.h
     27inc/
    2828install-sh
    2929jabber.log
     
    3232owl_prototypes.h.new
    3333perlglue.c
    34 perlwrap.c
    3534pm_to_blib
     35runtests.sh.log
     36runtests.sh.trs
    3637stamp-h1
     38test-driver
     39test-suite.log
     40tester
    3741varstubs.c
     42zcrypt
  • AUTHORS

    r1d2c4c3 r80c0fc7  
    33
    44The following people have provided patches or other contributions:
     5  Alex Vandiver
     6  Kevin Chen
     7  Arun Tharuvai
    58  Sam Hartman
    6   Alex Vandiver
    7   Geoffrey Thomas
    89  Derrick Brashear
    910  David Glasser
     11  Eric Price
    1012  Matthew Goldstein
    11   Arun Tharuvai
    12   Kevin Chen
    13   Eric Price
     13  Geoffrey Thomas
     14  Anders Kaseorg
     15  Greg Price
     16  Chris Lesniewski-Laas
     17  Alex Dehnert
     18  Edward Z. Yang
     19  Karl Ramm
     20  Evan Broder
     21  David Benjamin
     22  Cathy Zhang
     23  Joshua Oreman
     24  Leonid Grinberg
     25  Kevin Riggle
     26  Brian Sniffen
     27  William Throwe
     28  Jason Gross
     29  Adam Glasgall
     30  Tim Hill
     31  DD Liu
     32  Betsy Riley
     33  Robert Jacobs
    1434
    15 BarnOwl is based on code from Owl, which was originally primarly
     35BarnOwl is based on code from Owl, which was originally primarily
    1636written by James Kretchmar.  Erik Nygren also made substantial
    17 contributions and improvemnts to the program.
     37contributions and improvements to the program.
    1838
    19 The following people provided patches and other techincal support for
     39The following people provided patches and other technical support for
    2040Owl:
    2141
     
    3050  Mark Eichin
    3151
    32 Mark Eichin is also maintaining the debian package of Owl.
     52Mark Eichin is also maintaining the Debian package of Owl.
    3353
    3454The following people helped with beta testing the earliest versions of
  • COPYING

    rb03c714 rccc182c  
    549549
    550550That's all there is to it!
     551
     552======================================================================
     553
     554Files under perl/modules/Facebook/lib/Facebook are copyright (c) 2010 Plain
     555Black Corporation.
     556
     557This software is copyright (c) 2010 by Plain Black Corporation.
     558
     559This is free software; you can redistribute it and/or modify it under
     560the same terms as the Perl 5 programming language system itself.
     561
     562Terms of the Perl programming language system itself
     563
     564a) the GNU General Public License as published by the Free
     565   Software Foundation; either version 1, or (at your option) any
     566   later version, or
     567b) the "Artistic License"
     568
     569--- The GNU General Public License, Version 1, February 1989 ---
     570
     571This software is Copyright (c) 2010 by Plain Black Corporation.
     572
     573This is free software, licensed under:
     574
     575  The GNU General Public License, Version 1, February 1989
     576
     577                    GNU GENERAL PUBLIC LICENSE
     578                     Version 1, February 1989
     579
     580 Copyright (C) 1989 Free Software Foundation, Inc.
     581                    51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     582
     583 Everyone is permitted to copy and distribute verbatim copies
     584 of this license document, but changing it is not allowed.
     585
     586                            Preamble
     587
     588  The license agreements of most software companies try to keep users
     589at the mercy of those companies.  By contrast, our General Public
     590License is intended to guarantee your freedom to share and change free
     591software--to make sure the software is free for all its users.  The
     592General Public License applies to the Free Software Foundation's
     593software and to any other program whose authors commit to using it.
     594You can use it for your programs, too.
     595
     596  When we speak of free software, we are referring to freedom, not
     597price.  Specifically, the General Public License is designed to make
     598sure that you have the freedom to give away or sell copies of free
     599software, that you receive source code or can get it if you want it,
     600that you can change the software or use pieces of it in new free
     601programs; and that you know you can do these things.
     602
     603  To protect your rights, we need to make restrictions that forbid
     604anyone to deny you these rights or to ask you to surrender the rights.
     605These restrictions translate to certain responsibilities for you if you
     606distribute copies of the software, or if you modify it.
     607
     608  For example, if you distribute copies of a such a program, whether
     609gratis or for a fee, you must give the recipients all the rights that
     610you have.  You must make sure that they, too, receive or can get the
     611source code.  And you must tell them their rights.
     612
     613  We protect your rights with two steps: (1) copyright the software, and
     614(2) offer you this license which gives you legal permission to copy,
     615distribute and/or modify the software.
     616
     617  Also, for each author's protection and ours, we want to make certain
     618that everyone understands that there is no warranty for this free
     619software.  If the software is modified by someone else and passed on, we
     620want its recipients to know that what they have is not the original, so
     621that any problems introduced by others will not reflect on the original
     622authors' reputations.
     623
     624  The precise terms and conditions for copying, distribution and
     625modification follow.
     626
     627                    GNU GENERAL PUBLIC LICENSE
     628   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
     629
     630  0. This License Agreement applies to any program or other work which
     631contains a notice placed by the copyright holder saying it may be
     632distributed under the terms of this General Public License.  The
     633"Program", below, refers to any such program or work, and a "work based
     634on the Program" means either the Program or any work containing the
     635Program or a portion of it, either verbatim or with modifications.  Each
     636licensee is addressed as "you".
     637
     638  1. You may copy and distribute verbatim copies of the Program's source
     639code as you receive it, in any medium, provided that you conspicuously and
     640appropriately publish on each copy an appropriate copyright notice and
     641disclaimer of warranty; keep intact all the notices that refer to this
     642General Public License and to the absence of any warranty; and give any
     643other recipients of the Program a copy of this General Public License
     644along with the Program.  You may charge a fee for the physical act of
     645transferring a copy.
     646
     647  2. You may modify your copy or copies of the Program or any portion of
     648it, and copy and distribute such modifications under the terms of Paragraph
     6491 above, provided that you also do the following:
     650
     651    a) cause the modified files to carry prominent notices stating that
     652    you changed the files and the date of any change; and
     653
     654    b) cause the whole of any work that you distribute or publish, that
     655    in whole or in part contains the Program or any part thereof, either
     656    with or without modifications, to be licensed at no charge to all
     657    third parties under the terms of this General Public License (except
     658    that you may choose to grant warranty protection to some or all
     659    third parties, at your option).
     660
     661    c) If the modified program normally reads commands interactively when
     662    run, you must cause it, when started running for such interactive use
     663    in the simplest and most usual way, to print or display an
     664    announcement including an appropriate copyright notice and a notice
     665    that there is no warranty (or else, saying that you provide a
     666    warranty) and that users may redistribute the program under these
     667    conditions, and telling the user how to view a copy of this General
     668    Public License.
     669
     670    d) You may charge a fee for the physical act of transferring a
     671    copy, and you may at your option offer warranty protection in
     672    exchange for a fee.
     673
     674Mere aggregation of another independent work with the Program (or its
     675derivative) on a volume of a storage or distribution medium does not bring
     676the other work under the scope of these terms.
     677
     678  3. You may copy and distribute the Program (or a portion or derivative of
     679it, under Paragraph 2) in object code or executable form under the terms of
     680Paragraphs 1 and 2 above provided that you also do one of the following:
     681
     682    a) accompany it with the complete corresponding machine-readable
     683    source code, which must be distributed under the terms of
     684    Paragraphs 1 and 2 above; or,
     685
     686    b) accompany it with a written offer, valid for at least three
     687    years, to give any third party free (except for a nominal charge
     688    for the cost of distribution) a complete machine-readable copy of the
     689    corresponding source code, to be distributed under the terms of
     690    Paragraphs 1 and 2 above; or,
     691
     692    c) accompany it with the information you received as to where the
     693    corresponding source code may be obtained.  (This alternative is
     694    allowed only for noncommercial distribution and only if you
     695    received the program in object code or executable form alone.)
     696
     697Source code for a work means the preferred form of the work for making
     698modifications to it.  For an executable file, complete source code means
     699all the source code for all modules it contains; but, as a special
     700exception, it need not include source code for modules which are standard
     701libraries that accompany the operating system on which the executable
     702file runs, or for standard header files or definitions files that
     703accompany that operating system.
     704
     705  4. You may not copy, modify, sublicense, distribute or transfer the
     706Program except as expressly provided under this General Public License.
     707Any attempt otherwise to copy, modify, sublicense, distribute or transfer
     708the Program is void, and will automatically terminate your rights to use
     709the Program under this License.  However, parties who have received
     710copies, or rights to use copies, from you under this General Public
     711License will not have their licenses terminated so long as such parties
     712remain in full compliance.
     713
     714  5. By copying, distributing or modifying the Program (or any work based
     715on the Program) you indicate your acceptance of this license to do so,
     716and all its terms and conditions.
     717
     718  6. Each time you redistribute the Program (or any work based on the
     719Program), the recipient automatically receives a license from the original
     720licensor to copy, distribute or modify the Program subject to these
     721terms and conditions.  You may not impose any further restrictions on the
     722recipients' exercise of the rights granted herein.
     723
     724  7. The Free Software Foundation may publish revised and/or new versions
     725of the General Public License from time to time.  Such new versions will
     726be similar in spirit to the present version, but may differ in detail to
     727address new problems or concerns.
     728
     729Each version is given a distinguishing version number.  If the Program
     730specifies a version number of the license which applies to it and "any
     731later version", you have the option of following the terms and conditions
     732either of that version or of any later version published by the Free
     733Software Foundation.  If the Program does not specify a version number of
     734the license, you may choose any version ever published by the Free Software
     735Foundation.
     736
     737  8. If you wish to incorporate parts of the Program into other free
     738programs whose distribution conditions are different, write to the author
     739to ask for permission.  For software which is copyrighted by the Free
     740Software Foundation, write to the Free Software Foundation; we sometimes
     741make exceptions for this.  Our decision will be guided by the two goals
     742of preserving the free status of all derivatives of our free software and
     743of promoting the sharing and reuse of software generally.
     744
     745                            NO WARRANTY
     746
     747  9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
     748FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
     749OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
     750PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
     751OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     752MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
     753TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
     754PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
     755REPAIR OR CORRECTION.
     756
     757  10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
     758WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
     759REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
     760INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
     761OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
     762TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
     763YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
     764PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
     765POSSIBILITY OF SUCH DAMAGES.
     766
     767                     END OF TERMS AND CONDITIONS
     768
     769        Appendix: How to Apply These Terms to Your New Programs
     770
     771  If you develop a new program, and you want it to be of the greatest
     772possible use to humanity, the best way to achieve this is to make it
     773free software which everyone can redistribute and change under these
     774terms.
     775
     776  To do so, attach the following notices to the program.  It is safest to
     777attach them to the start of each source file to most effectively convey
     778the exclusion of warranty; and each file should have at least the
     779"copyright" line and a pointer to where the full notice is found.
     780
     781    <one line to give the program's name and a brief idea of what it does.>
     782    Copyright (C) 19yy  <name of author>
     783
     784    This program is free software; you can redistribute it and/or modify
     785    it under the terms of the GNU General Public License as published by
     786    the Free Software Foundation; either version 1, or (at your option)
     787    any later version.
     788
     789    This program is distributed in the hope that it will be useful,
     790    but WITHOUT ANY WARRANTY; without even the implied warranty of
     791    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     792    GNU General Public License for more details.
     793
     794    You should have received a copy of the GNU General Public License
     795    along with this program; if not, write to the Free Software
     796    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
     797
     798
     799Also add information on how to contact you by electronic and paper mail.
     800
     801If the program is interactive, make it output a short notice like this
     802when it starts in an interactive mode:
     803
     804    Gnomovision version 69, Copyright (C) 19xx name of author
     805    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
     806    This is free software, and you are welcome to redistribute it
     807    under certain conditions; type `show c' for details.
     808
     809The hypothetical commands `show w' and `show c' should show the
     810appropriate parts of the General Public License.  Of course, the
     811commands you use may be called something other than `show w' and `show
     812c'; they could even be mouse-clicks or menu items--whatever suits your
     813program.
     814
     815You should also get your employer (if you work as a programmer) or your
     816school, if any, to sign a "copyright disclaimer" for the program, if
     817necessary.  Here a sample; alter the names:
     818
     819  Yoyodyne, Inc., hereby disclaims all copyright interest in the
     820  program `Gnomovision' (a program to direct compilers to make passes
     821  at assemblers) written by James Hacker.
     822
     823  <signature of Ty Coon>, 1 April 1989
     824  Ty Coon, President of Vice
     825
     826That's all there is to it!
     827
     828
     829--- The Artistic License 1.0 ---
     830
     831This software is Copyright (c) 2010 by Plain Black Corporation.
     832
     833This is free software, licensed under:
     834
     835  The Artistic License 1.0
     836
     837The Artistic License
     838
     839Preamble
     840
     841The intent of this document is to state the conditions under which a Package
     842may be copied, such that the Copyright Holder maintains some semblance of
     843artistic control over the development of the package, while giving the users of
     844the package the right to use and distribute the Package in a more-or-less
     845customary fashion, plus the right to make reasonable modifications.
     846
     847Definitions:
     848
     849  - "Package" refers to the collection of files distributed by the Copyright
     850    Holder, and derivatives of that collection of files created through
     851    textual modification.
     852  - "Standard Version" refers to such a Package if it has not been modified,
     853    or has been modified in accordance with the wishes of the Copyright
     854    Holder.
     855  - "Copyright Holder" is whoever is named in the copyright or copyrights for
     856    the package.
     857  - "You" is you, if you're thinking about copying or distributing this Package.
     858  - "Reasonable copying fee" is whatever you can justify on the basis of media
     859    cost, duplication charges, time of people involved, and so on. (You will
     860    not be required to justify it to the Copyright Holder, but only to the
     861    computing community at large as a market that must bear the fee.)
     862  - "Freely Available" means that no fee is charged for the item itself, though
     863    there may be fees involved in handling the item. It also means that
     864    recipients of the item may redistribute it under the same conditions they
     865    received it.
     866
     8671. You may make and give away verbatim copies of the source form of the
     868Standard Version of this Package without restriction, provided that you
     869duplicate all of the original copyright notices and associated disclaimers.
     870
     8712. You may apply bug fixes, portability fixes and other modifications derived
     872from the Public Domain or from the Copyright Holder. A Package modified in such
     873a way shall still be considered the Standard Version.
     874
     8753. You may otherwise modify your copy of this Package in any way, provided that
     876you insert a prominent notice in each changed file stating how and when you
     877changed that file, and provided that you do at least ONE of the following:
     878
     879  a) place your modifications in the Public Domain or otherwise make them
     880     Freely Available, such as by posting said modifications to Usenet or an
     881     equivalent medium, or placing the modifications on a major archive site
     882     such as ftp.uu.net, or by allowing the Copyright Holder to include your
     883     modifications in the Standard Version of the Package.
     884
     885  b) use the modified Package only within your corporation or organization.
     886
     887  c) rename any non-standard executables so the names do not conflict with
     888     standard executables, which must also be provided, and provide a separate
     889     manual page for each non-standard executable that clearly documents how it
     890     differs from the Standard Version.
     891
     892  d) make other distribution arrangements with the Copyright Holder.
     893
     8944. You may distribute the programs of this Package in object code or executable
     895form, provided that you do at least ONE of the following:
     896
     897  a) distribute a Standard Version of the executables and library files,
     898     together with instructions (in the manual page or equivalent) on where to
     899     get the Standard Version.
     900
     901  b) accompany the distribution with the machine-readable source of the Package
     902     with your modifications.
     903
     904  c) accompany any non-standard executables with their corresponding Standard
     905     Version executables, giving the non-standard executables non-standard
     906     names, and clearly documenting the differences in manual pages (or
     907     equivalent), together with instructions on where to get the Standard
     908     Version.
     909
     910  d) make other distribution arrangements with the Copyright Holder.
     911
     9125. You may charge a reasonable copying fee for any distribution of this
     913Package.  You may charge any fee you choose for support of this Package. You
     914may not charge a fee for this Package itself. However, you may distribute this
     915Package in aggregate with other (possibly commercial) programs as part of a
     916larger (possibly commercial) software distribution provided that you do not
     917advertise this Package as a product of your own.
     918
     9196. The scripts and library files supplied as input to or produced as output
     920from the programs of this Package do not automatically fall under the copyright
     921of this Package, but belong to whomever generated them, and may be sold
     922commercially, and may be aggregated with this Package.
     923
     9247. C or perl subroutines supplied by you and linked into this Package shall not
     925be considered part of this Package.
     926
     9278. The name of the Copyright Holder may not be used to endorse or promote
     928products derived from this software without specific prior written permission.
     929
     9309. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
     931WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
     932MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
     933
     934The End
  • ChangeLog

    r2ff0693 r1b17f50  
     11.9
     2 * Add getnumlines() to perl interface -asedeno@mit.edu
     3 * Include names of invalid filters on filter errors -adehnert@mit.edu
     4 * Don't incorrectly mark decryption failures as decrypted -davidben@mit.edu
     5 * Hide the default cursor when possible -davidben@mit.edu
     6 * Complete viewperson and vp as viewuser and vu -davidben@mit.edu
     7 * Set z_charset = ZCHARSET_UTF_8 -andersk@mit.edu
     8 * Allow zsender spoofing on cross-realm classes -andersk@mit.edu
     9 * Append the realm to the zsender if missing -andersk@mit.edu
     10 * Redisplay on setting colorztext -jgross@mit.edu
     11 * Rename default config file to .owl/init.pl -kevinr@free-dissociation.com
     12 * Add completion for jabberlogout -adehnert@mit.edu
     13 * Switch to interactive context before sourcing the startup file -davidben@mit.edu
     14 * Add completion for reload-module -adehnert@mit.edu
     15 * editwin callback for canceling the editwin -jgross@mit.edu
     16 * Fix dirtying windows inside a redraw handler -davidben@mit.edu
     17 * Facebook module -ezyang@mit.edu
     18 * Complete unstartup command just like startup command -jgross@mit.edu
     19 * Fix the description of disable-ctrl-d -jgross@mit.edu
     20 * Use wbkgrndset instead of wbkgdset in _owl_fmtext_wcolor_set -davidben@mit.edu
     21 * Show the time zone in :info -jgross@mit.edu
     22 * Treat [!.?]" as end of sentence in edit:fill-paragraph -jgross@mit.edu
     23 * Correctly display multiline fields in :info -jgross@mit.edu
     24
     251.8.1
     26 * Only add outgoing messages for personal part of half-personal messages -andersk@mit.edu
     27 * Don’t write CC: line on zwrite -C '' -andersk@mit.edu
     28 * Don’t send public pings on zwrite '' or zwrite @REALM -andersk@mit.edu
     29 * Don’t treat zwrite '' as personal -andersk@mit.edu
     30 * Stop pretending to support zwrite * -andersk@mit.edu
     31 * Show foreign realms on non-personal zephyrs like Owl did -andersk@mit.edu
     32 * Fix memory leak in zcrypt -davidben@mit.edu
     33 * Don't attempt to switch filters in :view -d if invalid -davidben@mit.edu
     34 * Fixed typo in unbindkey usage error -rileyb@mit.edu
     35 * Fix bug generating filter text in 256-color mode -asedeno@mit.edu
     36 * Remove ^noc from reply-lockout -geofft@mit.edu
     37 * Avoid quadratic loops when receiving zephyrs -andersk@mit.edu
     38 * Fix hang on empty zcrypt messages -adehnert@MIT.EDU
     39
     401.8
     41 * Compute the home directory in zcrypt consistently with BarnOwl -davidben@mit.edu
     42 * Make help show the correct keybinding for A -jgross@mit.edu
     43 * Add a delete-and-expunge command. -jgross@mit.edu
     44 * Fix a bug in the expunge command -jgross@mit.edu
     45 * Replace 'Owl' with 'BarnOwl' in user visible places -jgross@mit.edu
     46 * Allow zsigs to be '0' -jgross@mit.edu
     47 * Reformat the man page to look more like others -davidben@mit.edu
     48 * Consistently use BarnOwl or barnowl -davidben@mit.edu
     49 * Update autoconf macros -andersk@mit.edu
     50 * history: Do not deduplicate a partial entry -andersk@mit.edu
     51 * Drop show timers feature -davidben@mit.edu
     52 * Add new dependencies, AnyEvent and perl-Glib -davidben@mit.edu
     53 * Bump required glib version to 2.16 -davidben@mit.edu
     54 * Don't leak timestr when setting time in a perl message -asedeno@mit.edu
     55 * Build with -Wwrite-strings -andersk@mit.edu
     56 * Build with C99 -davidben@mit.edu
     57 * Jabber: Handle nicks with leading dashes (e.g. Facebook XMPP) -ezyang@mit.edu
     58 * Move log-writing onto a background thread. -adam@crossproduct.net
     59 * Remove the length limit on field values in :info -jgross@mit.edu
     60 * Show how far you are in a long message -jgross@mit.edu
     61 * stderr_redirect_handler: Handle partial or failed reads -andersk@mit.edu
     62 * Inform the user when an unpunt command does nothing -davidben@mit.edu
     63 * Replace custom event loop with GLib's GMainLoop -davidben@mit.edu
     64 * Encode glib version requirements in pkg-config check -asedeno@mit.edu
     65 * Fix color pair usage on ncurses builds without ext-color -davidben@mit.edu
     66 * IRC: Fix reconnect behavior. -nelhage@mit.edu
     67 * IRC: Make nick-change events LOGIN messages instead of ADMIN. -nelhage@mit.edu
     68 * IRC: Port module to AnyEvent::IRC. -asedeno@mit.edu, nelhage@nelhage.com
     69 * Ability to set exposure arbitrarily (like "zctl set exposure") -jgross@mit.edu
     70 * Kill --remove-debug option -davidben@mit.edu
     71 * exec: Fix input redirection of multistatement commands -andersk@mit.edu
     72 * Correctly set the realm in outgoing zwrite errors -davidben@mit.edu
     73 * Correctly compute the realm for outgoing messages -davidben@mit.edu
     74 * In duplicated outgoing zephyrs only reply on the relevant recipient -davidben@mit.edu
     75 * Create per-recipient copies of outgoing messages for non-CC'd personals -liudi@mit.edu
     76 * Add black to :show colors -andersk@mit.edu
     77 * Fix reporting of errors from libzephyr -kcr@1ts.org
     78 * Load Encode module for IRC. -timhill@alum.mit.edu
     79 * IRC: Sort the output of :irc-names -nelhage@mit.edu
     80 * Prepend "UNAUTH: " to displayed sender for unauthenticated zephyrs -adam@crossproduct.net
     81 * For ‘punt’ with one argument, quote the filter name -andersk@mit.edu
     82 * Fix spurious error running ‘punt’ with no arguments -andersk@mit.edu
     83 * Only handle CCs in messages sent directly to you. -davidben@mit.edu
     84 * Update copyright notices for 2011 -davidben@mit.edu
     85 * If a smartfilter fails to parse, handle the error -davidben@mit.edu
     86 * Replace per-editwin killbuf with a global one. -adam@crossproduct.net
     87 * Don't use error_message if we are building without Zephyr. -nelhage@mit.edu
     88 * Fix replying to outgoing zwrite when -m is passed -davidben@mit.edu
     89 * Fix a number of quoting bugs -davidben@mit.edu
     90 * Check passwd entries to determine home dir -davidben@mit.edu
     91
     921.7.1
     93 * Append sender's realm to CC'd unqualified names when replying. -adam@crossproduct.net
     94 * Don't reset ncurses colorpairs in the middle of drawing. -davidben@mit.edu
     95 * Fix viewuser when an unqualified name is given. -davidben@mit.edu
     96
    1971.7
     98 * Fix quoting bugs in smartfilter, zpunt, and numerous other commands. -davidben@mit.edu
    299 * Download Twitter consumer keys from barnowl.mit.edu. -nelhage@MIT.EDU
    3100 * Fix unsub when .zephyr.subs is a symlink. -jgross@MIT.EDU
  • Makefile.am

    r3535a6e ra223b6b  
    44GIT_FLAGS := $(if $(GIT_DESCRIPTION),-DGIT_VERSION=$(GIT_DESCRIPTION:barnowl-%=%))
    55
    6 bin_PROGRAMS = barnowl.bin
     6bin_PROGRAMS = bin/barnowl
    77if ENABLE_ZCRYPT
    88bin_PROGRAMS += zcrypt
     
    1111zcrypt_SOURCES = zcrypt.c filterproc.c
    1212
    13 check_PROGRAMS = tester.bin
     13check_PROGRAMS = bin/tester
     14dist_check_DATA = t
     15dist_check_SCRIPTS = runtests.sh
    1416
    15 barnowl_bin_SOURCES = $(BASE_SRCS) \
    16      owl.h owl_perl.h config.h \
    17      owl.c \
    18      $(GEN_C) $(GEN_H)
     17noinst_SCRIPTS = barnowl
     18check_SCRIPTS = tester
    1919
    20 man_MANS = doc/barnowl.1
    21 doc_DATA = doc/intro.txt doc/advanced.txt
     20barnowl tester: %: barnowl-wrapper.in bin/% Makefile
     21        sed \
     22            -e 's,[@]abs_srcdir[@],$(abs_srcdir),g' \
     23            -e 's,[@]abs_builddir[@],$(abs_builddir),g' \
     24            $< > $@
     25        chmod +x $@
    2226
    23 barnowl_bin_LDADD = compat/libcompat.a libfaim/libfaim.a
     27bin_barnowl_SOURCES = $(BASE_SRCS) \
     28     owl.h owl_perl.h \
     29     owl.c
     30nodist_bin_barnowl_SOURCES = $(GEN_C) $(GEN_H)
    2431
    25 tester_bin_SOURCES = $(BASE_SRCS) \
    26      owl.h owl_perl.h config.h \
    27      $(GEN_C) $(GEN_H) \
     32dist_man_MANS = doc/barnowl.1
     33dist_doc_DATA = doc/intro.txt doc/advanced.txt
     34
     35bin_barnowl_LDADD = compat/libcompat.a libfaim/libfaim.a
     36
     37bin_tester_SOURCES = $(BASE_SRCS) \
     38     owl.h owl_perl.h \
    2839     tester.c
     40nodist_bin_tester_SOURCES = $(GEN_C) $(GEN_H)
    2941
    30 tester_bin_LDADD = compat/libcompat.a libfaim/libfaim.a
     42bin_tester_LDADD = compat/libcompat.a libfaim/libfaim.a
    3143
    3244TESTS=runtests.sh
    3345
    34 AM_CPPFLAGS = -I$(top_srcdir)/ \
     46AM_CPPFLAGS = \
    3547           -I$(top_srcdir)/libfaim/ \
    3648           -DDATADIR='"$(pkgdatadir)"' \
     
    3850           $(GIT_FLAGS)
    3951
    40 CODELIST_SRCS=list.c message.c mainwin.c popwin.c zephyr.c messagelist.c \
    41      commands.c global.c text.c fmtext.c editwin.c util.c logging.c \
     52CODELIST_SRCS=message.c mainwin.c popwin.c zephyr.c messagelist.c \
     53     commands.c global.c text.c fmtext.c editwin.c \
     54     util.c logging.c \
    4255     perlconfig.c keys.c functions.c zwrite.c viewwin.c help.c filter.c \
    4356     regex.c history.c view.c dict.c variable.c filterelement.c pair.c \
     
    4558     aim.c buddy.c buddylist.c style.c errqueue.c \
    4659     zbuddylist.c popexec.c select.c wcwidth.c \
    47      glib_compat.c mainpanel.c msgwin.c sepbar.c editcontext.c signal.c
     60     mainpanel.c msgwin.c sepbar.c editcontext.c signal.c closures.c
    4861
    49 NORMAL_SRCS = filterproc.c window.c windowcb.c
     62NORMAL_SRCS = filterproc.c filterproc.h window.c window.h windowcb.c
    5063
    5164BASE_SRCS = $(CODELIST_SRCS) $(NORMAL_SRCS)
    5265
    53 GEN_C = varstubs.c perlglue.c
    54 GEN_H = owl_prototypes.h
     66GEN_C = varstubs.c perlglue.c gmarshal_funcs.c
     67GEN_H = owl_prototypes.h owl_prototypes.h.new gmarshal_funcs.h
    5568
    5669BUILT_SOURCES = $(GEN_C) $(GEN_H)
     
    6578proto: owl_prototypes.h
    6679
    67 perlglue.c: perlglue.xs $(TYPEMAP)
    68         $(AM_V_GEN)perl $(XSUBPPDIR)/xsubpp $(XSUBPPFLAGS) -prototypes perlglue.xs > perlglue.c
     80perlglue.c: perlglue.xs typemap
     81        $(AM_V_GEN)perl $(XSUBPPDIR)/xsubpp $(XSUBPPFLAGS) -prototypes $< > $@
    6982
    7083varstubs.c: stubgen.pl variable.c
     
    7487        $(AM_V_GEN)perl $< $(sort $(filter-out $<,$+)) > $@
    7588
     89gmarshal_funcs.h: marshal_types
     90        glib-genmarshal --header $< > $@
     91gmarshal_funcs.c: marshal_types
     92        glib-genmarshal --body $< > $@
     93
    7694# For emacs flymake-mode
    7795check-syntax: proto
    7896        $(COMPILE) -Wall -Wextra -pedantic -fsyntax-only $(CHK_SOURCES)
    7997
    80 install-data-local:
    81         $(mkinstalldirs) ${DESTDIR}${pkgdatadir}/lib
    82         (cd perl/lib && tar -cf - . ) | (cd ${DESTDIR}${pkgdatadir}/lib && tar -xf - )
    83 
    84 do_transform = $(shell echo '$(1)' | sed '$(transform)')
    85 install-exec-hook:
    86         mv -f $(DESTDIR)$(bindir)/$(call do_transform,barnowl.bin) \
    87               $(DESTDIR)$(bindir)/$(call do_transform,barnowl)
     98CLEANFILES = $(BUILT_SOURCES) $(noinst_SCRIPTS) $(check_SCRIPTS)
     99EXTRA_DIST = \
     100    autogen.sh \
     101    barnowl-wrapper.in \
     102    codelist.pl \
     103    doc/code.txt \
     104    doc/owl-window.txt \
     105    doc/releasing-barnowl.txt \
     106    examples \
     107    marshal_types \
     108    perlglue.xs \
     109    scripts \
     110    stubgen.pl \
     111    typemap
    88112
    89113SUBDIRS = compat libfaim perl
  • README

    r13ee8f2 r1c22155  
    77Notes:
    88-----
    9 This project's perl/lib/ contains the lib directories from the
     9This project's perl/modules/ contains the lib directories from the
    1010following CPAN modules:
    1111
     12Facebook::Graph
    1213Net::Jabber
    1314Net::XMPP
    1415XML::Stream
    1516
    16 They have been modified slightly for the needs of this project.
     17Some have been modified slightly for the needs of this project.
    1718
    1819BarnOwl currently requires the following perl modules off of CPAN:
    1920
    2021AnyEvent
     22Class::Accessor
     23ExtUtils::Depends
     24Glib
     25Module::Install
    2126PAR
    22 Net::DNS
    23 Authen::SASL::Perl
    24 IO::Socket::SSL
    25 Digest::SHA1
    2627
    2728(Note that these are all available as Debian packages)
     
    2930these for you.
    3031
     32The Facebook module requires:
     33
     34Any::Moose
     35AnyEvent::HTTP
     36DateTime
     37DateTime::Format::Strptime
     38JSON
     39MIME::Base64::URLSafe
     40Ouch
     41URI
     42URI::Encode
     43
    3144The IRC module requires:
    3245
    3346AnyEvent::IRC
    34 Class::Accessor
     47
     48The Jabber module requires:
     49
     50Net::DNS
     51Authen::SASL::Perl
     52IO::Socket::SSL
     53Digest::SHA
     54
     55The Twitter module requires:
     56
     57HTML::Entities
     58Net::Twitter::Lite
    3559
    3660The WordWrap module requires:
  • aim.c

    rdc1edbd r8258ea5  
    1 #include <stdio.h>
    2 #include <stdio.h>
    3 #include <sys/stat.h>
    41#include "owl.h"
    52
     
    113110}
    114111
    115 void owl_aim_send_nop(owl_timer *t, void *data) {
    116     if(owl_global_is_doaimevents(&g)) {
    117         aim_session_t *sess = owl_global_get_aimsess(&g);
    118         aim_flap_nop(sess, aim_getconn_type(sess, AIM_CONN_TYPE_BOS));
    119     }
     112gboolean owl_aim_send_nop(gpointer data) {
     113  owl_global *g = data;
     114  if (owl_global_is_doaimevents(g)) {
     115    aim_session_t *sess = owl_global_get_aimsess(g);
     116    aim_flap_nop(sess, aim_getconn_type(sess, AIM_CONN_TYPE_BOS));
     117  }
     118  return TRUE;
    120119}
    121120
     
    183182  owl_function_debugmsg("owl_aim_login: connecting");
    184183
    185   g.aim_nop_timer = owl_select_add_timer("owl_aim_send_nop", 30, 30, owl_aim_send_nop, NULL, NULL);
     184  g.aim_nop_timer = g_timeout_add_seconds(30, owl_aim_send_nop, &g);
    186185
    187186  return(0);
    188187}
    189188
    190 static void owl_aim_unset_ignorelogin(owl_timer *t, void *data)
    191 {
    192     owl_global_unset_ignore_aimlogin(&g);
     189static gboolean owl_aim_unset_ignorelogin(void *data)
     190{
     191  owl_global *g = data;
     192  owl_global_unset_ignore_aimlogin(g);
     193  return FALSE;  /* only run once. */
    193194}
    194195
     
    209210  /* start the ingorelogin timer */
    210211  owl_global_set_ignore_aimlogin(&g);
    211   owl_select_add_timer("owl_aim_unset_ignorelogin",
    212                        owl_global_get_aim_ignorelogin_timer(&g),
    213                        0, owl_aim_unset_ignorelogin, NULL, NULL);
     212  g_timeout_add_seconds(owl_global_get_aim_ignorelogin_timer(&g),
     213                        owl_aim_unset_ignorelogin, &g);
    214214
    215215  /* aim_ssi_setpresence(owl_global_get_aimsess(&g), 0x00000400); */
     
    225225  owl_global_set_aimnologgedin(&g);
    226226  owl_global_set_no_doaimevents(&g);
    227   owl_select_remove_timer(g.aim_nop_timer);
     227  if (g.aim_nop_timer) {
     228    g_source_remove(g.aim_nop_timer);
     229    g.aim_nop_timer = 0;
     230  }
    228231}
    229232
     
    244247  owl_global_set_aimnologgedin(&g);
    245248  owl_global_set_no_doaimevents(&g);
    246   owl_select_remove_timer(g.aim_nop_timer);
     249  if (g.aim_nop_timer) {
     250    g_source_remove(g.aim_nop_timer);
     251    g.aim_nop_timer = 0;
     252  }
    247253}
    248254
     
    428434
    429435/* caller must free the return */
    430 char *owl_aim_normalize_screenname(const char *in)
     436CALLER_OWN char *owl_aim_normalize_screenname(const char *in)
    431437{
    432438  char *out;
     
    701707{
    702708  aim_clientready(sess, fr->conn);
    703   owl_function_debugmsg("conninitdone_admin: initializtion done for admin connection");
     709  owl_function_debugmsg("conninitdone_admin: initialization done for admin connection");
    704710  return(1);
    705711}
     
    830836  params = va_arg(ap, struct aim_icbmparameters *);
    831837  va_end(ap);
    832  
    833   owl_function_debugmsg("faimtest_icbmparaminfo: ICBM Parameters: maxchannel = %d, default flags = 0x%08x, max msg len = %d, max sender evil = %f, max reciever evil = %f, min msg interval = %u",
     838
     839  owl_function_debugmsg("faimtest_icbmparaminfo: ICBM Parameters: maxchannel = %d, default flags = 0x%08x, max msg len = %d, max sender evil = %f, max receiver evil = %f, min msg interval = %u",
    834840                       params->maxchan, params->flags, params->maxmsglen, ((float)params->maxsenderwarn)/10.0, ((float)params->maxrecverwarn)/10.0, params->minmsginterval);
    835841     
     
    10551061  g_free(wrapmsg);
    10561062  g_free(nz_screenname);
     1063  g_free(realmsg);
    10571064
    10581065  return(1);
    10591066
    1060   owl_function_debugmsg("faimtest_parse_incoming_im_chan1: icbm: message: %s\n", realmsg);
    1061  
    1062   if (args->icbmflags & AIM_IMFLAGS_MULTIPART) {
    1063     aim_mpmsg_section_t *sec;
    1064     int z;
    1065 
    1066     owl_function_debugmsg("faimtest_parse_incoming_im_chan1: icbm: multipart: this message has %d parts\n", args->mpmsg.numparts);
    1067    
    1068     for (sec = args->mpmsg.parts, z = 0; sec; sec = sec->next, z++) {
    1069       if ((sec->charset == 0x0000) || (sec->charset == 0x0003) || (sec->charset == 0xffff)) {
    1070         owl_function_debugmsg("faimtest_parse_incoming_im_chan1: icbm: multipart:   part %d: charset 0x%04x, subset 0x%04x, msg = %s\n", z, sec->charset, sec->charsubset, sec->data);
    1071       } else {
    1072         owl_function_debugmsg("faimtest_parse_incoming_im_chan1: icbm: multipart:   part %d: charset 0x%04x, subset 0x%04x, binary or UNICODE data\n", z, sec->charset, sec->charsubset);
    1073       }
    1074     }
    1075   }
    1076  
    1077   if (args->icbmflags & AIM_IMFLAGS_HASICON) {
    1078     /* aim_send_im(sess, userinfo->sn, AIM_IMFLAGS_BUDDYREQ, "You have an icon"); */
    1079     owl_function_debugmsg("faimtest_parse_incoming_im_chan1: icbm: their icon: iconstamp = %ld, iconlen = 0x%08x, iconsum = 0x%04x\n", args->iconstamp, args->iconlen, args->iconsum);
    1080   }
    1081 
    1082   g_free(realmsg);
    1083 
    1084   return(1);
     1067  /* TODO: Multipart? See history from before 1.8 release. */
    10851068}
    10861069
     
    14301413  const char *address, *SNs;
    14311414  int num, i;
    1432   owl_list list;
     1415  GPtrArray *list;
    14331416 
    14341417  va_start(ap, fr);
     
    14381421  va_end(ap);
    14391422
    1440   owl_list_create(&list);
     1423  list = g_ptr_array_new();
    14411424 
    14421425  owl_function_debugmsg("faimtest_parse_searchreply: E-Mail Search Results for %s: ", address);
    14431426  for (i=0; i<num; i++) {
    14441427    owl_function_debugmsg("  %s", &SNs[i*(MAXSNLEN+1)]);
    1445     owl_list_append_element(&list, (void *)&SNs[i*(MAXSNLEN+1)]);
    1446   }
    1447   owl_function_aimsearch_results(address, &list);
    1448   owl_list_cleanup(&list, NULL);
    1449   return(1);
     1428    g_ptr_array_add(list, (void *)&SNs[i*(MAXSNLEN+1)]);
     1429  }
     1430  owl_function_aimsearch_results(address, list);
     1431  g_ptr_array_free(list, true);
     1432  return 1;
    14501433}
    14511434
     
    18031786  GPollFD *fd;
    18041787  int i;
    1805   if (len < event_source->fds->len)
     1788  if (len < event_source->fds->len) {
    18061789    owl_function_debugmsg("Truncating AIM PollFDs to %d, was %d", len, event_source->fds->len);
    1807   for (i = len; i < event_source->fds->len; i++) {
    1808     fd = event_source->fds->pdata[i];
    1809     g_source_remove_poll(&event_source->source, fd);
    1810     g_free(fd);
    1811   }
    1812   g_ptr_array_remove_range(event_source->fds, len, event_source->fds->len - len);
     1790    for (i = len; i < event_source->fds->len; i++) {
     1791      fd = event_source->fds->pdata[i];
     1792      g_source_remove_poll(&event_source->source, fd);
     1793      g_free(fd);
     1794    }
     1795    g_ptr_array_remove_range(event_source->fds, len, event_source->fds->len - len);
     1796  }
    18131797}
    18141798
     
    18421826      fd = event_source->fds->pdata[i];
    18431827      fd->fd = cur->fd;
    1844       fd->events |= G_IO_IN | G_IO_HUP | G_IO_ERR;
     1828      fd->events = G_IO_IN | G_IO_HUP | G_IO_ERR;
    18451829      if (cur->status & AIM_CONN_STATUS_INPROGRESS) {
    1846         /* Yes, we're checking writable sockets here. Without it, AIM
    1847            login is really slow. */
     1830        /* AIM login requires checking writable sockets. See aim_select. */
    18481831        fd->events |= G_IO_OUT;
    18491832      }
     
    18811864{
    18821865  owl_aim_event_source *event_source = (owl_aim_event_source*)source;
    1883   truncate_pollfd_list(event_source, 0);
    1884   g_ptr_array_free(event_source->fds, TRUE);
     1866  /* Don't remove the GPollFDs. We are being finalized, so they'll be removed
     1867   * for us. Moreover, glib will fire asserts if g_source_remove_poll is called
     1868   * on a source which has been destroyed (which occurs when g_source_remove is
     1869   * called on it). */
     1870  owl_ptr_array_free(event_source->fds, g_free);
    18851871}
    18861872
  • buddylist.c

    r96828e4 r3cdd6d2  
    33void owl_buddylist_init(owl_buddylist *bl)
    44{
    5   owl_list_create(&(bl->buddies));
     5  bl->buddies = g_ptr_array_new();
    66}
    77
     
    1414 
    1515  owl_buddy_create(b, OWL_PROTOCOL_AIM, screenname);
    16   owl_list_append_element(&(bl->buddies), b);
     16  g_ptr_array_add(bl->buddies, b);
    1717}
    1818
     
    2121int owl_buddylist_remove_aim_buddy(owl_buddylist *bl, const char *name)
    2222{
    23   int i, j;
     23  int i;
    2424  owl_buddy *b;
    2525
    26   j=owl_list_get_size(&(bl->buddies));
    27   for (i=0; i<j; i++) {
    28     b=owl_list_get_element(&(bl->buddies), i);
     26  for (i = 0; i < bl->buddies->len; i++) {
     27    b = bl->buddies->pdata[i];
    2928    if (!strcasecmp(name, owl_buddy_get_name(b)) && owl_buddy_is_proto_aim(b)) {
    30       owl_list_remove_element(&(bl->buddies), i);
    31       owl_buddy_delete(b);
     29      owl_buddy_delete(g_ptr_array_remove_index(bl->buddies, i));
    3230      return(0);
    3331    }
     
    8785int owl_buddylist_get_size(const owl_buddylist *bl)
    8886{
    89   return(owl_list_get_size(&(bl->buddies)));
     87  return bl->buddies->len;
    9088}
    9189
     
    9795  if (index>(owl_buddylist_get_size(bl)-1)) return(NULL);
    9896
    99   return(owl_list_get_element(&(bl->buddies), index));
     97  return bl->buddies->pdata[index];
    10098}
    10199
     
    105103owl_buddy *owl_buddylist_get_aim_buddy(const owl_buddylist *bl, const char *name)
    106104{
    107   int i, j;
     105  int i;
    108106  owl_buddy *b;
    109107
    110   j=owl_list_get_size(&(bl->buddies));
    111   for (i=0; i<j; i++) {
    112     b=owl_list_get_element(&(bl->buddies), i);
     108  for (i = 0; i < bl->buddies->len; i++) {
     109    b = bl->buddies->pdata[i];
    113110    if (!strcasecmp(name, owl_buddy_get_name(b))) return(b);
    114111  }
     
    131128void owl_buddylist_clear(owl_buddylist *bl)
    132129{
    133   owl_list_cleanup(&(bl->buddies), (void (*)(void *))owl_buddy_delete);
    134   owl_list_create(&(bl->buddies));
     130  g_ptr_array_foreach(bl->buddies, (GFunc)owl_buddy_delete, NULL);
     131  g_ptr_array_set_size(bl->buddies, 0);
    135132}
    136133
    137134void owl_buddylist_cleanup(owl_buddylist *bl)
    138135{
    139   owl_list_cleanup(&(bl->buddies), (void (*)(void *))owl_buddy_delete);
     136  owl_ptr_array_free(bl->buddies, (GDestroyNotify)owl_buddy_delete);
    140137}
  • cmd.c

    r4c7c21f rf271129  
    1 #include <stdio.h>
    2 #include <stdlib.h>
    3 #include <string.h>
    4 #include <unistd.h>
    51#include "owl.h"
    6 
    7 extern const owl_cmd commands_to_init[];
    82
    93/**************************************************************************/
     
    115/**************************************************************************/
    126
    13 int owl_cmddict_setup(owl_cmddict *cd) {
     7void owl_cmddict_setup(owl_cmddict *cd)
     8{
    149  owl_cmddict_init(cd);
    15   if (0 != owl_cmddict_add_from_list(cd, commands_to_init)) return(-1);
    16   return(0);
     10  owl_cmd_add_defaults(cd);
    1711}
    1812
     
    2216
    2317/* for bulk initialization at startup */
    24 int owl_cmddict_add_from_list(owl_cmddict *cd, const owl_cmd *cmds) {
     18void owl_cmddict_add_from_list(owl_cmddict *cd, const owl_cmd *cmds)
     19{
    2520  const owl_cmd *cur;
    26   int ret = 0;
    2721  for (cur = cmds; cur->name != NULL; cur++) {
    28     ret = owl_cmddict_add_cmd(cd, cur);
    29     if (ret < 0) break;
    30   }
    31   return ret;
    32 }
    33 
    34 void owl_cmddict_get_names(const owl_cmddict *d, owl_list *l) {
    35   owl_dict_get_keys(d, l);
     22    owl_cmddict_add_cmd(cd, cur);
     23  }
     24}
     25
     26GPtrArray *owl_cmddict_get_names(const owl_cmddict *d) {
     27  return owl_dict_get_keys(d);
    3628}
    3729
     
    4133
    4234/* creates a new command alias */
    43 int owl_cmddict_add_alias(owl_cmddict *cd, const char *alias_from, const char *alias_to) {
     35void owl_cmddict_add_alias(owl_cmddict *cd, const char *alias_from, const char *alias_to) {
    4436  owl_cmd *cmd;
    4537  cmd = g_new(owl_cmd, 1);
     
    4739  owl_perlconfig_new_command(cmd->name);
    4840  owl_dict_insert_element(cd, cmd->name, cmd, (void (*)(void *))owl_cmd_delete);
    49   return(0);
    5041}
    5142
     
    6051}
    6152
    62 char *_owl_cmddict_execute(const owl_cmddict *cd, const owl_context *ctx, const char *const *argv, int argc, const char *buff) {
     53/* caller must free the return */
     54CALLER_OWN char *_owl_cmddict_execute(const owl_cmddict *cd, const owl_context *ctx, const char *const *argv, int argc, const char *buff)
     55{
    6356  char *retval = NULL;
    6457  const owl_cmd *cmd;
     
    7568}
    7669
    77 char *owl_cmddict_execute(const owl_cmddict *cd, const owl_context *ctx, const char *cmdbuff) {
     70/* caller must free the return */
     71CALLER_OWN char *owl_cmddict_execute(const owl_cmddict *cd, const owl_context *ctx, const char *cmdbuff)
     72{
    7873  char **argv;
    7974  int argc;
     
    9792}
    9893
    99 char *owl_cmddict_execute_argv(const owl_cmddict *cd, const owl_context *ctx, const char *const *argv, int argc) {
     94/* caller must free the return */
     95CALLER_OWN char *owl_cmddict_execute_argv(const owl_cmddict *cd, const owl_context *ctx, const char *const *argv, int argc)
     96{
    10097  char *buff;
    10198  char *retval = NULL;
     
    124121}
    125122
    126 int owl_cmd_create_alias(owl_cmd *cmd, const char *name, const char *aliased_to) {
     123void owl_cmd_create_alias(owl_cmd *cmd, const char *name, const char *aliased_to) {
    127124  memset(cmd, 0, sizeof(owl_cmd));
    128125  cmd->name = g_strdup(name);
    129126  cmd->cmd_aliased_to = g_strdup(aliased_to);
    130127  cmd->summary = g_strdup_printf("%s%s", OWL_CMD_ALIAS_SUMMARY_PREFIX, aliased_to);
    131   return(0);
    132128}
    133129
     
    153149}
    154150
    155 char *owl_cmd_execute(const owl_cmd *cmd, const owl_cmddict *cd, const owl_context *ctx, int argc, const char *const *argv, const char *cmdbuff) {
     151/* caller must free the result */
     152CALLER_OWN char *owl_cmd_execute(const owl_cmd *cmd, const owl_cmddict *cd, const owl_context *ctx, int argc, const char *const *argv, const char *cmdbuff)
     153{
    156154  static int alias_recurse_depth = 0;
    157155  int ival=0;
     
    226224
    227225/* returns a summary line describing this keymap.  the caller must free. */
    228 char *owl_cmd_describe(const owl_cmd *cmd) {
     226CALLER_OWN char *owl_cmd_describe(const owl_cmd *cmd)
     227{
    229228  if (!cmd || !cmd->name || !cmd->summary) return NULL;
    230229  return g_strdup_printf("%-25s - %s", cmd->name, cmd->summary);
     
    257256  if (cmd->usage && *cmd->usage) {
    258257    s = cmd->usage;
    259     indent = owl_text_indent(s, OWL_TAB);
     258    indent = owl_text_indent(s, OWL_TAB, true);
    260259    owl_fmtext_append_bold(fm, "\nSYNOPSIS\n");
    261260    owl_fmtext_append_normal(fm, indent);
     
    271270  if (cmd->description && *cmd->description) {
    272271    s = cmd->description;
    273     indent = owl_text_indent(s, OWL_TAB);
     272    indent = owl_text_indent(s, OWL_TAB, true);
    274273    owl_fmtext_append_bold(fm, "\nDESCRIPTION\n");
    275274    owl_fmtext_append_normal(fm, indent);
  • commands.c

    r697221f r3b9ca71  
     1#include "owl.h"
    12#include <getopt.h>
    2 #include <stdio.h>
    3 #include <stdlib.h>
    4 #include <string.h>
    5 #include <unistd.h>
    6 #include "owl.h"
    73
    84/* fn is "char *foo(int argc, const char *const *argv, const char *buff)" */
    95#define OWLCMD_ARGS(name, fn, ctx, summary, usage, description) \
    10         { name, summary, usage, description, ctx, \
     6        { g_strdup(name), g_strdup(summary), g_strdup(usage), g_strdup(description), ctx, \
    117          NULL, fn, NULL, NULL, NULL, NULL, NULL, NULL }
    128
    139/* fn is "void foo(void)" */
    1410#define OWLCMD_VOID(name, fn, ctx, summary, usage, description) \
    15         { name, summary, usage, description, ctx, \
     11        { g_strdup(name), g_strdup(summary), g_strdup(usage), g_strdup(description), ctx, \
    1612          NULL, NULL, fn, NULL, NULL, NULL, NULL, NULL }
    1713
    1814/* fn is "void foo(int)" */
    1915#define OWLCMD_INT(name, fn, ctx, summary, usage, description) \
    20         { name, summary, usage, description, ctx, \
     16        { g_strdup(name), g_strdup(summary), g_strdup(usage), g_strdup(description), ctx, \
    2117          NULL, NULL, NULL, fn, NULL, NULL, NULL, NULL }
    2218
    2319#define OWLCMD_ALIAS(name, actualname) \
    24         { name, OWL_CMD_ALIAS_SUMMARY_PREFIX actualname, "", "", OWL_CTX_ANY, \
    25           actualname, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
     20        { g_strdup(name), g_strdup(OWL_CMD_ALIAS_SUMMARY_PREFIX actualname), g_strdup(""), g_strdup(""), OWL_CTX_ANY, \
     21          g_strdup(actualname), NULL, NULL, NULL, NULL, NULL, NULL, NULL }
    2622
    2723/* fn is "char *foo(void *ctx, int argc, const char *const *argv, const char *buff)" */
    2824#define OWLCMD_ARGS_CTX(name, fn, ctx, summary, usage, description) \
    29         { name, summary, usage, description, ctx, \
     25        { g_strdup(name), g_strdup(summary), g_strdup(usage), g_strdup(description), ctx, \
    3026          NULL, NULL, NULL, NULL, ((char*(*)(void*,int,const char*const *,const char*))fn), NULL, NULL, NULL }
    3127
    3228/* fn is "void foo(void)" */
    3329#define OWLCMD_VOID_CTX(name, fn, ctx, summary, usage, description) \
    34         { name, summary, usage, description, ctx, \
     30        { g_strdup(name), g_strdup(summary), g_strdup(usage), g_strdup(description), ctx, \
    3531          NULL, NULL, NULL, NULL, NULL, ((void(*)(void*))(fn)), NULL, NULL }
    3632
    3733/* fn is "void foo(int)" */
    3834#define OWLCMD_INT_CTX(name, fn, ctx, summary, usage, description) \
    39         { name, summary, usage, description, ctx, \
     35        { g_strdup(name), g_strdup(summary), g_strdup(usage), g_strdup(description), ctx, \
    4036          NULL, NULL, NULL, NULL, NULL, NULL, ((void(*)(void*,int))fn), NULL }
    4137
    4238
    43 const owl_cmd commands_to_init[]
    44   = {
     39void owl_cmd_add_defaults(owl_cmddict *cd)
     40{
     41  owl_cmd commands_to_init[] = {
     42
    4543  OWLCMD_ARGS("zlog", owl_command_zlog, OWL_CTX_ANY,
    4644              "send a login or logout notification",
     
    4846              "zlog in will send a login notification, zlog out will send a\n"
    4947              "logout notification.  By default a login notification is sent\n"
    50               "when owl is started and a logout notification is sent when owl\n"
     48              "when BarnOwl is started and a logout notification is sent when owl\n"
    5149              "is exited.  This behavior can be changed with the 'startuplogin'\n"
    5250              "and 'shutdownlogout' variables.  If a tty is specified for zlog in\n"
    53               "then the owl variable 'tty' will be set to that string, causing\n"
     51              "then the BarnOwl variable 'tty' will be set to that string, causing\n"
    5452              "it to be used as the zephyr location tty.\n"),
    5553
    5654  OWLCMD_VOID("quit", owl_command_quit, OWL_CTX_ANY,
    57               "exit owl",
     55              "exit BarnOwl",
    5856              "",
    59               "Exit owl and run any shutdown activities."),
     57              "Exit BarnOwl and run any shutdown activities."),
    6058  OWLCMD_ALIAS("exit", "quit"),
    6159  OWLCMD_ALIAS("q",    "quit"),
     
    9896  OWLCMD_ARGS("unbindkey", owl_command_unbindkey, OWL_CTX_ANY,
    9997              "removes a binding in a keymap",
    100               "bindkey <keymap> <keyseq>",
     98              "unbindkey <keymap> <keyseq>",
    10199              "Removes a binding of a key sequence within a keymap.\n"
    102100              "Use 'show keymaps' to see the existing keymaps.\n"
     
    178176
    179177  OWLCMD_ARGS("startup", owl_command_startup, OWL_CTX_ANY,
    180               "run a command and set it to be run at every Owl startup",
     178              "run a command and set it to be run at every BarnOwl startup",
    181179              "startup <commands> ...",
    182180              "Everything on the command line after the startup command\n"
    183               "is executed as a normal owl command and is also placed in\n"
    184               "a file so that the command is executed every time owl\n"
     181              "is executed as a normal BarnOwl command and is also placed in\n"
     182              "a file so that the command is executed every time BarnOwl\n"
    185183              "is started"),
    186184
    187185  OWLCMD_ARGS("unstartup", owl_command_unstartup, OWL_CTX_ANY,
    188               "remove a command from the list of those to be run at Owl startup",
     186              "remove a command from the list of those to be run at BarnOwl startup",
    189187              "unstartup <commands> ...",
    190188              ""),
    191189
    192190  OWLCMD_VOID("version", owl_command_version, OWL_CTX_ANY,
    193               "print the version of the running owl", "", ""),
     191              "print the version of the running BarnOwl", "", ""),
    194192
    195193  OWLCMD_ARGS("subscribe", owl_command_subscribe, OWL_CTX_ANY,
     
    202200              "only be temporary, i.e., it will not be written to\n"
    203201              "the subscription file and will therefore not be\n"
    204               "present the next time owl is started.\n"),
     202              "present the next time BarnOwl is started.\n"),
    205203  OWLCMD_ALIAS("sub", "subscribe"),
    206204
     
    214212              "only be temporary, i.e., it will not be updated in\n"
    215213              "the subscription file and will therefore not be\n"
    216               "in effect the next time owl is started.\n"),
     214              "in effect the next time BarnOwl is started.\n"),
    217215  OWLCMD_ALIAS("unsub", "unsubscribe"),
    218216
     
    232230
    233231  OWLCMD_ARGS("source", owl_command_source, OWL_CTX_ANY,
    234               "execute owl commands from a file",
     232              "execute BarnOwl commands from a file",
    235233              "source <filename>",
    236               "Execute the owl commands in <filename>.\n"),
     234              "Execute the BarnOwl commands in <filename>.\n"),
    237235
    238236  OWLCMD_ARGS("aim", owl_command_aim, OWL_CTX_INTERACTIVE,
     
    303301 
    304302  OWLCMD_ARGS("help", owl_command_help, OWL_CTX_INTERACTIVE,
    305               "display help on using owl",
     303              "display help on using BarnOwl",
    306304              "help [command]", ""),
    307305
     
    416414
    417415  OWLCMD_VOID("suspend", owl_command_suspend, OWL_CTX_ANY,
    418               "suspend owl", "", ""),
     416              "suspend BarnOwl", "", ""),
    419417
    420418  OWLCMD_ARGS("echo", owl_command_echo, OWL_CTX_ANY,
     
    507505
    508506  OWLCMD_VOID("about", owl_command_about, OWL_CTX_INTERACTIVE,
    509               "print information about owl", "", ""),
     507              "print information about BarnOwl", "", ""),
    510508
    511509  OWLCMD_VOID("status", owl_command_status, OWL_CTX_ANY,
    512               "print status information about the running owl", "", ""),
     510              "print status information about the running BarnOwl", "", ""),
    513511 
    514512  OWLCMD_ARGS("zlocate", owl_command_zlocate, OWL_CTX_INTERACTIVE,
     
    588586              "The other usages listed above are abbreviated forms that simply set\n"
    589587              "the filter of the current view. The -d option allows you to write a\n"
    590               "filter expression that will be dynamically created by owl and then\n"
     588              "filter expression that will be dynamically created by BarnOwl and then\n"
    591589              "applied as the view's filter\n"
    592590              "SEE ALSO: filter, viewclass, viewuser\n"),
     
    654652              "show subscriptions / show subs\n"
    655653              "show terminal\n"
    656               "show timers\n"
    657654              "show variables\n"
    658655              "show variable <variable>\n"
     
    675672              "for formatting messages.\n\n"
    676673              "Show variables will list the names of all variables.\n\n"
    677               "Show errors will show a list of errors encountered by Owl.\n\n"
     674              "Show errors will show a list of errors encountered by BarnOwl.\n\n"
    678675              "SEE ALSO: filter, view, alias, bindkey, help\n"),
    679676 
     
    693690  OWLCMD_ALIAS("del", "delete"),
    694691
     692  OWLCMD_ARGS("delete-and-expunge", owl_command_delete_and_expunge, OWL_CTX_INTERACTIVE,
     693              "delete a message",
     694              "delete-and-expunge [-id msgid] [-q | --quiet]",
     695              "If no message id is specified the current message is deleted.\n"
     696              "Otherwise the message with the given message id is deleted.\n"
     697              "If --quiet is specified, then there is no message displayed on\n"
     698              "success.\n"),
     699  OWLCMD_ALIAS("delx", "delete-and-expunge"),
     700
    695701  OWLCMD_ARGS("undelete", owl_command_undelete, OWL_CTX_INTERACTIVE,
    696702              "unmark a message for deletion",
     
    10271033  OWLCMD_ARGS_CTX("popless:start-search", owl_viewwin_command_start_search, OWL_CTX_POPLESS,
    10281034                  "starts a command line to search for particular string",
    1029                   "popless:start-search [-r] [inital-value]",
     1035                  "popless:start-search [-r] [initial-value]",
    10301036                  "Initializes the command-line to search for initial-value. If\n"
    10311037                  "-r is used, the search will be performed backwards.\n\n"
     
    10371043  { NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
    10381044
    1039 };
     1045  };
     1046
     1047  owl_cmddict_add_from_list(cd, commands_to_init);
     1048  owl_cmd *cmd;
     1049  for (cmd = commands_to_init; cmd->name != NULL; cmd++)
     1050    owl_cmd_cleanup(cmd);
     1051}
    10401052
    10411053void owl_command_info(void)
     
    13661378}
    13671379
    1368 char *owl_command_smartfilter(int argc, const char *const *argv, const char *buff)
     1380CALLER_OWN char *owl_command_smartfilter(int argc, const char *const *argv, const char *buff)
    13691381{
    13701382  char *filtname = NULL;
     
    14061418}
    14071419
    1408 char *owl_command_get_shift(int argc, const char *const *argv, const char *buff)
     1420CALLER_OWN char *owl_command_get_shift(int argc, const char *const *argv, const char *buff)
    14091421{
    14101422  if(argc != 1)
     
    15651577  int  silent=0;
    15661578  int requirebool=0;
     1579  owl_variable *v;
    15671580
    15681581  if (argc == 1) {
     
    15871600    return NULL;
    15881601  }
    1589   owl_variable_set_fromstring(owl_global_get_vardict(&g), var, val, !silent, requirebool);
     1602
     1603  v = owl_variable_get_var(owl_global_get_vardict(&g), var);
     1604  if (v == NULL) {
     1605    if (!silent) owl_function_error("Unknown variable '%s'", var);
     1606  } else if (requirebool && !v->takes_on_off) {
     1607    if (!silent) owl_function_error("Variable '%s' is not a boolean", var);
     1608  } else {
     1609    owl_variable_set_fromstring(v, val, !silent);
     1610  }
    15901611  return NULL;
    15911612}
     
    15931614char *owl_command_unset(int argc, const char *const *argv, const char *buff)
    15941615{
     1616  owl_variable *v;
    15951617  const char *var, *val;
    15961618  int  silent=0;
     
    16071629    return NULL;
    16081630  }
    1609   owl_variable_set_fromstring(owl_global_get_vardict(&g), var, val, !silent, 1);
     1631
     1632  v = owl_variable_get_var(owl_global_get_vardict(&g), var);
     1633  if (v == NULL) {
     1634    if (!silent) owl_function_error("Unknown variable '%s'", var);
     1635  } else if (!v->takes_on_off) {
     1636    if (!silent) owl_function_error("Variable '%s' is not a boolean", var);
     1637  } else {
     1638    owl_variable_set_fromstring(v, val, !silent);
     1639  }
    16101640  return NULL;
    16111641}
     
    16151645  const char *var;
    16161646  char *value;
     1647  const owl_variable *v;
    16171648
    16181649  if (argc==1) {
     
    16261657  var=argv[1];
    16271658   
    1628   value = owl_variable_get_tostring(owl_global_get_vardict(&g), var);
    1629   if (value) {
    1630     owl_function_makemsg("%s = '%s'", var, value);
     1659  v = owl_variable_get_var(owl_global_get_vardict(&g), var);
     1660  if (v) {
     1661    value = owl_variable_get_tostring(v);
     1662    if (value == NULL)
     1663      owl_function_makemsg("%s = <null>", var);
     1664    else
     1665      owl_function_makemsg("%s = '%s'", var, value);
    16311666    g_free(value);
    16321667  } else {
     
    16371672
    16381673
    1639 char *owl_command_exec(int argc, const char *const *argv, const char *buff)
     1674CALLER_OWN char *owl_command_exec(int argc, const char *const *argv, const char *buff)
    16401675{
    16411676  return owl_function_exec(argc, argv, buff, OWL_OUTPUT_RETURN);
    16421677}
    16431678
    1644 char *owl_command_pexec(int argc, const char *const *argv, const char *buff)
     1679CALLER_OWN char *owl_command_pexec(int argc, const char *const *argv, const char *buff)
    16451680{
    16461681  return owl_function_exec(argc, argv, buff, OWL_OUTPUT_POPUP);
    16471682}
    16481683
    1649 char *owl_command_aexec(int argc, const char *const *argv, const char *buff)
     1684CALLER_OWN char *owl_command_aexec(int argc, const char *const *argv, const char *buff)
    16501685{
    16511686  return owl_function_exec(argc, argv, buff, OWL_OUTPUT_ADMINMSG);
    16521687}
    16531688
    1654 char *owl_command_perl(int argc, const char *const *argv, const char *buff)
     1689CALLER_OWN char *owl_command_perl(int argc, const char *const *argv, const char *buff)
    16551690{
    16561691  return owl_function_perl(argc, argv, buff, OWL_OUTPUT_RETURN);
    16571692}
    16581693
    1659 char *owl_command_pperl(int argc, const char *const *argv, const char *buff)
     1694CALLER_OWN char *owl_command_pperl(int argc, const char *const *argv, const char *buff)
    16601695{
    16611696  return owl_function_perl(argc, argv, buff, OWL_OUTPUT_POPUP);
    16621697}
    16631698
    1664 char *owl_command_aperl(int argc, const char *const *argv, const char *buff)
     1699CALLER_OWN char *owl_command_aperl(int argc, const char *const *argv, const char *buff)
    16651700{
    16661701  return owl_function_perl(argc, argv, buff, OWL_OUTPUT_ADMINMSG);
    16671702}
    16681703
    1669 char *owl_command_multi(int argc, const char *const *argv, const char *buff)
     1704CALLER_OWN char *owl_command_multi(int argc, const char *const *argv, const char *buff)
    16701705{
    16711706  char *lastrv = NULL, *newbuff;
     
    17431778
    17441779  if (argc < 3) {
    1745     owl_function_makemsg("Usage: bindkey <keymap> <binding>");
     1780    owl_function_makemsg("Usage: unbindkey <keymap> <binding>");
    17461781    return NULL;
    17471782  }
     
    19501985  }
    19511986  /* check for a zwrite -m */
    1952   z = owl_zwrite_new(buff);
     1987  z = owl_zwrite_new(argc, argv);
    19531988  if (!z) {
    19541989    owl_function_error("Error in zwrite arguments");
     
    21262161      myargv[i]=argv[i];
    21272162    }
    2128     owl_function_create_filter(argc, myargv);
    2129     owl_function_change_currentview_filter("owl-dynamic");
     2163    if (owl_function_create_filter(argc, myargv)) {
     2164      owl_function_change_currentview_filter("owl-dynamic");
     2165    }
    21302166    g_free(myargv);
    21312167    return NULL;
     
    21542190    if (!strcmp(argv[0], "-f")) {
    21552191      if (argc<2) {
    2156         owl_function_makemsg("Too few argments to the view command");
     2192        owl_function_makemsg("Too few arguments to the view command");
    21572193        return(NULL);
    21582194      }
     
    21662202    } else if (!strcmp(argv[0], "-s")) {
    21672203      if (argc<2) {
    2168         owl_function_makemsg("Too few argments to the view command");
     2204        owl_function_makemsg("Too few arguments to the view command");
    21692205        return(NULL);
    21702206      }
     
    21732209      argv+=2;
    21742210    } else {
    2175       owl_function_makemsg("Too few argments to the view command");
     2211      owl_function_makemsg("Too few arguments to the view command");
    21762212      return(NULL);
    21772213    }
     
    22252261  } else if (!strcmp(argv[1], "styles")) {
    22262262    owl_function_show_styles();
    2227   } else if (!strcmp(argv[1], "timers")) {
    2228     owl_function_show_timers();
    22292263  } else if (!strcmp(argv[1], "subs") || !strcmp(argv[1], "subscriptions")) {
    22302264    owl_function_getsubs();
     
    23262360}
    23272361
     2362char *owl_command_delete_and_expunge(int argc, const char *const *argv, const char *buff)
     2363{
     2364  bool exclaim_success = true;
     2365
     2366  if (argc > 1 && (!strcmp(argv[1], "-q") || !strcmp(argv[1], "--quiet"))) {
     2367    exclaim_success = false;
     2368    argc--;
     2369    argv++;
     2370  } else if (!strcmp(argv[argc - 1], "-q") || !strcmp(argv[argc - 1], "--quiet")) {
     2371    exclaim_success = false;
     2372    argc--;
     2373  }
     2374
     2375  if (argc == 1) {
     2376    owl_function_delete_and_expunge_cur(exclaim_success);
     2377    return NULL;
     2378  }
     2379
     2380  if (argc == 3 && (!strcmp(argv[1], "-id") || !strcmp(argv[1], "--id"))) {
     2381    owl_function_delete_and_expunge_by_id(atoi(argv[2]), exclaim_success);
     2382    return NULL;
     2383  }
     2384
     2385  owl_function_makemsg("Unknown arguments to delete-and-expunge command");
     2386  return NULL;
     2387}
     2388
    23282389char *owl_command_undelete(int argc, const char *const *argv, const char *buff)
    23292390{
     
    24622523void owl_command_punt_unpunt(int argc, const char *const * argv, const char *buff, int unpunt)
    24632524{
    2464   owl_list * fl;
    2465   owl_filter * f;
     2525  GPtrArray * fl;
    24662526  int i;
    24672527
     
    24712531  } else if(argc == 2) {
    24722532    /* Handle :unpunt <number> */
    2473     if(unpunt && (i=atoi(argv[1])) !=0) {
     2533    if (unpunt && (i = atoi(argv[1])) > 0) {
    24742534      i--;      /* Accept 1-based indexing */
    2475       if(i < owl_list_get_size(fl)) {
    2476         f = owl_list_get_element(fl, i);
    2477         owl_list_remove_element(fl, i);
    2478         owl_filter_delete(f);
     2535      if (i < fl->len) {
     2536        owl_filter_delete(g_ptr_array_remove_index(fl, i));
    24792537        return;
    24802538      } else {
     
    25032561}
    25042562
    2505 char *owl_command_getvar(int argc, const char *const *argv, const char *buff)
    2506 {
     2563CALLER_OWN char *owl_command_getvar(int argc, const char *const *argv, const char *buff)
     2564{
     2565  const owl_variable *v;
    25072566  if (argc != 2) {
    25082567    owl_function_makemsg("Wrong number of arguments for %s", argv[0]);
    25092568    return NULL;
    25102569  }
    2511   return owl_variable_get_tostring(owl_global_get_vardict(&g), argv[1]);
     2570  v = owl_variable_get_var(owl_global_get_vardict(&g), argv[1]);
     2571  if (v == NULL) return NULL;
     2572  return owl_variable_get_tostring(v);
    25122573}
    25132574
     
    25892650}
    25902651
    2591 char *owl_command_getstyle(int argc, const char *const *argv, const char *buff)
     2652CALLER_OWN char *owl_command_getstyle(int argc, const char *const *argv, const char *buff)
    25922653{
    25932654  const char *stylename;
     
    26272688  ptr = skiptokens(buff, 1);
    26282689  hist = owl_global_get_cmd_history(&g);
    2629   owl_history_store(hist, ptr);
    2630   owl_history_reset(hist);
     2690  owl_history_store(hist, ptr, false);
    26312691  /* owl_function_makemsg("History '%s' stored successfully", ptr+1); */
    26322692  return NULL;
    26332693}
    26342694
    2635 char *owl_command_with_history(int argc, const char *const *argv, const char *buff)
     2695CALLER_OWN char *owl_command_with_history(int argc, const char *const *argv, const char *buff)
    26362696{
    26372697  owl_history *hist;
     
    26502710
    26512711  hist = owl_global_get_cmd_history(&g);
    2652   owl_history_store(hist, ptr);
    2653   owl_history_reset(hist);
     2712  owl_history_store(hist, ptr, false);
    26542713  return owl_function_command(ptr);
    26552714}
     
    27342793
    27352794  hist = owl_editwin_get_history(e);
    2736   if (hist) {
    2737     owl_history_store(hist, owl_editwin_get_text(e));
    2738     owl_history_reset(hist);
    2739   }
    2740 
     2795  if (hist)
     2796    owl_history_store(hist, owl_editwin_get_text(e), false);
     2797
     2798  /* Take a reference to the editwin, so that it survives the pop
     2799   * context. TODO: We should perhaps refcount or otherwise protect
     2800   * the context so that, even if a command pops a context, the
     2801   * context itself will last until the command returns. */
     2802  owl_editwin_ref(e);
    27412803  owl_global_pop_context(&g);
     2804
     2805  owl_editwin_do_callback(e, false);
     2806  owl_editwin_unref(e);
    27422807}
    27432808
     
    27502815  if (!hist)
    27512816    return;
    2752   if (!owl_history_is_touched(hist)) {
    2753     owl_history_store(hist, owl_editwin_get_text(e));
    2754     owl_history_set_partial(hist);
    2755   }
     2817  if (!owl_history_is_touched(hist))
     2818    owl_history_store(hist, owl_editwin_get_text(e), true);
    27562819  ptr=owl_history_get_prev(hist);
    27572820  if (ptr) {
     
    27912854  owl_history *hist=owl_editwin_get_history(e);
    27922855
    2793   if (hist) {
    2794     owl_history_store(hist, owl_editwin_get_text(e));
    2795     owl_history_reset(hist);
    2796   }
     2856  if (hist)
     2857    owl_history_store(hist, owl_editwin_get_text(e), false);
    27972858
    27982859  /* Take a reference to the editwin, so that it survives the pop
     
    28032864  owl_global_pop_context(&g);
    28042865
    2805   owl_editwin_do_callback(e);
     2866  owl_editwin_do_callback(e, true);
    28062867  owl_editwin_unref(e);
    28072868}
  • compat/Makefile.am

    r12a6616 rb80bae0  
    11noinst_LIBRARIES = libcompat.a
    22
    3 libcompat_a_SOURCES =
     3libcompat_a_SOURCES = compat.h
    44libcompat_a_LIBADD = $(LIBOBJS)
  • compat/compat.h

    r4dde585 r6249a88f  
    22#define INC_BARNOWL_COMPAT_COMPAT_H
    33
    4 #include "../config.h"
     4#include <config.h>
    55
    66#include <stddef.h>
  • configure.ac

    rf97c1a6 re4b8f93  
    11dnl Process this file with autoconf to produce a configure script.
    2 AC_INIT([BarnOwl],[1.8dev],[bug-barnowl@mit.edu])
    3 AM_INIT_AUTOMAKE([1.7.0 -Wall -Wno-portability foreign])
     2AC_INIT([BarnOwl],[1.10dev],[bug-barnowl@mit.edu])
     3AM_INIT_AUTOMAKE([1.7.0 foreign std-options -Wall -Wno-portability])
     4AM_MAINTAINER_MODE([enable])
    45m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
    56
     
    89
    910AC_PROG_CC
     11AC_PROG_CC_C99
     12AC_PROG_LN_S
     13
     14AC_ARG_WITH([zephyr-default-format],
     15    [AS_HELP_STRING([--with-zephyr-default-format],
     16                    [value for the default format zephyrgram field])],
     17    [
     18        case $withval in
     19            yes) withval='Config error: see http://mit.edu/df';;
     20            no) withval='';;
     21        esac
     22        zephyr_default_format=$withval
     23    ],
     24    [zephyr_default_format='Config error: see http://mit.edu/df'])
     25AC_DEFINE_UNQUOTED(
     26    [ZEPHYR_DEFAULT_FORMAT], ["$zephyr_default_format"],
     27    [Value for the default format zephyrgram field]
     28)
    1029
    1130AC_ARG_WITH([stack-protector],
     
    1635
    1736AS_IF([test "x$with_stack_protector" != xno],
    18   [AX_C_CHECK_FLAG([-fstack-protector],[],[],
     37  [AX_CHECK_COMPILE_FLAG([-fstack-protector],
    1938    [AM_CFLAGS="$AM_CFLAGS -fstack-protector"],
    2039    [if test "x$with_stack_protector" != xcheck; then
     
    4059
    4160AS_IF([test "x$with_zephyr" != xno],
    42   [AS_IF([test "x$with_krb4" != "xno"],
     61  [have_krb4=no
     62
     63   AS_IF([test "x$with_krb4" != "xno"],
    4364   [AC_MSG_CHECKING([for Kerberos IV])
    4465    AS_IF([krb5-config krb4 --libs >/dev/null 2>&1],
    4566      [AC_MSG_RESULT([yes])
     67       have_krb4=yes
    4668       AC_DEFINE([HAVE_KERBEROS_IV], [1], [Define if you have kerberos IV])
    4769       AM_CFLAGS="${AM_CFLAGS} `krb5-config krb4 --cflags`"
     
    5072      [AC_MSG_RESULT([no])
    5173       AS_IF([test "x$with_krb4" = "xyes"],
    52              [AC_MSG_ERROR([Kerberos IV requested but not found])])
    53        PKG_CHECK_MODULES([LIBCRYPTO], [libcrypto])
    54        AM_CFLAGS="${AM_CFLAGS} ${LIBCRYPTO_CFLAGS}"
    55        LIBS="${LIBS} ${LIBCRYPTO_LIBS}"
    56      ])])
     74             [AC_MSG_ERROR([Kerberos IV requested but not found])])])])
     75
     76   AS_IF([test "x$have_krb4" != xyes],
     77     [PKG_CHECK_MODULES([LIBCRYPTO], [libcrypto],
     78        [AM_CFLAGS="${AM_CFLAGS} ${LIBCRYPTO_CFLAGS}"
     79         LIBS="${LIBS} ${LIBCRYPTO_LIBS}"
     80        ],
     81        [PKG_CHECK_MODULES([OPENSSL], [openssl],
     82           [AM_CFLAGS="${AM_CFLAGS} ${OPENSSL_CFLAGS}"
     83            LIBS="${LIBS} ${OPENSSL_LIBS}"
     84           ])])])
     85
    5786   AC_CHECK_LIB([zephyr], [ZGetSender],
    5887   [LIBS="$LIBS -lzephyr"
     
    80109AC_HEADER_STDC
    81110AC_HEADER_SYS_WAIT
    82 AC_HEADER_STDBOOL
    83 AC_CHECK_HEADERS(strings.h sys/ioctl.h sys/filio.h unistd.h)
     111AC_CHECK_HEADERS(stdbool.h strings.h sys/ioctl.h sys/filio.h unistd.h)
    84112
    85113dnl Add CFLAGS for embeded perl
     
    90118dnl Find the location of perl XSUBPP
    91119AC_MSG_CHECKING(for the perl xsubpp precompiler)
    92 XSUBPPDIR="`(perl -MExtUtils::MakeMaker -e 'print ExtUtils::MakeMaker->new({NAME => qw(owl)})->tool_xsubpp;') | grep \^XSUBPPDIR | sed -e 's/XSUBPPDIR = //g;'`"
     120XSUBPPDIR="`cd "$srcdir" && perl -MExtUtils::MakeMaker -e 'print ExtUtils::MakeMaker->new({NAME => qw(owl)})->tool_xsubpp;' | grep \^XSUBPPDIR | sed -e 's/XSUBPPDIR = //g;'`"
    93121if test -n "${XSUBPPDIR}"; then
    94122   AC_MSG_RESULT(${XSUBPPDIR})
     
    109137AC_CHECK_LIB([perl], [perl_alloc],, AC_MSG_ERROR([No libperl found]))
    110138
     139AX_PROG_PERL_MODULES([AnyEvent],,
     140                     [AC_MSG_ERROR([cannot find perl module AnyEvent.])])
    111141AX_PROG_PERL_MODULES([Class::Accessor::Fast],,
    112142                     [AC_MSG_ERROR([cannot find perl module Class::Accessor::Fast.])])
     143AX_PROG_PERL_MODULES([ExtUtils::Depends],,
     144                     [AC_MSG_ERROR([cannot find perl module ExtUtils::Depends])])
     145AX_PROG_PERL_MODULES([Glib],,
     146                     [AC_MSG_ERROR([cannot find perl module Glib.])])
     147AX_PROG_PERL_MODULES([Module::Install::Base],,
     148                     [AC_MSG_ERROR([cannot find perl module Module::Install::Base])])
    113149AX_PROG_PERL_MODULES([PAR],,
    114150                     [AC_MSG_WARN([PAR.pm not found. Loadable modules will be disabled.])])
    115151
    116152dnl Add CFLAGS and LIBS for glib-2.0
    117 PKG_CHECK_MODULES(GLIB,[glib-2.0 >= 2.12 gobject-2.0 gthread-2.0])
     153PKG_CHECK_MODULES(GLIB,[glib-2.0 >= 2.16 gobject-2.0 gthread-2.0])
    118154
    119155AC_MSG_NOTICE([Adding glib-2.0 CFLAGS ${GLIB_CFLAGS}])
     
    126162fi
    127163
     164dnl Add CFLAGS for glib-perl
     165GLIB_PERL_CFLAGS=`perl -MExtUtils::Depends -e 'my $e = ExtUtils::Depends->new("BarnOwl","Glib"); my %h = $e->get_makefile_vars; print $h{"INC"}'`
     166AC_MSG_NOTICE([Adding glib-perl CFLAGS ${GLIB_PERL_CFLAGS}])
     167AM_CFLAGS="${GLIB_PERL_CFLAGS} ${AM_CFLAGS}"
     168
    128169dnl Checks for typedefs, structures, and compiler characteristics.
    129170
    130171AX_CFLAGS_WARN_ALL([AM_CFLAGS])
    131 AX_C_CHECK_FLAG([-Wstrict-prototypes],[],[],[AM_CFLAGS="$AM_CFLAGS -Wstrict-prototypes"])
     172AX_APPEND_COMPILE_FLAGS([-Wstrict-prototypes -Wwrite-strings],[AM_CFLAGS])
    132173
    133174dnl Shut gcc up about zero-length format strings; the warning's apparently for
    134175dnl efficiency reasons, which is bogus for custom functions.
    135 AX_C_CHECK_FLAG([-Wno-format-zero-length],[],[],[AM_CFLAGS="$AM_CFLAGS -Wno-format-zero-length"])
    136 
    137 m4_foreach([myflag],
    138   [[-Wno-pointer-sign],[-Wno-empty-body],[-Wno-unused-value]],
    139   [AX_C_CHECK_FLAG([myflag],[],[],[LIBFAIM_CFLAGS="$LIBFAIM_CFLAGS myflag"])])
     176AX_APPEND_COMPILE_FLAGS([-Wno-format-zero-length],[AM_CFLAGS])
     177
     178AX_APPEND_COMPILE_FLAGS([-Wno-pointer-sign -Wno-empty-body -Wno-unused-value],[LIBFAIM_CFLAGS])
    140179
    141180AM_CONDITIONAL([ENABLE_ZCRYPT], [test "$HAVE_DES_STRING_TO_KEY" && dnl
     
    143182                                 test "$HAVE_DES_ECB_ENCRYPT"])
    144183
    145 AM_CFLAGS="$AM_CFLAGS -D_XOPEN_SOURCE=500"
     184AM_CFLAGS="$AM_CFLAGS -D_XOPEN_SOURCE=600"
    146185dnl Define _BSD_SOURCE because zephyr needs caddr_t.
    147186AM_CFLAGS="$AM_CFLAGS -D_BSD_SOURCE"
     
    166205AC_REPLACE_FUNCS([memrchr])
    167206
     207AC_SUBST([abs_builddir])
     208AC_SUBST([abs_srcdir])
     209
    168210AC_CONFIG_FILES([Makefile compat/Makefile libfaim/Makefile perl/Makefile perl/modules/Makefile])
    169211AC_OUTPUT
  • context.c

    rd4927a7 rf271129  
    1 #include <string.h>
    21#include "owl.h"
    32
     
    65
    76/* TODO: dependency from owl_context -> owl_window is annoying. */
    8 owl_context *owl_context_new(int mode, void *data, const char *keymap, owl_window *cursor)
     7CALLER_OWN owl_context *owl_context_new(int mode, void *data, const char *keymap, owl_window *cursor)
    98{
    109  owl_context *c;
  • dict.c

    r4c7c21f rf271129  
    66 */
    77
    8 #include <stdlib.h>
    9 #include <string.h>
    10 #include <unistd.h>
    118#include "owl.h"
    12 
    139
    1410#define INITSIZE 30
     
    5652}
    5753
    58 /* Appends dictionary keys to a list.  Duplicates the keys,
    59  * so they will need to be freed by the caller. */
    60 void owl_dict_get_keys(const owl_dict *d, owl_list *l) {
     54/* Returns a GPtrArray of dictionary keys. Duplicates the keys, so
     55 * they will need to be freed by the caller with g_free. */
     56CALLER_OWN GPtrArray *owl_dict_get_keys(const owl_dict *d) {
     57  GPtrArray *keys = g_ptr_array_sized_new(d->size);
    6158  int i;
    62   for (i=0; i<d->size; i++) {
    63     owl_list_append_element(l, g_strdup(d->els[i].k));
     59  for (i = 0; i < d->size; i++) {
     60    g_ptr_array_add(keys, g_strdup(d->els[i].k));
    6461  }
     62  return keys;
    6563}
    6664
     
    107105/* Doesn't free the value of the element, but does
    108106 * return it so the caller can free it. */
    109 void *owl_dict_remove_element(owl_dict *d, const char *k) {
     107CALLER_OWN void *owl_dict_remove_element(owl_dict *d, const char *k)
     108{
    110109  int i;
    111110  int pos, found;
  • doc/barnowl.1

    rfa1b15b r8135737  
    1 .TH barnowl 1 "23 Jun 2008"
     1.TH BARNOWL 1 "24 Jun 2011"
    22.SH NAME
    3 barnowl \- tty based zephyr client
     3BarnOwl \- tty\(hybased zephyr client
    44.SH SYNOPSIS
    55.B barnowl
    6 [ \-n
    7 ]
    8 [ \-d
    9 ]
    10 [ \-D
    11 ]
    12 [ \-v
    13 ]
    14 [ \-h
    15 ]
    16 [ \-c
    17 .I configfile
    18 ]
    19 [ \-t
    20 .I tty
    21 ]
    22 [ \-s
    23 .I configdir
    24 ]
     6[\-n]
     7[\-d]
     8[\-D]
     9[\-v]
     10[\-h]
     11[\-c \fICONFIGFILE\fP]
     12[\-t \fITTY\fP]
     13[\-s \fICONFIGDIR\fP]
    2514.br
    2615.SH DESCRIPTION
    2716.B BarnOwl
    28 is a fully integrated tty based instant messaging client.  Currently
    29 it supports AOL Instant Messenger, MIT Zephyr, and Jabber.  It is
    30 curses-based, allows for emacs-style editing of outgoing messages and
    31 uses perl as an extension and configuration language.  BarnOwl will
     17is a fully integrated tty\(hybased instant messaging client.  Currently
     18it supports AOL Instant Messenger, MIT Zephyr, Jabber, IRC, and Twitter.  It is
     19curses\(hybased, allows for emacs\(hystyle editing of outgoing messages, and
     20uses Perl as an extension and configuration language.  \fBBarnOwl\fP will
    3221also run happily without a configuration file.
    3322
    34 Once BarnOwl is started, typing 'h' will display a help screen.
    35 Typing \':\' enters command mode, allowing the user to type a barnowl
     23Once \fBBarnOwl\fP is started, typing \(oqh\(cq will display a help screen.
     24Typing \(oq:\(cq enters command mode, allowing the user to type a \fBBarnOwl\fP
    3625command line.
    3726
    38 .PP
    39 .SH USE
    40 The following command line options are avilable when running barnowl:
     27.SH OPTIONS
     28The following command\-line options are avilable when running \fBBarnOwl\fP:
     29.TP
     30\fB\-n\fP, \fB\-\-no\-subs\fP
     31Do not subscribe to zephyr messages on startup.  By default, \fBBarnOwl\fP
     32subscribes to the default subscriptions and to anything found in
     33\fI~/.zephyr.subs\fP.  When this option is used, no subscriptions are loaded.
    4134
    42 .B \-n
    43 .IP
    44 Do not subscribe to zephyr messages on startup.  By default BarnOwl
    45 subscribes to the default subscriptions and to anything found in
    46 ~/.zephyr.subs.  When this option is used no subscriptions are loaded.
    47 .LP
     35.TP
     36\fB\-c\fP, \fB\-\-config\-file\fP=\fIFILE\fP
     37Specify an alternate config file for \fBBarnOwl\fP to use.  The config file is
     38an arbitrary Perl script evaluated in the \fImain\fP package, and if it
     39overrides the \fIBarnOwl::startup\fP method that is run when \fBBarnOwl\fP
     40starts.  (Compare \fI~/.owl/startup\fP, which contains \fBBarnOwl\fP commands
     41that are run at startup after the config file is loaded.)
    4842
    49 .B \-c \fIconfigfile\fP
    50 .IP
    51 Specifiy an alternate config file for BarnOwl to use.  By default,
    52 barnowl uses ~/.barnowlconf if it exists, and ~/.owlconf otherwise.
    53 .LP
     43By default, \fBBarnOwl\fP uses the first of \fI~/.owl/init.pl\fP,
     44\fI~/.barnowlconf\fP, or \fI~/.owlconf\fP that exists.
    5445
    55 .B \-s \fIconfigdir\fP
    56 .IP
    57 Specify an alternate configuration directory. By default, BarnOwl uses
    58 ~/.owl/.
    59 .LP
     46.TP
     47\fB\-s\fP, \fB\-\-config\-dir\fP=\fIDIR\fP
     48Specify an alternate configuration directory.  By default, \fBBarnOwl\fP uses
     49\fI~/.owl/\fP.
    6050
    61 .B \-t \fItty\fP
    62 .IP
    63 Specifiy the tty name to use for the zephyr location.
    64 .LP
     51.TP
     52\fB\-t\fP, \fB\-\-tty\fP=\fITTY\fP
     53Specify the tty name to use for the zephyr location.
    6554
    66 .B \-v
    67 .IP
    68 Print the version number of barnowl and exit.
    69 .LP
     55.TP
     56\fB\-v\fP, \fB\-\-version\fP
     57Print the version number of \fBBarnOwl\fP and exit.
    7058
    71 .B \-d
    72 .IP
    73 Enable debugging.  By default debugging information is placed in
    74 /var/tmp/owldebug.
    75 .LP
     59.TP
     60\fB\-d\fP, \fB\-\-debug\fP
     61Enable debugging.  By default, debugging information is placed in
     62\fI/var/tmp/barnowl\-debug.PID\fP.
    7663
    77 .B \-D
    78 .IP
    79 Enable debugging, but first delete any existing debugging file.
    80 .LP
     64.TP
     65\fB\-h\fP, \fB\-\-help\fP
     66Print command\(hyline option help.
    8167
    82 .B \-h
    83 .IP
    84 Print command line option help.
    85 .LP
    86 
    87 .SH AUTHOR
     68.SH AUTHORS
    8869Written by Nelson Elhage and Alejandro Sedeno at the Massachusetts
    89 Institute of Technology. Based on Owl by James Kretchmar.
     70Institute of Technology.  Based on Owl by James Kretchmar.
    9071
    9172Comments, questions, and bug reports may be mailed to
    92 \fBbug-barnowl@mit.edu\fP.
     73\fBbug\-barnowl@mit.edu\fP.
  • editcontext.c

    r4a41f16 rf271129  
    11#include "owl.h"
    2 
    32#include <assert.h>
    43
     
    87}
    98
    10 owl_context *owl_editcontext_new(int mode, owl_editwin *e, const char *keymap, void (*deactivate_cb)(owl_context*), void *cbdata)
     9CALLER_OWN owl_context *owl_editcontext_new(int mode, owl_editwin *e, const char *keymap, void (*deactivate_cb)(owl_context*), void *cbdata)
    1110{
    1211  owl_context *ctx = owl_context_new(mode, owl_editwin_ref(e), keymap,
  • editwin.c

    r3b8a563 r8258ea5  
    11#include "owl.h"
    2 #include <stdlib.h>
    3 #include <unistd.h>
    4 #include <string.h>
    5 #include <ctype.h>
    62
    73#define VALID_EXCURSION (0x9a2b4729)
     
    3733  oe_excursion *excursions;
    3834
    39   void (*callback)(struct _owl_editwin*);
     35  void (*callback)(struct _owl_editwin *e, bool success);
    4036  void (*destroy_cbdata)(void *);
    4137  void *cbdata;
     
    6157static const char *oe_copy_buf(owl_editwin *e, const char *buf, int len);
    6258static int oe_copy_region(owl_editwin *e);
    63 static char *oe_chunk(owl_editwin *e, int start, int end);
     59static CALLER_OWN char *oe_chunk(owl_editwin *e, int start, int end);
    6460static void oe_destroy_cbdata(owl_editwin *e);
    6561static void oe_dirty(owl_editwin *e);
     
    7066#define WHITESPACE " \n\t"
    7167
    72 static owl_editwin *owl_editwin_allocate(void)
     68static CALLER_OWN owl_editwin *owl_editwin_allocate(void)
    7369{
    7470  owl_editwin *e = g_new0(owl_editwin, 1);
     
    142138}
    143139
    144 owl_editwin *owl_editwin_new(owl_window *win, int winlines, int wincols, int style, owl_history *hist)
     140CALLER_OWN owl_editwin *owl_editwin_new(owl_window *win, int winlines, int wincols, int style, owl_history *hist)
    145141{
    146142  owl_editwin *e = owl_editwin_allocate();
     
    224220}
    225221
    226 void owl_editwin_set_callback(owl_editwin *e, void (*cb)(owl_editwin*))
     222void owl_editwin_set_callback(owl_editwin *e, void (*cb)(owl_editwin *, bool))
    227223{
    228224  e->callback = cb;
    229225}
    230226
    231 void (*owl_editwin_get_callback(owl_editwin *e))(owl_editwin*)
     227void (*owl_editwin_get_callback(owl_editwin *e))(owl_editwin *, bool)
    232228{
    233229  return e->callback;
     
    252248}
    253249
    254 void owl_editwin_do_callback(owl_editwin *e) {
    255   void (*cb)(owl_editwin*);
    256   cb=owl_editwin_get_callback(e);
    257   if(!cb) {
     250void owl_editwin_do_callback(owl_editwin *e, bool success)
     251{
     252  void (*cb)(owl_editwin *, bool);
     253  cb = owl_editwin_get_callback(e);
     254  if (!cb) {
    258255    owl_function_error("Internal error: No editwin callback!");
    259256  } else {
    260     /* owl_function_error("text: |%s|", owl_editwin_get_text(e)); */
    261     cb(e);
     257    cb(e, success);
    262258  }
    263259}
     
    623619
    624620  if (!g_utf8_validate(s, -1, NULL)) {
    625     owl_function_debugmsg("owl_editwin_insert_string: received non-utf-8 string.");
     621    owl_function_debugmsg("owl_editwin_insert_string: received non-UTF-8 string.");
    626622    return 0;
    627623  }
     
    11511147{
    11521148  oe_excursion x;
    1153   gunichar ch;
     1149  gunichar ch = 0;
     1150  gunichar last_ch;
    11541151  int sentence;
    11551152
     
    11841181    }
    11851182
     1183    last_ch = ch;
    11861184    ch = owl_editwin_get_char_at_point(e);
    11871185
     
    12011199    }
    12021200
    1203     if(ch == '.' || ch == '!' || ch == '?')
     1201    if (ch == '.' || ch == '!' || ch == '?' ||
     1202        (ch == '"' && (last_ch == '.' || last_ch == '!' || last_ch == '?')))
    12041203      sentence = 1;
    12051204    else
     
    13691368}
    13701369
    1371 char *owl_editwin_get_region(owl_editwin *e)
     1370CALLER_OWN char *owl_editwin_get_region(owl_editwin *e)
    13721371{
    13731372  int start, end;
     
    13881387}
    13891388
    1390 static char *oe_chunk(owl_editwin *e, int start, int end)
     1389static CALLER_OWN char *oe_chunk(owl_editwin *e, int start, int end)
    13911390{
    13921391  char *p;
  • errqueue.c

    rd4927a7 reb897c6  
    33void owl_errqueue_init(owl_errqueue *eq)
    44{
    5   owl_list_create(&(eq->errlist));
     5  eq->errlist = g_ptr_array_new();
    66}
    77
    88void owl_errqueue_append_err(owl_errqueue *eq, const char *msg)
    99{
    10   owl_list_append_element(&(eq->errlist), g_strdup(msg));
     10  g_ptr_array_add(eq->errlist, g_strdup(msg));
    1111}
    1212
     
    1414void owl_errqueue_to_fmtext(const owl_errqueue *eq, owl_fmtext *fm)
    1515{
    16   int i, j;
    17 
    18   j=owl_list_get_size(&(eq->errlist));
    19   for (i=0; i<j; i++) {
    20     owl_fmtext_append_normal(fm, owl_list_get_element(&(eq->errlist), i));
     16  int i;
     17  for (i = 0; i < eq->errlist->len; i++) {
     18    owl_fmtext_append_normal(fm, eq->errlist->pdata[i]);
    2119    owl_fmtext_append_normal(fm, "\n");
    2220  }
  • filter.c

    re56303f rc068c03  
    1 #include <string.h>
    21#include "owl.h"
    32
     
    125124
    126125  op1 = owl_filter_parse_primitive_expression(argc-i, argv+i, &skip);
     126  if(!op1) goto err;
    127127  i += skip;
    128   if(!op1) goto err;
    129128
    130129  while(i < argc) {
     
    200199
    201200
    202 char* owl_filter_print(const owl_filter *f)
     201CALLER_OWN char *owl_filter_print(const owl_filter *f)
    203202{
    204203  GString *out = g_string_new("");
     
    220219    }
    221220    else {
    222       g_string_append_printf(out, "%i",f->fgcolor);
     221      g_string_append_printf(out, "%i",f->bgcolor);
    223222    }
    224223    g_string_append(out, " ");
  • filterelement.c

    rd4927a7 r7756dde  
    104104}
    105105
    106 /* XXX: Our boolea operators short-circuit here. The original owl did
     106/* XXX: Our boolean operators short-circuit here. The original owl did
    107107   not. Do we care?
    108108*/
  • filterproc.c

    re2cc848 r7155955  
    1 #include <signal.h>
     1#include "filterproc.h"
     2#include <sys/wait.h>
     3#include <fcntl.h>
     4#include <glib.h>
     5#include <poll.h>
     6#include <string.h>
    27#include <unistd.h>
    3 #include <sys/select.h>
    4 #include <sys/types.h>
    5 #include <sys/wait.h>
    6 #include <poll.h>
    7 #include <fcntl.h>
    8 #include <string.h>
    98
    10 #include <glib.h>
    11 
    12 int send_receive(int rfd, int wfd, const char *out, char **in)
     9/* Even in case of error, send_receive is responsible for closing wfd
     10 * (to EOF the child) and rfd (for consistency). */
     11static int send_receive(int rfd, int wfd, const char *out, char **in)
    1312{
    1413  GString *str = g_string_new("");
     
    2524  fds[1].fd = wfd;
    2625  fds[1].events = POLLOUT;
     26
     27  if(!out || !*out) {
     28    /* Nothing to write. Close our end so the child doesn't hang waiting. */
     29    close(wfd); wfd = -1;
     30    out = NULL;
     31  }
    2732
    2833  while(1) {
     
    4752      }
    4853      if(!out || !*out || fds[1].revents & (POLLERR | POLLHUP)) {
    49         close(wfd);
     54        close(wfd); wfd = -1;
    5055        out = NULL;
    5156      }
     
    6368  }
    6469
     70  if (wfd >= 0) close(wfd);
     71  close(rfd);
    6572  *in = g_string_free(str, err < 0);
    6673  return err;
    6774}
    6875
    69 int call_filter(const char *prog, const char *const *argv, const char *in, char **out, int *status)
     76int call_filter(const char *const *argv, const char *in, char **out, int *status)
    7077{
    71   int err = 0;
    72   pid_t pid;
    73   int rfd[2];
    74   int wfd[2];
     78  int err;
     79  GPid child_pid;
     80  int child_stdin, child_stdout;
    7581
    76   if((err = pipe(rfd))) goto out;
    77   if((err = pipe(wfd))) goto out_close_rfd;
    78 
    79   pid = fork();
    80   if(pid < 0) {
    81     err = pid;
    82     goto out_close_all;
    83   }
    84   if(pid) {
    85     /* parent */
    86     close(rfd[1]);
    87     close(wfd[0]);
    88     err = send_receive(rfd[0], wfd[1], in, out);
    89     if(err == 0) {
    90       waitpid(pid, status, 0);
    91     }
    92   } else {
    93     /* child */
    94     close(rfd[0]);
    95     close(wfd[1]);
    96     dup2(rfd[1], 1);
    97     dup2(wfd[0], 0);
    98     close(rfd[1]);
    99     close(wfd[0]);
    100 
    101     if(execvp(prog, (char *const *)argv)) {
    102       _exit(-1);
    103     }
     82  if (!g_spawn_async_with_pipes(NULL, (char**)argv, NULL,
     83                                G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
     84                                NULL, NULL,
     85                                &child_pid, &child_stdin, &child_stdout, NULL,
     86                                NULL)) {
     87    *out = NULL;
     88    return 1;
    10489  }
    10590
    106  out_close_all:
    107   close(wfd[0]);
    108   close(wfd[1]);
    109  out_close_rfd:
    110   close(rfd[0]);
    111   close(rfd[1]);
    112  out:
     91  err = send_receive(child_stdout, child_stdin, in, out);
     92  if (err == 0) {
     93    waitpid(child_pid, status, 0);
     94  }
    11395  return err;
    11496}
  • filterproc.h

    r06adc25 r97cdbaf5  
    22#define INC_BARNOWL_FILTER_PROC_H
    33
    4 int call_filter(const char *prog,
    5                 const char *const *argv,
     4int call_filter(const char *const *argv,
    65                const char *in,
    76                char **out, int *status);
  • fmtext.c

    r7b4f3be rf271129  
    11#include "owl.h"
    2 #include <stdlib.h>
    3 #include <string.h>
    42
    53/* initialize an fmtext with no data */
     
    171169 * freeing the return
    172170 */
    173 char *owl_fmtext_print_plain(const owl_fmtext *f)
     171CALLER_OWN char *owl_fmtext_print_plain(const owl_fmtext *f)
    174172{
    175173  return owl_strip_format_chars(f->buff->str);
     
    186184static void _owl_fmtext_wcolor_set(WINDOW *w, short pair)
    187185{
     186  cchar_t background;
     187  wchar_t blank[2] = { ' ', 0 };
    188188  if (has_colors()) {
    189       wcolor_set(w,pair,NULL);
    190       wbkgdset(w, COLOR_PAIR(pair));
     189      wcolor_set(w, pair, NULL);
     190      /* Set the background with wbkgrndset so that we can handle color-pairs
     191       * past 256 on ncurses ABI 6 and later. */
     192      setcchar(&background, blank, 0, pair, NULL);
     193      wbkgrndset(w, &background);
    191194  }
    192195}
     
    686689         * but zwgc seems to be smarter about some screw cases than I am
    687690         */
     691        g_free(buff);
    688692        owl_fmtext_append_attr(f, "@", curattrs, curcolor, OWL_COLOR_DEFAULT);
    689693        txtptr++;
     
    755759 * If format_fn is specified, passes it the list element value
    756760 * and it will return a string which this needs to free. */
    757 void owl_fmtext_append_list(owl_fmtext *f, const owl_list *l, const char *join_with, char *(format_fn)(const char *))
    758 {
    759   int i, size;
     761void owl_fmtext_append_list(owl_fmtext *f, const GPtrArray *l, const char *join_with, char *(format_fn)(const char *))
     762{
     763  int i;
    760764  const char *elem;
    761765  char *text;
    762766
    763   size = owl_list_get_size(l);
    764   for (i=0; i<size; i++) {
    765     elem = owl_list_get_element(l,i);
     767  for (i = 0; i < l->len; i++) {
     768    elem = l->pdata[i];
    766769    if (elem && format_fn) {
    767770      text = format_fn(elem);
     
    773776      owl_fmtext_append_normal(f, elem);
    774777    }
    775     if ((i < size-1) && join_with) {
     778    if ((i < l->len - 1) && join_with) {
    776779      owl_fmtext_append_normal(f, join_with);
    777780    }
  • functions.c

    r259e60a8 r60e8617  
     1#include "owl.h"
     2#include "filterproc.h"
    13#include <stdio.h>
    2 #include <stdlib.h>
    3 #include <unistd.h>
    4 #include <signal.h>
    5 #include <netinet/in.h>
    6 #include <string.h>
    7 #include <time.h>
    8 #include <sys/types.h>
    94#include <sys/stat.h>
    105#include <sys/wait.h>
    11 #include <errno.h>
    12 #include <signal.h>
    13 #include "owl.h"
    14 #include "filterproc.h"
    15 
    16 char *owl_function_command(const char *cmdbuff)
     6
     7CALLER_OWN char *owl_function_command(const char *cmdbuff)
    178{
    189  owl_function_debugmsg("executing command: %s", cmdbuff);
     
    2112}
    2213
    23 char *owl_function_command_argv(const char *const *argv, int argc)
     14CALLER_OWN char *owl_function_command_argv(const char *const *argv, int argc)
    2415{
    2516  return owl_cmddict_execute_argv(owl_global_get_cmddict(&g),
     
    4738void owl_function_show_commands(void)
    4839{
    49   owl_list l;
     40  GPtrArray *l;
    5041  owl_fmtext fm;
    5142
     
    5344  owl_fmtext_append_bold(&fm, "Commands:  ");
    5445  owl_fmtext_append_normal(&fm, "(use 'show command <name>' for details)\n");
    55   owl_list_create(&l);
    56   owl_cmddict_get_names(owl_global_get_cmddict(&g), &l);
    57   owl_fmtext_append_list(&fm, &l, "\n", owl_function_cmd_describe);
     46  l = owl_cmddict_get_names(owl_global_get_cmddict(&g));
     47  owl_fmtext_append_list(&fm, l, "\n", owl_function_cmd_describe);
    5848  owl_fmtext_append_normal(&fm, "\n");
    5949  owl_function_popless_fmtext(&fm);
    60   owl_list_cleanup(&l, g_free);
     50  owl_ptr_array_free(l, g_free);
    6151  owl_fmtext_cleanup(&fm);
    6252}
     
    8171
    8272void owl_function_show_styles(void) {
    83   owl_list l;
     73  GPtrArray *l;
    8474  owl_fmtext fm;
    8575
    8676  owl_fmtext_init_null(&fm);
    8777  owl_fmtext_append_bold(&fm, "Styles:\n");
    88   owl_list_create(&l);
    89   owl_global_get_style_names(&g, &l);
    90   owl_fmtext_append_list(&fm, &l, "\n", owl_function_style_describe);
     78  l = owl_global_get_style_names(&g);
     79  owl_fmtext_append_list(&fm, l, "\n", owl_function_style_describe);
    9180  owl_fmtext_append_normal(&fm, "\n");
    9281  owl_function_popless_fmtext(&fm);
    93   owl_list_cleanup(&l, g_free);
     82  owl_ptr_array_free(l, g_free);
    9483  owl_fmtext_cleanup(&fm);
    9584}
    9685
    97 static void _owl_function_timer_append_fmtext(gpointer data, gpointer user_data) {
    98   owl_fmtext *fm = user_data;
    99   owl_timer *timer = data;
    100   char *str = g_strdup_printf("- %s: in %d seconds",
    101                               timer->name ? timer->name : "(unnamed)",
    102                               (int)(timer->time - time(NULL)));
    103   owl_fmtext_append_normal(fm, str);
    104   g_free(str);
    105   if (timer->interval) {
    106     str = g_strdup_printf(", repeat every %d seconds", timer->interval);
    107     owl_fmtext_append_normal(fm, str);
    108     g_free(str);
    109   }
    110   owl_fmtext_append_normal(fm, "\n");
    111 }
    112 
    113 void owl_function_show_timers(void) {
    114   owl_fmtext fm;
    115   GList **timers;
    116 
    117   owl_fmtext_init_null(&fm);
    118   owl_fmtext_append_bold(&fm, "Active timers:\n");
    119 
    120   timers = owl_global_get_timerlist(&g);
    121   g_list_foreach(*timers, _owl_function_timer_append_fmtext, &fm);
    122 
    123   owl_function_popless_fmtext(&fm);
    124   owl_fmtext_cleanup(&fm);
    125 }
    126 
    127 char *owl_function_style_describe(const char *name) {
     86CALLER_OWN char *owl_function_style_describe(const char *name)
     87{
    12888  const char *desc;
    12989  char *s;
     
    141101}
    142102
    143 char *owl_function_cmd_describe(const char *name)
     103CALLER_OWN char *owl_function_cmd_describe(const char *name)
    144104{
    145105  const owl_cmd *cmd = owl_cmddict_find(owl_global_get_cmddict(&g), name);
     
    158118
    159119  text=""
    160     "barnowl version " OWL_VERSION_STRING "\n"
     120    "BarnOwl version " OWL_VERSION_STRING "\n"
    161121    "Copyright (c) 2006-2011 The BarnOwl Developers. All rights reserved.\n"
    162122    "Copyright (c) 2004 James Kretchmar. All rights reserved.\n"
     
    175135    "\n"
    176136    "   * Redistributions in any form must be accompanied by information on\n"
    177     "     how to obtain complete source code for the Owl software and any\n"
    178     "     accompanying software that uses the Owl software. The source code\n"
     137    "     how to obtain complete source code for the BarnOwl software and any\n"
     138    "     accompanying software that uses the BarnOwl software. The source code\n"
    179139    "     must either be included in the distribution or be available for no\n"
    180140    "     more than the cost of distribution plus a nominal fee, and must be\n"
     
    244204
    245205  /* do followlast if necessary */
    246   if (owl_global_should_followlast(&g)) owl_function_lastmsg_noredisplay();
     206  if (owl_global_should_followlast(&g)) owl_function_lastmsg();
    247207
    248208  /* redisplay etc. */
     
    256216void owl_function_add_outgoing_zephyrs(const owl_zwrite *z)
    257217{
    258   if (z->cc || owl_zwrite_get_numrecips(z) == 0) {
     218  if (z->cc && owl_zwrite_is_personal(z)) {
    259219    /* create the message */
    260220    owl_message *m = g_new(owl_message, 1);
     
    265225    int i;
    266226    for (i = 0; i < owl_zwrite_get_numrecips(z); i++) {
     227      owl_message *m;
     228
     229      if (!owl_zwrite_recip_is_personal(owl_zwrite_get_recip_n(z, i)))
     230        continue;
     231
    267232      /* create the message */
    268       owl_message *m = g_new(owl_message, 1);
     233      m = g_new(owl_message, 1);
    269234      owl_message_create_from_zwrite(m, z, owl_zwrite_get_message(z), i);
    270235
     
    279244 * owl_global_messagequeue_addmsg() for that.
    280245 */
    281 owl_message *owl_function_make_outgoing_aim(const char *body, const char *to)
     246CALLER_OWN owl_message *owl_function_make_outgoing_aim(const char *body, const char *to)
    282247{
    283248  owl_message *m;
     
    300265 * owl_global_messagequeue_addmsg() for that.
    301266 */
    302 owl_message *owl_function_make_outgoing_loopback(const char *body)
     267CALLER_OWN owl_message *owl_function_make_outgoing_loopback(const char *body)
    303268{
    304269  owl_message *m;
     
    312277}
    313278
    314 void owl_function_start_edit_win(const char *line, void (*callback)(owl_editwin *), void *data, void (*cleanup)(void *))
     279owl_editwin *owl_function_start_edit_win(const char *line)
    315280{
    316281  owl_editwin *e;
     
    326291  g_free(s);
    327292
    328   owl_editwin_set_cbdata(e, data, cleanup);
    329   owl_editwin_set_callback(e, callback);
    330293  ctx = owl_editcontext_new(OWL_CTX_EDITMULTI, e, "editmulti",
    331294                            owl_global_deactivate_editcontext, &g);
    332295  owl_global_push_context_obj(&g, ctx);
    333 
     296  return e;
    334297}
    335298
     
    349312void owl_function_zwrite_setup(owl_zwrite *z)
    350313{
     314  owl_editwin *e;
    351315  /* send a ping if necessary */
    352316  if (owl_global_is_txping(&g)) {
     
    356320
    357321  owl_function_write_setup("zephyr");
    358   owl_function_start_edit_win(z->zwriteline,
    359                               &owl_callback_zwrite,
    360                               z, (void(*)(void*))owl_zwrite_delete);
     322  e = owl_function_start_edit_win(z->zwriteline);
     323  owl_editwin_set_cbdata(e, z, (void (*)(void *))owl_zwrite_delete);
     324  owl_editwin_set_callback(e, &owl_callback_zwrite);
    361325}
    362326
    363327void owl_function_aimwrite_setup(const char *to)
    364328{
     329  owl_editwin *e;
    365330  /* TODO: We probably actually want an owl_aimwrite object like
    366331   * owl_zwrite. */
    367332  char *line = g_strdup_printf("aimwrite %s", to);
    368333  owl_function_write_setup("message");
    369   owl_function_start_edit_win(line,
    370                               &owl_callback_aimwrite,
    371                               g_strdup(to),
    372                               g_free);
     334  e = owl_function_start_edit_win(line);
     335  owl_editwin_set_cbdata(e, g_strdup(to), g_free);
     336  owl_editwin_set_callback(e, &owl_callback_aimwrite);
    373337  g_free(line);
    374338}
     
    376340void owl_function_loopwrite_setup(void)
    377341{
     342  owl_editwin *e;
    378343  owl_function_write_setup("message");
    379   owl_function_start_edit_win("loopwrite",
    380                               &owl_callback_loopwrite,
    381                               NULL, NULL);
    382 }
    383 
    384 void owl_callback_zwrite(owl_editwin *e) {
     344  e = owl_function_start_edit_win("loopwrite");
     345  owl_editwin_set_callback(e, &owl_callback_loopwrite);
     346}
     347
     348void owl_callback_zwrite(owl_editwin *e, bool success)
     349{
     350  if (!success) return;
    385351  owl_zwrite *z = owl_editwin_get_cbdata(e);
    386352  owl_function_zwrite(z, owl_editwin_get_text(e));
     
    412378  owl_function_makemsg("Waiting for ack...");
    413379
    414   /* If it's personal */
    415   if (owl_zwrite_is_personal(z)) {
    416     /* create the outgoing message */
    417     owl_function_add_outgoing_zephyrs(z);
    418   }
     380  /* create the outgoing message */
     381  owl_function_add_outgoing_zephyrs(z);
    419382}
    420383#else
     
    441404  old_msg = g_strdup(owl_zwrite_get_message(z));
    442405
    443   zcrypt = g_strdup_printf("%s/zcrypt", owl_get_bindir());
    444   argv[0] = "zcrypt";
     406  zcrypt = g_build_filename(owl_get_bindir(), "zcrypt", NULL);
     407  argv[0] = zcrypt;
    445408  argv[1] = "-E";
    446409  argv[2] = "-c"; argv[3] = owl_zwrite_get_class(z);
     
    448411  argv[6] = NULL;
    449412
    450   rv = call_filter(zcrypt, argv, owl_zwrite_get_message(z), &cryptmsg, &status);
     413  rv = call_filter(argv, owl_zwrite_get_message(z), &cryptmsg, &status);
    451414
    452415  g_free(zcrypt);
     
    466429  owl_function_makemsg("Waiting for ack...");
    467430
    468   /* If it's personal */
    469   if (owl_zwrite_is_personal(z)) {
    470     /* Create the outgoing message. Restore the un-crypted message for display. */
    471     owl_zwrite_set_message_raw(z, old_msg);
    472     owl_function_add_outgoing_zephyrs(z);
    473   }
    474 
    475   /* free the zwrite */
     431  /* Create the outgoing message. Restore the un-crypted message for display. */
     432  owl_zwrite_set_message_raw(z, old_msg);
     433  owl_function_add_outgoing_zephyrs(z);
     434
     435  /* Clean up. */
    476436  g_free(cryptmsg);
    477 }
    478 
    479 void owl_callback_aimwrite(owl_editwin *e) {
     437  g_free(old_msg);
     438}
     439
     440void owl_callback_aimwrite(owl_editwin *e, bool success)
     441{
     442  if (!success) return;
    480443  char *to = owl_editwin_get_cbdata(e);
    481444  owl_function_aimwrite(to, owl_editwin_get_text(e), true);
     
    541504}
    542505
    543 void owl_callback_loopwrite(owl_editwin *e) {
     506void owl_callback_loopwrite(owl_editwin *e, bool success)
     507{
     508  if (!success) return;
    544509  owl_function_loopwrite(owl_editwin_get_text(e));
    545510}
     
    691656{
    692657  owl_function_prevmsg_full(NULL, 1, 1);
     658}
     659
     660void owl_function_delete_and_expunge_message(int n)
     661{
     662  owl_messagelist *ml = owl_global_get_msglist(&g);
     663  owl_view *v = owl_global_get_current_view(&g);
     664  int lastmsgid = owl_function_get_curmsg_id(v);
     665
     666  /* delete and expunge the message */
     667  owl_messagelist_delete_and_expunge_element(ml, n);
     668
     669  owl_function_redisplay_to_nearest(lastmsgid, v);
     670}
     671
     672void owl_function_delete_and_expunge_cur(bool exclaim_success)
     673{
     674  int curmsg;
     675  const owl_view *v = owl_global_get_current_view(&g);
     676
     677  /* bail if there's no current message */
     678  if (owl_view_get_size(v) < 1) {
     679    owl_function_error("No current message to delete");
     680    return;
     681  }
     682
     683  /* delete the current message */
     684  curmsg = owl_global_get_curmsg(&g);
     685  owl_function_delete_and_expunge_message(curmsg);
     686  if (exclaim_success)
     687    owl_function_makemsg("Message deleted and expunged");
    693688}
    694689
     
    752747}
    753748
     749/* returns the current message id, if it exists.  Otherwise returns
     750 * -1 if we are past the end of the message list, and 0 otherwise. */
     751int owl_function_get_curmsg_id(const owl_view *v)
     752{
     753  int curmsg = owl_global_get_curmsg(&g);
     754  const owl_message *m = owl_view_get_element(v, curmsg);
     755  if (m)
     756    return owl_message_get_id(m);
     757  if (curmsg > 0) /* past the end of the message list (probably) */
     758    return -1;
     759  return 0;
     760}
     761
     762/* redisplays the view to the nearest message to the id given.
     763 * if msgid < 0, redisplay to past the end of the message list */
     764void owl_function_redisplay_to_nearest(int msgid, owl_view *v)
     765{
     766  int curmsg;
     767  /* update all views (we only have one right now) */
     768  owl_view_recalculate(v);
     769
     770  /* find where the new position should be */
     771  if (msgid < 0) {
     772    /* If already at the end, blank the screen and move curmsg
     773     * past the end of the messages. */
     774    curmsg = owl_view_get_size(v);
     775    owl_global_set_topmsg(&g, curmsg);
     776    owl_global_set_curmsg(&g, curmsg);
     777  } else {
     778    curmsg = owl_view_get_nearest_to_msgid(v, msgid);
     779    if (curmsg > owl_view_get_size(v) - 1)
     780      curmsg = owl_view_get_size(v) - 1;
     781    if (curmsg < 0)
     782      curmsg = 0;
     783    owl_global_set_curmsg(&g, curmsg);
     784    owl_function_calculate_topmsg(OWL_DIRECTION_NONE);
     785  }
     786  /* if there are no messages set the direction to down in case we
     787   * delete everything upwards */
     788  owl_global_set_direction_downwards(&g);
     789
     790  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
     791}
     792
    754793void owl_function_expunge(void)
    755794{
    756   int curmsg;
    757   const owl_message *m;
    758   owl_messagelist *ml;
    759   owl_view *v;
    760   int lastmsgid=0;
    761 
    762   curmsg=owl_global_get_curmsg(&g);
    763   v=owl_global_get_current_view(&g);
    764   ml=owl_global_get_msglist(&g);
    765 
    766   m=owl_view_get_element(v, curmsg);
    767   if (m) lastmsgid = owl_message_get_id(m);
     795  owl_messagelist *ml = owl_global_get_msglist(&g);
     796  owl_view *v = owl_global_get_current_view(&g);
     797  int lastmsgid = owl_function_get_curmsg_id(v);
    768798
    769799  /* expunge the message list */
    770800  owl_messagelist_expunge(ml);
    771801
    772   /* update all views (we only have one right now) */
    773   owl_view_recalculate(v);
    774 
    775   /* find where the new position should be
    776      (as close as possible to where we last where) */
    777   curmsg = owl_view_get_nearest_to_msgid(v, lastmsgid);
    778   if (curmsg>owl_view_get_size(v)-1) curmsg = owl_view_get_size(v)-1;
    779   if (curmsg<0) curmsg = 0;
    780   owl_global_set_curmsg(&g, curmsg);
    781   owl_function_calculate_topmsg(OWL_DIRECTION_NONE);
    782   /* if there are no messages set the direction to down in case we
    783      delete everything upwards */
    784   owl_global_set_direction_downwards(&g);
     802  owl_function_redisplay_to_nearest(lastmsgid, v);
    785803 
    786804  owl_function_makemsg("Messages expunged");
    787   owl_mainwin_redisplay(owl_global_get_mainwin(&g));
    788805}
    789806
     
    796813}
    797814
    798 void owl_function_lastmsg_noredisplay(void)
     815void owl_function_lastmsg(void)
    799816{
    800817  int oldcurmsg, curmsg;
     
    814831    owl_global_set_curmsg(&g, curmsg+1);
    815832  }
    816   /* owl_mainwin_redisplay(owl_global_get_mainwin(&g)); */
     833  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
    817834  owl_global_set_direction_downwards(&g);
    818 }
    819 
    820 void owl_function_lastmsg(void)
    821 {
    822   owl_function_lastmsg_noredisplay();
    823   owl_mainwin_redisplay(owl_global_get_mainwin(&g)); 
    824835}
    825836
     
    844855void owl_function_unsuball(void)
    845856{
    846   unsuball();
    847   owl_function_makemsg("Unsubscribed from all messages.");
     857  if (unsuball())
     858    owl_function_makemsg("Unsubscribed from all messages.");
    848859}
    849860
     
    860871void owl_function_loadsubs(const char *file)
    861872{
    862   int ret, ret2;
    863   const char *foo;
     873  int ret, ret2, ret3;
    864874  char *path;
    865875
     
    873883
    874884  /* for backwards compatibility for now */
    875   ret2=owl_zephyr_loaddefaultsubs();
     885  ret2 = owl_zephyr_loaddefaultsubs();
     886  ret3 = owl_zephyr_loadbarnowldefaultsubs();
    876887
    877888  if (!owl_context_is_interactive(owl_global_get_context(&g))) return;
    878889
    879   foo=file?file:"file";
    880   if (ret==0 && ret2==0) {
     890  if (ret == 0 && ret2 == 0 && ret3 == 0) {
    881891    if (!file) {
    882892      owl_function_makemsg("Subscribed to messages.");
     
    884894      owl_function_makemsg("Subscribed to messages from %s", file);
    885895    }
    886   } else if (ret==-1) {
    887     owl_function_error("Could not read %s", foo);
    888   } else {
     896  } else if (ret == -1) {
     897    owl_function_error("Could not read %s", file ? file : "file");
     898  } else if (ret2 == -1) {
    889899    owl_function_error("Error subscribing to messages");
     900  } else {
     901    owl_function_error("Error subscribing to instanced personals");
    890902  }
    891903}
     
    906918}
    907919
    908 void owl_callback_aimlogin(owl_editwin *e) {
     920void owl_callback_aimlogin(owl_editwin *e, bool success)
     921{
     922  if (!success) return;
    909923  char *user = owl_editwin_get_cbdata(e);
    910924  owl_function_aimlogin(user,
     
    10031017  }
    10041018
    1005   owl_function_debugmsg("Quitting Owl");
     1019  owl_function_debugmsg("Quitting BarnOwl");
    10061020  owl_select_quit_loop();
    10071021}
     
    12021216void G_GNUC_PRINTF(1, 2) owl_function_debugmsg(const char *fmt, ...)
    12031217{
     1218  char *tmpbuff;
    12041219  FILE *file;
    12051220  time_t now;
     
    12161231  now = time(NULL);
    12171232
    1218   fprintf(file, "[%d -  %.24s - %lds]: ",
    1219           (int) getpid(), ctime(&now), now - owl_global_get_starttime(&g));
     1233  tmpbuff = owl_util_format_time(localtime(&now));
     1234  fprintf(file, "[%d -  %s - %lds]: ",
     1235          (int) getpid(), tmpbuff, now - owl_global_get_starttime(&g));
     1236  g_free(tmpbuff);
    12201237  vfprintf(file, fmt, ap);
    12211238  putc('\n', file);
     
    12571274}
    12581275
    1259 static void _dirty_everything(owl_window *w) {
     1276static void _dirty_everything(gpointer data, gpointer user_data) {
     1277  owl_window *w = data;
    12601278  if (!owl_window_is_realized(w))
    12611279    return;
    12621280  owl_window_dirty(w);
    1263   owl_window_children_foreach(w, (GFunc)_dirty_everything, NULL);
     1281  owl_window_children_foreach(w, _dirty_everything, NULL);
    12641282}
    12651283
     
    12671285{
    12681286  /* Ask every widget to redraw itself. */
    1269   _dirty_everything(owl_window_get_screen());
     1287  _dirty_everything(owl_window_get_screen(), NULL);
    12701288  /* Force ncurses to redisplay everything. */
    12711289  clearok(stdscr, TRUE);
     
    13351353{
    13361354  owl_function_popless_text(
    1337     "This is barnowl version " OWL_VERSION_STRING ".\n\n"
    1338     "barnowl is a fork of the Owl zephyr client, written and\n"
     1355    "This is BarnOwl version " OWL_VERSION_STRING ".\n\n"
     1356    "BarnOwl is a fork of the Owl zephyr client, written and\n"
    13391357    "maintained by Alejandro Sedeno and Nelson Elhage at the\n"
    13401358    "Massachusetts Institute of Technology. \n"
     
    13451363    "The name 'owl' was chosen in reference to the owls in the\n"
    13461364    "Harry Potter novels, who are tasked with carrying messages\n"
    1347     "between Witches and Wizards. The name 'barnowl' was chosen\n"
     1365    "between Witches and Wizards. The name 'BarnOwl' was chosen\n"
    13481366    "because we feel our owls should live closer to our ponies.\n"
    13491367    "\n"
     
    13631381  owl_fmtext fm, attrfm;
    13641382  const owl_view *v;
     1383  char *time;
    13651384#ifdef HAVE_LIBZEPHYR
    13661385  const ZNotice_t *n;
     
    13931412  }
    13941413
    1395   owl_fmtext_appendf_normal(&fm, "  Time      : %s\n", owl_message_get_timestr(m));
     1414  time = owl_message_format_time(m);
     1415  owl_fmtext_appendf_normal(&fm, "  Time      : %s\n", time);
     1416  g_free(time);
    13961417
    13971418  if (!owl_message_is_type_admin(m)) {
     
    14071428    owl_fmtext_appendf_normal(&fm, "  Opcode    : %s\n", owl_message_get_opcode(m));
    14081429#ifdef HAVE_LIBZEPHYR
    1409     if (owl_message_is_direction_in(m)) {
    1410       char *tmpbuff;
     1430    n = owl_message_get_notice(m);
     1431    if (n != NULL) {
     1432      char *tmpbuff, *tmpbuff2;
    14111433      int i, fields;
    1412 
    1413       n=owl_message_get_notice(m);
     1434      const char *f;
    14141435
    14151436      if (!owl_message_is_pseudo(m)) {
     
    14531474        owl_fmtext_appendf_normal(&fm, "  Fields    : %i\n", fields);
    14541475
    1455         for (i = 0; i < fields; i++) {
    1456           tmpbuff = owl_zephyr_get_field_as_utf8(n, i + 1);
    1457 
    1458           g_strdelimit(tmpbuff, "\n", '~');
    1459           g_strdelimit(tmpbuff, "\r", '!');
    1460 
    1461           owl_fmtext_appendf_normal(&fm, "  Field %i   : %s\n", i + 1, tmpbuff);
    1462           g_free(tmpbuff);
     1476        for (i = 0, f = owl_zephyr_first_raw_field(n); f != NULL;
     1477             i++, f = owl_zephyr_next_raw_field(n, f)) {
     1478          tmpbuff = owl_zephyr_field_as_utf8(n, f);
     1479          tmpbuff2 = owl_text_indent(tmpbuff, 14, false);
     1480          owl_fmtext_appendf_normal(&fm, "  Field %i   : %s\n", i + 1, tmpbuff2);
     1481          g_free(tmpbuff2);
     1482          g_free(tmpbuff);
    14631483        }
    1464         owl_fmtext_appendf_normal(&fm, "  Default Fm: %s\n", n->z_default_format);
     1484        tmpbuff = owl_text_indent(n->z_default_format, 14, false);
     1485        owl_fmtext_appendf_normal(&fm, "  Default Fm: %s\n", tmpbuff);
     1486        g_free(tmpbuff);
    14651487      }
    14661488
     
    14691491  }
    14701492
    1471   owl_fmtext_append_bold(&fm, "\nOwl Message Attributes:\n");
     1493  owl_fmtext_append_bold(&fm, "\nBarnOwl Message Attributes:\n");
    14721494  owl_message_attributes_tofmtext(m, &attrfm);
    14731495  owl_fmtext_append_fmtext(&fm, &attrfm);
     
    16021624void owl_function_printallvars(void)
    16031625{
     1626  const owl_variable *v;
    16041627  const char *name;
    16051628  char *var;
    1606   owl_list varnames;
    1607   int i, numvarnames;
     1629  GPtrArray *varnames;
     1630  int i;
    16081631  GString *str   = g_string_new("");
    16091632
    16101633  g_string_append_printf(str, "%-20s = %s\n", "VARIABLE", "VALUE");
    16111634  g_string_append_printf(str, "%-20s   %s\n",  "--------", "-----");
    1612   owl_list_create(&varnames);
    1613   owl_variable_dict_get_names(owl_global_get_vardict(&g), &varnames);
    1614   numvarnames = owl_list_get_size(&varnames);
    1615   for (i=0; i<numvarnames; i++) {
    1616     name = owl_list_get_element(&varnames, i);
     1635  varnames = owl_variable_dict_get_names(owl_global_get_vardict(&g));
     1636  for (i = 0; i < varnames->len; i++) {
     1637    name = varnames->pdata[i];
    16171638    if (name && name[0]!='_') {
    16181639      g_string_append_printf(str, "\n%-20s = ", name);
    1619       var = owl_variable_get_tostring(owl_global_get_vardict(&g), name);
     1640      v = owl_variable_get_var(owl_global_get_vardict(&g), name);
     1641      var = owl_variable_get_tostring(v);
    16201642      if (var) {
    1621         g_string_append(str, var);
    1622         g_free(var);
     1643        g_string_append(str, var);
     1644        g_free(var);
     1645      } else {
     1646        g_string_append(str, "<null>");
    16231647      }
    16241648    }
    16251649  }
    16261650  g_string_append(str, "\n");
    1627   owl_list_cleanup(&varnames, g_free);
     1651  owl_ptr_array_free(varnames, g_free);
    16281652
    16291653  owl_function_popless_text(str->str);
     
    16331657void owl_function_show_variables(void)
    16341658{
    1635   owl_list varnames;
     1659  const owl_variable *v;
     1660  GPtrArray *varnames;
    16361661  owl_fmtext fm; 
    1637   int i, numvarnames;
     1662  int i;
    16381663  const char *varname;
    16391664
     
    16411666  owl_fmtext_append_bold(&fm,
    16421667      "Variables: (use 'show variable <name>' for details)\n");
    1643   owl_list_create(&varnames);
    1644   owl_variable_dict_get_names(owl_global_get_vardict(&g), &varnames);
    1645   numvarnames = owl_list_get_size(&varnames);
    1646   for (i=0; i<numvarnames; i++) {
    1647     varname = owl_list_get_element(&varnames, i);
     1668  varnames = owl_variable_dict_get_names(owl_global_get_vardict(&g));
     1669  for (i = 0; i < varnames->len; i++) {
     1670    varname = varnames->pdata[i];
    16481671    if (varname && varname[0]!='_') {
    1649       owl_variable_describe(owl_global_get_vardict(&g), varname, &fm);
    1650     }
    1651   }
    1652   owl_list_cleanup(&varnames, g_free);
     1672      v = owl_variable_get_var(owl_global_get_vardict(&g), varname);
     1673      owl_variable_describe(v, &fm);
     1674    }
     1675  }
     1676  owl_ptr_array_free(varnames, g_free);
    16531677  owl_function_popless_fmtext(&fm);
    16541678  owl_fmtext_cleanup(&fm);
     
    16571681void owl_function_show_variable(const char *name)
    16581682{
     1683  const owl_variable *v;
    16591684  owl_fmtext fm; 
    16601685
    16611686  owl_fmtext_init_null(&fm);
    1662   owl_variable_get_help(owl_global_get_vardict(&g), name, &fm);
     1687  v = owl_variable_get_var(owl_global_get_vardict(&g), name);
     1688  if (v)
     1689    owl_variable_get_help(v, &fm);
     1690  else
     1691    owl_fmtext_append_normal(&fm, "No such variable...\n");
    16631692  owl_function_popless_fmtext(&fm);
    16641693  owl_fmtext_cleanup(&fm);
     1694}
     1695
     1696void owl_function_delete_and_expunge_by_id(int id, bool exclaim_success)
     1697{
     1698  const owl_messagelist *ml = owl_global_get_msglist(&g);
     1699  int msg = owl_messagelist_get_index_by_id(ml, id);
     1700  if (msg < 0) {
     1701    owl_function_error("No message with id %d: unable to delete", id);
     1702  } else {
     1703    owl_function_delete_and_expunge_message(msg);
     1704    if (exclaim_success)
     1705      owl_function_makemsg("Message deleted and expunged");
     1706  }
    16651707}
    16661708
     
    17191761void owl_function_status(void)
    17201762{
     1763  char *tmpbuff;
    17211764  char buff[MAXPATHLEN+1];
    17221765  time_t start;
     
    17461789  owl_fmtext_append_normal(&fm, "\n");
    17471790
    1748   owl_fmtext_appendf_normal(&fm, "  Startup Time: %s", ctime(&start));
     1791  tmpbuff = owl_util_format_time(localtime(&start));
     1792  owl_fmtext_appendf_normal(&fm, "  Startup Time: %s\n", tmpbuff);
     1793  g_free(tmpbuff);
    17491794
    17501795  up=owl_global_get_runtime(&g);
     
    18691914    if (enter) {
    18701915      owl_history *hist = owl_global_get_cmd_history(&g);
    1871       owl_history_store(hist, buff);
    1872       owl_history_reset(hist);
     1916      owl_history_store(hist, buff, false);
    18731917      owl_function_command_norv(buff);
    18741918    } else {
     
    19001944}
    19011945
    1902 void owl_callback_command(owl_editwin *e)
    1903 {
     1946void owl_callback_command(owl_editwin *e, bool success)
     1947{
     1948  if (!success) return;
    19041949  char *rv;
    19051950  const char *line = owl_editwin_get_text(e);
     
    19121957}
    19131958
    1914 void owl_function_start_command(const char *line)
     1959owl_editwin *owl_function_start_command(const char *line)
    19151960{
    19161961  owl_editwin *tw;
     
    19271972  owl_global_push_context_obj(&g, ctx);
    19281973  owl_editwin_set_callback(tw, owl_callback_command);
     1974  return tw;
    19291975}
    19301976
     
    19612007}
    19622008
    1963 char *owl_function_exec(int argc, const char *const *argv, const char *buff, int type)
     2009CALLER_OWN char *owl_function_exec(int argc, const char *const *argv, const char *buff, int type)
    19642010{
    19652011  /* if type == 1 display in a popup
     
    20042050}
    20052051
    2006 char *owl_function_perl(int argc, const char *const *argv, const char *buff, int type)
     2052CALLER_OWN char *owl_function_perl(int argc, const char *const *argv, const char *buff, int type)
    20072053{
    20082054  /* if type == 1 display in a popup
     
    20852131
    20862132/* Create a new filter, or replace an existing one
    2087  * with a new definition.
     2133 * with a new definition. Returns true on success.
    20882134 */
    2089 void owl_function_create_filter(int argc, const char *const *argv)
     2135bool owl_function_create_filter(int argc, const char *const *argv)
    20902136{
    20912137  owl_filter *f;
     
    20952141  if (argc < 2) {
    20962142    owl_function_error("Wrong number of arguments to filter command");
    2097     return;
     2143    return false;
    20982144  }
    20992145
     
    21052151  if (!strcmp(argv[1], "all")) {
    21062152    owl_function_error("You may not change the 'all' filter.");
    2107     return;
     2153    return false;
    21082154  }
    21092155
     
    21132159    if (!f) {
    21142160      owl_function_error("The filter '%s' does not exist.", argv[1]);
    2115       return;
     2161      return false;
    21162162    }
    21172163    if (owl_util_string_to_color(argv[3])==OWL_COLOR_INVALID) {
    21182164      owl_function_error("The color '%s' is not available.", argv[3]);
    2119       return;
     2165      return false;
    21202166    }
    21212167    owl_filter_set_fgcolor(f, owl_util_string_to_color(argv[3]));
    21222168    owl_mainwin_redisplay(owl_global_get_mainwin(&g));
    2123     return;
     2169    return false;
    21242170  }
    21252171  if (argc==4 && !strcmp(argv[2], "-b")) {
     
    21272173    if (!f) {
    21282174      owl_function_error("The filter '%s' does not exist.", argv[1]);
    2129       return;
     2175      return false;
    21302176    }
    21312177    if (owl_util_string_to_color(argv[3])==OWL_COLOR_INVALID) {
    21322178      owl_function_error("The color '%s' is not available.", argv[3]);
    2133       return;
     2179      return false;
    21342180    }
    21352181    owl_filter_set_bgcolor(f, owl_util_string_to_color(argv[3]));
    21362182    owl_mainwin_redisplay(owl_global_get_mainwin(&g));
    2137     return;
     2183    return true;
    21382184  }
    21392185
     
    21412187  f = owl_filter_new(argv[1], argc-2, argv+2);
    21422188  if (f == NULL) {
    2143     owl_function_error("Invalid filter");
    2144     return;
     2189    owl_function_error("Invalid filter: %s", argv[1]);
     2190    return false;
    21452191  }
    21462192
     
    21632209  }
    21642210  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
     2211  return true;
    21652212}
    21662213
     
    21742221 * Returns the name of the negated filter, which the caller must free.
    21752222 */
    2176 char *owl_function_create_negative_filter(const char *filtername)
     2223CALLER_OWN char *owl_function_create_negative_filter(const char *filtername)
    21772224{
    21782225  char *newname;
     
    22442291{
    22452292  const owl_filter *f;
    2246   const owl_list *fl;
     2293  const GPtrArray *fl;
    22472294  char *tmp;
    22482295  owl_fmtext fm;
    2249   int i, j;
     2296  int i;
    22502297
    22512298  owl_fmtext_init_null(&fm);
    22522299
    22532300  fl=owl_global_get_puntlist(&g);
    2254   j=owl_list_get_size(fl);
    22552301  owl_fmtext_append_bold(&fm, "Active zpunt filters:\n");
    22562302
    2257   for (i=0; i<j; i++) {
    2258     f=owl_list_get_element(fl, i);
     2303  for (i = 0; i < fl->len; i++) {
     2304    f = fl->pdata[i];
    22592305    owl_fmtext_appendf_normal(&fm, "[% 2d] ", i+1);
    22602306    tmp = owl_filter_print(f);
     
    22712317 * If 'related' is nonzero, encompass unclasses and .d classes as well.
    22722318 */
    2273 char *owl_function_classinstfilt(const char *c, const char *i, int related)
     2319CALLER_OWN char *owl_function_classinstfilt(const char *c, const char *i, int related)
    22742320{
    22752321  owl_filter *f;
     
    23582404 * the filter, which the caller must free.
    23592405 */
    2360 char *owl_function_zuserfilt(const char *longuser)
     2406CALLER_OWN char *owl_function_zuserfilt(const char *longuser)
    23612407{
    23622408  owl_filter *f;
     
    24042450 * Returns the name of the filter, which the caller must free.
    24052451 */
    2406 char *owl_function_aimuserfilt(const char *user)
     2452CALLER_OWN char *owl_function_aimuserfilt(const char *user)
    24072453{
    24082454  owl_filter *f;
     
    24152461  /* if it already exists then go with it.  This lets users override */
    24162462  if (owl_global_get_filter(&g, filtname)) {
    2417     return(g_strdup(filtname));
     2463    return filtname;
    24182464  }
    24192465
     
    24422488}
    24432489
    2444 char *owl_function_typefilt(const char *type)
     2490CALLER_OWN char *owl_function_typefilt(const char *type)
    24452491{
    24462492  owl_filter *f;
     
    24982544}
    24992545
    2500 static char *owl_function_smartfilter_cc(const owl_message *m) {
     2546static CALLER_OWN char *owl_function_smartfilter_cc(const owl_message *m)
     2547{
    25012548  const char *ccs;
    25022549  char *ccs_quoted;
     
    25492596 *    name to the AIM conversation with that user
    25502597 */
    2551 char *owl_function_smartfilter(int type, int invert_related)
     2598CALLER_OWN char *owl_function_smartfilter(int type, int invert_related)
    25522599{
    25532600  const owl_view *v;
     
    28082855
    28092856  owl_function_punt(argv->len, (const char *const*) argv->pdata, direction);
    2810   g_ptr_array_foreach(argv, (GFunc)g_free, NULL);
    2811   g_ptr_array_free(argv, true);
     2857  owl_ptr_array_free(argv, g_free);
    28122858}
    28132859
     
    28152861{
    28162862  owl_filter *f;
    2817   owl_list *fl;
    2818   int i, j;
     2863  GPtrArray *fl;
     2864  int i;
    28192865  fl=owl_global_get_puntlist(&g);
    28202866
     
    28272873
    28282874  /* Check for an identical filter */
    2829   j=owl_list_get_size(fl);
    2830   for (i=0; i<j; i++) {
    2831     if (owl_filter_equiv(f, owl_list_get_element(fl, i))) {
     2875  for (i = 0; i < fl->len; i++) {
     2876    if (owl_filter_equiv(f, fl->pdata[i])) {
    28322877      owl_function_debugmsg("found an equivalent punt filter");
    28332878      /* if we're punting, then just silently bow out on this duplicate */
     
    28392884      /* if we're unpunting, then remove this filter from the puntlist */
    28402885      if (direction==1) {
    2841         owl_filter_delete(owl_list_get_element(fl, i));
    2842         owl_list_remove_element(fl, i);
     2886        owl_filter_delete(g_ptr_array_remove_index(fl, i));
    28432887        owl_filter_delete(f);
    28442888        return;
     
    28502894    owl_function_debugmsg("punting");
    28512895    /* If we're punting, add the filter to the global punt list */
    2852     owl_list_append_element(fl, f);
     2896    g_ptr_array_add(fl, f);
    28532897  } else if (direction == 1) {
    28542898    owl_function_makemsg("No matching punt filter");
     
    28582902void owl_function_show_keymaps(void)
    28592903{
    2860   owl_list l;
     2904  GPtrArray *l;
    28612905  owl_fmtext fm;
    28622906  const owl_keymap *km;
    28632907  const owl_keyhandler *kh;
    2864   int i, numkm;
     2908  int i;
    28652909  const char *kmname;
    28662910
     
    28692913  owl_fmtext_append_bold(&fm, "Keymaps:   ");
    28702914  owl_fmtext_append_normal(&fm, "(use 'show keymap <name>' for details)\n");
    2871   owl_list_create(&l);
    2872   owl_keyhandler_get_keymap_names(kh, &l);
    2873   owl_fmtext_append_list(&fm, &l, "\n", owl_function_keymap_summary);
     2915  l = owl_keyhandler_get_keymap_names(kh);
     2916  owl_fmtext_append_list(&fm, l, "\n", owl_function_keymap_summary);
    28742917  owl_fmtext_append_normal(&fm, "\n");
    28752918
    2876   numkm = owl_list_get_size(&l);
    2877   for (i=0; i<numkm; i++) {
    2878     kmname = owl_list_get_element(&l, i);
     2919  for (i = 0; i < l->len; i++) {
     2920    kmname = l->pdata[i];
    28792921    km = owl_keyhandler_get_keymap(kh, kmname);
    28802922    owl_fmtext_append_bold(&fm, "\n\n----------------------------------------------------------------------------------------------------\n\n");
     
    28842926 
    28852927  owl_function_popless_fmtext(&fm);
    2886   owl_list_cleanup(&l, g_free);
     2928  owl_ptr_array_free(l, g_free);
    28872929  owl_fmtext_cleanup(&fm);
    28882930}
    28892931
    2890 char *owl_function_keymap_summary(const char *name)
     2932CALLER_OWN char *owl_function_keymap_summary(const char *name)
    28912933{
    28922934  const owl_keymap *km
     
    30023044/* strips formatting from ztext and returns the unformatted text.
    30033045 * caller is responsible for freeing. */
    3004 char *owl_function_ztext_stylestrip(const char *zt)
     3046CALLER_OWN char *owl_function_ztext_stylestrip(const char *zt)
    30053047{
    30063048  owl_fmtext fm;
     
    30253067#ifdef HAVE_LIBZEPHYR
    30263068  int x;
    3027   owl_list anyone;
     3069  GPtrArray *anyone;
    30283070  const char *user;
    30293071  char *tmp;
     
    30453087      idle=owl_buddy_get_idle_time(b);
    30463088      if (idle!=0) {
    3047         timestr=owl_util_minutes_to_timestr(idle);
     3089        timestr=owl_util_format_minutes(idle);
    30483090      } else {
    30493091        timestr=g_strdup("");
     
    30603102    } else {
    30613103      owl_fmtext_append_bold(&fm, "Zephyr users logged in:\n");
    3062       owl_list_create(&anyone);
    3063       ret=owl_zephyr_get_anyone_list(&anyone, filename);
    3064       if (ret) {
     3104      anyone = owl_zephyr_get_anyone_list(filename);
     3105      if (anyone == NULL) {
    30653106        if (errno == ENOENT) {
    30663107          owl_fmtext_append_normal(&fm, " You have not added any zephyr buddies.  Use the\n");
     
    30723113        }
    30733114      } else {
    3074         j=owl_list_get_size(&anyone);
    3075         for (i=0; i<j; i++) {
    3076           user=owl_list_get_element(&anyone, i);
     3115        for (i = 0; i < anyone->len; i++) {
     3116          user = anyone->pdata[i];
    30773117          ret=ZLocateUser(zstr(user), &numlocs, ZAUTH);
    30783118
     
    31063146        }
    31073147      }
    3108       owl_list_cleanup(&anyone, g_free);
     3148      owl_ptr_array_free(anyone, g_free);
    31093149    }
    31103150  }
     
    31833223    }
    31843224   
    3185     /* if it exited, fork & exec a new one */
     3225    /* if it exited, spawn a new one */
    31863226    if (owl_global_get_newmsgproc_pid(&g)==0) {
    3187       pid_t i;
    31883227      int myargc;
    3189       i=fork();
    3190       if (i) {
    3191         /* parent set the child's pid */
    3192         owl_global_set_newmsgproc_pid(&g, i);
    3193         owl_function_debugmsg("I'm the parent and I started a new newmsgproc with pid %i", i);
    3194       } else {
    3195         /* child exec's the program */
    3196         char **parsed;
    3197         parsed=owl_parseline(owl_global_get_newmsgproc(&g), &myargc);
    3198         if (myargc < 0) {
    3199           owl_function_debugmsg("Could not parse newmsgproc '%s': unbalanced quotes?", owl_global_get_newmsgproc(&g));
    3200         }
    3201         if (myargc <= 0) {
    3202           _exit(127);
    3203         }
    3204         owl_function_debugmsg("About to exec \"%s\" with %d arguments", parsed[0], myargc);
    3205        
    3206         execvp(parsed[0], parsed);
    3207        
    3208        
    3209         /* was there an error exec'ing? */
    3210         owl_function_debugmsg("Cannot run newmsgproc '%s': cannot exec '%s': %s",
    3211                               owl_global_get_newmsgproc(&g), parsed[0], strerror(errno));
    3212         _exit(127);
     3228      char **argv = owl_parseline(owl_global_get_newmsgproc(&g), &myargc);
     3229      if (myargc < 0) {
     3230        owl_function_debugmsg("Could not parse newmsgproc '%s': unbalanced quotes?",
     3231                              owl_global_get_newmsgproc(&g));
     3232      } else if (myargc > 0) {
     3233        /* Spawn the child. */
     3234        GPid pid;
     3235        GError *error = NULL;
     3236        owl_function_debugmsg("About to exec \"%s\" with %d arguments", argv[0], myargc);
     3237        if (g_spawn_async(NULL, argv, NULL,
     3238                          G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
     3239                          NULL, NULL, &pid, &error)) {
     3240          owl_global_set_newmsgproc_pid(&g, pid);
     3241          owl_function_debugmsg("I'm the parent and I started a new newmsgproc with pid %i", pid);
     3242        } else {
     3243          owl_function_debugmsg("Cannot run newmsgproc '%s': %s",
     3244                                owl_global_get_newmsgproc(&g), error->message);
     3245          g_error_free(error);
     3246        }
    32133247      }
     3248      g_strfreev(argv);
    32143249    }
    32153250  }
     
    33803415  char *buff;
    33813416
    3382   now=time(NULL);
    3383   date=g_strdup(ctime(&now));
    3384   date[strlen(date)-1]='\0';
     3417  now = time(NULL);
     3418  date = owl_util_format_time(localtime(&now));
    33853419
    33863420  buff = g_strdup_printf("%s %s", date, string);
     
    34233457{
    34243458#ifdef HAVE_LIBZEPHYR
    3425   int i, j;
    3426   owl_list anyone;
     3459  int i;
     3460  GPtrArray *anyone;
    34273461  GList **zaldlist;
    34283462  GList *zaldptr;
     
    34443478  *zaldlist = NULL;
    34453479
    3446   owl_list_create(&anyone);
    3447   owl_zephyr_get_anyone_list(&anyone, NULL);
    3448   j = owl_list_get_size(&anyone);
    3449   for (i = 0; i < j; i++) {
    3450     user = owl_list_get_element(&anyone, i);
    3451     zald = g_new(ZAsyncLocateData_t, 1);
    3452     if (ZRequestLocations(zstr(user), zald, UNACKED, ZAUTH) == ZERR_NONE) {
    3453       *zaldlist = g_list_append(*zaldlist, zald);
    3454     } else {
    3455       g_free(zald);
    3456     }
    3457   }
    3458 
    3459   owl_list_cleanup(&anyone, g_free);
     3480  anyone = owl_zephyr_get_anyone_list(NULL);
     3481  if (anyone != NULL) {
     3482    for (i = 0; i < anyone->len; i++) {
     3483      user = anyone->pdata[i];
     3484      zald = g_new(ZAsyncLocateData_t, 1);
     3485      if (ZRequestLocations(zstr(user), zald, UNACKED, ZAUTH) == ZERR_NONE) {
     3486        *zaldlist = g_list_append(*zaldlist, zald);
     3487      } else {
     3488        g_free(zald);
     3489      }
     3490    }
     3491    owl_ptr_array_free(anyone, g_free);
     3492  }
    34603493#endif
    34613494}
    34623495
    3463 void owl_function_aimsearch_results(const char *email, owl_list *namelist)
     3496void owl_function_aimsearch_results(const char *email, GPtrArray *namelist)
    34643497{
    34653498  owl_fmtext fm;
    3466   int i, j;
     3499  int i;
    34673500
    34683501  owl_fmtext_init_null(&fm);
     
    34713504  owl_fmtext_append_normal(&fm, ":\n");
    34723505
    3473   j=owl_list_get_size(namelist);
    3474   for (i=0; i<j; i++) {
     3506  for (i = 0; i < namelist->len; i++) {
    34753507    owl_fmtext_append_normal(&fm, "  ");
    3476     owl_fmtext_append_normal(&fm, owl_list_get_element(namelist, i));
     3508    owl_fmtext_append_normal(&fm, namelist->pdata[i]);
    34773509    owl_fmtext_append_normal(&fm, "\n");
    34783510  }
  • global.c

    rf97c1a6 r6383920  
     1#include "owl.h"
    12#include <stdio.h>
    2 #include <unistd.h>
    3 #include <stdlib.h>
    4 #include <string.h>
    5 #include <netdb.h>
    6 #include <termios.h>
    73#include <sys/ioctl.h>
    8 #include <time.h>
    9 #include "owl.h"
    104
    115static void _owl_global_init_windows(owl_global *g);
     
    159  const char *homedir;
    1610
     11#if !GLIB_CHECK_VERSION(2, 35, 0)
    1712  g_type_init();
     13#endif
     14#if !GLIB_CHECK_VERSION(2, 31, 0)
    1815  g_thread_init(NULL);
     16#endif
    1917
    2018  owl_select_init();
     
    4745  owl_dict_create(&(g->filters));
    4846  g->filterlist = NULL;
    49   owl_list_create(&(g->puntlist));
     47  g->puntlist = g_ptr_array_new();
    5048  g->messagequeue = g_queue_new();
    5149  owl_dict_create(&(g->styledict));
     
    5351  g->resizepending=0;
    5452  g->direction=OWL_DIRECTION_DOWNWARDS;
    55   g->zaway=0;
    5653  owl_fmtext_init_colorpair_mgr(&(g->cpmgr));
    5754  g->debug=OWL_DEBUG;
     
    6562  owl_history_init(&(g->msghist));
    6663  owl_history_init(&(g->cmdhist));
    67   owl_history_set_norepeats(&(g->cmdhist));
    6864  g->nextmsgid=0;
    6965
     
    7975  g->confdir = NULL;
    8076  g->startupfile = NULL;
    81   cd = g_strdup_printf("%s/%s", g->homedir, OWL_CONFIG_DIR);
     77  cd = g_build_filename(g->homedir, OWL_CONFIG_DIR, NULL);
    8278  owl_global_set_confdir(g, cd);
    8379  g_free(cd);
    8480
    85   owl_messagelist_create(&(g->msglist));
     81  g->msglist = owl_messagelist_new();
    8682
    8783  _owl_global_init_windows(g);
     
    105101
    106102  owl_message_init_fmtext_cache();
    107   owl_list_create(&(g->io_dispatch_list));
    108   g->timerlist = NULL;
    109103  g->kill_buffer = NULL;
    110104
    111105  g->interrupt_count = 0;
     106#if GLIB_CHECK_VERSION(2, 31, 0)
     107  g_mutex_init(&g->interrupt_lock);
     108#else
    112109  g->interrupt_lock = g_mutex_new();
     110#endif
    113111}
    114112
     
    119117
    120118  /* Create the widgets */
    121   owl_mainwin_init(&(g->mw), g->mainpanel.recwin);
     119  g->mw = owl_mainwin_new(g->mainpanel.recwin);
    122120  owl_msgwin_init(&(g->msgwin), g->mainpanel.msgwin);
    123121  owl_sepbar_init(g->mainpanel.sepwin);
     
    175173/* Pops the current context from the context stack and returns it. Caller is
    176174 * responsible for freeing. */
    177 owl_context *owl_global_pop_context_no_delete(owl_global *g) {
     175CALLER_OWN owl_context *owl_global_pop_context_no_delete(owl_global *g)
     176{
    178177  owl_context *c;
    179178  if (!g->context_stack)
     
    250249/* windows */
    251250
    252 owl_mainwin *owl_global_get_mainwin(owl_global *g) {
    253   return(&(g->mw));
     251owl_mainwin *owl_global_get_mainwin(owl_global *g)
     252{
     253  return g->mw;
    254254}
    255255
     
    265265
    266266owl_messagelist *owl_global_get_msglist(owl_global *g) {
    267   return(&(g->msglist));
     267  return g->msglist;
    268268}
    269269
     
    367367  g->confdir = g_strdup(cd);
    368368  g_free(g->startupfile);
    369   g->startupfile = g_strdup_printf("%s/startup", cd);
     369  g->startupfile = g_build_filename(cd, "startup", NULL);
    370370}
    371371
     
    581581/* puntlist */
    582582
    583 owl_list *owl_global_get_puntlist(owl_global *g) {
    584   return(&(g->puntlist));
     583GPtrArray *owl_global_get_puntlist(owl_global *g) {
     584  return g->puntlist;
    585585}
    586586
    587587int owl_global_message_is_puntable(owl_global *g, const owl_message *m) {
    588   const owl_list *pl;
    589   int i, j;
    590 
    591   pl=owl_global_get_puntlist(g);
    592   j=owl_list_get_size(pl);
    593   for (i=0; i<j; i++) {
    594     if (owl_filter_message_match(owl_list_get_element(pl, i), m)) return(1);
    595   }
    596   return(0);
     588  const GPtrArray *pl;
     589  int i;
     590
     591  pl = owl_global_get_puntlist(g);
     592  for (i = 0; i < pl->len; i++) {
     593    if (owl_filter_message_match(pl->pdata[i], m)) return 1;
     594  }
     595  return 0;
    597596}
    598597
     
    727726 * necessary.
    728727 */
    729 owl_message *owl_global_messagequeue_popmsg(owl_global *g)
     728CALLER_OWN owl_message *owl_global_messagequeue_popmsg(owl_global *g)
    730729{
    731730  owl_message *out;
     
    756755}
    757756
    758 void owl_global_get_style_names(const owl_global *g, owl_list *l) {
    759   owl_dict_get_keys(&(g->styledict), l);
     757CALLER_OWN GPtrArray *owl_global_get_style_names(const owl_global *g)
     758{
     759  return owl_dict_get_keys(&g->styledict);
    760760}
    761761
     
    841841}
    842842
    843 owl_list *owl_global_get_io_dispatch_list(owl_global *g)
    844 {
    845   return &(g->io_dispatch_list);
    846 }
    847 
    848 GList **owl_global_get_timerlist(owl_global *g)
    849 {
    850   return &(g->timerlist);
    851 }
    852 
    853843void owl_global_setup_default_filters(owl_global *g)
    854844{
     
    859849  } filters[] = {
    860850    { "personal",
    861       "isprivate ^true$ and ( not type ^zephyr$ or ( class ^message  ) )" },
     851      "isprivate ^true$ and ( not type ^zephyr$ or ( class ^message$ ) )" },
    862852    { "trash",
    863853      "class ^mail$ or opcode ^ping$ or type ^admin$ or ( not login ^none$ )" },
     
    866856    { "auto", "opcode ^auto$" },
    867857    { "login", "not login ^none$" },
    868     { "reply-lockout", "class ^noc or class ^mail$" },
     858    { "reply-lockout", "class ^mail$ or class ^filsrv$" },
    869859    { "out", "direction ^out$" },
    870860    { "aim", "type ^aim$" },
     
    917907}
    918908
     909static GMutex *owl_global_get_interrupt_lock(owl_global *g)
     910{
     911#if GLIB_CHECK_VERSION(2, 31, 0)
     912  return &g->interrupt_lock;
     913#else
     914  return g->interrupt_lock;
     915#endif
     916}
     917
    919918void owl_global_add_interrupt(owl_global *g) {
    920919  /* TODO: This can almost certainly be done with atomic
    921920   * operations. Whatever. */
    922   g_mutex_lock(g->interrupt_lock);
     921  g_mutex_lock(owl_global_get_interrupt_lock(g));
    923922  g->interrupt_count++;
    924   g_mutex_unlock(g->interrupt_lock);
     923  g_mutex_unlock(owl_global_get_interrupt_lock(g));
    925924}
    926925
    927926bool owl_global_take_interrupt(owl_global *g) {
    928927  bool ans = false;
    929   g_mutex_lock(g->interrupt_lock);
     928  g_mutex_lock(owl_global_get_interrupt_lock(g));
    930929  if (g->interrupt_count > 0) {
    931930    ans = true;
    932931    g->interrupt_count--;
    933932  }
    934   g_mutex_unlock(g->interrupt_lock);
     933  g_mutex_unlock(owl_global_get_interrupt_lock(g));
    935934  return ans;
    936935}
  • help.c

    rf25df21 r8258ea5  
    11#include "owl.h"
    2 #include <string.h>
    32
    43void owl_help(void)
    54{
     5  const owl_variable *v;
    66  owl_fmtext fm;
    77  const char *varname;
    8   owl_list varnames;
    9   int i, numvarnames;
     8  GPtrArray *varnames;
     9  int i;
    1010
    1111  owl_fmtext_init_null(&fm);
     
    6565     "\n"
    6666     "    l             Print a zephyr/AIM buddy listing\n"
    67      "    A             Toggle zaway\n"
     67     "    A             Toggle away\n"
    6868     "    o             Toggle one-line display mode\n"
    6969     "    w             Open a URL in the current message\n"
    7070     "    C-l           Refresh the screen\n"
    71      "    C-z           Suspend Owl\n"
     71     "    C-z           Suspend BarnOwl\n"
    7272     "    h             Print this help message\n"
    7373     "    : , M-x       Enter command mode\n"
    7474     "\n"
    75      "    /             Foward search\n"
     75     "    /             Forward search\n"
    7676     "    ?             Reverse search\n"
    7777     "\n\n"
     
    8383  owl_fmtext_append_normal
    8484    (&fm,
    85      "    quit, exit    Exit owl\n"
     85     "    quit, exit    Exit BarnOwl\n"
    8686     "    help          Get help about commands\n"
    87      "    show          Show information about owl (see detailed help)\n"
     87     "    show          Show information about BarnOwl (see detailed help)\n"
    8888     "\n"
    8989     "    zwrite        Send a zephyr\n"
     
    101101     "    set           Set a variable (see list below)\n"
    102102     "    print         Print a variable's value (variables listed below)\n"
    103      "    startup       Set a command to be run at every Owl startup\n"
    104      "    unstartup     Remove a command to be run at every Owl startup\n"
     103     "    startup       Set a command to be run at every BarnOwl startup\n"
     104     "    unstartup     Remove a command to be run at every BarnOwl startup\n"
    105105     "\n"
    106106     "    getsubs       Print a list of current subscriptions\n"
    107107     "    unsuball      Unsubscribe from all zephyr classes\n"
    108108     "    load-subs     Load zephyr subscriptions from a file\n"
    109      "    zpunt         Supress messages from a zephyr triplet\n"
     109     "    zpunt         Suppress messages from a zephyr triplet\n"
    110110     "    zlog          Send a login or logout notification\n"
    111111     "    zlist         Print a list of zephyr buddies logged in\n"
     
    121121     "    dump          Dump messagelist as text to a file\n"
    122122     "\n"
    123      "    about         Print information about owl\n"
    124      "    status        Print status information about the running owl\n"
    125      "    version       Print the version number of owl\n"
     123     "    about         Print information about BarnOwl\n"
     124     "    status        Print status information about the running BarnOwl\n"
     125     "    version       Print the version number of BarnOwl\n"
    126126     "\n");
    127127 
     
    129129  owl_fmtext_append_bold(&fm,
    130130                         "Variables:\n");
    131   owl_list_create(&varnames);
    132   owl_variable_dict_get_names(owl_global_get_vardict(&g), &varnames);
    133   numvarnames = owl_list_get_size(&varnames);
    134   for (i=0; i<numvarnames; i++) {
    135     varname = owl_list_get_element(&varnames, i);
     131  varnames = owl_variable_dict_get_names(owl_global_get_vardict(&g));
     132  for (i = 0; i < varnames->len; i++) {
     133    varname = varnames->pdata[i];
    136134    if (varname && varname[0]!='_') {
    137       owl_variable_describe(owl_global_get_vardict(&g), varname, &fm);
     135      v = owl_variable_get_var(owl_global_get_vardict(&g), varname);
     136      owl_variable_describe(v, &fm);
    138137    }
    139138  }
    140   owl_list_cleanup(&varnames, g_free);
     139  owl_ptr_array_free(varnames, g_free);
    141140
    142141  owl_fmtext_append_normal(&fm, "\n");
  • history.c

    rd4927a7 r25891a8  
    33void owl_history_init(owl_history *h)
    44{
    5   owl_list_create(&(h->hist));
    6   h->cur=0;                     /* current position in history */
    7   h->touched=0;                 /* whether we've gone into history */
    8   h->partial=0;                 /* is the 0th element is partially composed? */
    9   h->repeats=1;                 /* by default we'll allow repeat entries */
     5  g_queue_init(&h->hist);
     6  h->cur = h->hist.tail;        /* current position in history */
     7  h->partial = false;           /* is the 0th element is partially composed? */
    108}
    119
    12 void owl_history_set_norepeats(owl_history *h)
     10void owl_history_cleanup(owl_history *h)
    1311{
    14   h->repeats=0;
     12  g_queue_foreach(&h->hist, (GFunc)g_free, NULL);
     13  g_queue_clear(&h->hist);
    1514}
    1615
    1716const char *owl_history_get_prev(owl_history *h)
    1817{
     18  if (!h) return NULL;
    1919
    20   if (!h) return NULL;
    21   h->touched=1;
     20  if (h->cur == NULL || g_list_previous(h->cur) == NULL) return NULL;
    2221
    23   if (owl_list_get_size(&(h->hist))==0) return(NULL);
    24 
    25   if (h->cur == owl_list_get_size(&(h->hist))-1) {
    26     return(NULL);
    27   }
    28 
    29   h->cur++;
    30 
    31   return(owl_list_get_element(&(h->hist), h->cur));
     22  h->cur = g_list_previous(h->cur);
     23  return h->cur->data;
    3224}
    3325
     
    3527{
    3628  if (!h) return NULL;
    37   if (owl_list_get_size(&(h->hist))==0) return(NULL);
    38   if (h->cur==0) {
    39     return(NULL);
    40   }
    4129
    42   h->cur--;
    43   return(owl_list_get_element(&(h->hist), h->cur));
     30  if (h->cur == NULL || g_list_next(h->cur) == NULL) return NULL;
     31
     32  h->cur = g_list_next(h->cur);
     33  return h->cur->data;
    4434}
    4535
    46 void owl_history_store(owl_history *h, const char *line)
     36void owl_history_store(owl_history *h, const char *line, bool partial)
    4737{
    48   int size;
     38  if (!h) return;
    4939
    50   if (!h) return;
    51   size=owl_list_get_size(&(h->hist));
     40  owl_history_reset(h);
    5241
    53   /* if partial is set, remove the first entry first */
    54   if (h->partial) {
    55     g_free(owl_list_get_element(&(h->hist), 0));
    56     owl_list_remove_element(&(h->hist), 0);
    57   }
    58 
    59   /* if repeats are disallowed, check if the line is the same as the last */
    60   if (owl_list_get_size(&(h->hist))>0) {
    61     if (!strcmp(line, owl_list_get_element(&(h->hist), 0))) return;
    62   }
     42  /* check if the line is the same as the last */
     43  if (!partial && !g_queue_is_empty(&h->hist) &&
     44      strcmp(line, g_queue_peek_tail(&h->hist)) == 0)
     45    return;
    6346
    6447  /* if we've reached the max history size, pop off the last element */
    65   if (size>OWL_HISTORYSIZE) {
    66     g_free(owl_list_get_element(&(h->hist), size-1));
    67     owl_list_remove_element(&(h->hist), size-1);
    68   }
     48  if (g_queue_get_length(&h->hist) >= OWL_HISTORYSIZE)
     49    g_free(g_queue_pop_head(&h->hist));
    6950
    7051  /* add the new line */
    71   owl_list_prepend_element(&(h->hist), g_strdup(line));
    72 }
    73 
    74 void owl_history_set_partial(owl_history *h)
    75 {
    76   if (!h) return;
    77   h->partial=1;
     52  g_queue_push_tail(&h->hist, g_strdup(line));
     53  h->partial = partial;
     54  h->cur = h->hist.tail;
    7855}
    7956
     
    8158{
    8259  if (!h) return;
    83   h->cur=0;
    84   h->touched=0;
    85   h->partial=0;
     60
     61  /* if partial is set, remove the first entry first */
     62  if (h->partial) {
     63    g_free(g_queue_pop_tail(&h->hist));
     64    h->partial = false;
     65  }
     66
     67  h->cur = h->hist.tail;
    8668}
    8769
     
    8971{
    9072  if (!h) return(0);
    91   if (h->touched) return(1);
    92   return(0);
     73  return h->cur != NULL && g_list_next(h->cur) != NULL;
    9374}
  • keybinding.c

    r3b8a563 rf271129  
    1 #include <ctype.h>
    2 #include <string.h>
    31#include "owl.h"
    42
     
    1412
    1513/* sets up a new keybinding for a command */
    16 owl_keybinding *owl_keybinding_new(const char *keyseq, const char *command, void (*function_fn)(void), const char *desc)
     14CALLER_OWN owl_keybinding *owl_keybinding_new(const char *keyseq, const char *command, void (*function_fn)(void), const char *desc)
    1715{
    1816  owl_keybinding *kb = g_new(owl_keybinding, 1);
     
    8583}
    8684
    87 char *owl_keybinding_stack_tostring(int *j, int len)
     85CALLER_OWN char *owl_keybinding_stack_tostring(int *j, int len)
    8886{
    8987  GString *string;
     
    10098}
    10199
    102 char *owl_keybinding_tostring(const owl_keybinding *kb)
     100CALLER_OWN char *owl_keybinding_tostring(const owl_keybinding *kb)
    103101{
    104102  return owl_keybinding_stack_tostring(kb->keys, kb->len);
  • keymap.c

    r4c7c21f rf271129  
    1 #include <string.h>
    21#include "owl.h"
    32
     
    1110  km->name = g_strdup(name);
    1211  km->desc = g_strdup(desc);
    13   owl_list_create(&km->bindings);
     12  km->bindings = g_ptr_array_new();
    1413  km->parent = NULL;
    1514  km->default_fn = default_fn;
     
    2423  g_free(km->name);
    2524  g_free(km->desc);
    26   owl_list_cleanup(&km->bindings, (void (*)(void *))owl_keybinding_delete);
     25  owl_ptr_array_free(km->bindings, (GDestroyNotify)owl_keybinding_delete);
    2726}
    2827
     
    3534int owl_keymap_create_binding(owl_keymap *km, const char *keyseq, const char *command, void (*function_fn)(void), const char *desc)
    3635{
    37   owl_keybinding *kb, *curkb;
     36  owl_keybinding *kb;
    3837  int i;
    3938
     
    4443   * otherwise just add this one.
    4544   */
    46   for (i = owl_list_get_size(&km->bindings)-1; i>=0; i--) {
    47     curkb = owl_list_get_element(&km->bindings, i);
    48     if (owl_keybinding_equal(curkb, kb)) {
    49       owl_list_remove_element(&km->bindings, i);
    50       owl_keybinding_delete(curkb);
    51     }
    52   }
    53   return owl_list_append_element(&km->bindings, kb); 
    54 
     45  for (i = km->bindings->len-1; i >= 0; i--) {
     46    if (owl_keybinding_equal(km->bindings->pdata[i], kb)) {
     47      owl_keybinding_delete(g_ptr_array_remove_index(km->bindings, i));
     48    }
     49  }
     50  g_ptr_array_add(km->bindings, kb);
     51  return 0;
    5552}
    5653
     
    5855int owl_keymap_remove_binding(owl_keymap *km, const char *keyseq)
    5956{
    60   owl_keybinding *kb, *curkb;
     57  owl_keybinding *kb;
    6158  int i;
    6259
     
    6562    return -1;
    6663
    67   for (i = owl_list_get_size(&km->bindings)-1; i >= 0; i--) {
    68     curkb = owl_list_get_element(&km->bindings, i);
    69     if (owl_keybinding_equal(curkb, kb)) {
    70       owl_list_remove_element(&km->bindings, i);
    71       owl_keybinding_delete(curkb);
     64  for (i = km->bindings->len-1; i >= 0; i--) {
     65    if (owl_keybinding_equal(km->bindings->pdata[i], kb)) {
     66      owl_keybinding_delete(g_ptr_array_remove_index(km->bindings, i));
    7267      owl_keybinding_delete(kb);
    7368      return(0);
     
    8075
    8176/* returns a summary line describing this keymap.  the caller must free. */
    82 char *owl_keymap_summary(const owl_keymap *km)
     77CALLER_OWN char *owl_keymap_summary(const owl_keymap *km)
    8378{
    8479  if (!km || !km->name || !km->desc) return NULL;
     
    139134static void _owl_keymap_format_bindings(const owl_keymap *km, owl_fmtext *fm)
    140135{
    141   int i, nbindings;
     136  int i;
    142137  const owl_keybinding *kb;
    143138 
    144   nbindings = owl_list_get_size(&km->bindings);
    145   for (i=0; i<nbindings; i++) {
     139  for (i = 0; i < km->bindings->len; i++) {
    146140    char *kbstr;
    147141    const owl_cmd *cmd;
    148142    const char *tmpdesc, *desc = "";
    149143
    150     kb = owl_list_get_element(&km->bindings, i);
     144    kb = km->bindings->pdata[i];
    151145    kbstr = owl_keybinding_tostring(kb);
    152146    owl_fmtext_append_normal(fm, OWL_TABSTR);
     
    214208}
    215209
    216 void owl_keyhandler_get_keymap_names(const owl_keyhandler *kh, owl_list *l)
    217 {
    218   owl_dict_get_keys(&kh->keymaps, l);
     210CALLER_OWN GPtrArray *owl_keyhandler_get_keymap_names(const owl_keyhandler *kh)
     211{
     212  return owl_dict_get_keys(&kh->keymaps);
    219213}
    220214
     
    274268   * keyhandler and keymap apart.  */
    275269  for (km=kh->active; km; km=km->parent) {
    276     for (i=owl_list_get_size(&km->bindings)-1; i>=0; i--) {
    277       kb = owl_list_get_element(&km->bindings, i);
     270    for (i = km->bindings->len-1; i >= 0; i--) {
     271      kb = km->bindings->pdata[i];
    278272      match = owl_keybinding_match(kb, kh);
    279273      if (match == 1) {         /* subset match */
  • keypress.c

    rd07af84 rf271129  
    1 #include <ctype.h>
    2 #include <string.h>
    31#include "owl.h"
    42
     
    129127/* OWL_META is definied in owl.h */
    130128
    131 char *owl_keypress_tostring(int j, int esc)
     129CALLER_OWN char *owl_keypress_tostring(int j, int esc)
    132130{
    133131  GString *kb;
  • libfaim/Makefile.am

    r215c119 rb80bae0  
    1313libfaim_a_CPPFLAGS = -DAIM_BUILDDATE=\"x\" -DAIM_BUILDTIME=\"x\" \
    1414                     -I${top_srcdir}/libfaim
     15
     16EXTRA_DIST = oscar.c
  • libfaim/aim.h

    r63de71c rfe73d0c  
    1818
    1919#include "config.h"
    20 #ifdef HAVE_STDBOOL_H
    2120#include <stdbool.h>
    22 #else
    23 #ifndef HAVE__BOOL
    24 #define _Bool signed char
    25 #endif
    26 #define bool _Bool
    27 #define false 0
    28 #define true 1
    29 #define __bool_true_false_are_defined 1
    30 #endif  /* HAVE_STDBOOL_H */
    3121
    3222#include <stdio.h>
  • logging.c

    rcc305b5 r0792d99  
    11#include "owl.h"
    2 #include <stdlib.h>
    3 #include <string.h>
    4 #include <ctype.h>
    5 #include <sys/param.h>
     2#include <stdio.h>
    63
    74typedef struct _owl_log_entry { /* noproto */
     
    8077}
    8178
    82 char *owl_log_zephyr(const owl_message *m) {
     79CALLER_OWN char *owl_log_zephyr(const owl_message *m)
     80{
    8381    char *tmp = NULL;
    8482    GString *buffer = NULL;
     
    103101}
    104102
    105 char *owl_log_aim(const owl_message *m) {
     103CALLER_OWN char *owl_log_aim(const owl_message *m)
     104{
    106105    GString *buffer = NULL;
    107106    buffer = g_string_new("");
     
    120119}
    121120
    122 char *owl_log_jabber(const owl_message *m) {
     121CALLER_OWN char *owl_log_jabber(const owl_message *m)
     122{
    123123    GString *buffer = NULL;
    124124    buffer = g_string_new("");
     
    132132}
    133133
    134 char *owl_log_generic(const owl_message *m) {
     134CALLER_OWN char *owl_log_generic(const owl_message *m)
     135{
    135136    GString *buffer;
    136137    buffer = g_string_new("");
     
    220221    while (cc != NULL) {
    221222      temp = short_zuser(cc->data);
    222       filename = g_strdup_printf("%s/%s", logpath, temp);
     223      filename = g_build_filename(logpath, temp, NULL);
    223224      owl_log_append(m, filename);
    224225
     
    244245  }
    245246
    246   filename = g_strdup_printf("%s/%s", logpath, to);
     247  filename = g_build_filename(logpath, to, NULL);
    247248  owl_log_append(m, filename);
    248249  g_free(to);
    249250  g_free(filename);
    250251
    251   filename = g_strdup_printf("%s/all", logpath);
     252  filename = g_build_filename(logpath, "all", NULL);
    252253  owl_log_append(m, filename);
    253254  g_free(logpath);
     
    281282  /* expand ~ in path names */
    282283  logpath = owl_util_makepath(owl_global_get_logpath(&g));
    283   filename = g_strdup_printf("%s/%s", logpath, tobuff);
     284  filename = g_build_filename(logpath, tobuff, NULL);
    284285  msgbuf = g_string_new("");
    285286  g_string_printf(msgbuf, "ERROR (owl): %s\n%s\n", tobuff, text);
     
    290291  g_string_free(msgbuf, TRUE);
    291292
    292   filename = g_strdup_printf("%s/all", logpath);
     293  filename = g_build_filename(logpath, "all", NULL);
    293294  g_free(logpath);
    294295  msgbuf = g_string_new("");
     
    389390  if (personal) {
    390391    logpath = owl_util_makepath(owl_global_get_logpath(&g));
    391     filename = g_strdup_printf("%s/%s", logpath, from);
    392     allfilename = g_strdup_printf("%s/all", logpath);
     392    filename = g_build_filename(logpath, from, NULL);
     393    allfilename = g_build_filename(logpath, "all", NULL);
    393394    owl_log_append(m, allfilename);
    394395    g_free(allfilename);
    395396  } else {
    396397    logpath = owl_util_makepath(owl_global_get_classlogpath(&g));
    397     filename = g_strdup_printf("%s/%s", logpath, from);
     398    filename = g_build_filename(logpath, from, NULL);
    398399  }
    399400
     
    411412      temp = short_zuser(cc->data);
    412413      if (strcasecmp(temp, frombuff) != 0) {
    413         filename = g_strdup_printf("%s/%s", logpath, temp);
     414        filename = g_build_filename(logpath, temp, NULL);
    414415        owl_log_append(m, filename);
    415416        g_free(filename);
     
    428429static gpointer owl_log_thread_func(gpointer data)
    429430{
    430   log_context = g_main_context_new();
    431431  log_loop = g_main_loop_new(log_context, FALSE);
    432432  g_main_loop_run(log_loop);
     
    436436void owl_log_init(void)
    437437{
     438  log_context = g_main_context_new();
     439#if GLIB_CHECK_VERSION(2, 31, 0)
     440  logging_thread = g_thread_new("logging",
     441                                owl_log_thread_func,
     442                                NULL);
     443#else
    438444  GError *error = NULL;
    439445  logging_thread = g_thread_create(owl_log_thread_func,
     
    447453    exit(1);
    448454  }
     455#endif
    449456 
    450457}
  • m4/ax_append_compile_flags.m4

    r8073852 re9b4a2c  
    11# ===========================================================================
    2           http://autoconf-archive.cryp.to/ax_c_check_flag.html
     2http://www.gnu.org/software/autoconf-archive/ax_append_compile_flags.html
    33# ===========================================================================
    44#
    55# SYNOPSIS
    66#
    7 #   AX_C_CHECK_FLAG(FLAG-TO-CHECK,[PROLOGUE],[BODY],[ACTION-IF-SUCCESS],[ACTION-IF-FAILURE])
     7#   AX_APPEND_COMPILE_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS])
    88#
    99# DESCRIPTION
    1010#
    11 #   This macro tests if the C compiler supports the flag FLAG-TO-CHECK. If
    12 #   successfull execute ACTION-IF-SUCCESS otherwise ACTION-IF-FAILURE.
    13 #   PROLOGUE and BODY are optional and should be used as in AC_LANG_PROGRAM
    14 #   macro.
     11#   For every FLAG1, FLAG2 it is checked whether the compiler works with the
     12#   flag.  If it does, the flag is added FLAGS-VARIABLE
    1513#
    16 #   This code is inspired from KDE_CHECK_COMPILER_FLAG macro. Thanks to
    17 #   Bogdan Drozdowski <bogdandr@op.pl> for testing and bug fixes.
     14#   If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
     15#   CFLAGS) is used.  During the check the flag is always added to the
     16#   current language's flags.
     17#
     18#   If EXTRA-FLAGS is defined, it is added to the current language's default
     19#   flags (e.g. CFLAGS) when the check is done.  The check is thus made with
     20#   the flags: "CFLAGS EXTRA-FLAGS FLAG".  This can for example be used to
     21#   force the compiler to issue an error when a bad flag is given.
     22#
     23#   NOTE: This macro depends on the AX_APPEND_FLAG and
     24#   AX_CHECK_COMPILE_FLAG. Please keep this macro in sync with
     25#   AX_APPEND_LINK_FLAGS.
    1826#
    1927# LICENSE
    2028#
    21 #   Copyright (c) 2008 Francesco Salvestrini <salvestrini@users.sourceforge.net>
     29#   Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
    2230#
    23 #   This program is free software; you can redistribute it and/or modify it
     31#   This program is free software: you can redistribute it and/or modify it
    2432#   under the terms of the GNU General Public License as published by the
    25 #   Free Software Foundation; either version 2 of the License, or (at your
     33#   Free Software Foundation, either version 3 of the License, or (at your
    2634#   option) any later version.
    2735#
     
    4755#   exception to the GPL to apply to your modified version as well.
    4856
    49 AC_DEFUN([AX_C_CHECK_FLAG],[
    50   AC_PREREQ([2.61])
    51   AC_REQUIRE([AC_PROG_CC])
    52   AC_REQUIRE([AC_PROG_SED])
     57#serial 3
    5358
    54   flag=`echo "$1" | $SED 'y% .=/+-(){}<>:*,%_______________%'`
    55 
    56   AC_CACHE_CHECK([whether the C compiler accepts the $1 flag],
    57     [ax_cv_c_check_flag_$flag],[
    58 
    59     AC_LANG_PUSH([C])
    60 
    61     save_CFLAGS="$CFLAGS"
    62     CFLAGS="$CFLAGS $1"
    63     AC_COMPILE_IFELSE([
    64       AC_LANG_PROGRAM([$2],[$3])
    65     ],[
    66       eval "ax_cv_c_check_flag_$flag=yes"
    67     ],[
    68       eval "ax_cv_c_check_flag_$flag=no"
    69     ])
    70 
    71     CFLAGS="$save_CFLAGS"
    72 
    73     AC_LANG_POP
    74 
    75   ])
    76 
    77   AS_IF([eval "test \"`echo '$ax_cv_c_check_flag_'$flag`\" = yes"],[
    78     :
    79     $4
    80   ],[
    81     :
    82     $5
    83   ])
    84 ])
     59AC_DEFUN([AX_APPEND_COMPILE_FLAGS],
     60[AC_REQUIRE([AX_CHECK_COMPILE_FLAG])
     61AC_REQUIRE([AX_APPEND_FLAG])
     62for flag in $1; do
     63  AX_CHECK_COMPILE_FLAG([$flag], [AX_APPEND_FLAG([$flag], [$2])], [], [$3])
     64done
     65])dnl AX_APPEND_COMPILE_FLAGS
  • m4/ax_cflags_warn_all.m4

    r8073852 re9b4a2c  
    11# ===========================================================================
    2 #           http://autoconf-archive.cryp.to/ax_cflags_warn_all.html
     2#    http://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html
    33# ===========================================================================
    44#
    55# SYNOPSIS
    66#
    7 #   AX_CFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
     7#   AX_CFLAGS_WARN_ALL   [(shellvar [,default, [A/NA]])]
     8#   AX_CXXFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
     9#   AX_FCFLAGS_WARN_ALL  [(shellvar [,default, [A/NA]])]
    810#
    911# DESCRIPTION
    1012#
    1113#   Try to find a compiler option that enables most reasonable warnings.
    12 #   This macro is directly derived from VL_PROG_CC_WARNINGS which is split
    13 #   up into two AX_CFLAGS_WARN_ALL and AX_CFLAGS_WARN_ALL_ANSI
    1414#
    15 #   For the GNU CC compiler it will be -Wall (and -ansi -pedantic) The
    16 #   result is added to the shellvar being CFLAGS by default.
     15#   For the GNU compiler it will be -Wall (and -ansi -pedantic) The result
     16#   is added to the shellvar being CFLAGS, CXXFLAGS, or FCFLAGS by default.
    1717#
    18 #   Currently this macro knows about GCC, Solaris C compiler, Digital Unix C
    19 #   compiler, C for AIX Compiler, HP-UX C compiler, IRIX C compiler, NEC
    20 #   SX-5 (Super-UX 10) C compiler, and Cray J90 (Unicos 10.0.0.8) C
    21 #   compiler.
     18#   Currently this macro knows about the GCC, Solaris, Digital Unix, AIX,
     19#   HP-UX, IRIX, NEC SX-5 (Super-UX 10), Cray J90 (Unicos 10.0.0.8), and
     20#   Intel compilers.  For a given compiler, the Fortran flags are much more
     21#   experimental than their C equivalents.
    2222#
    23 #    - $1 shell-variable-to-add-to : CFLAGS
     23#    - $1 shell-variable-to-add-to : CFLAGS, CXXFLAGS, or FCFLAGS
    2424#    - $2 add-value-if-not-found : nothing
    2525#    - $3 action-if-found : add value to shellvariable
    2626#    - $4 action-if-not-found : nothing
    2727#
     28#   NOTE: These macros depend on AX_APPEND_FLAG.
     29#
    2830# LICENSE
    2931#
    3032#   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
     33#   Copyright (c) 2010 Rhys Ulerich <rhys.ulerich@gmail.com>
    3134#
    3235#   This program is free software; you can redistribute it and/or modify it
    3336#   under the terms of the GNU General Public License as published by the
    34 #   Free Software Foundation; either version 2 of the License, or (at your
     37#   Free Software Foundation; either version 3 of the License, or (at your
    3538#   option) any later version.
    3639#
     
    5659#   exception to the GPL to apply to your modified version as well.
    5760
    58 AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl
    59 AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl
    60 AS_VAR_PUSHDEF([VAR],[ac_cv_cflags_warn_all])dnl
     61#serial 14
     62
     63AC_DEFUN([AX_FLAGS_WARN_ALL],[dnl
     64AS_VAR_PUSHDEF([FLAGS],[_AC_LANG_PREFIX[]FLAGS])dnl
     65AS_VAR_PUSHDEF([VAR],[ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl
    6166AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings],
    6267VAR,[VAR="no, unknown"
    63  AC_LANG_SAVE
    64  AC_LANG_C
    65  ac_save_[]FLAGS="$[]FLAGS"
     68ac_save_[]FLAGS="$[]FLAGS"
    6669for ac_arg dnl
    67 in "-pedantic  % -Wall"       dnl   GCC
     70in "-warn all  % -warn all"   dnl Intel
     71   "-pedantic  % -Wall"       dnl GCC
    6872   "-xstrconst % -v"          dnl Solaris C
    6973   "-std1      % -verbose -w0 -warnprotos" dnl Digital Unix
     
    7579   #
    7680do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
    77    AC_TRY_COMPILE([],[return 0;],
    78    [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
     81   AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
     82                     [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
    7983done
    80  FLAGS="$ac_save_[]FLAGS"
    81  AC_LANG_RESTORE
     84FLAGS="$ac_save_[]FLAGS"
    8285])
     86AS_VAR_POPDEF([FLAGS])dnl
     87AC_REQUIRE([AX_APPEND_FLAG])
    8388case ".$VAR" in
    8489     .ok|.ok,*) m4_ifvaln($3,$3) ;;
    85    .|.no|.no,*) m4_ifvaln($4,$4,[m4_ifval($2,[
    86         AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])
    87                       m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])]) ;;
    88    *) m4_ifvaln($3,$3,[
    89    if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null
    90    then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR])
    91    else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"])
    92                       m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"
    93    fi ]) ;;
     90   .|.no|.no,*) m4_default($4,[m4_ifval($2,[AX_APPEND_FLAG([$2], [$1])])]) ;;
     91   *) m4_default($3,[AX_APPEND_FLAG([$VAR], [$1])]) ;;
    9492esac
    9593AS_VAR_POPDEF([VAR])dnl
    96 AS_VAR_POPDEF([FLAGS])dnl
    97 ])
    98 
    99 dnl the only difference - the LANG selection... and the default FLAGS
    100 
    101 AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl
    102 AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl
    103 AS_VAR_PUSHDEF([VAR],[ac_cv_cxxflags_warn_all])dnl
    104 AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings],
    105 VAR,[VAR="no, unknown"
    106  AC_LANG_SAVE
    107  AC_LANG_CPLUSPLUS
    108  ac_save_[]FLAGS="$[]FLAGS"
    109 for ac_arg dnl
    110 in "-pedantic  % -Wall"       dnl   GCC
    111    "-xstrconst % -v"          dnl Solaris C
    112    "-std1      % -verbose -w0 -warnprotos" dnl Digital Unix
    113    "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX
    114    "-ansi -ansiE % -fullwarn" dnl IRIX
    115    "+ESlit     % +w1"         dnl HP-UX C
    116    "-Xc        % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10)
    117    "-h conform % -h msglevel 2" dnl Cray C (Unicos)
    118    #
    119 do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
    120    AC_TRY_COMPILE([],[return 0;],
    121    [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
    122 done
    123  FLAGS="$ac_save_[]FLAGS"
    124  AC_LANG_RESTORE
    125 ])
    126 case ".$VAR" in
    127      .ok|.ok,*) m4_ifvaln($3,$3) ;;
    128    .|.no|.no,*) m4_ifvaln($4,$4,[m4_ifval($2,[
    129         AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])
    130                       m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])]) ;;
    131    *) m4_ifvaln($3,$3,[
    132    if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null
    133    then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR])
    134    else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"])
    135                       m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"
    136    fi ]) ;;
    137 esac
    138 AS_VAR_POPDEF([VAR])dnl
    139 AS_VAR_POPDEF([FLAGS])dnl
    140 ])
    141 
     94])dnl AX_FLAGS_WARN_ALL
    14295dnl  implementation tactics:
    14396dnl   the for-argument contains a list of options. The first part of
     
    148101dnl   like -Woption or -Xoption as they think of it is a pass-through
    149102dnl   to later compile stages or something. The "%" is used as a
    150 dnl   delimimiter. A non-option comment can be given after "%%" marks
     103dnl   delimiter. A non-option comment can be given after "%%" marks
    151104dnl   which will be shown but not added to the respective C/CXXFLAGS.
     105
     106AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl
     107AC_LANG_PUSH([C])
     108AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
     109AC_LANG_POP([C])
     110])
     111
     112AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl
     113AC_LANG_PUSH([C++])
     114AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
     115AC_LANG_POP([C++])
     116])
     117
     118AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl
     119AC_LANG_PUSH([Fortran])
     120AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
     121AC_LANG_POP([Fortran])
     122])
  • m4/ax_prog_perl_modules.m4

    r2d3ed95 r378ede7  
    11# ===========================================================================
    2 #      http://www.nongnu.org/autoconf-archive/ax_prog_perl_modules.html
     2#   http://www.gnu.org/software/autoconf-archive/ax_prog_perl_modules.html
    33# ===========================================================================
    44#
     
    3333#   warranty.
    3434
    35 #serial 6
     35#serial 7
    3636
    3737AU_ALIAS([AC_PROG_PERL_MODULES], [AX_PROG_PERL_MODULES])
  • m4/pkg.m4

    r8073852 r13a39ae8  
    11# pkg.m4 - Macros to locate and utilise pkg-config.            -*- Autoconf -*-
     2# serial 1 (pkg-config-0.24)
    23#
    34# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
     
    2627AC_DEFUN([PKG_PROG_PKG_CONFIG],
    2728[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
    28 m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
    29 AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl
     29m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
     30m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
     31AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
     32AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
     33AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
     34
    3035if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
    3136        AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
     
    4045                PKG_CONFIG=""
    4146        fi
    42                
    4347fi[]dnl
    4448])# PKG_PROG_PKG_CONFIG
     
    4953# to PKG_CHECK_MODULES(), but does not set variables or print errors.
    5054#
    51 #
    52 # Similar to PKG_CHECK_MODULES, make sure that the first instance of
    53 # this or PKG_CHECK_MODULES is called, or make sure to call
    54 # PKG_CHECK_EXISTS manually
     55# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
     56# only at the first occurence in configure.ac, so if the first place
     57# it's called might be skipped (such as if it is within an "if", you
     58# have to call PKG_CHECK_EXISTS manually
    5559# --------------------------------------------------------------
    5660AC_DEFUN([PKG_CHECK_EXISTS],
     
    5862if test -n "$PKG_CONFIG" && \
    5963    AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
    60   m4_ifval([$2], [$2], [:])
     64  m4_default([$2], [:])
    6165m4_ifvaln([$3], [else
    6266  $3])dnl
    6367fi])
    6468
    65 
    6669# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
    6770# ---------------------------------------------
    6871m4_define([_PKG_CONFIG],
    69 [if test -n "$PKG_CONFIG"; then
    70     if test -n "$$1"; then
    71         pkg_cv_[]$1="$$1"
    72     else
    73         PKG_CHECK_EXISTS([$3],
    74                          [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
    75                          [pkg_failed=yes])
    76     fi
    77 else
    78         pkg_failed=untried
     72[if test -n "$$1"; then
     73    pkg_cv_[]$1="$$1"
     74 elif test -n "$PKG_CONFIG"; then
     75    PKG_CHECK_EXISTS([$3],
     76                     [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
     77                      test "x$?" != "x0" && pkg_failed=yes ],
     78                     [pkg_failed=yes])
     79 else
     80    pkg_failed=untried
    7981fi[]dnl
    8082])# _PKG_CONFIG
     
    118120
    119121if test $pkg_failed = yes; then
     122        AC_MSG_RESULT([no])
    120123        _PKG_SHORT_ERRORS_SUPPORTED
    121124        if test $_pkg_short_errors_supported = yes; then
    122                 $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"`
     125                $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
    123126        else
    124                 $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
     127                $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
    125128        fi
    126129        # Put the nasty error message in config.log where it belongs
    127130        echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
    128131
    129         ifelse([$4], , [AC_MSG_ERROR(dnl
     132        m4_default([$4], [AC_MSG_ERROR(
    130133[Package requirements ($2) were not met:
    131134
     
    135138installed software in a non-standard prefix.
    136139
    137 _PKG_TEXT
    138 ])],
    139                 [AC_MSG_RESULT([no])
    140                 $4])
     140_PKG_TEXT])[]dnl
     141        ])
    141142elif test $pkg_failed = untried; then
    142         ifelse([$4], , [AC_MSG_FAILURE(dnl
     143        AC_MSG_RESULT([no])
     144        m4_default([$4], [AC_MSG_FAILURE(
    143145[The pkg-config script could not be found or is too old.  Make sure it
    144146is in your PATH or set the PKG_CONFIG environment variable to the full
     
    147149_PKG_TEXT
    148150
    149 To get pkg-config, see <http://pkg-config.freedesktop.org/>.])],
    150                 [$4])
     151To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
     152        ])
    151153else
    152154        $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
    153155        $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
    154156        AC_MSG_RESULT([yes])
    155         ifelse([$3], , :, [$3])
     157        $3
    156158fi[]dnl
    157159])# PKG_CHECK_MODULES
     160
     161
     162# PKG_INSTALLDIR(DIRECTORY)
     163# -------------------------
     164# Substitutes the variable pkgconfigdir as the location where a module
     165# should install pkg-config .pc files. By default the directory is
     166# $libdir/pkgconfig, but the default can be changed by passing
     167# DIRECTORY. The user can override through the --with-pkgconfigdir
     168# parameter.
     169AC_DEFUN([PKG_INSTALLDIR],
     170[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
     171m4_pushdef([pkg_description],
     172    [pkg-config installation directory @<:@]pkg_default[@:>@])
     173AC_ARG_WITH([pkgconfigdir],
     174    [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
     175    [with_pkgconfigdir=]pkg_default)
     176AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
     177m4_popdef([pkg_default])
     178m4_popdef([pkg_description])
     179]) dnl PKG_INSTALLDIR
     180
     181
     182# PKG_NOARCH_INSTALLDIR(DIRECTORY)
     183# -------------------------
     184# Substitutes the variable noarch_pkgconfigdir as the location where a
     185# module should install arch-independent pkg-config .pc files. By
     186# default the directory is $datadir/pkgconfig, but the default can be
     187# changed by passing DIRECTORY. The user can override through the
     188# --with-noarch-pkgconfigdir parameter.
     189AC_DEFUN([PKG_NOARCH_INSTALLDIR],
     190[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
     191m4_pushdef([pkg_description],
     192    [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
     193AC_ARG_WITH([noarch-pkgconfigdir],
     194    [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
     195    [with_noarch_pkgconfigdir=]pkg_default)
     196AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
     197m4_popdef([pkg_default])
     198m4_popdef([pkg_description])
     199]) dnl PKG_NOARCH_INSTALLDIR
     200
     201
     202# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
     203# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
     204# -------------------------------------------
     205# Retrieves the value of the pkg-config variable for the given module.
     206AC_DEFUN([PKG_CHECK_VAR],
     207[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
     208AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
     209
     210_PKG_CONFIG([$1], [variable="][$3]["], [$2])
     211AS_VAR_COPY([$1], [pkg_cv_][$1])
     212
     213AS_VAR_IF([$1], [""], [$5], [$4])dnl
     214])# PKG_CHECK_VAR
  • mainwin.c

    r099597c rab88b05  
    44static void owl_mainwin_resized(owl_window *w, void *user_data);
    55
    6 void owl_mainwin_init(owl_mainwin *mw, owl_window *window)
     6CALLER_OWN owl_mainwin *owl_mainwin_new(owl_window *window)
    77{
     8  owl_mainwin *mw = g_new(owl_mainwin, 1);
    89  mw->curtruncated=0;
    910  mw->lastdisplayed=-1;
     
    1617  /* For now, we do not bother with connecting up dependencies; that'll be a
    1718   * future refactor of the mainwin */
     19
     20  return mw;
    1821}
    1922
  • message.c

    r259e60a8 r2354e9a  
    1 #include <stdlib.h>
    2 #include <unistd.h>
    3 #include <string.h>
    4 #include <sys/socket.h>
    5 #include <netdb.h>
    6 #include <sys/types.h>
    7 #include <sys/socket.h>
    8 #include <netinet/in.h>
    9 #include <arpa/inet.h>
    10 #include <time.h>
    111#include "owl.h"
    122#include "filterproc.h"
     3#include <sys/socket.h>
     4#include <arpa/inet.h>
    135
    146static owl_fmtext_cache fmtext_cache[OWL_FMTEXT_CACHE_SIZE];
     
    4234  m->delete=0;
    4335
     36#ifdef HAVE_LIBZEPHYR
     37  m->has_notice = false;
     38#endif
     39
    4440  owl_message_set_hostname(m, "");
    45   owl_list_create(&(m->attributes));
     41  m->attributes = g_ptr_array_new();
    4642 
    4743  /* save the time */
    48   m->time=time(NULL);
    49   m->timestr=g_strdup(ctime(&(m->time)));
    50   m->timestr[strlen(m->timestr)-1]='\0';
     44  m->time = time(NULL);
     45  m->timestr = g_strdup(ctime(&m->time));
     46  m->timestr[strlen(m->timestr)-1] = '\0';
    5147
    5248  m->fmtext = NULL;
     
    5854void owl_message_set_attribute(owl_message *m, const char *attrname, const char *attrvalue)
    5955{
    60   int i, j;
     56  int i;
    6157  owl_pair *p = NULL, *pair = NULL;
    6258
     
    6460
    6561  /* look for an existing pair with this key, */
    66   j=owl_list_get_size(&(m->attributes));
    67   for (i=0; i<j; i++) {
    68     p=owl_list_get_element(&(m->attributes), i);
     62  for (i = 0; i < m->attributes->len; i++) {
     63    p = m->attributes->pdata[i];
    6964    if (owl_pair_get_key(p) == attrname) {
    7065      g_free(owl_pair_get_value(p));
     
    7772    pair = g_new(owl_pair, 1);
    7873    owl_pair_create(pair, attrname, NULL);
    79     owl_list_append_element(&(m->attributes), pair);
     74    g_ptr_array_add(m->attributes, pair);
    8075  }
    8176  owl_pair_set_value(pair, owl_validate_or_convert(attrvalue));
     
    8782const char *owl_message_get_attribute_value(const owl_message *m, const char *attrname)
    8883{
    89   int i, j;
     84  int i;
    9085  owl_pair *p;
    9186  GQuark quark;
     
    9792  attrname = g_quark_to_string(quark);
    9893
    99   j=owl_list_get_size(&(m->attributes));
    100   for (i=0; i<j; i++) {
    101     p=owl_list_get_element(&(m->attributes), i);
     94  for (i = 0; i < m->attributes->len; i++) {
     95    p = m->attributes->pdata[i];
    10296    if (owl_pair_get_key(p) == attrname) {
    10397      return(owl_pair_get_value(p));
     
    118112 */
    119113void owl_message_attributes_tofmtext(const owl_message *m, owl_fmtext *fm) {
    120   int i, j;
     114  int i;
    121115  owl_pair *p;
    122116  char *buff, *tmpbuff;
     
    124118  owl_fmtext_init_null(fm);
    125119
    126   j=owl_list_get_size(&(m->attributes));
    127   for (i=0; i<j; i++) {
    128     p=owl_list_get_element(&(m->attributes), i);
    129 
    130     tmpbuff = g_strdup(owl_pair_get_value(p));
    131     g_strdelimit(tmpbuff, "\n", '~');
    132     g_strdelimit(tmpbuff, "\r", '!');
    133     buff = g_strdup_printf("  %-15.15s: %s\n", owl_pair_get_key(p), tmpbuff);
    134     g_free(tmpbuff);
     120  for (i = 0; i < m->attributes->len; i++) {
     121    p = m->attributes->pdata[i];
     122
     123    buff = g_strdup(owl_pair_get_value(p));
     124    if (buff) {
     125      tmpbuff = owl_text_indent(buff, 19, false);
     126      g_free(buff);
     127      buff = g_strdup_printf("  %-15.15s: %s\n", owl_pair_get_key(p), tmpbuff);
     128      g_free(tmpbuff);
     129    }
    135130
    136131    if(buff == NULL) {
     
    352347}
    353348
     349CALLER_OWN char *owl_message_format_time(const owl_message *m)
     350{
     351  return owl_util_format_time(localtime(&m->time));
     352}
     353
    354354void owl_message_set_type_admin(owl_message *m)
    355355{
     
    500500const ZNotice_t *owl_message_get_notice(const owl_message *m)
    501501{
    502   return(&(m->notice));
     502  return m->has_notice ? &m->notice : NULL;
    503503}
    504504#else
     
    580580
    581581/* caller must free return value. */
    582 char *owl_message_get_cc(const owl_message *m)
     582CALLER_OWN char *owl_message_get_cc(const owl_message *m)
    583583{
    584584  const char *cur;
     
    597597
    598598/* caller must free return value */
    599 GList *owl_message_get_cc_without_recipient(const owl_message *m)
     599CALLER_OWN GList *owl_message_get_cc_without_recipient(const owl_message *m)
    600600{
    601601  char *cc, *shortuser, *recip;
     
    791791  /* first save the full notice */
    792792  m->notice = *n;
     793  m->has_notice = true;
    793794
    794795  /* a little gross, we'll replace \r's with ' ' for now */
     
    797798  /* save the time, we need to nuke the string saved by message_init */
    798799  if (m->timestr) g_free(m->timestr);
    799   m->time=n->z_time.tv_sec;
    800   m->timestr=g_strdup(ctime(&(m->time)));
    801   m->timestr[strlen(m->timestr)-1]='\0';
     800  m->time = n->z_time.tv_sec;
     801  m->timestr = g_strdup(ctime(&m->time));
     802  m->timestr[strlen(m->timestr)-1] = '\0';
    802803
    803804  /* set other info */
     
    835836
    836837 
    837   /* set the "isprivate" attribute if it's a private zephyr.
    838    ``private'' means recipient is non-empty and doesn't start wit
    839    `@' */
    840   if (*n->z_recipient && *n->z_recipient != '@') {
     838  /* set the "isprivate" attribute if it's a private zephyr. */
     839  if (owl_zwrite_recip_is_personal(n->z_recipient)) {
    841840    owl_message_set_isprivate(m);
    842841  }
     
    876875  if (owl_global_is_zcrypt(&g) && !strcasecmp(n->z_opcode, "crypt")) {
    877876    const char *argv[] = {
    878       "zcrypt",
     877      NULL,
    879878      "-D",
    880879      "-c", owl_message_get_class(m),
     
    882881      NULL
    883882    };
    884     char *out;
     883    char *out = NULL;
    885884    int rv;
    886885    int status;
    887886    char *zcrypt;
    888887
    889     zcrypt = g_strdup_printf("%s/zcrypt", owl_get_bindir());
    890 
    891     rv = call_filter(zcrypt, argv, owl_message_get_body(m), &out, &status);
     888    zcrypt = g_build_filename(owl_get_bindir(), "zcrypt", NULL);
     889    argv[0] = zcrypt;
     890
     891    rv = call_filter(argv, owl_message_get_body(m), &out, &status);
    892892    g_free(zcrypt);
    893893
     
    898898      }
    899899      owl_message_set_body(m, out);
    900       g_free(out);
    901     } else if(out) {
    902       g_free(out);
    903     }
     900    } else {
     901      /* Replace the opcode. Otherwise the UI and other bits of code think the
     902       * message was encrypted. */
     903      owl_message_set_opcode(m, "failed-decrypt");
     904    }
     905    g_free(out);
    904906  }
    905907
     
    10041006void owl_message_cleanup(owl_message *m)
    10051007{
    1006   int i, j;
     1008  int i;
    10071009  owl_pair *p;
    10081010#ifdef HAVE_LIBZEPHYR   
    1009   if (owl_message_is_type_zephyr(m) && owl_message_is_direction_in(m)) {
     1011  if (m->has_notice) {
    10101012    ZFreeNotice(&(m->notice));
    10111013  }
     
    10141016
    10151017  /* free all the attributes */
    1016   j=owl_list_get_size(&(m->attributes));
    1017   for (i=0; i<j; i++) {
    1018     p=owl_list_get_element(&(m->attributes), i);
     1018  for (i = 0; i < m->attributes->len; i++) {
     1019    p = m->attributes->pdata[i];
    10191020    g_free(owl_pair_get_value(p));
    10201021    g_free(p);
    10211022  }
    10221023
    1023   owl_list_cleanup(&(m->attributes), NULL);
     1024  g_ptr_array_free(m->attributes, true);
    10241025 
    10251026  owl_message_invalidate_format(m);
  • messagelist.c

    r66a8cd6 r219f52c  
    11#include "owl.h"
    2 #include <stdlib.h>
    3 #include <string.h>
    42
    5 int owl_messagelist_create(owl_messagelist *ml)
     3CALLER_OWN owl_messagelist *owl_messagelist_new(void)
    64{
    7   owl_list_create(&(ml->list));
    8   return(0);
     5  owl_messagelist *ml = g_new(owl_messagelist, 1);
     6  ml->list = g_ptr_array_new();
     7  return ml;
     8}
     9
     10void owl_messagelist_delete(owl_messagelist *ml, bool free_messages)
     11{
     12  if (free_messages)
     13    g_ptr_array_foreach(ml->list, (GFunc)owl_message_delete, NULL);
     14  g_ptr_array_free(ml->list, true);
     15  g_free(ml);
    916}
    1017
    1118int owl_messagelist_get_size(const owl_messagelist *ml)
    1219{
    13   return(owl_list_get_size(&(ml->list)));
     20  return ml->list->len;
    1421}
    1522
    1623void *owl_messagelist_get_element(const owl_messagelist *ml, int n)
    1724{
    18   return(owl_list_get_element(&(ml->list), n));
     25  /* we assume things like owl_view_get_element(v, owl_global_get_curmsg(&g))
     26   * work even when there are no messages in the message list.  So don't
     27   * segfault if someone asks for the zeroth element of an empty list.
     28   */
     29  if (n >= ml->list->len) return NULL;
     30  return ml->list->pdata[n];
    1931}
    2032
    21 owl_message *owl_messagelist_get_by_id(const owl_messagelist *ml, int target_id)
     33int owl_messagelist_get_index_by_id(const owl_messagelist *ml, int target_id)
    2234{
    23   /* return the message with id == 'id'.  If it doesn't exist return NULL. */
     35  /* return the message index with id == 'id'.  If it doesn't exist return -1. */
    2436  int first, last, mid, msg_id;
    2537  owl_message *m;
    2638
    2739  first = 0;
    28   last = owl_list_get_size(&(ml->list)) - 1;
     40  last = ml->list->len - 1;
    2941  while (first <= last) {
    3042    mid = (first + last) / 2;
    31     m = owl_list_get_element(&(ml->list), mid);
     43    m = ml->list->pdata[mid];
    3244    msg_id = owl_message_get_id(m);
    3345    if (msg_id == target_id) {
    34       return(m);
     46      return mid;
    3547    } else if (msg_id < target_id) {
    3648      first = mid + 1;
     
    3951    }
    4052  }
    41   return(NULL);
     53  return -1;
    4254}
    4355
    44 int owl_messagelist_append_element(owl_messagelist *ml, void *element)
     56owl_message *owl_messagelist_get_by_id(const owl_messagelist *ml, int target_id)
    4557{
    46   return(owl_list_append_element(&(ml->list), element));
     58  /* return the message with id == 'id'.  If it doesn't exist return NULL. */
     59  int n = owl_messagelist_get_index_by_id(ml, target_id);
     60  if (n < 0) return NULL;
     61  return ml->list->pdata[n];
     62}
     63
     64void owl_messagelist_append_element(owl_messagelist *ml, void *element)
     65{
     66  g_ptr_array_add(ml->list, element);
    4767}
    4868
     
    5171{
    5272  /* mark a message as deleted */
    53   owl_message_mark_delete(owl_list_get_element(&(ml->list), n));
     73  owl_message_mark_delete(ml->list->pdata[n]);
    5474  return(0);
    5575}
     
    5878{
    5979  /* mark a message as deleted */
    60   owl_message_unmark_delete(owl_list_get_element(&(ml->list), n));
     80  owl_message_unmark_delete(ml->list->pdata[n]);
    6181  return(0);
     82}
     83
     84void owl_messagelist_delete_and_expunge_element(owl_messagelist *ml, int n)
     85{
     86  owl_message_delete(g_ptr_array_remove_index(ml->list, n));
    6287}
    6388
     
    6590{
    6691  /* expunge deleted messages */
    67   int i, j;
    68   owl_list newlist;
     92  int i;
     93  GPtrArray *newlist;
    6994  owl_message *m;
    7095
    71   owl_list_create(&newlist);
     96  newlist = g_ptr_array_new();
    7297  /*create a new list without messages marked as deleted */
    73   j=owl_list_get_size(&(ml->list));
    74   for (i=0; i<j; i++) {
    75     m=owl_list_get_element(&(ml->list), i);
     98  for (i = 0; i < ml->list->len; i++) {
     99    m = ml->list->pdata[i];
    76100    if (owl_message_is_delete(m)) {
    77101      owl_message_delete(m);
    78102    } else {
    79       owl_list_append_element(&newlist, m);
     103      g_ptr_array_add(newlist, m);
    80104    }
    81105  }
    82106
    83107  /* free the old list */
    84   owl_list_cleanup(&(ml->list), NULL);
     108  g_ptr_array_free(ml->list, true);
    85109
    86110  /* copy the new list to the old list */
     
    92116void owl_messagelist_invalidate_formats(const owl_messagelist *ml)
    93117{
    94   int i, j;
     118  int i;
    95119  owl_message *m;
    96120
    97   j=owl_list_get_size(&(ml->list));
    98   for (i=0; i<j; i++) {
    99     m=owl_list_get_element(&(ml->list), i);
     121  for (i = 0; i < ml->list->len; i++) {
     122    m = ml->list->pdata[i];
    100123    owl_message_invalidate_format(m);
    101124  }
  • owl.c

    rcc305b5 r499224d  
    77 */
    88
     9#include "owl.h"
    910#include <stdio.h>
    10 #include <unistd.h>
    1111#include <getopt.h>
    12 #include <stdlib.h>
    13 #include <string.h>
    14 #include <signal.h>
    15 #include <time.h>
    16 #include <sys/param.h>
    17 #include <sys/types.h>
    18 #include <sys/time.h>
    19 #include <termios.h>
    2012#include <sys/stat.h>
    2113#include <locale.h>
    22 #include "owl.h"
    23 
     14#include <unistd.h>
    2415
    2516#if OWL_STDERR_REDIR
     
    4334} owl_options;
    4435
    45 void usage(void)
     36void usage(FILE *file)
    4637{
    47   fprintf(stderr, "Barnowl version %s\n", OWL_VERSION_STRING);
    48   fprintf(stderr, "Usage: barnowl [-n] [-d] [-D] [-v] [-h] [-c <configfile>] [-s <confdir>] [-t <ttyname>]\n");
    49   fprintf(stderr, "  -n,--no-subs        don't load zephyr subscriptions\n");
    50   fprintf(stderr, "  -d,--debug          enable debugging\n");
    51   fprintf(stderr, "  -v,--version        print the Barnowl version number and exit\n");
    52   fprintf(stderr, "  -h,--help           print this help message\n");
    53   fprintf(stderr, "  -c,--config-file    specify an alternate config file\n");
    54   fprintf(stderr, "  -s,--config-dir     specify an alternate config dir (default ~/.owl)\n");
    55   fprintf(stderr, "  -t,--tty            set the tty name\n");
     38  fprintf(file, "Barnowl version %s\n", OWL_VERSION_STRING);
     39  fprintf(file, "Usage: barnowl [-n] [-d] [-D] [-v] [-h] [-c <configfile>] [-s <confdir>] [-t <ttyname>]\n");
     40  fprintf(file, "  -n,--no-subs        don't load zephyr subscriptions\n");
     41  fprintf(file, "  -d,--debug          enable debugging\n");
     42  fprintf(file, "  -v,--version        print the Barnowl version number and exit\n");
     43  fprintf(file, "  -h,--help           print this help message\n");
     44  fprintf(file, "  -s,--config-dir     specify an alternate config dir (default ~/.owl)\n");
     45  fprintf(file, "  -c,--config-file    specify an alternate config file (default ~/.owl/init.pl)\n");
     46  fprintf(file, "  -t,--tty            set the tty name\n");
    5647}
    5748
     
    8980      break;
    9081    case 'v':
    91       printf("This is barnowl version %s\n", OWL_VERSION_STRING);
     82      printf("This is BarnOwl version %s\n", OWL_VERSION_STRING);
    9283      exit(0);
    9384    case 'h':
     85      usage(stdout);
     86      exit(0);
    9487    default:
    95       usage();
     88      usage(stderr);
    9689      exit(1);
    9790    }
     
    272265    /* follow the last message if we're supposed to */
    273266    if (followlast)
    274       owl_function_lastmsg_noredisplay();
     267      owl_function_lastmsg();
    275268
    276269    /* do the newmsgproc thing */
     
    302295}
    303296
    304 void owl_process_input(const owl_io_dispatch *d, void *data)
     297gboolean owl_process_input(GIOChannel *source, GIOCondition condition, void *data)
    305298{
     299  owl_global *g = data;
    306300  owl_input j;
    307301
    308302  while (1) {
    309     j.ch = wgetch(g.input_pad);
    310     if (j.ch == ERR) return;
     303    j.ch = wgetch(g->input_pad);
     304    if (j.ch == ERR) return TRUE;
    311305
    312306    j.uch = '\0';
     
    330324     
    331325      for (i = 1; i < bytes; i++) {
    332         int tmp = wgetch(g.input_pad);
     326        int tmp = wgetch(g->input_pad);
    333327        /* If what we got was not a byte, or not a continuation byte */
    334328        if (tmp > 0xff || !(tmp & 0x80 && ~tmp & 0x40)) {
     
    357351    owl_process_input_char(j);
    358352  }
     353  return TRUE;
    359354}
    360355
     
    387382}
    388383
    389 #define CHECK_RESULT(s, syscall) \
     384#define OR_DIE(s, syscall)      \
    390385  G_STMT_START {                 \
    391     if ((syscall) != 0) {        \
     386    if ((syscall) == -1) {       \
    392387      perror((s));               \
    393388      exit(1);                   \
     
    400395  sigset_t sigset;
    401396  int ret, i;
    402   const int signals[] = { SIGABRT, SIGBUS, SIGCHLD, SIGFPE, SIGHUP, SIGILL,
    403                           SIGINT, SIGQUIT, SIGSEGV, SIGTERM, SIGWINCH };
     397  const int reset_signals[] = { SIGABRT, SIGBUS, SIGCHLD, SIGFPE, SIGILL,
     398                                SIGQUIT, SIGSEGV, };
     399  /* Don't bother resetting watched ones because owl_signal_init will. */
     400  const int watch_signals[] = { SIGWINCH, SIGTERM, SIGHUP, SIGINT, };
    404401
    405402  /* Sanitize our signals; the mask and dispositions from our parent
    406403   * aren't really useful. Signal list taken from equivalent code in
    407404   * Chromium. */
    408   CHECK_RESULT("sigemptyset", sigemptyset(&sigset));
     405  OR_DIE("sigemptyset", sigemptyset(&sigset));
    409406  if ((ret = pthread_sigmask(SIG_SETMASK, &sigset, NULL)) != 0) {
    410407    errno = ret;
    411408    perror("pthread_sigmask");
    412   }
    413   for (i = 0; i < G_N_ELEMENTS(signals); i++) {
    414     CHECK_RESULT("sigaction", sigaction(signals[i], &sig_default, NULL));
     409    exit(1);
     410  }
     411  for (i = 0; i < G_N_ELEMENTS(reset_signals); i++) {
     412    OR_DIE("sigaction", sigaction(reset_signals[i], &sig_default, NULL));
    415413  }
    416414
    417415  /* Turn off SIGPIPE; we check the return value of write. */
    418   CHECK_RESULT("sigaction", sigaction(SIGPIPE, &sig_ignore, NULL));
     416  OR_DIE("sigaction", sigaction(SIGPIPE, &sig_ignore, NULL));
    419417
    420418  /* Register some signals with the signal thread. */
    421   CHECK_RESULT("sigaddset", sigaddset(&sigset, SIGWINCH));
    422   CHECK_RESULT("sigaddset", sigaddset(&sigset, SIGTERM));
    423   CHECK_RESULT("sigaddset", sigaddset(&sigset, SIGHUP));
    424   CHECK_RESULT("sigaddset", sigaddset(&sigset, SIGINT));
    425   owl_signal_init(&sigset, sig_handler, NULL);
     419  owl_signal_init(watch_signals, G_N_ELEMENTS(watch_signals),
     420                  sig_handler, NULL);
    426421}
    427422
     
    435430  if (0 != pipe(pipefds)) {
    436431    perror("pipe");
    437     owl_function_debugmsg("stderr_replace: pipe FAILED\n");
     432    owl_function_debugmsg("stderr_replace: pipe FAILED");
    438433    return -1;
    439434  }
    440     owl_function_debugmsg("stderr_replace: pipe: %d,%d\n", pipefds[0], pipefds[1]);
    441   if (-1 == dup2(pipefds[1], 2 /*stderr*/)) {
    442     owl_function_debugmsg("stderr_replace: dup2 FAILED (%s)\n", strerror(errno));
     435    owl_function_debugmsg("stderr_replace: pipe: %d,%d", pipefds[0], pipefds[1]);
     436  if (-1 == dup2(pipefds[1], STDERR_FILENO)) {
     437    owl_function_debugmsg("stderr_replace: dup2 FAILED (%s)", strerror(errno));
    443438    perror("dup2");
    444439    return -1;
     
    448443
    449444/* Sends stderr (read from rfd) messages to the error console */
    450 void stderr_redirect_handler(const owl_io_dispatch *d, void *data)
     445gboolean stderr_redirect_handler(GIOChannel *source, GIOCondition condition, void *data)
    451446{
    452447  int navail, bread;
    453448  char buf[4096];
    454   int rfd = d->fd;
     449  int rfd = g_io_channel_unix_get_fd(source);
    455450  char *err;
    456451
    457   if (rfd<0) return;
     452  /* TODO: Use g_io_channel_read_line? We'd have to be careful about
     453   * blocking on the read. */
     454
     455  if (rfd<0) return TRUE;
    458456  if (-1 == ioctl(rfd, FIONREAD, &navail)) {
    459     return;
     457    return TRUE;
    460458  }
    461459  /*owl_function_debugmsg("stderr_redirect: navail = %d\n", navail);*/
    462   if (navail <= 0) return;
     460  if (navail <= 0) return TRUE;
    463461  if (navail > sizeof(buf)-1) {
    464462    navail = sizeof(buf)-1;
     
    466464  bread = read(rfd, buf, navail);
    467465  if (bread == -1)
    468     return;
     466    return TRUE;
    469467
    470468  err = g_strdup_printf("[stderr]\n%.*s", bread, buf);
     
    472470  owl_function_log_err(err);
    473471  g_free(err);
     472  return TRUE;
    474473}
    475474
     
    485484  owl_options opts;
    486485  GSource *source;
    487 
    488   if (!GLIB_CHECK_VERSION (2, 12, 0))
    489     g_error ("GLib version 2.12.0 or above is needed.");
     486  GIOChannel *channel;
    490487
    491488  argc_copy = argc;
     
    513510
    514511  /* register STDIN dispatch; throw away return, we won't need it */
    515   owl_select_add_io_dispatch(STDIN_FILENO, OWL_IO_READ, &owl_process_input, NULL, NULL);
     512  channel = g_io_channel_unix_new(STDIN_FILENO);
     513  g_io_add_watch(channel, G_IO_IN | G_IO_HUP | G_IO_ERR, &owl_process_input, &g);
     514  g_io_channel_unref(channel);
    516515  owl_zephyr_initialize();
    517516
    518517#if OWL_STDERR_REDIR
    519518  /* Do this only after we've started curses up... */
    520   owl_function_debugmsg("startup: doing stderr redirection");
    521   owl_select_add_io_dispatch(stderr_replace(), OWL_IO_READ, &stderr_redirect_handler, NULL, NULL);
     519  if (isatty(STDERR_FILENO)) {
     520    owl_function_debugmsg("startup: doing stderr redirection");
     521    channel = g_io_channel_unix_new(stderr_replace());
     522    g_io_add_watch(channel, G_IO_IN | G_IO_HUP | G_IO_ERR, &stderr_redirect_handler, NULL);
     523    g_io_channel_unref(channel);
     524  }
    522525#endif
    523526
     
    576579  owl_function_adminmsg("",
    577580    "-----------------------------------------------------------------------\n"
    578     "Welcome to barnowl version " OWL_VERSION_STRING ".\n"
     581    "Welcome to BarnOwl version " OWL_VERSION_STRING ".\n"
    579582    "To see a quick introduction, type ':show quickstart'.                  \n"
    580583    "Press 'h' for on-line help.                                            \n"
     
    587590  );
    588591
     592  owl_function_debugmsg("startup: setting context interactive");
     593
     594  owl_global_pop_context(&g);
     595  owl_global_push_context(&g, OWL_CTX_INTERACTIVE|OWL_CTX_RECV, NULL, "recv", NULL);
     596
    589597  /* process the startup file */
    590598  owl_function_debugmsg("startup: processing startup file");
     
    598606      owl_function_error("No such style: %s", owl_global_get_default_style(&g));
    599607
    600   owl_function_debugmsg("startup: setting context interactive");
    601 
    602   owl_global_pop_context(&g);
    603   owl_global_push_context(&g, OWL_CTX_INTERACTIVE|OWL_CTX_RECV, NULL, "recv", NULL);
    604 
    605608  source = owl_window_redraw_source_new();
    606609  g_source_attach(source, NULL);
  • owl.h

    r33b6431b r6249a88f  
    1010#define INC_BARNOWL_OWL_H
    1111
    12 #include "config.h"
     12#include <config.h>
    1313
    1414#include "compat/compat.h"
    1515
    16 #ifdef HAVE_STDBOOL_H
    1716#include <stdbool.h>
    18 #else
    19 #ifndef HAVE__BOOL
    20 #define _Bool signed char
    21 #endif
    22 #define bool _Bool
    23 #define false 0
    24 #define true 1
    25 #define __bool_true_false_are_defined 1
    26 #endif  /* HAVE_STDBOOL_H */
    2717
    2818#ifndef OWL_PERL
    29 #include <curses.h>
    30 #include <panel.h>
     19#define NCURSES_ENABLE_STDBOOL_H 1
     20#include <ncursesw/curses.h>
     21#include <ncursesw/panel.h>
    3122#endif
    3223#include <sys/param.h>
     24#include <sys/types.h>
     25#include <ctype.h>
     26#include <errno.h>
    3327#include <EXTERN.h>
     28#include <fcntl.h>
    3429#include <netdb.h>
    3530#include <regex.h>
    3631#include <time.h>
    3732#include <signal.h>
     33#include <stdlib.h>
     34#include <string.h>
    3835#include <termios.h>
     36#include <unistd.h>
    3937#include "libfaim/aim.h"
    4038#include <wchar.h>
    41 #include "glib.h"
     39#include <glib.h>
    4240#ifdef HAVE_LIBZEPHYR
    4341#include <zephyr/zephyr.h>
     
    4947/* Perl and curses don't play nice. */
    5048#ifdef OWL_PERL
    51 typedef void WINDOW;
    52 typedef void PANEL;
     49typedef struct _owl_fake_WINDOW WINDOW;
     50typedef struct _owl_fake_PANEL PANEL;
    5351/* logout is defined in FreeBSD. */
    5452#define logout logout_
     
    5957#include "XSUB.h"
    6058#else
    61 typedef void SV;
    62 typedef void AV;
    63 typedef void HV;
     59typedef struct _owl_fake_SV SV;
     60typedef struct _owl_fake_AV AV;
     61typedef struct _owl_fake_HV HV;
    6462#endif
    6563
     
    8482
    8583#define OWL_CONFIG_DIR "/.owl"             /* this is relative to the user's home directory */
    86 #define OWL_STARTUP_FILE "/.owl/startup"   /* this is relative to the user's home directory */
    8784
    8885#define OWL_FMTEXT_ATTR_NONE      0
     
    130127#define OWL_MESSAGE_DIRECTION_IN    1
    131128#define OWL_MESSAGE_DIRECTION_OUT   2
    132 
    133 #define OWL_IO_READ   1
    134 #define OWL_IO_WRITE  2
    135 #define OWL_IO_EXCEPT 4
    136129
    137130#define OWL_DIRECTION_NONE      0
     
    213206#endif
    214207
     208/* Annotate functions in which the caller owns the return value and is
     209 * responsible for ensuring it is freed. */
     210#define CALLER_OWN G_GNUC_WARN_UNUSED_RESULT
     211
    215212#define OWL_META(key) ((key)|010000)
    216213/* OWL_CTRL is definied in kepress.c */
    217 
    218 #define LINE 2048
    219214
    220215#ifdef HAVE_LIBZEPHYR
     
    240235  char *name;
    241236  int   type;  /* OWL_VARIABLE_* */
    242   void *pval_default;  /* for types other and string */
    243   int   ival_default;  /* for types int and bool     */
    244   char *validsettings;          /* documentation of valid settings */
     237  char *default_str;            /* the default value as a string */
     238  char *validsettings;          /* documentation of valid settings */
    245239  char *summary;                /* summary of usage */
    246240  char *description;            /* detailed description */
    247   void *val;                    /* current value */
    248   int  (*validate_fn)(const struct _owl_variable *v, const void *newval);
     241  bool takes_on_off;            /* allow passing on/off in argument-less set/unset */
     242  GClosure *set_fromstring_fn;
     243                                /* sets the variable to a value
     244                                 * of the appropriate type.
     245                                 * unless documented, this
     246                                 * should make a copy.
     247                                 * returns 0 on success. */
     248  GClosure *get_tostring_fn;
     249                                /* converts val to a string;
     250                                 * caller must free the result */
     251
     252  /* These are only valid for OWL_VARIABLE_{INT,BOOL,STRING} */
     253  GValue val;                   /* current value, if default get_fn/set_fn */
     254
     255  GCallback get_fn;
     256                                /* returns a reference to the current value.
     257                                 * WARNING:  this approach is hard to make
     258                                 * thread-safe... */
     259  GCallback validate_fn;
    249260                                /* returns 1 if newval is valid */
    250   int  (*set_fn)(struct _owl_variable *v, const void *newval);
     261  GCallback set_fn;
    251262                                /* sets the variable to a value
    252                                  * of the appropriate type.
    253                                  * unless documented, this
    254                                  * should make a copy.
    255                                  * returns 0 on success. */
    256   int  (*set_fromstring_fn)(struct _owl_variable *v, const char *newval);
    257                                 /* sets the variable to a value
    258                                  * of the appropriate type.
    259                                  * unless documented, this
    260                                  * should make a copy.
    261                                  * returns 0 on success. */
    262   const void *(*get_fn)(const struct _owl_variable *v);
    263                                 /* returns a reference to the current value.
    264                                  * WARNING:  this approach is hard to make
    265                                  * thread-safe... */
    266   char *(*get_tostring_fn)(const struct _owl_variable *v, const void *val);
    267                                 /* converts val to a string;
    268                                  * caller must free the result */
    269   void (*delete_fn)(struct _owl_variable *v);
    270                                 /* frees val as needed */
     263                                 * of the appropriate type.
     264                                 * unless documented, this
     265                                 * should make a copy.
     266                                 * returns 0 on success. */
    271267} owl_variable;
     268
    272269
    273270typedef struct _owl_input {
     
    279276  GString *buff;
    280277} owl_fmtext;
    281 
    282 typedef struct _owl_list {
    283   int size;
    284   int avail;
    285   void **list;
    286 } owl_list;
    287278
    288279typedef struct _owl_dict_el {
     
    326317 
    327318  /* These don't take any context */
    328   char *(*cmd_args_fn)(int argc, const char *const *argv, const char *buff); 
     319  CALLER_OWN char *(*cmd_args_fn)(int argc, const char *const *argv, const char *buff);
    329320                                /* takes argv and the full command as buff.
    330321                                 * caller must free return value if !NULL */
     
    333324
    334325  /* The following also take the active context if it's valid */
    335   char *(*cmd_ctxargs_fn)(void *ctx, int argc, const char *const *argv, const char *buff); 
     326  CALLER_OWN char *(*cmd_ctxargs_fn)(void *ctx, int argc, const char *const *argv, const char *buff);
    336327                                /* takes argv and the full command as buff.
    337328                                 * caller must free return value if !NULL */
     
    351342  char *zsig;
    352343  char *message;
    353   owl_list recips;
     344  GPtrArray *recips;
    354345  int cc;
    355346  int noping;
     
    367358  int direction;
    368359#ifdef HAVE_LIBZEPHYR
     360  bool has_notice;
    369361  ZNotice_t notice;
    370362#endif
     
    372364  int delete;
    373365  const char *hostname;
    374   owl_list attributes;            /* this is a list of pairs */
     366  GPtrArray *attributes;          /* this is a list of pairs */
    375367  char *timestr;
    376368  time_t time;
     
    431423
    432424typedef struct _owl_messagelist {
    433   owl_list list;
     425  GPtrArray *list;
    434426} owl_messagelist;
    435427
     
    462454  char *name;
    463455  owl_filter *filter;
    464   owl_messagelist ml;
     456  owl_messagelist *ml;
    465457  const owl_style *style;
    466458  int cachedmsgid;
     
    468460
    469461typedef struct _owl_history {
    470   owl_list hist;
    471   int cur;
    472   int touched;
    473   int partial;
    474   int repeats;
     462  GQueue hist;
     463  GList *cur;
     464  bool partial;
    475465} owl_history;
    476466
     
    496486  char     *name;               /* name of keymap */
    497487  char     *desc;               /* description */
    498   owl_list  bindings;           /* key bindings */
     488  GPtrArray *bindings;          /* key bindings */
    499489  const struct _owl_keymap *parent;     /* parent */
    500490  void (*default_fn)(owl_input j);      /* default action (takes a keypress) */
     
    519509
    520510typedef struct _owl_buddylist {
    521   owl_list buddies;
     511  GPtrArray *buddies;
    522512} owl_buddylist;
    523513
    524514typedef struct _owl_zbuddylist {
    525   owl_list zusers;
     515  GPtrArray *zusers;
    526516} owl_zbuddylist;
    527517
    528 typedef struct _owl_timer {
    529   time_t time;
    530   int interval;
    531   void (*callback)(struct _owl_timer *, void *);
    532   void (*destroy)(struct _owl_timer *);
    533   void *data;
    534   char *name;
    535 } owl_timer;
    536 
    537518typedef struct _owl_errqueue {
    538   owl_list errlist;
     519  GPtrArray *errlist;
    539520} owl_errqueue;
    540521
     
    545526} owl_colorpair_mgr;
    546527
    547 typedef struct _owl_io_dispatch {
    548   int fd;                                     /* FD to watch for dispatch. */
    549   int mode;
    550   bool valid;
    551   int needs_gc;
    552   void (*callback)(const struct _owl_io_dispatch *, void *); /* C function to dispatch to. */
    553   void (*destroy)(const struct _owl_io_dispatch *);  /* Destructor */
    554   void *data;
    555   GPollFD pollfd;
    556 } owl_io_dispatch;
    557 
    558528typedef struct _owl_popexec {
    559529  int refcount;
     
    561531  int winactive;
    562532  pid_t pid;                    /* or 0 if it has terminated */
    563   const owl_io_dispatch *dispatch;
     533  guint io_watch;
    564534} owl_popexec;
    565535
    566536typedef struct _owl_global {
    567   owl_mainwin mw;
     537  owl_mainwin *mw;
    568538  owl_popwin *pw;
    569539  owl_msgwin msgwin;
     
    573543  owl_dict filters;
    574544  GList *filterlist;
    575   owl_list puntlist;
     545  GPtrArray *puntlist;
    576546  owl_vardict vars;
    577547  owl_cmddict cmds;
     
    583553  int curmsg_vert_offset;
    584554  owl_view current_view;
    585   owl_messagelist msglist;
     555  owl_messagelist *msglist;
    586556  WINDOW *input_pad;
    587557  owl_mainpanel mainpanel;
     
    593563  char *startupfile;
    594564  int direction;
    595   int zaway;
    596   char *cur_zaway_msg;
    597565  int haveconfig;
    598566  int config_format;
     
    625593  int pseudologin_notify;
    626594  struct termios startup_tio;
    627   owl_list io_dispatch_list;
    628   GList *timerlist;
    629   owl_timer *aim_nop_timer;
     595  guint aim_nop_timer;
    630596  int load_initial_subs;
    631597  FILE *debug_file;
    632598  char *kill_buffer;
    633599  int interrupt_count;
     600#if GLIB_CHECK_VERSION(2, 31, 0)
     601  GMutex interrupt_lock;
     602#else
    634603  GMutex *interrupt_lock;
     604#endif
    635605} owl_global;
    636606
     
    638608extern owl_global g;
    639609
    640 #include "owl_prototypes.h"
     610#include <owl_prototypes.h>
    641611
    642612/* These were missing from the Zephyr includes before Zephyr 3. */
     
    646616#endif
    647617
     618/* We have to dynamically bind these ourselves */
     619extern gboolean (*gvalue_from_sv) (GValue * value, SV * sv);
     620extern SV * (*sv_from_gvalue) (const GValue * value);
     621extern GClosure * (*perl_closure_new) (SV * callback, SV * data, gboolean swap);
     622
     623
    648624#endif /* INC_BARNOWL_OWL_H */
  • owl_perl.h

    r06adc25 r92ffd89  
    22#define INC_BARNOWL_OWL_PERL_H
    33
    4 #define OWL_PERL_VOID_CALL (void)POPs;
     4#include <stdio.h>
     5
     6/*
     7 * This macro defines a convenience wrapper around the boilerplate
     8 * of pushing char * arguments on to the stack for perl calling.
     9 *
     10 * Arguments are
     11 * * i     - the counter variable to use, which must be declared prior
     12 *           to calling this macro
     13 * * argc  - the number of arguments
     14 * * argv  - an array of char*s, of length at least argc; the arguments
     15 *           to push on to the stack
     16 */
     17#define OWL_PERL_PUSH_ARGS(i, argc, argv) { \
     18  for (i = 0; i < argc; i++) { \
     19    XPUSHs(sv_2mortal(owl_new_sv(argv[i]))); \
     20  } \
     21}
    522
    623/*
    724 * This macro defines a convenience wrapper around the boilerplate of
    8  * calling a method on a perl object (SV*) from C.
     25 * the perlcall methods.
    926 *
    1027 * Arguments are
    11  * * obj    - the SV* to call the method on
    12  * * meth   - a char* method name
    13  * * args   - a code block responsible for pushing args (other than the object)
    14  * * err    - a string with a %s format specifier to log in case of error
    15  * * fatalp - if true, perl errors terminate barnowl
    16  * * ret    - a code block executed if the call succeeded
     28 * * call       - the line of code to make the perl call
     29 * * args       - a code block responsible for pushing args
     30 * * err        - a string with a %s format specifier to log in case of error
     31 * * fatalp     - if true, perl errors terminate BarnOwl
     32 * * discardret - should be true if no return is expected
     33 *                (if the call is passed the flag G_DISCARD or G_VOID)
     34 * * ret        - a code block executed if the call succeeded
    1735 *
    1836 * See also: `perldoc perlcall', `perldoc perlapi'
    1937 */
    20 #define OWL_PERL_CALL_METHOD(obj, meth, args, err, fatalp, ret) { \
    21     int count; \
    22     dSP; \
    23     ENTER; \
    24     SAVETMPS; \
    25     PUSHMARK(SP); \
    26     XPUSHs(obj); \
    27     {args} \
    28     PUTBACK; \
    29     \
    30     count = call_method(meth, G_SCALAR|G_EVAL); \
    31     \
    32     SPAGAIN; \
    33     \
    34     if(count != 1) { \
    35       fprintf(stderr, "perl returned wrong count: %d\n", count); \
    36       abort();                                                   \
     38#define OWL_PERL_CALL(call, args, err, fatalp, discardret, ret) { \
     39  int count; \
     40  dSP; \
     41  \
     42  ENTER; \
     43  SAVETMPS; \
     44  \
     45  PUSHMARK(SP); \
     46  {args} \
     47  PUTBACK; \
     48  \
     49  count = call; \
     50  \
     51  SPAGAIN; \
     52  \
     53  if (!discardret && count != 1) { \
     54    croak("Perl returned wrong count: %d\n", count); \
     55  } \
     56  \
     57  if (SvTRUE(ERRSV)) { \
     58    if (fatalp) { \
     59      fprintf(stderr, err, SvPV_nolen(ERRSV)); \
     60      exit(-1); \
     61    } else { \
     62      owl_function_error(err, SvPV_nolen(ERRSV)); \
     63      if (!discardret) (void)POPs; \
     64      sv_setsv(ERRSV, &PL_sv_undef); \
    3765    } \
    38     if (SvTRUE(ERRSV)) { \
    39       if(fatalp) { \
    40         printf(err, SvPV_nolen(ERRSV)); \
    41         exit(-1); \
    42       } else { \
    43         owl_function_error(err, SvPV_nolen(ERRSV)); \
    44         (void)POPs; \
    45         sv_setsv(ERRSV, &PL_sv_undef); \
    46       } \
    47     } else { \
    48       ret; \
    49     } \
    50     PUTBACK; \
    51     FREETMPS; \
    52     LEAVE; \
     66  } else if (!discardret) { \
     67    ret; \
     68  } \
     69  PUTBACK; \
     70  FREETMPS; \
     71  LEAVE; \
    5372}
    5473
  • perl/Makefile.am

    r10557e6 ra870319  
    11SUBDIRS = modules
     2nobase_dist_pkgdata_DATA = \
     3        lib/BarnOwl.pm \
     4        lib/BarnOwl/Complete/AIM.pm \
     5        lib/BarnOwl/Complete/Client.pm \
     6        lib/BarnOwl/Complete/Filter.pm \
     7        lib/BarnOwl/Complete/Zephyr.pm \
     8        lib/BarnOwl/Completion.pm \
     9        lib/BarnOwl/Completion/Context.pm \
     10        lib/BarnOwl/Completion/Util.pm \
     11        lib/BarnOwl/Editwin.pm \
     12        lib/BarnOwl/Help.pm \
     13        lib/BarnOwl/Hook.pm \
     14        lib/BarnOwl/Hooks.pm \
     15        lib/BarnOwl/MainLoopCompatHook.pm \
     16        lib/BarnOwl/Message.pm \
     17        lib/BarnOwl/Message/AIM.pm \
     18        lib/BarnOwl/Message/Admin.pm \
     19        lib/BarnOwl/Message/Generic.pm \
     20        lib/BarnOwl/Message/Loopback.pm \
     21        lib/BarnOwl/Message/Zephyr.pm \
     22        lib/BarnOwl/ModuleLoader.pm \
     23        lib/BarnOwl/Parse.pm \
     24        lib/BarnOwl/Style.pm \
     25        lib/BarnOwl/Style/Basic.pm \
     26        lib/BarnOwl/Style/Default.pm \
     27        lib/BarnOwl/Style/Legacy.pm \
     28        lib/BarnOwl/Style/OneLine.pm \
     29        lib/BarnOwl/Timer.pm \
     30        lib/BarnOwl/Zephyr.pm \
     31        lib/Module/Install/BarnOwl.pm
  • perl/lib/BarnOwl.pm

    rf2d71cfa r1ced34f  
    55
    66use base qw(Exporter);
    7 our @EXPORT_OK = qw(command getcurmsg getnumcols getidletime
     7our @EXPORT_OK = qw(command getcurmsg getnumcols getnumlines getidletime
    88                    zephyr_getsender zephyr_getrealm zephyr_zwrite
    99                    zephyr_stylestrip zephyr_smartstrip_user zephyr_getsubs
    1010                    queue_message admin_message
     11                    start_edit
    1112                    start_question start_password start_edit_win
    1213                    get_data_dir get_config_dir popless_text popless_ztext
    1314                    error debug
    1415                    create_style getnumcolors wordwrap
     16                    message_matches_filter
    1517                    add_dispatch remove_dispatch
    1618                    add_io_dispatch remove_io_dispatch
    1719                    new_command
    1820                    new_variable_int new_variable_bool new_variable_string
     21                    new_variable_enum
    1922                    quote redisplay);
    2023our %EXPORT_TAGS = (all => \@EXPORT_OK);
     
    2831use lib(get_data_dir() . "/lib");
    2932use lib(get_config_dir() . "/lib");
     33
     34use Glib;
     35use AnyEvent;
    3036
    3137use BarnOwl::Hook;
     
    3844use BarnOwl::Completion;
    3945use BarnOwl::Help;
    40 use BarnOwl::AnyEvent;
    41 
    42 unshift @AnyEvent::REGISTRY, [BarnOwl => BarnOwl::AnyEvent::];
    43 require AnyEvent;
    4446
    4547use List::Util qw(max);
     
    5355The BarnOwl module contains the core of BarnOwl's perl
    5456bindings. Source in this module is also run at startup to bootstrap
    55 barnowl by defining things like the default style.
     57BarnOwl by defining things like the default style.
    5658
    5759=for NOTE
     
    8183=head2 zephyr_getrealm
    8284
    83 Returns the zephyr realm barnowl is running in
     85Returns the zephyr realm BarnOwl is running in
    8486
    8587=head2 zephyr_getsender
    8688
    87 Returns the fully-qualified name of the zephyr sender barnowl is
     89Returns the fully-qualified name of the zephyr sender BarnOwl is
    8890running as, e.g. C<nelhage@ATHENA.MIT.EDU>
    8991
     
    9294Sends a zephyr programmatically. C<COMMAND> should be a C<zwrite>
    9395command line, and C<MESSAGE> is the zephyr body to send.
     96
     97=cut
     98
     99sub zephyr_zwrite {
     100    my ($command, $message) = @_;
     101    my $ret = BarnOwl::Internal::zephyr_zwrite($command, $message);
     102    die "Error sending zephyr" unless $ret == 0;
     103}
    94104
    95105=head2 ztext_stylestrip STRING
     
    112122Display a BarnOwl B<Admin> message, with the given header and body.
    113123
     124=head2 start_edit %ARGS
     125
     126Displays a prompt on the screen and lets the user enter text,
     127and calls a callback when the editwin is closed.
     128
     129C<%ARGS> must contain the following keys:
     130
     131=over 4
     132
     133=item prompt
     134
     135The line to display on the screen
     136
     137=item type
     138
     139One of:
     140
     141=over 4
     142
     143=item edit_win
     144
     145Displays the prompt on a line of its own and opens the edit_win.
     146
     147=item question
     148
     149Displays prompt on the screen and lets the user enter a line of
     150text.
     151
     152=item password
     153
     154Like question, but echoes the user's input as C<*>s when they
     155input.
     156
     157=back
     158
     159=item callback
     160
     161A Perl subroutine that is called when the user closes the edit_win.
     162C<CALLBACK> gets called with two parameters: the text the user entered,
     163and a C<SUCCESS> boolean parameter which is false if the user canceled
     164the edit_win and true otherwise.
     165
     166=back
     167
    114168=head2 start_question PROMPT CALLBACK
    115169
    116 Displays C<PROMPT> on the screen and lets the user enter a line of
    117 text, and calls C<CALLBACK>, which must be a perl subroutine
    118 reference, with the text the user entered
    119 
    120170=head2 start_password PROMPT CALLBACK
    121171
    122 Like C<start_question>, but echoes the user's input as C<*>s when they
    123 input.
    124 
    125172=head2 start_edit_win PROMPT CALLBACK
    126173
    127 Like C<start_question>, but displays C<PROMPT> on a line of its own
    128 and opens the editwin. If the user cancels the edit win, C<CALLBACK>
    129 is not invoked.
     174Roughly equivalent to C<start_edit> called with the appropriate parameters.
     175C<CALLBACK> is only called on success, for compatibility.
     176
     177These are deprecated wrappers around L<BarnOwl::start_edit>, and should not
     178be uesd in new code.
     179
     180=cut
     181
     182sub start_edit {
     183    my %args = (@_);
     184    BarnOwl::Internal::start_edit($args{type}, $args{prompt}, $args{callback});
     185}
     186
     187sub start_question {
     188    my ($prompt, $callback) = @_;
     189    BarnOwl::start_edit(type => 'question', prompt => $prompt, callback => sub {
     190            my ($text, $success) = @_;
     191            $callback->($text) if $success;
     192        });
     193}
     194
     195sub start_password {
     196    my ($prompt, $callback) = @_;
     197    BarnOwl::start_edit(type => 'password', prompt => $prompt, callback => sub {
     198            my ($text, $success) = @_;
     199            $callback->($text) if $success;
     200        });
     201}
     202
     203sub start_edit_win {
     204    my ($prompt, $callback) = @_;
     205    BarnOwl::start_edit(type => 'edit_win', prompt => $prompt, callback => sub {
     206            my ($text, $success) = @_;
     207            $callback->($text) if $success;
     208        });
     209}
    130210
    131211=head2 get_data_dir
     
    161241Returns the number of colors this BarnOwl is capable of displaying
    162242
     243=head2 message_matches_filter MESSAGE FILTER_NAME [QUIET = 0]
     244
     245Returns 1 if C<FILTER_NAME> is the name of a valid filter, and
     246C<MESSAGE> matches that filter.  Returns 0 otherwise.  If
     247C<QUIET> is false, this method displays an error message if
     248if C<FILTER_NAME> does not name a valid filter.
     249
    163250=head2 add_dispatch FD CALLBACK
    164251
     
    167254read from C<FD>.
    168255
    169 C<add_dispatch> has been deprecated in favor of C<add_io_dispatch>,
    170 and is now a wrapper for it called with C<mode> set to C<'r'>.
     256C<add_dispatch> has been deprecated in favor of C<AnyEvent>, and is
     257now a wrapper for C<add_io_dispatch> called with C<mode> set to
     258C<'r'>.
    171259
    172260=cut
     
    182270Remove a file descriptor previously registered via C<add_dispatch>
    183271
    184 C<remove_dispatch> has been deprecated in favor of
    185 C<remove_io_dispatch>.
     272C<remove_dispatch> has been deprecated in favor of C<AnyEvent>.
    186273
    187274=cut
     
    198285registered, the old one is removed.
    199286
    200 =cut
     287C<add_io_dispatch> has been deprecated in favor of C<AnyEvent>.
     288
     289=cut
     290
     291our %_io_dispatches;
    201292
    202293sub add_io_dispatch {
     
    204295    my $modeStr = shift;
    205296    my $cb = shift;
    206     my $mode = 0;
    207 
    208     $mode |= 0x1 if ($modeStr =~ /r/i); # Read
    209     $mode |= 0x2 if ($modeStr =~ /w/i); # Write
    210     if ($mode) {
    211         $mode |= 0x4;                  # Exceptional
    212         BarnOwl::Internal::add_io_dispatch($fd, $mode, $cb);
     297    my @modes;
     298
     299    push @modes, 'r' if $modeStr =~ /r/i; # Read
     300    push @modes, 'w' if $modeStr =~ /w/i; # Write
     301    if (@modes) {
     302        BarnOwl::remove_io_dispatch($fd);
     303        for my $mode (@modes) {
     304            push @{$_io_dispatches{$fd}}, AnyEvent->io(fh => $fd,
     305                                                       poll => $mode,
     306                                                       cb => $cb);
     307        }
    213308    } else {
    214309        die("Invalid I/O Dispatch mode: $modeStr");
     
    220315Remove a file descriptor previously registered via C<add_io_dispatch>
    221316
     317C<remove_io_dispatch> has been deprecated in favor of C<AnyEvent>.
     318
     319=cut
     320
     321sub remove_io_dispatch {
     322    my $fd = shift;
     323    undef $_ foreach @{$_io_dispatches{$fd}};
     324    delete $_io_dispatches{$fd};
     325}
     326
    222327=head2 create_style NAME OBJECT
    223328
    224 Creates a new barnowl style with the given NAME defined by the given
     329Creates a new BarnOwl style with the given NAME defined by the given
    225330object. The object must have a C<description> method which returns a
    226331string description of the style, and a and C<format_message> method
     
    241346our @all_commands;
    242347
    243 if(!$configfile && -f $ENV{HOME} . "/.barnowlconf") {
    244     $configfile = $ENV{HOME} . "/.barnowlconf";
    245 }
    246 $configfile ||= $ENV{HOME}."/.owlconf";
     348if(!$configfile) {
     349    if (-f get_config_dir() . "/init.pl") {
     350        $configfile = get_config_dir() . "/init.pl";
     351    } elsif (-f $ENV{HOME} . "/.barnowlconf") {
     352        $configfile = $ENV{HOME} . "/.barnowlconf";
     353    } else {
     354        $configfile = $ENV{HOME}."/.owlconf";
     355    }
     356}
    247357
    248358# populate global variable space for legacy owlconf files
     
    301411=head2 new_variable_string NAME [{ARGS}]
    302412
    303 Add a new owl variable, either an int, a bool, or a string, with the
     413=head2 new_variable_enum NAME [{ARGS}]
     414
     415Add a new owl variable, either an int, a bool, a string, or an enum with the
    304416specified name.
    305417
    306 ARGS can optionally contain the following keys:
     418For new_variable_enum, ARGS is required to contain a validsettings key pointing
     419to an array reference. For all four, it can optionally contain the following
     420keys:
    307421
    308422=over 4
     
    322436=back
    323437
     438In addition, new_variable_string optionally accepts a string validsettings
     439parameter, in case people want to set it to "<path>".
     440
    324441=cut
    325442
    326443sub new_variable_int {
    327     unshift @_, \&BarnOwl::Internal::new_variable_int, 0;
    328     goto \&_new_variable;
     444    my ($name, $args) = @_;
     445    my $storage = defined($args->{default}) ? $args->{default} : 0;
     446    BarnOwl::new_variable_full($name, {
     447            %{$args},
     448            get_tostring => sub { "$storage" },
     449            set_fromstring => sub {
     450                die "Expected integer" unless $_[0] =~ /^-?[0-9]+$/;
     451                $storage = 0 + $_[0];
     452            },
     453            validsettings => "<int>",
     454            takes_on_off => 0,
     455        });
    329456}
    330457
    331458sub new_variable_bool {
    332     unshift @_, \&BarnOwl::Internal::new_variable_bool, 0;
    333     goto \&_new_variable;
     459    my ($name, $args) = @_;
     460    my $storage = defined($args->{default}) ? $args->{default} : 0;
     461    BarnOwl::new_variable_full($name, {
     462            %{$args},
     463            get_tostring => sub { $storage ? "on" : "off" },
     464            set_fromstring => sub {
     465                die "Valid settings are on/off" unless $_[0] eq "on" || $_[0] eq "off";
     466                $storage = $_[0] eq "on";
     467            },
     468            validsettings => "on,off",
     469            takes_on_off => 1,
     470        });
    334471}
    335472
    336473sub new_variable_string {
    337     unshift @_, \&BarnOwl::Internal::new_variable_string, "";
    338     goto \&_new_variable;
    339 }
    340 
    341 sub _new_variable {
    342     my $func = shift;
    343     my $default_default = shift;
     474    my ($name, $args) = @_;
     475    my $storage = defined($args->{default}) ? $args->{default} : "";
     476    BarnOwl::new_variable_full($name, {
     477            # Allow people to override this one if they /reaaally/ want to for
     478            # some reason. Though we still reserve the right to interpret this
     479            # value in interesting ways for tab-completion purposes.
     480            validsettings => "<string>",
     481            %{$args},
     482            get_tostring => sub { $storage },
     483            set_fromstring => sub { $storage = $_[0]; },
     484            takes_on_off => 0,
     485        });
     486}
     487
     488sub new_variable_enum {
     489    my ($name, $args) = @_;
     490
     491    # Gather the valid settings.
     492    die "validsettings is required" unless defined($args->{validsettings});
     493    my %valid;
     494    map { $valid{$_} = 1 } @{$args->{validsettings}};
     495
     496    my $storage = (defined($args->{default}) ?
     497                   $args->{default} :
     498                   $args->{validsettings}->[0]);
     499    BarnOwl::new_variable_full($name, {
     500            %{$args},
     501            get_tostring => sub { $storage },
     502            set_fromstring => sub {
     503                die "Invalid input" unless $valid{$_[0]};
     504                $storage = $_[0];
     505            },
     506            validsettings => join(",", @{$args->{validsettings}})
     507        });
     508}
     509
     510=head2 new_variable_full NAME {ARGS}
     511
     512Create a variable, in full generality. The keyword arguments have types below:
     513
     514 get_tostring : ()  -> string
     515 set_fromstring : string -> int
     516 -- optional --
     517 summary : string
     518 description : string
     519 validsettings : string
     520 takes_on_off : int
     521
     522The get/set functions are required. Note that the caller manages storage for the
     523variable. get_tostring/set_fromstring both convert AND store the value.
     524set_fromstring dies on failure.
     525
     526If the variable takes parameters 'on' and 'off' (i.e. is boolean-looking), set
     527takes_on_off to 1. This makes :set VAR and :unset VAR work. set_fromstring will
     528be called with those arguments.
     529
     530=cut
     531
     532sub new_variable_full {
    344533    my $name = shift;
    345534    my $args = shift || {};
    346535    my %args = (
    347         summary     => "",
     536        summary => "",
    348537        description => "",
    349         default     => $default_default,
     538        takes_on_off => 0,
     539        validsettings => "<string>",
    350540        %{$args});
    351     $func->($name, $args{default}, $args{summary}, $args{description});
     541
     542    die "get_tostring required" unless $args{get_tostring};
     543    die "set_fromstring required" unless $args{set_fromstring};
     544
     545    # Strip off the bogus dummy argument. Aargh perl-Glib.
     546    my $get_tostring_fn = sub { $args{get_tostring}->() };
     547    my $set_fromstring_fn = sub {
     548      my ($dummy, $val) = @_;
     549      # Translate from user-supplied die-on-failure callback to expected
     550      # non-zero on error. Less of a nuisance than interacting with ERRSV.
     551      eval { $args{set_fromstring}->($val) };
     552      # TODO: Consider changing B::I::new_variable to expect string|NULL with
     553      # string as the error message. That can then be translated to a GError in
     554      # owl_variable_set_fromstring. For now the string is ignored.
     555      return ($@ ? -1 : 0);
     556    };
     557
     558    BarnOwl::Internal::new_variable($name, $args{summary}, $args{description}, $args{validsettings},
     559                                    $args{takes_on_off}, $get_tostring_fn, $set_fromstring_fn, undef);
    352560}
    353561
     
    553761{
    554762  my $zsig = getvar('zsig');
    555   if (!$zsig) {
    556       if (my $zsigproc = getvar('zsigproc')) {
     763  if (!defined($zsig) || $zsig eq '') {
     764      my $zsigproc = getvar('zsigproc');
     765      if (defined($zsigproc) && $zsigproc ne '') {
    557766          $zsig = `$zsigproc`;
    558767      } elsif (!defined($zsig = get_zephyr_variable('zwrite-signature'))) {
  • perl/lib/BarnOwl/Complete/Client.pm

    rc6adf17 r4626016  
    2020
    2121my %show = (
    22     information => undef,
    2322    colors      => undef,
    2423    commands    => undef,
     
    3736    subs        => undef,
    3837    terminal    => undef,
    39     timers      => undef,
    4038    variables   => undef,
    4139    variable    => \&complete_variable,
     
    206204BarnOwl::Completion::register_completer(set     => \&complete_set);
    207205BarnOwl::Completion::register_completer(unset   => \&complete_set);
    208 BarnOwl::Completion::register_completer(startup => \&complete_startup);
     206BarnOwl::Completion::register_completer(startup   => \&complete_startup);
     207BarnOwl::Completion::register_completer(unstartup => \&complete_startup);
    209208BarnOwl::Completion::register_completer(bindkey => \&complete_bindkey);
    210209BarnOwl::Completion::register_completer(print   => \&complete_print);
  • perl/lib/BarnOwl/Complete/Zephyr.pm

    r3e8625f re6e7842  
    6464BarnOwl::Completion::register_completer(viewuser  => \&complete_viewuser);
    6565BarnOwl::Completion::register_completer(vu        => \&complete_viewuser);
     66BarnOwl::Completion::register_completer(viewperson => \&complete_viewuser);
     67BarnOwl::Completion::register_completer(vp        => \&complete_viewuser);
    6668
    6769BarnOwl::Completion::register_completer(unsub     => \&complete_unsub);
  • perl/lib/BarnOwl/Hooks.pm

    r3aa0522 rb8a3e00  
    146146}
    147147
    148 # These are the internal hooks called by the barnowl C code, which
     148# These are the internal hooks called by the BarnOwl C code, which
    149149# take care of dispatching to the appropriate perl hooks, and deal
    150150# with compatibility by calling the old, fixed-name hooks.
  • perl/lib/BarnOwl/Message.pm

    rd1ae4a4 r0adbce1  
    5151sub is_ping     { return 0; }
    5252sub is_mail     { return 0; }
    53 sub is_personal { return shift->is_private; }
     53sub is_personal { return BarnOwl::message_matches_filter(shift, "personal"); }
    5454sub class       { return undef; }
    5555sub instance    { return undef; }
     
    8080# (eg, the oneline style)
    8181sub short_personal_context { return ""; }
     82
     83sub delete_and_expunge {
     84    my ($m) = @_;
     85    &BarnOwl::command("delete-and-expunge --quiet --id " . $m->id);
     86}
    8287
    8388sub delete {
  • perl/lib/BarnOwl/Message/Zephyr.pm

    redd0be7 r0adbce1  
    5151    my ($m) = @_;
    5252    return undef if (!$m->is_loginout);
     53    return undef if (!defined($m->fields));
    5354    return $m->fields->[2];
    5455}
     
    5758    my ($m) = @_;
    5859    return undef if (!$m->is_loginout);
     60    return undef if (!defined($m->fields));
    5961    return $m->fields->[0];
    6062}
     
    6365
    6466sub is_ping     { return (lc(shift->opcode) eq "ping"); }
    65 
    66 sub is_personal {
    67     my ($m) = @_;
    68     return ((lc($m->class) eq "message")
    69             && $m->is_private);
    70 }
    7167
    7268sub is_mail {
     
    171167        $class = $self->class;
    172168        $instance = $self->instance;
    173         if ($self->recipient eq '*' || $self->recipient eq '') {
    174             $to = '';
    175         } elsif ($self->recipient =~ /^@/) {
     169        if ($self->recipient eq '' || $self->recipient =~ /^@/) {
    176170            $to = $self->recipient;
    177171        } else {
  • perl/lib/BarnOwl/ModuleLoader.pm

    rf544216 rf34728b  
    127127}
    128128
     129sub complete_module_name {
     130    return sort(keys %modules);
     131}
     132
    129133sub register_keybindings {
    130134    BarnOwl::new_command('reload-modules', sub {BarnOwl::ModuleLoader->reload}, {
     
    138142                           description => q{Reloads a single module located in ~/.owl/modules or the system modules directory}
    139143                          });
     144
     145    BarnOwl::Completion::register_completer('reload-module', \&complete_module_name);
    140146}
    141147
  • perl/lib/BarnOwl/Style/Default.pm

    r5738650 r732d5c0  
    113113        }
    114114        $header .= '@b{' . maybe($m->pretty_sender) . '}';
     115        if (defined($m->realm) && $m->realm ne BarnOwl::zephyr_getrealm()) {
     116            $header .= ' {' . $self->humanize($m->realm, 1) . '}';
     117        }
    115118    }
    116119
  • perl/lib/BarnOwl/Timer.pm

    rc6adf17 r074bdaa  
    33
    44package BarnOwl::Timer;
     5
     6use AnyEvent;
    57
    68sub new {
     
    1315    my $self = {cb => $cb};
    1416
    15     my $name = $args->{name};
    16     $name = "(unnamed)" unless defined $name;
    17 
    1817    bless($self, $class);
    1918
    20     $self->{timer} = BarnOwl::Internal::add_timer($args->{after} || 0,
    21                                                   $args->{interval} || 0,
    22                                                   $self,
    23                                                   $name);
     19    $self->{timer} = AnyEvent->timer(%$args);
    2420    return $self;
    2521}
     
    2723sub stop {
    2824    my $self = shift;
    29     if(defined($self->{timer})) {
    30         BarnOwl::Internal::remove_timer($self->{timer});
    31         undef $self->{timer};
    32     }
     25    undef $self->{timer};
    3326}
    3427
  • perl/lib/BarnOwl/Zephyr.pm

    rdf569c5 r53151d4  
    1212use BarnOwl::Hook;
    1313
    14 my $zephyrStartup = BarnOwl::Hook->new;
     14our $zephyrStartup = BarnOwl::Hook->new;
    1515
    1616sub _zephyr_startup {
  • perl/lib/Module/Install/BarnOwl.pm

    r3519d06 re4b8f93  
    88=head1 DESCRIPTION
    99
    10 Module::Install::BarnOwl is a M::I module to help building barnowl
     10Module::Install::BarnOwl is a M::I module to help building BarnOwl
    1111modules,
    1212
     
    2828
    2929As well as make rules to generate Jabber.par, and to put some
    30 additional barnowl-specific information into META.yml
     30additional BarnOwl-specific information into META.yml
    3131
    3232=cut
     
    4141    my $class = ref $self;
    4242
     43    my $srcdir = $ENV{BARNOWL_SRCDIR} || '.';
     44
    4345    $self->name("BarnOwl-Module-$name");
    44     $self->all_from("lib/BarnOwl/Module/$name.pm");
     46    $self->all_from("$srcdir/lib/BarnOwl/Module/$name.pm");
     47    $self->makemaker_args(PMLIBDIRS => ["$srcdir/lib"],
     48                          PMLIBPARENTDIRS => ["$srcdir/lib"]);
    4549
    4650    $self->postamble(<<"END_MAKEFILE");
    4751
    4852# --- $class section:
     53
     54BARNOWL_SRCDIR = $srcdir
     55export BARNOWL_SRCDIR
    4956
    5057$name.par: pm_to_blib
  • perl/modules/IRC/lib/BarnOwl/Module/IRC.pm

    r5c6d661 r731e921  
    1010=head1 DESCRIPTION
    1111
    12 This module implements IRC support for barnowl.
     12This module implements IRC support for BarnOwl.
    1313
    1414=cut
     
    2323use Getopt::Long;
    2424use Encode;
     25use Text::Wrap;
    2526
    2627our $VERSION = 0.02;
     
    6566        description => 'If set, each (space-separated) message type ' .
    6667        'provided will be hidden and ignored if received.'
     68       });
     69
     70    BarnOwl::new_variable_int('irc:max-message-length', {
     71        default     => 450,
     72        summary     => 'Split messages to at most this many characters.' .
     73                       "If non-positive, don't split messages",
     74        description => 'If set to a positive number, any paragraph in an ' .
     75                       'IRC message will be split after this many characters.'
    6776       });
    6877
     
    427436    @msgs = split "\n\n", $fullbody;
    428437    map { tr/\n/ / } @msgs;
     438    # split each body at irc:max-message-length characters, if that number
     439    # is positive.  Only split at space boundaries.  Start counting a-fresh
     440    # at the beginning of each paragraph
     441    my $max_len = BarnOwl::getvar('irc:max-message-length');
     442    if ($max_len > 0) {
     443        local($Text::Wrap::columns) = $max_len;
     444        @msgs = split "\n", wrap("", "", join "\n", @msgs);
     445    }
    429446    for my $body (@msgs) {
    430447        if ($body =~ /^\/me (.*)/) {
     
    598615        }
    599616
    600         if(!$channel &&
     617        if(!defined($channel) &&
    601618           ($flags & CHANNEL_ARG) &&
    602619           !($flags & CHANNEL_OPTIONAL)) {
  • perl/modules/Jabber/lib/BarnOwl/Message/Jabber.pm

    rb401ef2 ra27acf7  
    161161    my ($recip, $account, $subject) = @_;
    162162    if (defined $recip) {
    163         my @cmd = ('jwrite', $recip, '-a', $account);
     163        my @cmd = ('jwrite', '-a', $account);
    164164        if (defined $subject) {
    165165            push @cmd, '-s', $subject;
    166166        }
     167        push @cmd, '--', $recip;
    167168        return BarnOwl::quote(@cmd);
    168169    } else {
  • perl/modules/Jabber/lib/BarnOwl/Module/Jabber.pm

    rc8d9f84 r8258ea5  
    1010=head1 DESCRIPTION
    1111
    12 This module implements Jabber support for barnowl.
     12This module implements Jabber support for BarnOwl.
    1313
    1414=cut
     
    3636        if($IO::Socket::SSL::VERSION eq "0.97") {
    3737            BarnOwl::error("You are using IO::Socket:SSL 0.97, which \n" .
    38                            "contains bugs causing it not to work with barnowl's\n" .
     38                           "contains bugs causing it not to work with BarnOwl's\n" .
    3939                           "Jabber support. We recommend updating to the latest\n" .
    4040                           "IO::Socket::SSL from CPAN. \n");
     
    320320              . "configure [<muc>]\n"
    321321              . "            Configures a MUC.\n"
    322               . "            Necessary to initalize a new MUC.\n"
     322              . "            Necessary to initialize a new MUC.\n"
    323323              . "            At present, only the default configuration is supported.\n"
    324324              . "            The MUC is taken from the current message if not supplied.\n\n"
     
    14821482}
    14831483
     1484sub complete_jabberlogout {
     1485    my $ctx = shift;
     1486    if($ctx->word == 1) {
     1487        return ("-A", complete_account() );
     1488    } else {
     1489        return ();
     1490    }
     1491}
     1492
    14841493BarnOwl::Completion::register_completer(jwrite => sub { BarnOwl::Module::Jabber::complete_jwrite(@_) });
     1494BarnOwl::Completion::register_completer(jabberlogout => sub { BarnOwl::Module::Jabber::complete_jabberlogout(@_) });
    14851495
    148614961;
  • perl/modules/Jabber/lib/BarnOwl/Module/Jabber/ConnectionManager.pm

    r2cca044 rb8a3e00  
    88=head1 DESCRIPTION
    99
    10 A class to keep track of all the active connection in the barnowl
    11 jabber module
     10A class to keep track of all the active connection in the BarnOwl
     11Jabber module
    1212
    1313=cut
  • perl/modules/Jabber/lib/Net/Jabber/Component.pm

    rc2bed55 ra8c55b5  
    220220    $self->{STREAM}->SetCallBacks(node=>undef);
    221221
    222     $self->Send("<handshake>".Digest::SHA1::sha1_hex($self->{SESSION}->{id}.$args{secret})."</handshake>");
     222    $self->Send("<handshake>".Digest::SHA::sha1_hex($self->{SESSION}->{id}.$args{secret})."</handshake>");
    223223    my $handshake = $self->Process();
    224224
  • perl/modules/Jabber/lib/Net/Jabber/Key.pm

    rc2bed55 ra8c55b5  
    104104    $self->{CACHE} = {};
    105105
    106     if (eval "require Digest::SHA1")
     106    if (eval "require Digest::SHA")
    107107    {
    108108        $self->{DIGEST} = 1;
    109         Digest::SHA1->import(qw(sha1 sha1_hex sha1_base64));
     109        Digest::SHA->import(qw(sha1 sha1_hex sha1_base64));
    110110    }
    111111    else
    112112    {
    113         print "ERROR:  You cannot use Key.pm unless you have Digest::SHA1 installed.\n";
     113        print "ERROR:  You cannot use Key.pm unless you have Digest::SHA installed.\n";
    114114        exit(0);
    115115    }
     
    132132
    133133    my $string = $$.time.rand(1000000);
    134     $string = Digest::SHA1::sha1_hex($string);
     134    $string = Digest::SHA::sha1_hex($string);
    135135    $self->{DEBUG}->Log1("Generate: key($string)");
    136136    return $string;
  • perl/modules/Jabber/lib/Net/XMPP.pm

    rc2bed55 ra8c55b5  
    213213use Time::Local;
    214214use Carp;
    215 use Digest::SHA1;
     215use Digest::SHA;
    216216use Authen::SASL;
    217217use MIME::Base64;
  • perl/modules/Jabber/lib/Net/XMPP/Protocol.pm

    r7f33c18 ra8c55b5  
    18491849    if ($authType eq "zerok")
    18501850    {
    1851         my $hashA = Digest::SHA1::sha1_hex($password);
    1852         $args{hash} = Digest::SHA1::sha1_hex($hashA.$token);
     1851        my $hashA = Digest::SHA::sha1_hex($password);
     1852        $args{hash} = Digest::SHA::sha1_hex($hashA.$token);
    18531853
    18541854        for (1..$sequence)
    18551855        {
    1856             $args{hash} = Digest::SHA1::sha1_hex($args{hash});
     1856            $args{hash} = Digest::SHA::sha1_hex($args{hash});
    18571857        }
    18581858    }
     
    18681868    if ($authType eq "digest")
    18691869    {
    1870         $args{digest} = Digest::SHA1::sha1_hex($self->GetStreamID().$password);
     1870        $args{digest} = Digest::SHA::sha1_hex($self->GetStreamID().$password);
    18711871    }
    18721872
  • perl/modules/Makefile.am

    r1fd469d4 re4b8f93  
    1 MODULES = Jabber IRC WordWrap Twitter
     1MODULES = Jabber IRC WordWrap Twitter Facebook
    22
    3 EXTRA_DIST = $(MODULES:=/Makefile.PL) $(MODULES:=/inc) $(MODULES:=/lib)
     3EXTRA_DIST = $(MODULES:=/Makefile.PL) $(MODULES:=/lib)
     4EXTRA_DIST += \
     5    Facebook/README \
     6    Twitter/README \
     7    Twitter/twitter.example
    48
    59all-local: $(MODULES)
     
    711        (cd $* && $(MAKE) $*.par)
    812
     13BARNOWL_PERL := $(shell which perl) -I$(abs_srcdir)/../lib
     14
    915MODULES_MAKEFILE = $(MODULES:=/Makefile)
    10 $(MODULES_MAKEFILE): %/Makefile: %/Makefile.PL
    11         $(AM_V_GEN)(cd $* && perl -I../../lib Makefile.PL)
     16$(MODULES_MAKEFILE): %/Makefile: %/Makefile.PL ../lib/Module/Install/BarnOwl.pm
     17        $(AM_V_GEN)test -d $* || mkdir $*
     18        $(AM_V_at)test $(srcdir) = . || $(LN_S) $(abs_srcdir)/$*/Makefile.PL $*/Makefile.PL
     19        $(AM_V_at)(cd $* && BARNOWL_SRCDIR='$(abs_srcdir)/$*' && export BARNOWL_SRCDIR && $(BARNOWL_PERL) Makefile.PL 'PERL=$(BARNOWL_PERL)')
    1220
    1321MODULES_CLEAN = $(MODULES:%=clean_%)
    1422clean-local: $(MODULES_CLEAN)
    1523$(MODULES_CLEAN): clean_%:
    16         (cd $* && (test ! -f Makefile || $(MAKE) clean))
     24        (cd $* && { test ! -f Makefile || $(MAKE) realclean; })
     25        rm -f $*/$*.par
     26        rm -rf $*/inc
     27        test $(srcdir) = . || rm -f $*/Makefile.PL
    1728
    1829MODULES_INSTALL = $(MODULES:%=module_install_%)
     
    2334        ${INSTALL_DATA} $*/$*.par ${DESTDIR}${pkgdatadir}/modules/$*.par
    2435
     36uninstall-local:
     37        rm -f $(MODULES:%=${DESTDIR}${pkgdatadir}/modules/%.par)
     38
    2539.PHONY: $(MODULES) $(MODULES_CLEAN) $(MODULES_INSTALL)
  • perl/modules/Twitter/README

    r8c6e2c1 rb8a3e00  
    118118    the sender. Has no effect if poll_for_tweets is false.
    119119
    120 * oauth_key, oauth_secret (strings, default barnowl's consumer credentials)
     120* oauth_key, oauth_secret (strings, default BarnOwl's consumer credentials)
    121121    These are the OAuth consumer key and secret to use to negotiate an
    122122    OAuth connection to Twitter. These credentials must be enabled for
  • perl/modules/Twitter/lib/BarnOwl/Module/Twitter.pm

    rf6e1262 rb8a3e00  
    193193
    194194sub poll_messages {
    195     # If we are reloaded into a barnowl with the old
     195    # If we are reloaded into a BarnOwl with the old
    196196    # BarnOwl::Module::Twitter loaded, it still has a main loop hook
    197197    # that will call this function every second. If we just delete it,
  • perl/modules/Twitter/lib/BarnOwl/Module/Twitter/Handle.pm

    r7aa1fa5 r4ebbfbc  
    2929use BarnOwl;
    3030use BarnOwl::Message::Twitter;
    31 use POSIX qw(asctime);
     31use POSIX qw(strftime);
    3232
    3333use LWP::UserAgent;
     
    247247                       ($self->{cfg}->{account_nickname} ?
    248248                        "[$self->{cfg}->{account_nickname}]" : "") .
    249                         ": ratelimited until " . asctime(localtime($timeout)));
     249                        ": ratelimited until " . strftime('%c', localtime($timeout)));
    250250    } elsif(exists($ratelimit->{error})) {
    251251        $self->sleep(60*20);
  • perlconfig.c

    r3b8a563 r96d80e9  
    1 #include <stdio.h>
    2 #include <stdlib.h>
    3 #include <string.h>
    4 #include <sys/types.h>
    5 #include <sys/stat.h>
    6 #include <errno.h>
    71#define OWL_PERL
    82#include "owl.h"
     3#include <stdio.h>
    94
    105extern XS(boot_BarnOwl);
     
    2318
    2419
    25 SV *owl_new_sv(const char * str)
     20CALLER_OWN SV *owl_new_sv(const char * str)
    2621{
    2722  SV *ret = newSVpv(str, 0);
     
    3631}
    3732
    38 AV *owl_new_av(const owl_list *l, SV *(*to_sv)(const void *))
     33CALLER_OWN AV *owl_new_av(const GPtrArray *l, SV *(*to_sv)(const void *))
    3934{
    4035  AV *ret;
     
    4439  ret = newAV();
    4540
    46   for (i = 0; i < owl_list_get_size(l); i++) {
    47     element = owl_list_get_element(l, i);
     41  for (i = 0; i < l->len; i++) {
     42    element = l->pdata[i];
    4843    av_push(ret, to_sv(element));
    4944  }
     
    5247}
    5348
    54 HV *owl_new_hv(const owl_dict *d, SV *(*to_sv)(const void *))
     49CALLER_OWN HV *owl_new_hv(const owl_dict *d, SV *(*to_sv)(const void *))
    5550{
    5651  HV *ret;
    57   owl_list l;
     52  GPtrArray *keys;
    5853  const char *key;
    5954  void *element;
     
    6358
    6459  /* TODO: add an iterator-like interface to owl_dict */
    65   owl_list_create(&l);
    66   owl_dict_get_keys(d, &l);
    67   for (i = 0; i < owl_list_get_size(&l); i++) {
    68     key = owl_list_get_element(&l, i);
     60  keys = owl_dict_get_keys(d);
     61  for (i = 0; i < keys->len; i++) {
     62    key = keys->pdata[i];
    6963    element = owl_dict_find_element(d, key);
    7064    (void)hv_store(ret, key, strlen(key), to_sv(element), 0);
    7165  }
    72   owl_list_cleanup(&l, g_free);
     66  owl_ptr_array_free(keys, g_free);
    7367
    7468  return ret;
    7569}
    7670
    77 SV *owl_perlconfig_message2hashref(const owl_message *m)
     71CALLER_OWN SV *owl_perlconfig_message2hashref(const owl_message *m)
    7872{
    7973  HV *h, *stash;
     
    8175  const char *type;
    8276  char *ptr, *utype, *blessas;
    83   int i, j;
     77  const char *f;
     78  int i;
    8479  const owl_pair *pair;
    8580  const owl_filter *wrap;
     
    9792                                      owl_new_sv(owl_message_get_##field(m)), 0)
    9893
    99   if (owl_message_is_type_zephyr(m)
    100       && owl_message_is_direction_in(m)) {
     94  if (owl_message_is_type_zephyr(m) && owl_message_is_direction_in(m)) {
    10195    /* Handle zephyr-specific fields... */
    102     AV *av_zfields;
    103 
    104     av_zfields = newAV();
    105     j=owl_zephyr_get_num_fields(owl_message_get_notice(m));
    106     for (i=0; i<j; i++) {
    107       ptr=owl_zephyr_get_field_as_utf8(owl_message_get_notice(m), i+1);
    108       av_push(av_zfields, owl_new_sv(ptr));
    109       g_free(ptr);
     96    AV *av_zfields = newAV();
     97    if (owl_message_get_notice(m)) {
     98      for (f = owl_zephyr_first_raw_field(owl_message_get_notice(m)); f != NULL;
     99           f = owl_zephyr_next_raw_field(owl_message_get_notice(m), f)) {
     100        ptr = owl_zephyr_field_as_utf8(owl_message_get_notice(m), f);
     101        av_push(av_zfields, owl_new_sv(ptr));
     102        g_free(ptr);
     103      }
     104      (void)hv_store(h, "auth", strlen("auth"),
     105                     owl_new_sv(owl_zephyr_get_authstr(owl_message_get_notice(m))), 0);
     106    } else {
     107      /* Incoming zephyrs without a ZNotice_t are pseudo-logins. To appease
     108       * existing styles, put in bogus 'auth' and 'fields' keys. */
     109      (void)hv_store(h, "auth", strlen("auth"), owl_new_sv("NO"), 0);
    110110    }
    111111    (void)hv_store(h, "fields", strlen("fields"), newRV_noinc((SV*)av_zfields), 0);
    112 
    113     (void)hv_store(h, "auth", strlen("auth"),
    114                    owl_new_sv(owl_zephyr_get_authstr(owl_message_get_notice(m))),0);
    115   }
    116 
    117   j=owl_list_get_size(&(m->attributes));
    118   for(i=0; i<j; i++) {
    119     pair=owl_list_get_element(&(m->attributes), i);
     112  }
     113
     114  for (i = 0; i < m->attributes->len; i++) {
     115    pair = m->attributes->pdata[i];
    120116    (void)hv_store(h, owl_pair_get_key(pair), strlen(owl_pair_get_key(pair)),
    121117                   owl_new_sv(owl_pair_get_value(pair)),0);
     
    165161}
    166162
    167 SV *owl_perlconfig_curmessage2hashref(void)
     163CALLER_OWN SV *owl_perlconfig_curmessage2hashref(void)
    168164{
    169165  int curmsg;
     
    180176   message2hashref and hashref2message. Currently we lose
    181177   zephyr-specific properties stored in the ZNotice_t
    182 
    183    This has been somewhat addressed, but is still not lossless.
    184178 */
    185 owl_message * owl_perlconfig_hashref2message(SV *msg)
     179CALLER_OWN owl_message *owl_perlconfig_hashref2message(SV *msg)
    186180{
    187181  owl_message * m;
     
    215209      owl_message_set_zwriteline(m, val);
    216210    } else if (!strcmp(key, "time")) {
     211      g_free(m->timestr);
    217212      m->timestr = g_strdup(val);
    218213      strptime(val, "%a %b %d %T %Y", &tm);
     
    226221      owl_message_set_attribute(m, "adminheader", "");
    227222  }
    228 #ifdef HAVE_LIBZEPHYR
    229   if (owl_message_is_type_zephyr(m)) {
    230     ZNotice_t *n = &(m->notice);
    231     n->z_kind = ACKED;
    232     n->z_port = 0;
    233     n->z_auth = ZAUTH_NO;
    234     n->z_checked_auth = 0;
    235     n->z_class = zstr(owl_message_get_class(m));
    236     n->z_class_inst = zstr(owl_message_get_instance(m));
    237     n->z_opcode = zstr(owl_message_get_opcode(m));
    238     n->z_sender = zstr(owl_message_get_sender(m));
    239     n->z_recipient = zstr(owl_message_get_recipient(m));
    240     n->z_default_format = zstr("[zephyr created from perl]");
    241     n->z_multinotice = zstr("[zephyr created from perl]");
    242     n->z_num_other_fields = 0;
    243     n->z_message = g_strdup_printf("%s%c%s", owl_message_get_zsig(m), '\0', owl_message_get_body(m));
    244     n->z_message_len = strlen(owl_message_get_zsig(m)) + strlen(owl_message_get_body(m)) + 1;
    245   }
    246 #endif
    247223  return m;
    248224}
     
    250226/* Calls in a scalar context, passing it a hash reference.
    251227   If return value is non-null, caller must free. */
    252 char *owl_perlconfig_call_with_message(const char *subname, const owl_message *m)
    253 {
    254   dSP ;
    255   int count;
    256   SV *msgref, *srv;
    257   char *out;
    258  
    259   ENTER ;
    260   SAVETMPS;
    261  
    262   PUSHMARK(SP) ;
     228CALLER_OWN char *owl_perlconfig_call_with_message(const char *subname, const owl_message *m)
     229{
     230  SV *msgref, *rv;
     231  char *out = NULL;
     232
    263233  msgref = owl_perlconfig_message2hashref(m);
    264   XPUSHs(sv_2mortal(msgref));
    265   PUTBACK ;
    266  
    267   count = call_pv(subname, G_SCALAR|G_EVAL);
    268  
    269   SPAGAIN ;
    270 
    271   if (SvTRUE(ERRSV)) {
    272     owl_function_error("Perl Error: '%s'", SvPV_nolen(ERRSV));
    273     /* and clear the error */
    274     sv_setsv (ERRSV, &PL_sv_undef);
    275   }
    276 
    277   if (count != 1) {
    278     fprintf(stderr, "bad perl!  no biscuit!  returned wrong count!\n");
    279     abort();
    280   }
    281 
    282   srv = POPs;
    283 
    284   if (srv) {
    285     out = g_strdup(SvPV_nolen(srv));
    286   } else {
    287     out = NULL;
    288   }
    289  
    290   PUTBACK ;
    291   FREETMPS ;
    292   LEAVE ;
    293 
     234
     235  OWL_PERL_CALL((call_pv(subname, G_SCALAR|G_EVAL))
     236                ,
     237                XPUSHs(sv_2mortal(msgref));
     238                ,
     239                "Perl Error: '%s'"
     240                ,
     241                false
     242                ,
     243                false
     244                ,
     245                rv = POPs;
     246                if (rv && SvPOK(rv))
     247                  out = g_strdup(SvPV_nolen(rv));
     248                );
    294249  return out;
    295250}
     
    299254   If the return value is non-null, the caller must free it.
    300255 */
    301 char * owl_perlconfig_message_call_method(const owl_message *m, const char *method, int argc, const char ** argv)
    302 {
    303   dSP;
    304   unsigned int count, i;
    305   SV *msgref, *srv;
    306   char *out;
     256CALLER_OWN char *owl_perlconfig_message_call_method(const owl_message *m, const char *method, int argc, const char **argv)
     257{
     258  SV *msgref, *rv;
     259  char *out = NULL;
     260  int i;
    307261
    308262  msgref = owl_perlconfig_message2hashref(m);
    309263
    310   ENTER;
    311   SAVETMPS;
    312 
    313   PUSHMARK(SP);
    314   XPUSHs(sv_2mortal(msgref));
    315   for(i=0;i<argc;i++) {
    316     XPUSHs(sv_2mortal(owl_new_sv(argv[i])));
    317   }
    318   PUTBACK;
    319 
    320   count = call_method(method, G_SCALAR|G_EVAL);
    321 
    322   SPAGAIN;
    323 
    324   if(count != 1) {
    325     fprintf(stderr, "perl returned wrong count %u\n", count);
    326     abort();
    327   }
    328 
    329   if (SvTRUE(ERRSV)) {
    330     owl_function_error("Error: '%s'", SvPV_nolen(ERRSV));
    331     /* and clear the error */
    332     sv_setsv (ERRSV, &PL_sv_undef);
    333   }
    334 
    335   srv = POPs;
    336 
    337   if (srv) {
    338     out = g_strdup(SvPV_nolen(srv));
    339   } else {
    340     out = NULL;
    341   }
    342 
    343   PUTBACK;
    344   FREETMPS;
    345   LEAVE;
    346 
     264  OWL_PERL_CALL(call_method(method, G_SCALAR|G_EVAL)
     265                ,
     266                XPUSHs(sv_2mortal(msgref));
     267                OWL_PERL_PUSH_ARGS(i, argc, argv);
     268                ,
     269                "Perl Error: '%s'"
     270                ,
     271                false
     272                ,
     273                false
     274                ,
     275                rv = POPs;
     276                if (rv && SvPOK(rv))
     277                  out = g_strdup(SvPV_nolen(rv));
     278                );
    347279  return out;
    348280}
    349281
    350 
    351 char *owl_perlconfig_initperl(const char * file, int *Pargc, char ***Pargv, char *** Penv)
     282/* caller must free result, if not NULL */
     283CALLER_OWN char *owl_perlconfig_initperl(const char *file, int *Pargc, char ***Pargv, char ***Penv)
    352284{
    353285  int ret;
     
    355287  char *err;
    356288  const char *args[4] = {"", "-e", "0;", NULL};
     289  const char *dlerr;
    357290  AV *inc;
    358291  char *path;
     
    407340  /* Add the system lib path to @INC */
    408341  inc = get_av("INC", 0);
    409   path = g_strdup_printf("%s/lib", owl_get_datadir());
     342  path = g_build_filename(owl_get_datadir(), "lib", NULL);
    410343  av_unshift(inc, 1);
    411344  av_store(inc, 0, owl_new_sv(path));
    412345  g_free(path);
    413346
     347  /* Load up perl-Glib. */
     348  eval_pv("use Glib;", FALSE);
     349
     350  /* Now, before BarnOwl tries to use them, get the relevant function pointers out. */
     351  dlerr = owl_closure_init();
     352  if (dlerr) {
     353    return g_strdup(dlerr);
     354  }
     355
     356  /* And now it's safe to import BarnOwl. */
    414357  eval_pv("use BarnOwl;", FALSE);
    415358
     
    435378
    436379/* caller is responsible for freeing returned string */
    437 char *owl_perlconfig_execute(const char *line)
     380CALLER_OWN char *owl_perlconfig_execute(const char *line)
    438381{
    439382  STRLEN len;
     
    483426void owl_perlconfig_new_command(const char *name)
    484427{
    485   dSP;
    486 
    487   ENTER;
    488   SAVETMPS;
    489 
    490   PUSHMARK(SP);
    491   XPUSHs(sv_2mortal(owl_new_sv(name)));
    492   PUTBACK;
    493 
    494   call_pv("BarnOwl::Hooks::_new_command", G_SCALAR|G_VOID|G_EVAL);
    495 
    496   SPAGAIN;
    497 
    498   if(SvTRUE(ERRSV)) {
    499     owl_function_error("%s", SvPV_nolen(ERRSV));
    500   }
    501 
    502   FREETMPS;
    503   LEAVE;
    504 }
    505 
    506 char *owl_perlconfig_perlcmd(const owl_cmd *cmd, int argc, const char *const *argv)
    507 {
    508   int i, count;
    509   char * ret = NULL;
     428  OWL_PERL_CALL(call_pv("BarnOwl::Hooks::_new_command", G_VOID|G_EVAL);
     429                ,
     430                XPUSHs(sv_2mortal(owl_new_sv(name)));
     431                ,
     432                "Perl Error: '%s'"
     433                ,
     434                false
     435                ,
     436                true
     437                ,
     438                );
     439}
     440
     441CALLER_OWN char *owl_perlconfig_perl_call(const char *method, int argc, const char *const *argv)
     442{
    510443  SV *rv;
    511   dSP;
    512 
    513   ENTER;
    514   SAVETMPS;
    515 
    516   PUSHMARK(SP);
    517   for(i=0;i<argc;i++) {
    518     XPUSHs(sv_2mortal(owl_new_sv(argv[i])));
    519   }
    520   PUTBACK;
    521 
    522   count = call_sv(cmd->cmd_perl, G_SCALAR|G_EVAL);
    523 
    524   SPAGAIN;
    525 
    526   if(SvTRUE(ERRSV)) {
    527     owl_function_error("%s", SvPV_nolen(ERRSV));
    528     (void)POPs;
    529   } else {
    530     if(count != 1)
    531       croak("Perl command %s returned more than one value!", cmd->name);
    532     rv = POPs;
    533     if(SvTRUE(rv)) {
    534       ret = g_strdup(SvPV_nolen(rv));
    535     }
    536   }
    537 
    538   FREETMPS;
    539   LEAVE;
    540 
     444  char *out = NULL;
     445  int i;
     446  OWL_PERL_CALL(call_pv(method, G_SCALAR|G_EVAL)
     447                ,
     448                OWL_PERL_PUSH_ARGS(i, argc, argv);
     449                ,
     450                "Perl Error: '%s'"
     451                ,
     452                false
     453                ,
     454                false
     455                ,
     456                rv = POPs;
     457                if (rv && SvPOK(rv))
     458                  out = g_strdup(SvPV_nolen(rv));
     459                );
     460  return out;
     461}
     462
     463int owl_perlconfig_perl_call_int(const char *method, int argc, const char *const *argv)
     464{
     465  SV *rv;
     466  int ret = -1;
     467  int i;
     468  OWL_PERL_CALL(call_pv(method, G_SCALAR|G_EVAL)
     469                ,
     470                OWL_PERL_PUSH_ARGS(i, argc, argv);
     471                ,
     472                "Perl Error: '%s'"
     473                ,
     474                false
     475                ,
     476                false
     477                ,
     478                rv = POPs;
     479                if (rv && SvIOK(rv))
     480                  ret = SvIV(rv);
     481                );
    541482  return ret;
    542483}
    543484
     485bool owl_perlconfig_perl_call_bool(const char *method, int argc, const char *const *argv)
     486{
     487  SV *rv;
     488  bool ret = false;
     489  int i;
     490  OWL_PERL_CALL(call_pv(method, G_SCALAR|G_EVAL)
     491                ,
     492                OWL_PERL_PUSH_ARGS(i, argc, argv);
     493                ,
     494                "Perl Error: '%s'"
     495                ,
     496                false
     497                ,
     498                false
     499                ,
     500                rv = POPs;
     501                if (rv)
     502                  ret = SvTRUE(rv);
     503                );
     504  return ret;
     505}
     506
     507void owl_perlconfig_perl_call_norv(const char *method, int argc, const char *const *argv)
     508{
     509  int i;
     510  OWL_PERL_CALL(call_pv(method, G_DISCARD|G_EVAL)
     511                ,
     512                OWL_PERL_PUSH_ARGS(i, argc, argv);
     513                ,
     514                "Perl Error: '%s'"
     515                ,
     516                false
     517                ,
     518                true
     519                ,
     520                );
     521}
     522
     523/* caller must free the result */
     524CALLER_OWN char *owl_perlconfig_perlcmd(const owl_cmd *cmd, int argc, const char *const *argv)
     525{
     526  int i;
     527  SV* rv;
     528  char *out = NULL;
     529
     530  OWL_PERL_CALL(call_sv(cmd->cmd_perl, G_SCALAR|G_EVAL)
     531                ,
     532                OWL_PERL_PUSH_ARGS(i, argc, argv);
     533                ,
     534                "Perl Error: '%s'"
     535                ,
     536                false
     537                ,
     538                false
     539                ,
     540                rv = POPs;
     541                if (rv && SvPOK(rv))
     542                  out = g_strdup(SvPV_nolen(rv));
     543                );
     544  return out;
     545}
     546
    544547void owl_perlconfig_cmd_cleanup(owl_cmd *cmd)
    545548{
     
    547550}
    548551
    549 void owl_perlconfig_io_dispatch_destroy(const owl_io_dispatch *d)
    550 {
    551   SvREFCNT_dec(d->data);
    552 }
    553 
    554 void owl_perlconfig_edit_callback(owl_editwin *e)
     552void owl_perlconfig_edit_callback(owl_editwin *e, bool success)
    555553{
    556554  SV *cb = owl_editwin_get_cbdata(e);
    557   SV *text;
    558   dSP;
    559 
    560   if(cb == NULL) {
     555  SV *text = owl_new_sv(owl_editwin_get_text(e));
     556
     557  if (cb == NULL) {
    561558    owl_function_error("Perl callback is NULL!");
    562559    return;
    563560  }
    564   text = owl_new_sv(owl_editwin_get_text(e));
    565 
    566   ENTER;
    567   SAVETMPS;
    568 
    569   PUSHMARK(SP);
    570   XPUSHs(sv_2mortal(text));
    571   PUTBACK;
    572  
    573   call_sv(cb, G_DISCARD|G_EVAL);
    574 
    575   if(SvTRUE(ERRSV)) {
    576     owl_function_error("%s", SvPV_nolen(ERRSV));
    577   }
    578 
    579   FREETMPS;
    580   LEAVE;
     561
     562  OWL_PERL_CALL(call_sv(cb, G_DISCARD|G_EVAL)
     563                ,
     564                XPUSHs(sv_2mortal(text));
     565                XPUSHs(sv_2mortal(newSViv(success)));
     566                ,
     567                "Perl Error: '%s'"
     568                ,
     569                false
     570                ,
     571                true
     572                ,
     573                );
    581574}
    582575
     
    586579  SvREFCNT_dec(v);
    587580}
    588 
    589 void owl_perlconfig_io_dispatch(const owl_io_dispatch *d, void *data)
    590 {
    591   SV *cb = data;
    592   dSP;
    593   if(cb == NULL) {
    594     owl_function_error("Perl callback is NULL!");
    595     return;
    596   }
    597 
    598   ENTER;
    599   SAVETMPS;
    600 
    601   PUSHMARK(SP);
    602   PUTBACK;
    603 
    604   call_sv(cb, G_DISCARD|G_EVAL);
    605 
    606   if(SvTRUE(ERRSV)) {
    607     owl_function_error("%s", SvPV_nolen(ERRSV));
    608   }
    609 
    610   FREETMPS;
    611   LEAVE;
    612 }
    613 
    614 void owl_perlconfig_perl_timer(owl_timer *t, void *data)
    615 {
    616   dSP;
    617   SV *obj = data;
    618 
    619   if(!SvROK(obj)) {
    620     return;
    621   }
    622 
    623   ENTER;
    624   SAVETMPS;
    625 
    626   PUSHMARK(SP);
    627   XPUSHs(obj);
    628   PUTBACK;
    629 
    630   call_method("do_callback", G_DISCARD|G_EVAL);
    631 
    632   SPAGAIN;
    633 
    634   if (SvTRUE(ERRSV)) {
    635     owl_function_error("Error in callback: '%s'", SvPV_nolen(ERRSV));
    636     sv_setsv (ERRSV, &PL_sv_undef);
    637   }
    638 
    639   PUTBACK;
    640   FREETMPS;
    641   LEAVE;
    642 }
    643 
    644 void owl_perlconfig_perl_timer_destroy(owl_timer *t)
    645 {
    646   if(SvOK((SV*)t->data)) {
    647     SvREFCNT_dec((SV*)t->data);
    648   }
    649 }
  • perlglue.xs

    r3b8a563 r1ced34f  
    11/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8 -*- */
    2 #ifdef HAVE_LIBZEPHYR
    3 #include <zephyr/zephyr.h>
    4 #endif
    5 #include <EXTERN.h>
    6 
    72#define OWL_PERL
    83#include "owl.h"
     
    7267        OUTPUT:
    7368                RETVAL
    74                
     69
     70int
     71getnumlines()
     72        CODE:
     73                RETVAL = owl_global_get_lines(&g);
     74        OUTPUT:
     75                RETVAL
     76
    7577time_t
    7678getidletime()
     
    9395        OUTPUT:
    9496                RETVAL
    95 
    96 void
    97 zephyr_zwrite(cmd,msg)
    98         const char *cmd
    99         const char *msg
    100         PREINIT:
    101                 int i;
    102         CODE:
    103                 i = owl_zwrite_create_and_send_from_line(cmd, msg);
    10497
    10598const utf8 *
     
    143136                g_free(rv);
    144137
    145 void
     138SV *
    146139queue_message(msg)
    147140        SV *msg
     
    157150
    158151                owl_global_messagequeue_addmsg(&g, m);
    159         }
     152
     153                RETVAL = owl_perlconfig_message2hashref(m);
     154        }
     155        OUTPUT:
     156                RETVAL
    160157
    161158void
     
    166163        {
    167164                owl_function_adminmsg(header, body);           
    168         }
    169 
    170 void
    171 start_question(line, callback)
    172         const char *line
    173         SV *callback
    174         PREINIT:
    175                 owl_editwin *e;
    176         CODE:
    177         {
    178                 if(!SV_IS_CODEREF(callback))
    179                         croak("Callback must be a subref");
    180 
    181                 e = owl_function_start_question(line);
    182 
    183                 owl_editwin_set_cbdata(e,
    184                                        newSVsv(callback),
    185                                        owl_perlconfig_dec_refcnt);
    186                 owl_editwin_set_callback(e, owl_perlconfig_edit_callback);
    187         }
    188 
    189 void
    190 start_password(line, callback)
    191         const char *line
    192         SV *callback
    193         PREINIT:
    194                 owl_editwin *e;
    195         CODE:
    196         {
    197                 if(!SV_IS_CODEREF(callback))
    198                         croak("Callback must be a subref");
    199 
    200                 e = owl_function_start_password(line);
    201 
    202                 owl_editwin_set_cbdata(e,
    203                                        newSVsv(callback),
    204                                        owl_perlconfig_dec_refcnt);
    205                 owl_editwin_set_callback(e, owl_perlconfig_edit_callback);
    206         }
    207 
    208 void
    209 start_edit_win(line, callback)
    210         const char *line
    211         SV *callback
    212         CODE:
    213         {
    214                 if(!SV_IS_CODEREF(callback))
    215                         croak("Callback must be a subref");
    216 
    217                 owl_function_start_edit_win(line,
    218                                             owl_perlconfig_edit_callback,
    219                                             newSVsv(callback),
    220                                             owl_perlconfig_dec_refcnt);
    221165        }
    222166
     
    312256        }
    313257
     258bool
     259message_matches_filter(message, filter_name, quiet = false)
     260        SV *message
     261        const char *filter_name
     262        bool quiet
     263        PREINIT:
     264                owl_message *m;
     265                const owl_filter *f;
     266        CODE:
     267        {
     268                if (!SvROK(message) || SvTYPE(SvRV(message)) != SVt_PVHV) {
     269                        croak("Usage: BarnOwl::message_matches_filter($message, $filter_name[, $quiet])");
     270                }
     271
     272                m = owl_perlconfig_hashref2message(message);
     273                f = owl_global_get_filter(&g, filter_name);
     274                if (!f && !quiet) {
     275                        owl_function_error("%s filter is not defined", filter_name);
     276                }
     277                RETVAL = f && owl_filter_message_match(f, m);
     278        }
     279        OUTPUT:
     280                RETVAL
     281        CLEANUP:
     282                owl_message_delete(m);
     283
    314284const utf8 *
    315285wordwrap(in, cols)
     
    326296                g_free(rv);
    327297
    328 void
    329 remove_io_dispatch(fd)
    330         int fd
    331         CODE:
    332         owl_select_remove_perl_io_dispatch(fd);
    333 
    334298AV*
    335299all_filters()
    336300        PREINIT:
    337                 owl_list fl;
    338         CODE:
    339         {
    340                 owl_list_create(&fl);
    341                 owl_dict_get_keys(&g.filters, &fl);
    342                 RETVAL = owl_new_av(&fl, (SV*(*)(const void*))owl_new_sv);
     301                GPtrArray *fl;
     302        CODE:
     303        {
     304                fl = owl_dict_get_keys(&g.filters);
     305                RETVAL = owl_new_av(fl, (SV*(*)(const void*))owl_new_sv);
    343306                sv_2mortal((SV*)RETVAL);
    344                 owl_list_cleanup(&fl, g_free);
     307                owl_ptr_array_free(fl, g_free);
    345308        }
    346309        OUTPUT:
     
    350313all_styles()
    351314        PREINIT:
    352                 owl_list l;
    353         CODE:
    354         {
    355                 owl_list_create(&l);
    356                 owl_global_get_style_names(&g, &l);
    357                 RETVAL = owl_new_av(&l, (SV*(*)(const void*))owl_new_sv);
     315                GPtrArray *l;
     316        CODE:
     317        {
     318                l = owl_global_get_style_names(&g);
     319                RETVAL = owl_new_av(l, (SV*(*)(const void*))owl_new_sv);
    358320                sv_2mortal((SV*)RETVAL);
    359321        }
     
    361323                RETVAL
    362324        CLEANUP:
    363                 owl_list_cleanup(&l, g_free);
     325                owl_ptr_array_free(l, g_free);
    364326
    365327
     
    367329all_variables()
    368330        PREINIT:
    369                 owl_list l;
    370         CODE:
    371         {
    372                 owl_list_create(&l);
    373                 owl_dict_get_keys(owl_global_get_vardict(&g), &l);
    374                 RETVAL = owl_new_av(&l, (SV*(*)(const void*))owl_new_sv);
     331                GPtrArray *l;
     332        CODE:
     333        {
     334                l = owl_dict_get_keys(owl_global_get_vardict(&g));
     335                RETVAL = owl_new_av(l, (SV*(*)(const void*))owl_new_sv);
    375336                sv_2mortal((SV*)RETVAL);
    376337        }
     
    378339                RETVAL
    379340        CLEANUP:
    380                 owl_list_cleanup(&l, g_free);
     341                owl_ptr_array_free(l, g_free);
    381342
    382343
     
    384345all_keymaps()
    385346        PREINIT:
    386                 owl_list l;
     347                GPtrArray *l;
    387348                const owl_keyhandler *kh;
    388349        CODE:
    389350        {
    390351                kh = owl_global_get_keyhandler(&g);
    391                 owl_list_create(&l);
    392                 owl_keyhandler_get_keymap_names(kh, &l);
    393                 RETVAL = owl_new_av(&l, (SV*(*)(const void*))owl_new_sv);
     352                l = owl_keyhandler_get_keymap_names(kh);
     353                RETVAL = owl_new_av(l, (SV*(*)(const void*))owl_new_sv);
    394354                sv_2mortal((SV*)RETVAL);
    395355        }
     
    397357                RETVAL
    398358        CLEANUP:
    399                 owl_list_cleanup(&l, g_free);
     359                owl_ptr_array_free(l, g_free);
    400360
    401361void
     
    468428           }
    469429
    470 void
    471 new_variable_string(name, ival, summ, desc)
    472         const char * name
    473         const char * ival
    474         const char * summ
    475         const char * desc
    476         CODE:
    477         owl_variable_dict_newvar_string(owl_global_get_vardict(&g),
    478                                         name,
    479                                         summ,
    480                                         desc,
    481                                         ival);
    482 
    483 void
    484 new_variable_int(name, ival, summ, desc)
    485         const char * name
    486         int ival
    487         const char * summ
    488         const char * desc
    489         CODE:
    490         owl_variable_dict_newvar_int(owl_global_get_vardict(&g),
    491                                      name,
    492                                      summ,
    493                                      desc,
    494                                      ival);
    495 
    496 void
    497 new_variable_bool(name, ival, summ, desc)
    498         const char * name
    499         int ival
    500         const char * summ
    501         const char * desc
    502         CODE:
    503         owl_variable_dict_newvar_bool(owl_global_get_vardict(&g),
    504                                       name,
    505                                       summ,
    506                                       desc,
    507                                       ival);
    508 
    509 void
    510 add_io_dispatch(fd, mode, cb)
    511         int fd
    512         int mode
    513         SV * cb
    514         CODE:
    515         owl_select_add_perl_io_dispatch(fd, mode, newSVsv(cb));
    516 
    517 IV
    518 add_timer(after, interval, cb, name = NULL)
    519         int after
    520         int interval
    521         SV *cb
    522         const char *name
    523         PREINIT:
    524                 SV *ref;
    525                 owl_timer *t;
    526         CODE:
    527                 ref = sv_rvweaken(newSVsv(cb));
    528                 t = owl_select_add_timer(name,
    529                                          after,
    530                                          interval,
    531                                          owl_perlconfig_perl_timer,
    532                                          owl_perlconfig_perl_timer_destroy,
    533                                          ref);
    534                 owl_function_debugmsg("Created timer %s: %p", t->name ? t->name : "(unnamed)", t);
    535         RETVAL = (IV)t;
    536         OUTPUT:
    537                 RETVAL
    538 
    539 void
    540 remove_timer(timer)
    541         IV timer
    542         PREINIT:
    543                 owl_timer *t;
    544         CODE:
    545                 t = (owl_timer*)timer;
    546                 owl_function_debugmsg("Freeing timer %s: %p", t->name ? t->name : "(unnamed)", t);
    547                 owl_select_remove_timer(t);
     430
     431MODULE = BarnOwl                PACKAGE = BarnOwl::Internal
     432
     433void
     434new_variable(name, summary, description, validsettings, takes_on_off, get_tostring_fn, set_fromstring_fn, data)
     435    const char *name
     436    const char *summary
     437    const char *description
     438    const char *validsettings
     439    int takes_on_off
     440    SV *get_tostring_fn
     441    SV *set_fromstring_fn
     442    SV *data
     443    CODE:
     444{
     445        /* data is somewhat redundant given we can create closures, but oh
     446         * well. Might be convenient sometimes. */
     447        if(!SV_IS_CODEREF(get_tostring_fn)) {
     448                croak("To-string function must be a coderef!");
     449        }
     450        if(!SV_IS_CODEREF(set_fromstring_fn)) {
     451                croak("From-string function must be a coderef!");
     452        }
     453
     454        owl_variable_dict_newvar_other(owl_global_get_vardict(&g),
     455                                       name, summary, description, validsettings, takes_on_off,
     456                                       perl_closure_new(get_tostring_fn, data, false),
     457                                       perl_closure_new(set_fromstring_fn, data, false));
     458}
     459
     460void
     461start_edit(edit_type, line, callback)
     462        const char *edit_type
     463        const char *line
     464        SV *callback
     465        PREINIT:
     466                owl_editwin *e;
     467        CODE:
     468        {
     469                if (!SV_IS_CODEREF(callback))
     470                        croak("Callback must be a subref");
     471
     472                if (!strcmp(edit_type, "question"))
     473                        e = owl_function_start_question(line);
     474                else if (!strcmp(edit_type, "password"))
     475                        e = owl_function_start_password(line);
     476                else if (!strcmp(edit_type, "edit_win"))
     477                        e = owl_function_start_edit_win(line);
     478                else
     479                        croak("edit_type must be one of 'password', 'question', 'edit_win', not '%s'", edit_type);
     480
     481                owl_editwin_set_cbdata(e, newSVsv(callback), owl_perlconfig_dec_refcnt);
     482                owl_editwin_set_callback(e, owl_perlconfig_edit_callback);
     483        }
     484
     485int
     486zephyr_zwrite(cmd,msg)
     487        const char *cmd
     488        const char *msg
     489        CODE:
     490                RETVAL = owl_zwrite_create_and_send_from_line(cmd, msg);
     491        OUTPUT:
     492                RETVAL
    548493
    549494MODULE = BarnOwl                PACKAGE = BarnOwl::Editwin
  • popexec.c

    r47e0a6a re146cd7  
    1616  int pipefds[2], child_write_fd, parent_read_fd;
    1717  pid_t pid;
     18  GIOChannel *channel;
    1819
    1920  if (owl_global_get_popwin(&g) || owl_global_get_viewwin(&g)) {
     
    5455    pe->pid=pid;
    5556    pe->winactive=1;
    56     pe->dispatch = owl_select_add_io_dispatch(parent_read_fd, OWL_IO_READ|OWL_IO_EXCEPT, &owl_popexec_inputhandler, &owl_popexec_delete_dispatch, pe);
     57    channel = g_io_channel_unix_new(parent_read_fd);
     58    g_io_channel_set_close_on_unref(channel, TRUE);
     59    pe->io_watch = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT,
     60                                       G_IO_IN | G_IO_ERR | G_IO_HUP,
     61                                       owl_popexec_inputhandler, pe,
     62                                       (GDestroyNotify)owl_popexec_unref);
     63    g_io_channel_unref(channel);
    5764    pe->refcount++;
    5865  } else {
     
    7582}
    7683
    77 void owl_popexec_inputhandler(const owl_io_dispatch *d, void *data)
     84gboolean owl_popexec_inputhandler(GIOChannel *source, GIOCondition condition, void *data)
    7885{
    7986  owl_popexec *pe = data;
     
    8188  char *buf;
    8289  int status;
     90  int fd = g_io_channel_unix_get_fd(source);
    8391
    84   if (!pe) return;
     92  /* TODO: Reading from GIOChannel may be more convenient. */
     93
     94  if (!pe) return FALSE;
    8595
    8696  /* If pe->winactive is 0 then the vwin has closed.
     
    96106  /* the viewwin has closed */
    97107  if (!pe->pid && !pe->winactive) {
    98     owl_select_remove_io_dispatch(d);
    99     pe->dispatch = NULL;
    100     return;
     108    pe->io_watch = 0;
     109    return FALSE;
    101110  }
    102111
    103   if (0 != (rv_navail = ioctl(d->fd, FIONREAD, &navail))) {
     112  if (0 != (rv_navail = ioctl(fd, FIONREAD, &navail))) {
    104113    owl_function_debugmsg("ioctl error");
    105114  }
     
    113122      owl_viewwin_append_text(pe->vwin, "\n");
    114123    }
    115     owl_select_remove_io_dispatch(d);
    116     pe->dispatch = NULL;
    117     return;
     124    pe->io_watch = 0;
     125    return FALSE;
    118126  }
    119127
    120   if (d->fd<0 || !pe->pid || !pe->winactive || rv_navail) {
     128  if (fd<0 || !pe->pid || !pe->winactive || rv_navail) {
    121129    owl_function_error("popexec should not have reached this point");
    122     return;
     130    return FALSE;
    123131  }
    124132
    125   if (navail<=0) return;
     133  if (navail<=0) return TRUE;
    126134  if (navail>1024) { navail = 1024; }
    127135  buf = g_new(char, navail+1);
    128136  owl_function_debugmsg("about to read %d", navail);
    129   bread = read(d->fd, buf, navail);
     137  bread = read(fd, buf, navail);
    130138  if (bread<0) {
    131139    perror("read");
     
    140148  }
    141149  g_free(buf);
    142  
    143 }
    144 
    145 void owl_popexec_delete_dispatch(const owl_io_dispatch *d)
    146 {
    147   owl_popexec *pe = d->data;
    148   close(d->fd);
    149   owl_popexec_unref(pe);
     150  return TRUE;
    150151}
    151152
     
    156157
    157158  pe->winactive = 0;
    158   if (pe->dispatch) {
    159     owl_select_remove_io_dispatch(pe->dispatch);
    160     pe->dispatch = NULL;
     159  if (pe->io_watch) {
     160    g_source_remove(pe->io_watch);
     161    pe->io_watch = 0;
    161162  }
    162163  if (pe->pid) {
  • popwin.c

    rddbbcffa r6829afc  
    11#include "owl.h"
    22
    3 owl_popwin *owl_popwin_new(void)
     3CALLER_OWN owl_popwin *owl_popwin_new(void)
    44{
    55  owl_popwin *pw = g_new0(owl_popwin, 1);
  • regex.c

    rd4927a7 rf271129  
    1 #include <string.h>
    21#include "owl.h"
    32
     
    1110{
    1211  int ret;
    13   char buff1[LINE];
     12  size_t errbuf_size;
     13  char *errbuf;
    1414  const char *ptr;
    1515 
     
    2626  ret=regcomp(&(re->re), ptr, REG_EXTENDED|REG_ICASE);
    2727  if (ret) {
    28     regerror(ret, NULL, buff1, LINE);
    29     owl_function_makemsg("Error in regular expression: %s", buff1);
     28    errbuf_size = regerror(ret, NULL, NULL, 0);
     29    errbuf = g_new(char, errbuf_size);
     30    regerror(ret, NULL, errbuf, errbuf_size);
     31    owl_function_error("Error in regular expression: %s", errbuf);
     32    g_free(errbuf);
    3033    g_free(re->string);
    3134    re->string=NULL;
     
    3942{
    4043  char *quoted;
     44  int ret;
    4145 
    42   quoted=owl_text_quote(string, OWL_REGEX_QUOTECHARS, OWL_REGEX_QUOTEWITH);
    43   owl_regex_create(re, quoted);
     46  quoted = owl_text_quote(string, OWL_REGEX_QUOTECHARS, OWL_REGEX_QUOTEWITH);
     47  ret = owl_regex_create(re, quoted);
    4448  g_free(quoted);
    45   return(0);
     49  return ret;
    4650}
    4751
  • runtests.sh

    r5aa33fd r5db8835  
    11#!/bin/sh
    2 SRCDIR=`dirname "${0}"`
    3 
    4 export BARNOWL_DATA_DIR="$SRCDIR/perl/"
    5 export BARNOWL_BIN_DIR="$SRCDIR/"
    6 
    7 HARNESS_PERL=./tester exec prove t/
     2exec env HARNESS_PERL=./tester prove --failures "${srcdir:=$(dirname "$0")}/t/"
  • scripts/do-release

    r74312ad rb8a3e00  
    99    cat >&2 <<EOF
    1010Usage: $0 [options]
    11 Generate a barnowl release tarball.
     11Generate a BarnOwl release tarball.
    1212
    1313OPTIONS:
     
    3737else
    3838    VERS=$(perl -ne 'print $1 if m{^AC_INIT\(\[[^\]]+\],\s*\[([^\]]+)\]}' configure.ac) \
    39         || die "Unable to parse barnowl version"
     39        || die "Unable to parse BarnOwl version"
    4040fi
    4141TAG=barnowl-$VERS
  • scripts/locker-build

    r0fd5bd5 r055e366  
    8585    BARNOWL="/afs/sipb.mit.edu/project/barnowl/arch/$ATHENA_SYS"
    8686    export PKG_CONFIG_PATH="$BARNOWL/lib/pkgconfig"
     87    eval $("$BARNOWL/bin/barnowl-perl-config")
    8788
    8889    SUFFIX=
     
    102103    esac
    103104
    104     CFLAGS="-I$BARNOWL/include" \
    105         LDFLAGS="-L$BARNOWL/lib $opt_rpath$BARNOWL/lib" \
     105    CPPFLAGS="-I$BARNOWL/include -I/usr/athena/include" \
     106        LDFLAGS="-L$BARNOWL/lib -L/usr/athena/lib $opt_rpath$BARNOWL/lib" \
    106107        ./configure --exec-prefix="/mit/barnowl/arch/$ATHENA_SYS" \
    107108        --prefix="/mit/barnowl/builds/barnowl-$VERS" --mandir=/mit/barnowl/man \
     
    118119
    119120    $MAKE -j$CPUS all || die "make failed"
     121
     122    $MAKE check || die "Unit tests failed"
    120123
    121124    if [ -n "$DRYRUN" ]; then
  • select.c

    r44976fe r84a071f  
    22
    33static GMainLoop *loop = NULL;
    4 static GMainContext *main_context;
    5 static int dispatch_active = 0;
    6 
    7 static GSource *owl_timer_source;
    8 static GSource *owl_io_dispatch_source;
    9 
    10 static int _owl_select_timer_cmp(const owl_timer *t1, const owl_timer *t2) {
    11   return t1->time - t2->time;
    12 }
    13 
    14 owl_timer *owl_select_add_timer(const char* name, int after, int interval, void (*cb)(owl_timer *, void *), void (*destroy)(owl_timer*), void *data)
    15 {
    16   owl_timer *t = g_new(owl_timer, 1);
    17   GList **timers = owl_global_get_timerlist(&g);
    18 
    19   t->time = time(NULL) + after;
    20   t->interval = interval;
    21   t->callback = cb;
    22   t->destroy = destroy;
    23   t->data = data;
    24   t->name = name ? g_strdup(name) : NULL;
    25 
    26   *timers = g_list_insert_sorted(*timers, t,
    27                                  (GCompareFunc)_owl_select_timer_cmp);
    28   return t;
    29 }
    30 
    31 void owl_select_remove_timer(owl_timer *t)
    32 {
    33   GList **timers = owl_global_get_timerlist(&g);
    34   if (t && g_list_find(*timers, t)) {
    35     *timers = g_list_remove(*timers, t);
    36     if(t->destroy) {
    37       t->destroy(t);
    38     }
    39     g_free(t->name);
    40     g_free(t);
    41   }
    42 }
    43 
    44 static gboolean owl_timer_prepare(GSource *source, int *timeout) {
    45   GList **timers = owl_global_get_timerlist(&g);
    46   GTimeVal now;
    47 
    48   /* TODO: In the far /far/ future, g_source_get_time is what the cool
    49    * kids use to get system monotonic time. */
    50   g_source_get_current_time(source, &now);
    51 
    52   /* FIXME: bother with millisecond accuracy now that we can? */
    53   if (*timers) {
    54     owl_timer *t = (*timers)->data;
    55     *timeout = t->time - now.tv_sec;
    56     if (*timeout <= 0) {
    57       *timeout = 0;
    58       return TRUE;
    59     }
    60     if (*timeout > 60 * 1000)
    61       *timeout = 60 * 1000;
    62   } else {
    63     *timeout = 60 * 1000;
    64   }
    65   return FALSE;
    66 }
    67 
    68 static gboolean owl_timer_check(GSource *source) {
    69   GList **timers = owl_global_get_timerlist(&g);
    70   GTimeVal now;
    71 
    72   /* TODO: In the far /far/ future, g_source_get_time is what the cool
    73    * kids use to get system monotonic time. */
    74   g_source_get_current_time(source, &now);
    75 
    76   /* FIXME: bother with millisecond accuracy now that we can? */
    77   if (*timers) {
    78     owl_timer *t = (*timers)->data;
    79     return t->time >= now.tv_sec;
    80   }
    81   return FALSE;
    82 }
    83 
    84 
    85 static gboolean owl_timer_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) {
    86   GList **timers = owl_global_get_timerlist(&g);
    87   GTimeVal now;
    88 
    89   /* TODO: In the far /far/ future, g_source_get_time is what the cool
    90    * kids use to get system monotonic time. */
    91   g_source_get_current_time(source, &now);
    92 
    93   /* FIXME: bother with millisecond accuracy now that we can? */
    94   while(*timers) {
    95     owl_timer *t = (*timers)->data;
    96     int remove = 0;
    97 
    98     if(t->time > now.tv_sec)
    99       break;
    100 
    101     /* Reschedule if appropriate */
    102     if(t->interval > 0) {
    103       t->time = now.tv_sec + t->interval;
    104       *timers = g_list_remove(*timers, t);
    105       *timers = g_list_insert_sorted(*timers, t,
    106                                      (GCompareFunc)_owl_select_timer_cmp);
    107     } else {
    108       remove = 1;
    109     }
    110 
    111     /* Do the callback */
    112     t->callback(t, t->data);
    113     if(remove) {
    114       owl_select_remove_timer(t);
    115     }
    116   }
    117   return TRUE;
    118 }
    119 
    120 static GSourceFuncs owl_timer_funcs = {
    121   owl_timer_prepare,
    122   owl_timer_check,
    123   owl_timer_dispatch,
    124   NULL
    125 };
    126 
    127 /* Returns the valid owl_io_dispatch for a given file descriptor. */
    128 static owl_io_dispatch *owl_select_find_valid_io_dispatch_by_fd(const int fd)
    129 {
    130   int i, len;
    131   const owl_list *dl;
    132   owl_io_dispatch *d;
    133   dl = owl_global_get_io_dispatch_list(&g);
    134   len = owl_list_get_size(dl);
    135   for(i = 0; i < len; i++) {
    136     d = owl_list_get_element(dl, i);
    137     if (d->fd == fd && d->valid) return d;
    138   }
    139   return NULL;
    140 }
    141 
    142 static int owl_select_find_io_dispatch(const owl_io_dispatch *in)
    143 {
    144   int i, len;
    145   const owl_list *dl;
    146 
    147   if (in != NULL) {
    148     dl = owl_global_get_io_dispatch_list(&g);
    149     len = owl_list_get_size(dl);
    150     for(i = 0; i < len; i++) {
    151       const owl_io_dispatch *d = owl_list_get_element(dl, i);
    152       if (d == in) return i;
    153     }
    154   }
    155   return -1;
    156 }
    157 
    158 static void owl_select_invalidate_io_dispatch(owl_io_dispatch *d)
    159 {
    160   if (d == NULL || !d->valid)
    161     return;
    162   d->valid = false;
    163   g_source_remove_poll(owl_io_dispatch_source, &d->pollfd);
    164 }
    165 
    166 void owl_select_remove_io_dispatch(const owl_io_dispatch *in)
    167 {
    168   int elt;
    169   if (in != NULL) {
    170     elt = owl_select_find_io_dispatch(in);
    171     if (elt != -1) {
    172       owl_list *dl = owl_global_get_io_dispatch_list(&g);
    173       owl_io_dispatch *d = owl_list_get_element(dl, elt);
    174       if (dispatch_active)
    175         d->needs_gc = 1;
    176       else {
    177         owl_select_invalidate_io_dispatch(d);
    178         owl_list_remove_element(dl, elt);
    179         if (d->destroy)
    180           d->destroy(d);
    181         g_free(d);
    182       }
    183     }
    184   }
    185 }
    186 
    187 static void owl_select_io_dispatch_gc(void)
    188 {
    189   int i;
    190   owl_list *dl;
    191 
    192   dl = owl_global_get_io_dispatch_list(&g);
    193   /*
    194    * Count down so we aren't set off by removing items from the list
    195    * during the iteration.
    196    */
    197   for(i = owl_list_get_size(dl) - 1; i >= 0; i--) {
    198     owl_io_dispatch *d = owl_list_get_element(dl, i);
    199     if(d->needs_gc) {
    200       owl_select_remove_io_dispatch(d);
    201     }
    202   }
    203 }
    204 
    205 /* Each FD may have at most one valid dispatcher.
    206  * If a new dispatch is added for an FD, the old one is removed.
    207  * mode determines what types of events are watched for, and may be any combination of:
    208  * OWL_IO_READ, OWL_IO_WRITE, OWL_IO_EXCEPT
    209  */
    210 const owl_io_dispatch *owl_select_add_io_dispatch(int fd, int mode, void (*cb)(const owl_io_dispatch *, void *), void (*destroy)(const owl_io_dispatch *), void *data)
    211 {
    212   owl_io_dispatch *d = g_new(owl_io_dispatch, 1);
    213   owl_list *dl = owl_global_get_io_dispatch_list(&g);
    214   owl_io_dispatch *other;
    215 
    216   d->fd = fd;
    217   d->valid = true;
    218   d->needs_gc = 0;
    219   d->mode = mode;
    220   d->callback = cb;
    221   d->destroy = destroy;
    222   d->data = data;
    223 
    224   /* TODO: Allow changing fd and mode in the middle? Probably don't care... */
    225   d->pollfd.fd = fd;
    226   d->pollfd.events = 0;
    227   if (d->mode & OWL_IO_READ)
    228     d->pollfd.events |= G_IO_IN | G_IO_HUP | G_IO_ERR;
    229   if (d->mode & OWL_IO_WRITE)
    230     d->pollfd.events |= G_IO_OUT | G_IO_ERR;
    231   if (d->mode & OWL_IO_EXCEPT)
    232     d->pollfd.events |= G_IO_PRI | G_IO_ERR;
    233   g_source_add_poll(owl_io_dispatch_source, &d->pollfd);
    234 
    235 
    236   other = owl_select_find_valid_io_dispatch_by_fd(fd);
    237   if (other)
    238     owl_select_invalidate_io_dispatch(other);
    239   owl_list_append_element(dl, d);
    240 
    241   return d;
    242 }
    243 
    244 static gboolean owl_io_dispatch_prepare(GSource *source, int *timeout) {
    245   *timeout = -1;
    246   return FALSE;
    247 }
    248 
    249 static gboolean owl_io_dispatch_check(GSource *source) {
    250   int i, len;
    251   const owl_list *dl;
    252 
    253   dl = owl_global_get_io_dispatch_list(&g);
    254   len = owl_list_get_size(dl);
    255   for(i = 0; i < len; i++) {
    256     owl_io_dispatch *d = owl_list_get_element(dl, i);
    257     if (!d->valid) continue;
    258     if (d->pollfd.revents & G_IO_NVAL) {
    259       owl_function_debugmsg("Pruning defunct dispatch on fd %d.", d->fd);
    260       owl_select_invalidate_io_dispatch(d);
    261     }
    262     if (d->pollfd.revents & d->pollfd.events)
    263       return TRUE;
    264   }
    265   return FALSE;
    266 }
    267 
    268 static gboolean owl_io_dispatch_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) {
    269   int i, len;
    270   const owl_list *dl;
    271 
    272   dispatch_active = 1;
    273   dl = owl_global_get_io_dispatch_list(&g);
    274   len = owl_list_get_size(dl);
    275   for (i = 0; i < len; i++) {
    276     owl_io_dispatch *d = owl_list_get_element(dl, i);
    277     if (!d->valid) continue;
    278     if ((d->pollfd.revents & d->pollfd.events) && d->callback != NULL) {
    279       d->callback(d, d->data);
    280     }
    281   }
    282   dispatch_active = 0;
    283   owl_select_io_dispatch_gc();
    284 
    285   return TRUE;
    286 }
    287 
    288 static GSourceFuncs owl_io_dispatch_funcs = {
    289   owl_io_dispatch_prepare,
    290   owl_io_dispatch_check,
    291   owl_io_dispatch_dispatch,
    292   NULL
    293 };
    294 
    295 int owl_select_add_perl_io_dispatch(int fd, int mode, SV *cb)
    296 {
    297   const owl_io_dispatch *d = owl_select_find_valid_io_dispatch_by_fd(fd);
    298   if (d != NULL && d->callback != owl_perlconfig_io_dispatch) {
    299     /* Don't mess with non-perl dispatch functions from here. */
    300     return 1;
    301   }
    302   /* Also remove any invalidated perl dispatch functions that may have
    303    * stuck around. */
    304   owl_select_remove_perl_io_dispatch(fd);
    305   owl_select_add_io_dispatch(fd, mode, owl_perlconfig_io_dispatch, owl_perlconfig_io_dispatch_destroy, cb);
    306   return 0;
    307 }
    308 
    309 static owl_io_dispatch *owl_select_find_perl_io_dispatch(int fd)
    310 {
    311   int i, len;
    312   const owl_list *dl;
    313   owl_io_dispatch *d;
    314   dl = owl_global_get_io_dispatch_list(&g);
    315   len = owl_list_get_size(dl);
    316   for(i = 0; i < len; i++) {
    317     d = owl_list_get_element(dl, i);
    318     if (d->fd == fd && d->callback == owl_perlconfig_io_dispatch)
    319       return d;
    320   }
    321   return NULL;
    322 }
    323 
    324 int owl_select_remove_perl_io_dispatch(int fd)
    325 {
    326   owl_io_dispatch *d = owl_select_find_perl_io_dispatch(fd);
    327   if (d != NULL) {
    328     /* Only remove perl io dispatchers from here. */
    329     owl_select_remove_io_dispatch(d);
    330     return 0;
    331   }
    332   return 1;
    333 }
    3344
    3355void owl_select_init(void)
    3366{
    337   owl_timer_source = g_source_new(&owl_timer_funcs, sizeof(GSource));
    338   g_source_attach(owl_timer_source, NULL);
    339 
    340   owl_io_dispatch_source = g_source_new(&owl_io_dispatch_funcs, sizeof(GSource));
    341   g_source_attach(owl_io_dispatch_source, NULL);
    3427}
    3438
    3449void owl_select_run_loop(void)
    34510{
    346   main_context = g_main_context_default();
    347   loop = g_main_loop_new(main_context, FALSE);
     11  loop = g_main_loop_new(NULL, FALSE);
    34812  g_main_loop_run(loop);
    34913}
     
    35317  if (loop) {
    35418    g_main_loop_quit(loop);
     19    g_main_loop_unref(loop);
    35520    loop = NULL;
    35621  }
  • signal.c

    r1d21d9f ra7fac14  
    11#include <errno.h>
     2#include <glib.h>
    23#include <pthread.h>
    34#include <signal.h>
     
    1314static void *signal_thread_func(void *data);
    1415
    15 /* Initializes the signal thread to listen for 'set' on a dedicated
     16static void dummy_handler(int signum)
     17{
     18  /* Do nothing. This should never get called. It'd be nice to report the error
     19   * or something, but you can't have nice things in a signal handler. */
     20}
     21
     22#define OR_DIE(s, syscall)       \
     23  G_STMT_START {                 \
     24    if ((syscall) == -1) {       \
     25      perror((s));               \
     26      exit(1);                   \
     27    }                            \
     28  } G_STMT_END
     29
     30/* Initializes the signal thread to listen for 'signals' on a dedicated
    1631 * thread. 'callback' is called *on the signal thread* when a signal
    1732 * is received.
     
    1934 * This function /must/ be called before any other threads are
    2035 * created. (Otherwise the signals will not get blocked correctly.) */
    21 void owl_signal_init(const sigset_t *set, void (*callback)(const siginfo_t*, void*), void *data) {
     36void owl_signal_init(const int *signals, int num_signals, void (*callback)(const siginfo_t*, void*), void *data) {
     37  struct sigaction sig_dummy = { .sa_handler = dummy_handler };
    2238  int ret;
     39  int i;
    2340
    24   signal_set = *set;
    2541  signal_cb = callback;
    2642  signal_cbdata = data;
     43
     44  /* Stuff the signals into our sigset_t. Also assign all of them to a dummy
     45   * handler. Otherwise, if their default is SIG_IGN, they will get dropped if
     46   * delivered while processing. On Solaris, they will not get delivered at
     47   * all. */
     48  OR_DIE("sigemptyset", sigemptyset(&signal_set));
     49  for (i = 0; i < num_signals; i++) {
     50    OR_DIE("sigaddset", sigaddset(&signal_set, signals[i]));
     51    OR_DIE("sigaction", sigaction(signals[i], &sig_dummy, NULL));
     52  }
     53
    2754  /* Block these signals in all threads, so we can get them. */
    28   if ((ret = pthread_sigmask(SIG_BLOCK, set, NULL)) != 0) {
     55  if ((ret = pthread_sigmask(SIG_BLOCK, &signal_set, NULL)) != 0) {
    2956    errno = ret;
    3057    perror("pthread_sigmask");
     58    exit(1);
    3159  }
    3260  /* Spawn a dedicated thread to sigwait. */
  • stubgen.pl

    rfd03b12 rca54fd6  
    1414    if ($vartype =~ /^BOOL/) {
    1515        print "void owl_global_set_${altvarname}_on(owl_global *g) {\n";
    16         print "  owl_variable_set_bool_on(&g->vars, \"$varname\");\n}\n";
     16        print "  owl_variable_set_bool_on(owl_variable_get_var(&g->vars, \"$varname\"));\n}\n";
    1717        print "void owl_global_set_${altvarname}_off(owl_global *g) {\n";
    18         print "  owl_variable_set_bool_off(&g->vars, \"$varname\");\n}\n";
     18        print "  owl_variable_set_bool_off(owl_variable_get_var(&g->vars, \"$varname\"));\n}\n";
    1919        print "int owl_global_is_$altvarname(const owl_global *g) {\n";
    20         print "  return owl_variable_get_bool(&g->vars, \"$varname\");\n}\n";
     20        print "  return owl_variable_get_bool(owl_variable_get_var(&g->vars, \"$varname\"));\n}\n";
    2121    } elsif ($vartype =~ /^PATH/ or $vartype =~ /^STRING/) {
    2222        print "void owl_global_set_$altvarname(owl_global *g, const char *text) {\n";
    23         print "  owl_variable_set_string(&g->vars, \"$varname\", text);\n}\n";
     23        print "  owl_variable_set_string(owl_variable_get_var(&g->vars, \"$varname\"), text);\n}\n";
    2424        print "const char *owl_global_get_$altvarname(const owl_global *g) {\n";
    25         print "  return owl_variable_get_string(&g->vars, \"$varname\");\n}\n";
     25        print "  return owl_variable_get_string(owl_variable_get_var(&g->vars, \"$varname\"));\n}\n";
    2626    } elsif ($vartype =~ /^INT/ or $vartype =~ /^ENUM/) {
    2727        print "void owl_global_set_$altvarname(owl_global *g, int n) {\n";
    28         print "  owl_variable_set_int(&g->vars, \"$varname\", n);\n}\n";
     28        print "  owl_variable_set_int(owl_variable_get_var(&g->vars, \"$varname\"), n);\n}\n";
    2929        print "int owl_global_get_$altvarname(const owl_global *g) {\n";
    30         print "  return owl_variable_get_int(&g->vars, \"$varname\");\n}\n";
     30        print "  return owl_variable_get_int(owl_variable_get_var(&g->vars, \"$varname\"));\n}\n";
    3131    }
    3232    }
  • style.c

    rd4927a7 r92ffd89  
    2323{
    2424  SV *sv = NULL;
    25   OWL_PERL_CALL_METHOD(s->perlobj,
    26                        "description",
    27                        ;,
    28                        "Error in style_get_description: %s",
    29                        0,
    30                        sv = SvREFCNT_inc(POPs);
    31                        );
    32   if(sv) {
     25  OWL_PERL_CALL(call_method("description", G_SCALAR|G_EVAL),
     26                XPUSHs(s->perlobj);,
     27                "Error in style_get_description: %s",
     28                0,
     29                false,
     30                sv = SvREFCNT_inc(POPs);
     31                );
     32  if (sv) {
    3333    return SvPV_nolen(sv_2mortal(sv));
    3434  } else {
     
    5050 
    5151  /* Call the perl object */
    52   OWL_PERL_CALL_METHOD(s->perlobj,
    53                        "format_message",
    54                        XPUSHs(sv_2mortal(owl_perlconfig_message2hashref(m)));,
    55                        "Error in format_message: %s",
    56                        0,
    57                        sv = SvREFCNT_inc(POPs);
    58                        );
     52  OWL_PERL_CALL(call_method("format_message", G_SCALAR|G_EVAL),
     53                XPUSHs(s->perlobj);
     54                XPUSHs(sv_2mortal(owl_perlconfig_message2hashref(m)));,
     55                "Error in format_message: %s",
     56                0,
     57                false,
     58                sv = SvREFCNT_inc(POPs);
     59                );
    5960
    60   if(sv) {
     61  if (sv) {
    6162    body = SvPV_nolen(sv);
    6263  } else {
     
    6566
    6667  /* indent and ensure ends with a newline */
    67   indent = owl_text_indent(body, OWL_TAB);
     68  indent = owl_text_indent(body, OWL_TAB, true);
    6869  curlen = strlen(indent);
    69   if (curlen==0 || indent[curlen-1] != '\n') {
    70     indent[curlen] = '\n';
    71     indent[curlen+1] = '\0';
     70  if (curlen == 0 || indent[curlen-1] != '\n') {
     71    char *tmp = indent;
     72    indent = g_strconcat(tmp, "\n", NULL);
     73    g_free(tmp);
    7274  }
    7375
  • t/00-core-tests.t

    r95414bf r5db8835  
    11#!/usr/bin/env perl
    2 use File::Basename;
    3 system(dirname($0) . "/../tester", "--builtin");
     2system("./tester", "--builtin");
  • t/completion.t

    r3001c11 re59d775  
    323323}
    324324
    325 mkpath("$tmpdir/.owl/",
    326        "$tmpdir/.owl/modules/",
    327        "$tmpdir/Public/",
    328        "$tmpdir/Private/",
    329        "$tmpdir/.ours",
    330        "$tmpdir/www",
    331      {mode => 0700});
     325mkpath(["$tmpdir/.owl/",
     326        "$tmpdir/.owl/modules/",
     327        "$tmpdir/Public/",
     328        "$tmpdir/Private/",
     329        "$tmpdir/.ours",
     330        "$tmpdir/www"],
     331       0, 0700);
    332332touch("$tmpdir/.zephyr.subs");
    333333touch("$tmpdir/wheee");
  • t/unicode.t

    r09ff1eb rf415f83  
    55use Encode;
    66
    7 BEGIN { bootstrap BarnOwl; };
     7use Test::More qw(no_plan);
    88
    9 use Test::More qw(no_plan);
     9use BarnOwl;
    1010
    1111my $unicode = "“hello”";
  • tester.c

    r4c7c21f r6a8b519  
    33#include "owl.h"
    44#undef WINDOW
    5 
    6 #include <unistd.h>
    7 #include <stdlib.h>
     5#include "filterproc.h"
     6
     7#include <stdio.h>
    88
    99#undef instr
    10 #include <curses.h>
     10#include <ncursesw/curses.h>
    1111
    1212owl_global g;
     
    2323int owl_fmtext_regtest(void);
    2424int owl_smartfilter_regtest(void);
     25int owl_history_regtest(void);
     26int call_filter_regtest(void);
    2527
    2628extern void owl_perl_xs_init(pTHX);
     
    3234  char *perlerr;
    3335  int status = 0;
     36  SCREEN *screen;
    3437
    3538  if (argc <= 1) {
     
    4144  wnull = fopen("/dev/null", "w");
    4245  rnull = fopen("/dev/null", "r");
    43   newterm("xterm", wnull, rnull);
     46  screen = newterm("xterm", wnull, rnull);
    4447  /* initialize global structures */
    4548  owl_global_init(&g);
     
    9194  /* probably not necessary, but tear down the screen */
    9295  endwin();
     96  delscreen(screen);
    9397  fclose(rnull);
    9498  fclose(wnull);
     
    110114  numfailures += owl_fmtext_regtest();
    111115  numfailures += owl_smartfilter_regtest();
     116  numfailures += owl_history_regtest();
     117  numfailures += call_filter_regtest();
    112118  if (numfailures) {
    113119      fprintf(stderr, "# *** WARNING: %d failures total\n", numfailures);
     
    120126#define FAIL_UNLESS(desc,pred) do { int __pred = (pred);                \
    121127    numtests++;                                                         \
    122     printf("%s %s", (__pred)?"ok":(numfailed++,"not ok"), desc);        \
     128    printf("%s %d %s", (__pred) ? "ok" : (numfailed++, "not ok"), numtests, desc); \
    123129    if(!(__pred)) printf("\t(%s:%d)", __FILE__, __LINE__); printf("%c", '\n'); } while(0)
    124130
     
    127133{
    128134  int numfailed=0;
     135  char *path, *home;
    129136
    130137  printf("# BEGIN testing owl_util\n");
     
    215222                "\"");
    216223
    217   GString *g = g_string_new("");
    218   owl_string_appendf_quoted(g, "%q foo %q%q %s %", "hello", "world is", "can't");
     224  GString *quoted = g_string_new("");
     225  owl_string_appendf_quoted(quoted, "%q foo %q%q %s %", "hello", "world is", "can't");
    219226  FAIL_UNLESS("owl_string_appendf",
    220               !strcmp(g_string_free(g, false),
    221                       "hello foo 'world is'\"can't\" %s %"));
     227              !strcmp(quoted->str, "hello foo 'world is'\"can't\" %s %"));
     228  g_string_free(quoted, true);
     229
     230
     231  CHECK_STR_AND_FREE("baseclass barnowl",
     232                     "barnowl", owl_util_baseclass("barnowl"));
     233  CHECK_STR_AND_FREE("baseclass unbarnowl",
     234                     "barnowl", owl_util_baseclass("unbarnowl"));
     235  CHECK_STR_AND_FREE("baseclass unununbarnowl.d.d",
     236                     "barnowl", owl_util_baseclass("unununbarnowl.d.d"));
     237  CHECK_STR_AND_FREE("baseclass ununun.d.d",
     238                     "", owl_util_baseclass("ununun.d.d"));
     239  CHECK_STR_AND_FREE("baseclass d.d.d.d",
     240                     "d", owl_util_baseclass("d.d.d.d"));
     241  CHECK_STR_AND_FREE("baseclass n.d.d.d",
     242                     "n", owl_util_baseclass("n.d.d.d"));
     243  CHECK_STR_AND_FREE("baseclass ununun.",
     244                     ".", owl_util_baseclass("ununun."));
     245  CHECK_STR_AND_FREE("baseclass unununu",
     246                     "u", owl_util_baseclass("unununu"));
     247
     248
     249  CHECK_STR_AND_FREE("makepath foo/bar",
     250                     "foo/bar", owl_util_makepath("foo/bar"));
     251  CHECK_STR_AND_FREE("makepath //foo///bar",
     252                     "/foo/bar", owl_util_makepath("//foo///bar"));
     253  CHECK_STR_AND_FREE("makepath foo/~//bar/",
     254                     "foo/~/bar/", owl_util_makepath("foo/~//bar/"));
     255  CHECK_STR_AND_FREE("makepath ~thisuserhadreallybetternotexist/foobar/",
     256                     "~thisuserhadreallybetternotexist/foobar/",
     257                     owl_util_makepath("~thisuserhadreallybetternotexist/foobar/"));
     258
     259  home = g_strdup(owl_global_get_homedir(&g));
     260  CHECK_STR_AND_FREE("makepath ~",
     261                     home, owl_util_makepath("~"));
     262
     263  path = g_build_filename(home, "foo/bar/baz", NULL);
     264  CHECK_STR_AND_FREE("makepath ~///foo/bar//baz",
     265                     path, owl_util_makepath("~///foo/bar//baz"));
     266  g_free(path);
     267  g_free(home);
     268
     269  home = owl_util_homedir_for_user("root");
     270  if (home == NULL) {
     271    /* Just make some noise so we notice. */
     272    home = g_strdup("<WHAT>");
     273    fprintf(stderr, "owl_util_homedir_for_user failed");
     274  }
     275
     276  CHECK_STR_AND_FREE("makepath ~root",
     277                     home, owl_util_makepath("~root"));
     278
     279  path = g_build_filename(home, "foo/bar/baz", NULL);
     280  CHECK_STR_AND_FREE("makepath ~root///foo/bar//baz",
     281                     path, owl_util_makepath("~root///foo/bar//baz"));
     282  g_free(path);
     283  g_free(home);
    222284
    223285  /* if (numfailed) printf("*** WARNING: failures encountered with owl_util\n"); */
     
    228290int owl_dict_regtest(void) {
    229291  owl_dict d;
    230   owl_list l;
     292  GPtrArray *l;
    231293  int numfailed=0;
    232   char *av="aval", *bv="bval", *cv="cval", *dv="dval";
     294  char *av = g_strdup("aval"), *bv = g_strdup("bval"), *cv = g_strdup("cval"),
     295    *dv = g_strdup("dval");
    233296
    234297  printf("# BEGIN testing owl_dict\n");
     
    248311
    249312  FAIL_UNLESS("get_size", 3==owl_dict_get_size(&d));
    250   owl_list_create(&l);
    251   owl_dict_get_keys(&d, &l);
    252   FAIL_UNLESS("get_keys result size", 3==owl_list_get_size(&l));
     313  l = owl_dict_get_keys(&d);
     314  FAIL_UNLESS("get_keys result size", 3 == l->len);
    253315 
    254316  /* these assume the returned keys are sorted */
    255   FAIL_UNLESS("get_keys result val",0==strcmp("a",owl_list_get_element(&l,0)));
    256   FAIL_UNLESS("get_keys result val",0==strcmp("b",owl_list_get_element(&l,1)));
    257   FAIL_UNLESS("get_keys result val",0==strcmp("c",owl_list_get_element(&l,2)));
    258 
    259   owl_list_cleanup(&l, g_free);
     317  FAIL_UNLESS("get_keys result val", 0 == strcmp("a", l->pdata[0]));
     318  FAIL_UNLESS("get_keys result val", 0 == strcmp("b", l->pdata[1]));
     319  FAIL_UNLESS("get_keys result val", 0 == strcmp("c", l->pdata[2]));
     320
     321  owl_ptr_array_free(l, g_free);
    260322  owl_dict_cleanup(&d, NULL);
     323
     324  g_free(av);
     325  g_free(bv);
     326  g_free(cv);
     327  g_free(dv);
    261328
    262329  /*  if (numfailed) printf("*** WARNING: failures encountered with owl_dict\n"); */
     
    267334int owl_variable_regtest(void) {
    268335  owl_vardict vd;
     336  owl_variable *var;
    269337  int numfailed=0;
    270338  char *value;
    271   const void *v;
    272339
    273340  printf("# BEGIN testing owl_variable\n");
    274   FAIL_UNLESS("setup", 0==owl_variable_dict_setup(&vd));
    275 
    276   FAIL_UNLESS("get bool", 0==owl_variable_get_bool(&vd,"rxping"));
    277   FAIL_UNLESS("get bool (no such)", -1==owl_variable_get_bool(&vd,"mumble"));
     341  owl_variable_dict_setup(&vd);
     342
     343  FAIL_UNLESS("get bool var", NULL != (var = owl_variable_get_var(&vd, "rxping")));
     344  FAIL_UNLESS("get bool", 0 == owl_variable_get_bool(var));
     345  FAIL_UNLESS("get bool (no such)", NULL == owl_variable_get_var(&vd, "mumble"));
    278346  FAIL_UNLESS("get bool as string",
    279               !strcmp((value = owl_variable_get_tostring(&vd,"rxping")), "off"));
     347              !strcmp((value = owl_variable_get_tostring(var)), "off"));
    280348  g_free(value);
    281   FAIL_UNLESS("set bool 1", 0==owl_variable_set_bool_on(&vd,"rxping"));
    282   FAIL_UNLESS("get bool 2", 1==owl_variable_get_bool(&vd,"rxping"));
    283   FAIL_UNLESS("set bool 3", 0==owl_variable_set_fromstring(&vd,"rxping","off",0,0));
    284   FAIL_UNLESS("get bool 4", 0==owl_variable_get_bool(&vd,"rxping"));
    285   FAIL_UNLESS("set bool 5", -1==owl_variable_set_fromstring(&vd,"rxping","xxx",0,0));
    286   FAIL_UNLESS("get bool 6", 0==owl_variable_get_bool(&vd,"rxping"));
    287 
    288 
    289   FAIL_UNLESS("get string", 0==strcmp("~/zlog/people", owl_variable_get_string(&vd,"logpath")));
    290   FAIL_UNLESS("set string 7", 0==owl_variable_set_string(&vd,"logpath","whee"));
    291   FAIL_UNLESS("get string", 0==strcmp("whee", owl_variable_get_string(&vd,"logpath")));
    292 
    293   FAIL_UNLESS("get int", 8==owl_variable_get_int(&vd,"typewinsize"));
    294   FAIL_UNLESS("get int (no such)", -1==owl_variable_get_int(&vd,"mmble"));
     349  FAIL_UNLESS("set bool 1", 0 == owl_variable_set_bool_on(var));
     350  FAIL_UNLESS("get bool 2", 1 == owl_variable_get_bool(var));
     351  FAIL_UNLESS("set bool 3", 0 == owl_variable_set_fromstring(var, "off", 0));
     352  FAIL_UNLESS("get bool 4", 0 == owl_variable_get_bool(var));
     353  FAIL_UNLESS("set bool 5", -1 == owl_variable_set_fromstring(var, "xxx", 0));
     354  FAIL_UNLESS("get bool 6", 0 == owl_variable_get_bool(var));
     355
     356
     357  FAIL_UNLESS("get string var", NULL != (var = owl_variable_get_var(&vd, "logpath")));
     358  FAIL_UNLESS("get string", 0 == strcmp("~/zlog/people", owl_variable_get_string(var)));
     359  FAIL_UNLESS("set string 7", 0 == owl_variable_set_string(var, "whee"));
     360  FAIL_UNLESS("get string", !strcmp("whee", owl_variable_get_string(var)));
     361
     362  FAIL_UNLESS("get int var", NULL != (var = owl_variable_get_var(&vd, "typewinsize")));
     363  FAIL_UNLESS("get int", 8 == owl_variable_get_int(var));
     364  FAIL_UNLESS("get int (no such)", NULL == owl_variable_get_var(&vd, "mumble"));
    295365  FAIL_UNLESS("get int as string",
    296               !strcmp((value = owl_variable_get_tostring(&vd,"typewinsize")), "8"));
     366              !strcmp((value = owl_variable_get_tostring(var)), "8"));
    297367  g_free(value);
    298   FAIL_UNLESS("set int 1", 0==owl_variable_set_int(&vd,"typewinsize",12));
    299   FAIL_UNLESS("get int 2", 12==owl_variable_get_int(&vd,"typewinsize"));
    300   FAIL_UNLESS("set int 1b", -1==owl_variable_set_int(&vd,"typewinsize",-3));
    301   FAIL_UNLESS("get int 2b", 12==owl_variable_get_int(&vd,"typewinsize"));
    302   FAIL_UNLESS("set int 3", 0==owl_variable_set_fromstring(&vd,"typewinsize","9",0,0));
    303   FAIL_UNLESS("get int 4", 9==owl_variable_get_int(&vd,"typewinsize"));
    304   FAIL_UNLESS("set int 5", -1==owl_variable_set_fromstring(&vd,"typewinsize","xxx",0,0));
    305   FAIL_UNLESS("set int 6", -1==owl_variable_set_fromstring(&vd,"typewinsize","",0,0));
    306   FAIL_UNLESS("get int 7", 9==owl_variable_get_int(&vd,"typewinsize"));
    307 
    308   owl_variable_dict_newvar_string(&vd, "stringvar", "", "", "testval");
    309   FAIL_UNLESS("get new string var", NULL != (v = owl_variable_get(&vd, "stringvar", OWL_VARIABLE_STRING)));
    310   FAIL_UNLESS("get new string val", !strcmp("testval", owl_variable_get_string(&vd, "stringvar")));
    311   owl_variable_set_string(&vd, "stringvar", "new val");
    312   FAIL_UNLESS("update string val", !strcmp("new val", owl_variable_get_string(&vd, "stringvar")));
    313 
    314   owl_variable_dict_newvar_int(&vd, "intvar", "", "", 47);
    315   FAIL_UNLESS("get new int var", NULL != (v = owl_variable_get(&vd, "intvar", OWL_VARIABLE_INT)));
    316   FAIL_UNLESS("get new int val", 47 == owl_variable_get_int(&vd, "intvar"));
    317   owl_variable_set_int(&vd, "intvar", 17);
    318   FAIL_UNLESS("update bool val", 17 == owl_variable_get_int(&vd, "intvar"));
    319 
    320   owl_variable_dict_newvar_bool(&vd, "boolvar", "", "", 1);
    321   FAIL_UNLESS("get new bool var", NULL != (v = owl_variable_get(&vd, "boolvar", OWL_VARIABLE_BOOL)));
    322   FAIL_UNLESS("get new bool val", owl_variable_get_bool(&vd, "boolvar"));
    323   owl_variable_set_bool_off(&vd, "boolvar");
    324   FAIL_UNLESS("update string val", !owl_variable_get_bool(&vd, "boolvar"));
     368  FAIL_UNLESS("set int 1", 0 == owl_variable_set_int(var, 12));
     369  FAIL_UNLESS("get int 2", 12 == owl_variable_get_int(var));
     370  FAIL_UNLESS("set int 1b", -1 == owl_variable_set_int(var, -3));
     371  FAIL_UNLESS("get int 2b", 12 == owl_variable_get_int(var));
     372  FAIL_UNLESS("set int 3", 0 == owl_variable_set_fromstring(var, "9", 0));
     373  FAIL_UNLESS("get int 4", 9 == owl_variable_get_int(var));
     374  FAIL_UNLESS("set int 5", -1 == owl_variable_set_fromstring(var, "xxx", 0));
     375  FAIL_UNLESS("set int 6", -1 == owl_variable_set_fromstring(var, "", 0));
     376  FAIL_UNLESS("get int 7", 9 == owl_variable_get_int(var));
     377
     378  FAIL_UNLESS("get enum var", NULL != (var = owl_variable_get_var(&vd, "scrollmode")));
     379  FAIL_UNLESS("get enum", OWL_SCROLLMODE_NORMAL == owl_variable_get_int(var));
     380  FAIL_UNLESS("get enum as string",
     381              !strcmp((value = owl_variable_get_tostring(var)), "normal"));
     382  g_free(value);
     383  FAIL_UNLESS("set enum 1", 0 == owl_variable_set_int(var, OWL_SCROLLMODE_TOP));
     384  FAIL_UNLESS("get enum 1", OWL_SCROLLMODE_TOP == owl_variable_get_int(var));
     385  FAIL_UNLESS("set enum 2a", -1 == owl_variable_set_int(var, -1));
     386  FAIL_UNLESS("set enum 2b", -1 == owl_variable_set_int(var, OWL_SCROLLMODE_PAGEDCENTER + 1));
     387  FAIL_UNLESS("get enum 2", OWL_SCROLLMODE_TOP == owl_variable_get_int(var));
     388  FAIL_UNLESS("set enum 3", 0 == owl_variable_set_fromstring(var, "center", 0));
     389  FAIL_UNLESS("get enum 4", OWL_SCROLLMODE_CENTER == owl_variable_get_int(var));
     390  FAIL_UNLESS("set enum 5", -1 == owl_variable_set_fromstring(var, "bogus", 0));
     391  FAIL_UNLESS("set enum 6", -1 == owl_variable_set_fromstring(var, "", 0));
     392  FAIL_UNLESS("get enum 7", OWL_SCROLLMODE_CENTER == owl_variable_get_int(var));
     393
     394  owl_variable_dict_newvar_string(&vd, "stringvar", "testval", "", "");
     395  FAIL_UNLESS("get new string var", NULL != (var = owl_variable_get_var(&vd, "stringvar")));
     396  FAIL_UNLESS("get new string val", !strcmp("testval", owl_variable_get_string(var)));
     397  owl_variable_set_string(var, "new val");
     398  FAIL_UNLESS("update string val", !strcmp("new val", owl_variable_get_string(var)));
     399
     400  owl_variable_dict_newvar_int(&vd, "intvar", 47, "", "");
     401  FAIL_UNLESS("get new int var", NULL != (var = owl_variable_get_var(&vd, "intvar")));
     402  FAIL_UNLESS("get new int val", 47 == owl_variable_get_int(var));
     403  owl_variable_set_int(var, 17);
     404  FAIL_UNLESS("update int val", 17 == owl_variable_get_int(var));
     405
     406  owl_variable_dict_newvar_bool(&vd, "boolvar", true, "", "");
     407  FAIL_UNLESS("get new bool var", NULL != (var = owl_variable_get_var(&vd, "boolvar")));
     408  FAIL_UNLESS("get new bool val", owl_variable_get_bool(var));
     409  owl_variable_set_bool_off(var);
     410  FAIL_UNLESS("update bool val", !owl_variable_get_bool(var));
     411
     412  owl_variable_dict_newvar_string(&vd, "nullstringvar", NULL, "", "");
     413  FAIL_UNLESS("get new string (NULL) var", NULL != (var = owl_variable_get_var(&vd, "nullstringvar")));
     414  FAIL_UNLESS("get string (NULL)", NULL == (value = owl_variable_get_tostring(var)));
     415  g_free(value);
     416  var = owl_variable_get_var(&vd, "zsigproc");
     417  FAIL_UNLESS("get string (NULL) 2", NULL == (value = owl_variable_get_tostring(var)));
     418  g_free(value);
     419
     420  owl_variable_dict_newvar_enum(&vd, "enumvar", 0, "", "", "a,b,c,d");
     421  FAIL_UNLESS("get new enum var", NULL != (var = owl_variable_get_var(&vd, "enumvar")));
     422  FAIL_UNLESS("get new enum val", 0 == owl_variable_get_int(var));
     423  owl_variable_set_fromstring(var, "c", 0);
     424  FAIL_UNLESS("update enum val", 2 == owl_variable_get_int(var));
    325425
    326426  owl_variable_dict_cleanup(&vd);
     
    417517  FAIL_UNLESS("DAG", (f5 = owl_filter_new_fromstring("dag", "filter f1 or filter f1")) != NULL);
    418518  owl_filter_delete(f5);
     519
     520  owl_message_cleanup(&m);
    419521
    420522  return 0;
     
    796898  return numfailed;
    797899}
     900
     901int owl_history_regtest(void)
     902{
     903  int numfailed = 0;
     904  int i;
     905  owl_history h;
     906
     907  printf("# BEGIN testing owl_history\n");
     908  owl_history_init(&h);
     909
     910  /* Operations on empty history. */
     911  FAIL_UNLESS("prev NULL", owl_history_get_prev(&h) == NULL);
     912  FAIL_UNLESS("next NULL", owl_history_get_next(&h) == NULL);
     913  FAIL_UNLESS("untouched", !owl_history_is_touched(&h));
     914
     915  /* Insert a few records. */
     916  owl_history_store(&h, "a", false);
     917  owl_history_store(&h, "b", false);
     918  owl_history_store(&h, "c", false);
     919  owl_history_store(&h, "d", true);
     920
     921  /* Walk up and down the history a bit. */
     922  FAIL_UNLESS("untouched", !owl_history_is_touched(&h));
     923  FAIL_UNLESS("prev c", strcmp(owl_history_get_prev(&h), "c") == 0);
     924  FAIL_UNLESS("touched", owl_history_is_touched(&h));
     925  FAIL_UNLESS("next d", strcmp(owl_history_get_next(&h), "d") == 0);
     926  FAIL_UNLESS("untouched", !owl_history_is_touched(&h));
     927  FAIL_UNLESS("next NULL", owl_history_get_next(&h) == NULL);
     928  FAIL_UNLESS("prev c", strcmp(owl_history_get_prev(&h), "c") == 0);
     929  FAIL_UNLESS("prev b", strcmp(owl_history_get_prev(&h), "b") == 0);
     930  FAIL_UNLESS("prev a", strcmp(owl_history_get_prev(&h), "a") == 0);
     931  FAIL_UNLESS("prev NULL", owl_history_get_prev(&h) == NULL);
     932
     933  /* Now insert something. It should reset and blow away 'd'. */
     934  owl_history_store(&h, "e", false);
     935  FAIL_UNLESS("untouched", !owl_history_is_touched(&h));
     936  FAIL_UNLESS("next NULL", owl_history_get_next(&h) == NULL);
     937  FAIL_UNLESS("prev c", strcmp(owl_history_get_prev(&h), "c") == 0);
     938  FAIL_UNLESS("touched", owl_history_is_touched(&h));
     939  FAIL_UNLESS("next e", strcmp(owl_history_get_next(&h), "e") == 0);
     940  FAIL_UNLESS("untouched", !owl_history_is_touched(&h));
     941
     942  /* Lines get de-duplicated on insert. */
     943  owl_history_store(&h, "e", false);
     944  owl_history_store(&h, "e", false);
     945  owl_history_store(&h, "e", false);
     946  FAIL_UNLESS("prev c", strcmp(owl_history_get_prev(&h), "c") == 0);
     947  FAIL_UNLESS("next e", strcmp(owl_history_get_next(&h), "e") == 0);
     948
     949  /* But a partial is not deduplicated, as it'll go away soon. */
     950  owl_history_store(&h, "e", true);
     951  FAIL_UNLESS("prev e", strcmp(owl_history_get_prev(&h), "e") == 0);
     952  FAIL_UNLESS("prev c", strcmp(owl_history_get_prev(&h), "c") == 0);
     953  FAIL_UNLESS("next e", strcmp(owl_history_get_next(&h), "e") == 0);
     954  FAIL_UNLESS("next e", strcmp(owl_history_get_next(&h), "e") == 0);
     955
     956  /* Reset moves to the front... */
     957  owl_history_store(&h, "f", true);
     958  FAIL_UNLESS("prev e", strcmp(owl_history_get_prev(&h), "e") == 0);
     959  FAIL_UNLESS("prev c", strcmp(owl_history_get_prev(&h), "c") == 0);
     960  owl_history_reset(&h);
     961  FAIL_UNLESS("untouched", !owl_history_is_touched(&h));
     962  /* ...and destroys any pending partial entry... */
     963  FAIL_UNLESS("prev c", strcmp(owl_history_get_prev(&h), "c") == 0);
     964  FAIL_UNLESS("prev b", strcmp(owl_history_get_prev(&h), "b") == 0);
     965  /* ...but not non-partial ones. */
     966  owl_history_reset(&h);
     967  FAIL_UNLESS("untouched", !owl_history_is_touched(&h));
     968
     969  /* Finally, check we are bounded by OWL_HISTORYSIZE. */
     970  for (i = 0; i < OWL_HISTORYSIZE; i++) {
     971    char *string = g_strdup_printf("mango%d", i);
     972    owl_history_store(&h, string, false);
     973    g_free(string);
     974  }
     975  /* The OWL_HISTORYSIZE'th prev gets NULL. */
     976  for (i = OWL_HISTORYSIZE - 2; i >= 0; i--) {
     977    char *string = g_strdup_printf("mango%d", i);
     978    FAIL_UNLESS("prev mango_N", strcmp(owl_history_get_prev(&h), string) == 0);
     979    g_free(string);
     980  }
     981  FAIL_UNLESS("prev NULL", owl_history_get_prev(&h) == NULL);
     982
     983  owl_history_cleanup(&h);
     984
     985  printf("# END testing owl_history (%d failures)\n", numfailed);
     986  return numfailed;
     987}
     988
     989int call_filter_regtest(void)
     990{
     991  int numfailed = 0;
     992  int ret;
     993  char *out = NULL;
     994  int status;
     995
     996  printf("# BEGIN testing call_filter\n");
     997
     998  const char *cat_argv[] = { "cat", NULL };
     999  ret = call_filter(cat_argv, "Mangos!", &out, &status);
     1000  FAIL_UNLESS("call_filter cat", (ret == 0 &&
     1001                                  status == 0 &&
     1002                                  strcmp(out, "Mangos!") == 0));
     1003  g_free(out); out = NULL;
     1004
     1005  ret = call_filter(cat_argv, "", &out, &status);
     1006  FAIL_UNLESS("call_filter cat", (ret == 0 &&
     1007                                  status == 0 &&
     1008                                  strcmp(out, "") == 0));
     1009  g_free(out); out = NULL;
     1010
     1011  ret = call_filter(cat_argv, NULL, &out, &status);
     1012  FAIL_UNLESS("call_filter cat", (ret == 0 &&
     1013                                  status == 0 &&
     1014                                  strcmp(out, "") == 0));
     1015  g_free(out); out = NULL;
     1016
     1017  printf("# END testing call_filter (%d failures)\n", numfailed);
     1018  return numfailed;
     1019}
  • text.c

    r7865479 rf271129  
    1 #include <stdio.h>
    2 #include <string.h>
    3 #include <stdlib.h>
    4 #include <ctype.h>
    51#include "owl.h"
    62
    73/* Returns a copy of 'in' with each line indented 'n'
    84 * characters. Result must be freed with g_free. */
    9 char *owl_text_indent(const char *in, int n)
     5CALLER_OWN char *owl_text_indent(const char *in, int n, bool indent_first_line)
    106{
    117  const char *ptr1, *ptr2, *last;
    128  GString *out = g_string_new("");
    139  int i;
     10  bool indent_this_line = indent_first_line;
    1411
    1512  last=in+strlen(in)-1;
    1613  ptr1=in;
    1714  while (ptr1<=last) {
    18     for (i=0; i<n; i++) {
    19       g_string_append_c(out, ' ');
    20     }
     15    if (indent_this_line) {
     16      for (i = 0; i < n; i++) {
     17        g_string_append_c(out, ' ');
     18      }
     19    }
     20    indent_this_line = true;
    2121    ptr2=strchr(ptr1, '\n');
    2222    if (!ptr2) {
     
    4848
    4949/* caller must free the return */
    50 char *owl_text_htmlstrip(const char *in)
     50CALLER_OWN char *owl_text_htmlstrip(const char *in)
    5151{
    5252  const char *ptr1, *end, *ptr2, *ptr3;
     
    129129
    130130/* Caller must free return */
    131 char *owl_text_expand_tabs(const char *in)
     131CALLER_OWN char *owl_text_expand_tabs(const char *in)
    132132{
    133133  int len = 0;
     
    188188
    189189/* caller must free the return */
    190 char *owl_text_wordwrap(const char *in, int col)
     190CALLER_OWN char *owl_text_wordwrap(const char *in, int col)
    191191{
    192192  char *out;
     
    269269 * Caller must free returned string.
    270270 */
    271 char *owl_text_substitute(const char *in, const char *from, const char *to)
     271CALLER_OWN char *owl_text_substitute(const char *in, const char *from, const char *to)
    272272{
    273273  char **split = g_strsplit(in, from, 0), *out;
     
    284284 * On success returns the string, on error returns NULL.
    285285 */
    286 char *owl_text_quote(const char *in, const char *toquote, const char *quotestr)
     286CALLER_OWN char *owl_text_quote(const char *in, const char *toquote, const char *quotestr)
    287287{
    288288  int i, x, r, place, escape;
  • util.c

    r83a4af3 r7b89e8c  
    11#include "owl.h"
    2 #include <stdlib.h>
    3 #include <string.h>
    4 #include <unistd.h>
    5 #include <ctype.h>
    62#include <pwd.h>
    73#include <sys/stat.h>
    8 #include <sys/types.h>
    9 #include <assert.h>
    104#include <stdarg.h>
    11 #include <glib.h>
    125#include <glib/gstdio.h>
    136#include <glib-object.h>
     
    3225}
    3326
     27CALLER_OWN char *owl_util_homedir_for_user(const char *name)
     28{
     29  int err;
     30  struct passwd pw_buf;
     31  struct passwd *pw;
     32
     33  char *pw_strbuf, *ret;
     34  long pw_strbuf_len = sysconf(_SC_GETPW_R_SIZE_MAX);
     35  if (pw_strbuf_len < 0) {
     36    /* If we really hate ourselves, we can be fancy and loop until we stop
     37     * getting ERANGE. For now just pick a random number. */
     38    owl_function_error("owl_util_homedir_for_user: Could not get _SC_GETPW_R_SIZE_MAX");
     39    pw_strbuf_len = 16384;
     40  }
     41  pw_strbuf = g_new0(char, pw_strbuf_len);
     42  err = getpwnam_r(name, &pw_buf, pw_strbuf, pw_strbuf_len, &pw);
     43  if (err) {
     44    owl_function_error("getpwuid_r: %s", strerror(err));
     45    /* Fall through; pw will be NULL. */
     46  }
     47  ret = pw ? g_strdup(pw->pw_dir) : NULL;
     48  g_free(pw_strbuf);
     49  return ret;
     50}
     51
    3452/* Return a "nice" version of the path.  Tilde expansion is done, and
    3553 * duplicate slashes are removed.  Caller must free the return.
    3654 */
    37 char *owl_util_makepath(const char *in)
    38 {
    39   int i, j, x;
    40   char *out, user[MAXPATHLEN];
    41   struct passwd *pw;
    42 
    43   out=g_new(char, MAXPATHLEN+1);
    44   out[0]='\0';
    45   j=strlen(in);
    46   x=0;
    47   for (i=0; i<j; i++) {
    48     if (in[i]=='~') {
    49       if ( (i==(j-1)) ||          /* last character */
    50            (in[i+1]=='/') ) {     /* ~/ */
    51         /* use my homedir */
    52         pw=getpwuid(getuid());
    53         if (!pw) {
    54           out[x]=in[i];
    55         } else {
    56           out[x]='\0';
    57           strcat(out, pw->pw_dir);
    58           x+=strlen(pw->pw_dir);
    59         }
     55CALLER_OWN char *owl_util_makepath(const char *in)
     56{
     57  char *out;
     58  int i, j;
     59  if (in[0] == '~') {
     60    /* Attempt tilde-expansion of the first component. Get the
     61       tilde-prefix, which goes up to the next slash. */
     62    const char *end = strchr(in + 1, '/');
     63    if (end == NULL)
     64      end = in + strlen(in);
     65
     66    /* Patch together a new path. Replace the ~ and tilde-prefix with
     67       the homedir, if available. */
     68    if (end == in + 1) {
     69      /* My home directory. Use the one in owl_global for consistency with
     70       * owl_zephyr_dotfile. */
     71      out = g_strconcat(owl_global_get_homedir(&g), end, NULL);
     72    } else {
     73      /* Someone else's home directory. */
     74      char *user = g_strndup(in + 1, end - (in + 1));
     75      char *home = owl_util_homedir_for_user(user);
     76      if (home) {
     77        out = g_strconcat(home, end, NULL);
    6078      } else {
    61         /* another user homedir */
    62         int a, b;
    63         b=0;
    64         for (a=i+1; i<j; a++) {
    65           if (in[a]==' ' || in[a]=='/') {
    66             break;
    67           } else {
    68             user[b]=in[a];
    69             i++;
    70             b++;
    71           }
    72         }
    73         user[b]='\0';
    74         pw=getpwnam(user);
    75         if (!pw) {
    76           out[x]=in[i];
    77         } else {
    78           out[x]='\0';
    79           strcat(out, pw->pw_dir);
    80           x+=strlen(pw->pw_dir);
    81         }
     79        out = g_strdup(in);
    8280      }
    83     } else if (in[i]=='/') {
    84       /* check for a double / */
    85       if (i<(j-1) && (in[i+1]=='/')) {
    86         /* do nothing */
    87       } else {
    88         out[x]=in[i];
    89         x++;
    90       }
    91     } else {
    92       out[x]=in[i];
    93       x++;
    94     }
    95   }
    96   out[x]='\0';
    97   return(out);
     81      g_free(home);
     82      g_free(user);
     83    }
     84  } else {
     85    out = g_strdup(in);
     86  }
     87
     88  /* And a quick pass to remove duplicate slashes. */
     89  for (i = j = 0; out[i] != '\0'; i++) {
     90    if (out[i] != '/' || i == 0 || out[i-1] != '/')
     91      out[j++] = out[i];
     92  }
     93  out[j] = '\0';
     94  return out;
     95}
     96
     97void owl_ptr_array_free(GPtrArray *array, GDestroyNotify element_free_func)
     98{
     99  /* TODO: when we move to requiring glib 2.22+, use
     100   * g_ptr_array_new_with_free_func instead. */
     101  if (element_free_func)
     102    g_ptr_array_foreach(array, (GFunc)element_free_func, NULL);
     103  g_ptr_array_free(array, true);
    98104}
    99105
     
    102108   to -1, argv will be NULL and the caller does not need to free anything. The
    103109   returned vector is NULL-terminated. */
    104 char **owl_parseline(const char *line, int *argc)
     110CALLER_OWN char **owl_parseline(const char *line, int *argc)
    105111{
    106112  GPtrArray *argv;
     
    170176  /* check for unbalanced quotes */
    171177  if (quote!='\0') {
    172     /* TODO: when we move to requiring glib 2.22+, use
    173      * g_ptr_array_new_with_free_func. */
    174     g_ptr_array_foreach(argv, (GFunc)g_free, NULL);
    175     g_ptr_array_free(argv, true);
     178    owl_ptr_array_free(argv, g_free);
    176179    if (argc) *argc = -1;
    177180    return(NULL);
     
    215218/*
    216219 * Appends 'tmpl' to 'buf', replacing any instances of '%q' with arguments from
    217  * the varargs provided, quoting them to be safe for placing in a barnowl
     220 * the varargs provided, quoting them to be safe for placing in a BarnOwl
    218221 * command line.
    219222 */
     
    245248}
    246249
    247 char *owl_string_build_quoted(const char *tmpl, ...)
     250CALLER_OWN char *owl_string_build_quoted(const char *tmpl, ...)
    248251{
    249252  GString *buf = g_string_new("");
     
    257260/* Returns a quoted version of arg suitable for placing in a
    258261 * command-line. Result should be freed with g_free. */
    259 char *owl_arg_quote(const char *arg)
    260 {
    261   GString *buf = g_string_new("");;
     262CALLER_OWN char *owl_arg_quote(const char *arg)
     263{
     264  GString *buf = g_string_new("");
    262265  owl_string_append_quoted_arg(buf, arg);
    263266  return g_string_free(buf, false);
    264267}
    265268
     269/* Returns a quoted version of argv. owl_parseline on the result should give
     270 * back the input. */
     271CALLER_OWN char *owl_argv_quote(int argc, const char *const *argv)
     272{
     273  int i;
     274  GString *buf = g_string_new("");
     275  for (i = 0; i < argc; i++) {
     276    if (i > 0)
     277      g_string_append_c(buf, ' ');
     278    owl_string_append_quoted_arg(buf, argv[i]);
     279  }
     280  return g_string_free(buf, false);
     281}
     282
    266283/* caller must free the return */
    267 char *owl_util_minutes_to_timestr(int in)
     284CALLER_OWN char *owl_util_format_minutes(int in)
    268285{
    269286  int days, hours;
     
    284301  }
    285302  return(out);
     303}
     304
     305CALLER_OWN char *owl_util_format_time(const struct tm *time)
     306{
     307  /* 32 chosen for first attempt because timestr will end up being
     308   * something like "Www Mmm dd hh:mm:ss AM yyyy UTC\0" */
     309  size_t timestr_size = 16;
     310  char *timestr = NULL;
     311  do {
     312    timestr_size *= 2;
     313    timestr = g_renew(char, timestr, timestr_size);
     314  } while (strftime(timestr, timestr_size, "%c", time) == 0);
     315  return timestr;
    286316}
    287317
     
    331361
    332362/* Get the default tty name.  Caller must free the return */
    333 char *owl_util_get_default_tty(void)
     363CALLER_OWN char *owl_util_get_default_tty(void)
    334364{
    335365  const char *tmp;
     
    353383 * return.
    354384 */
    355 char *owl_util_stripnewlines(const char *in)
     385CALLER_OWN char *owl_util_stripnewlines(const char *in)
    356386{
    357387 
     
    384414 * Error conditions are the same as g_file_read_link.
    385415 */
    386 gchar *owl_util_recursive_resolve_link(const char *filename)
     416CALLER_OWN gchar *owl_util_recursive_resolve_link(const char *filename)
    387417{
    388418  gchar *last_path = g_strdup(filename);
     
    403433    if (!g_path_is_absolute(link_path)) {
    404434      char *last_dir = g_path_get_dirname(last_path);
    405       char *tmp = g_build_path(G_DIR_SEPARATOR_S,
    406                                last_dir,
    407                                link_path,
    408                                NULL);
     435      char *tmp = g_build_filename(last_dir, link_path, NULL);
    409436      g_free(last_dir);
    410437      g_free(link_path);
     
    511538   The caller is responsible for freeing the allocated string.
    512539*/
    513 char * owl_util_baseclass(const char * class)
     540CALLER_OWN char *owl_util_baseclass(const char *class)
    514541{
    515542  char *start, *end;
     
    546573
    547574/* Strips format characters from a valid utf-8 string. Returns the
    548    empty string if 'in' does not validate. */
    549 char * owl_strip_format_chars(const char *in)
     575   empty string if 'in' does not validate.  Caller must free the return. */
     576CALLER_OWN char *owl_strip_format_chars(const char *in)
    550577{
    551578  char *r;
     
    584611 * out characters in Unicode Plane 16, as we use that plane internally
    585612 * for formatting.
    586  */
    587 char * owl_validate_or_convert(const char *in)
     613 * Caller must free the return.
     614 */
     615CALLER_OWN char *owl_validate_or_convert(const char *in)
    588616{
    589617  if (g_utf8_validate(in, -1, NULL)) {
     
    599627 * Validate 'in' as UTF-8, and either return a copy of it, or an empty
    600628 * string if it is invalid utf-8.
    601  */
    602 char * owl_validate_utf8(const char *in)
     629 * Caller must free the return.
     630 */
     631CALLER_OWN char *owl_validate_utf8(const char *in)
    603632{
    604633  char *out;
     
    632661}
    633662
    634 char *owl_escape_highbit(const char *str)
     663/* caller must free the return */
     664CALLER_OWN char *owl_escape_highbit(const char *str)
    635665{
    636666  GString *out = g_string_new("");
     
    695725
    696726/* Read the rest of the input available in fp into a string. */
    697 char *owl_slurp(FILE *fp)
     727CALLER_OWN char *owl_slurp(FILE *fp)
    698728{
    699729  char *buf = NULL;
  • variable.c

    r4c7c21f r9d4dfdc  
     1#include "owl.h"
    12#include <stdio.h>
    2 #include <stdlib.h>
    3 #include <string.h>
    4 #include <unistd.h>
    5 #include <ctype.h>
    6 #include "owl.h"
    7 
    8 #define OWLVAR_BOOL(name,default,summary,description) \
    9         { name, OWL_VARIABLE_BOOL, NULL, default, "on,off", summary,description, NULL, \
    10         NULL, NULL, NULL, NULL, NULL, NULL }
    11 
    12 #define OWLVAR_BOOL_FULL(name,default,summary,description,validate,set,get) \
    13         { name, OWL_VARIABLE_BOOL, NULL, default, "on,off", summary,description, NULL, \
    14         validate, set, NULL, get, NULL, NULL }
    15 
    16 #define OWLVAR_INT(name,default,summary,description) \
    17         { name, OWL_VARIABLE_INT, NULL, default, "<int>", summary,description, NULL, \
    18         NULL, NULL, NULL, NULL, NULL, NULL }
     3#include "gmarshal_funcs.h"
     4
     5/* TODO(davidben): When we can require 2.30 and up, remove this. */
     6#ifndef G_VALUE_INIT
     7#define G_VALUE_INIT { 0, { { 0 } } }
     8#endif
     9
     10typedef const char *(*get_string_t)(const owl_variable *);
     11typedef int (*get_int_t)(const owl_variable *);
     12typedef bool (*get_bool_t)(const owl_variable *);
     13
     14typedef int (*set_string_t)(owl_variable *, const char *);
     15typedef int (*set_int_t)(owl_variable *, int);
     16typedef int (*set_bool_t)(owl_variable *, bool);
     17
     18typedef int (*validate_string_t)(const owl_variable *, const char *);
     19typedef int (*validate_int_t)(const owl_variable *, int);
     20typedef int (*validate_bool_t)(const owl_variable *, bool);
     21
     22static void owl_variable_dict_newvar_bool_full(owl_vardict *vd,
     23                                               const char *name,
     24                                               bool default_val,
     25                                               const char *summary,
     26                                               const char *description,
     27                                               validate_bool_t validate_fn,
     28                                               set_bool_t set_fn,
     29                                               get_bool_t get_fn);
     30
     31static void owl_variable_dict_newvar_string_full(owl_vardict *vd,
     32                                                 const char *name,
     33                                                 const char *default_val,
     34                                                 const char *summary,
     35                                                 const char *description,
     36                                                 const char *validsettings,
     37                                                 validate_string_t validate_fn,
     38                                                 set_string_t set_fn,
     39                                                 get_string_t get_fn);
     40
     41static void owl_variable_dict_newvar_int_full(owl_vardict *vd,
     42                                              const char *name,
     43                                              int default_val,
     44                                              const char *summary,
     45                                              const char *description,
     46                                              const char *validsettings,
     47                                              validate_int_t validate_fn,
     48                                              set_int_t set_fn,
     49                                              get_int_t get_fn);
     50
     51static void owl_variable_dict_newvar_enum_full(owl_vardict *vd,
     52                                               const char *name,
     53                                               int default_val,
     54                                               const char *summary,
     55                                               const char *description,
     56                                               const char *validsettings,
     57                                               validate_int_t validate_fn,
     58                                               set_int_t set_fn,
     59                                               get_int_t get_fn);
     60
     61#define OWLVAR_BOOL(name, default, summary, description) \
     62        owl_variable_dict_newvar_bool(vd, name, default, summary, description)
     63
     64#define OWLVAR_BOOL_FULL(name, default, summary, description, validate, set, get) \
     65        owl_variable_dict_newvar_bool_full(vd, name, default, summary, description, \
     66                                           validate, set, get)
     67
     68#define OWLVAR_INT(name, default, summary, description) \
     69        owl_variable_dict_newvar_int(vd, name, default, summary, description)
    1970
    2071#define OWLVAR_INT_FULL(name,default,summary,description,validset,validate,set,get) \
    21         { name, OWL_VARIABLE_INT, NULL, default, validset, summary,description, NULL, \
    22         validate, set, NULL, get, NULL, NULL }
    23 
    24 #define OWLVAR_PATH(name,default,summary,description) \
    25         { name, OWL_VARIABLE_STRING, default, 0, "<path>", summary,description,  NULL, \
    26         NULL, NULL, NULL, NULL, NULL, NULL }
    27 
    28 #define OWLVAR_STRING(name,default,summary,description) \
    29         { name, OWL_VARIABLE_STRING, default, 0, "<string>", summary,description, NULL, \
    30         NULL, NULL, NULL, NULL, NULL, NULL }
    31 
    32 #define OWLVAR_STRING_FULL(name,default,validset,summary,description,validate,set,get) \
    33         { name, OWL_VARIABLE_STRING, default, 0, validset, summary,description, NULL, \
    34         validate, set, NULL, get, NULL, NULL }
     72        owl_variable_dict_newvar_int_full(vd, name, default, summary, description, \
     73                                          validset, validate, set, get)
     74
     75#define OWLVAR_PATH(name, default, summary, description) \
     76        owl_variable_dict_newvar_path(vd, name, default, summary, description)
     77
     78#define OWLVAR_STRING(name, default, summary, description) \
     79        owl_variable_dict_newvar_string(vd, name, default, summary, description)
     80
     81#define OWLVAR_STRING_FULL(name, default, validset, summary, description, validate, set, get) \
     82        owl_variable_dict_newvar_string_full(vd, name, default, summary, description, \
     83                                             validset, validate, set, get)
    3584
    3685/* enums are really integers, but where validset is a comma-separated
    3786 * list of strings which can be specified.  The tokens, starting at 0,
    3887 * correspond to the values that may be specified. */
    39 #define OWLVAR_ENUM(name,default,summary,description,validset) \
    40         { name, OWL_VARIABLE_INT, NULL, default, validset, summary,description, NULL, \
    41         owl_variable_enum_validate, \
    42         NULL, owl_variable_enum_set_fromstring, \
    43         NULL, owl_variable_enum_get_tostring, \
    44         NULL }
     88#define OWLVAR_ENUM(name, default, summary, description, validset) \
     89        owl_variable_dict_newvar_enum(vd, name, default, summary, description, validset)
    4590
    4691#define OWLVAR_ENUM_FULL(name,default,summary,description,validset,validate, set, get) \
    47         { name, OWL_VARIABLE_INT, NULL, default, validset, summary,description, NULL, \
    48         validate, \
    49         set, owl_variable_enum_set_fromstring, \
    50         get, owl_variable_enum_get_tostring, \
    51         NULL }
    52 
    53 static owl_variable variables_to_init[] = {
    54 
     92        owl_variable_dict_newvar_enum_full(vd, name, default, summary, description, \
     93                                           validset, validate, set, get)
     94
     95void owl_variable_add_defaults(owl_vardict *vd)
     96{
    5597  OWLVAR_STRING( "personalbell" /* %OwlVarStub */, "off",
    5698                 "ring the terminal bell when personal messages are received",
    5799                 "Can be set to 'on', 'off', or the name of a filter which\n"
    58                  "messages need to match in order to ring the bell"),
     100                 "messages need to match in order to ring the bell");
    59101
    60102  OWLVAR_BOOL( "bell" /* %OwlVarStub */, 1,
    61                "enable / disable the terminal bell", "" ),
     103               "enable / disable the terminal bell", "" );
    62104
    63105  OWLVAR_BOOL_FULL( "debug" /* %OwlVarStub */, OWL_DEBUG,
     
    65107                    "If set to 'on', debugging messages are logged to the\n"
    66108                    "file specified by the debugfile variable.\n",
    67                     NULL, owl_variable_debug_set, NULL),
     109                    NULL, owl_variable_debug_set, NULL);
    68110
    69111  OWLVAR_BOOL( "startuplogin" /* %OwlVarStub */, 1,
    70                "send a login message when owl starts", "" ),
     112               "send a login message when BarnOwl starts", "" );
    71113
    72114  OWLVAR_BOOL( "shutdownlogout" /* %OwlVarStub */, 1,
    73                "send a logout message when owl exits", "" ),
     115               "send a logout message when BarnOwl exits", "" );
    74116
    75117  OWLVAR_BOOL( "rxping" /* %OwlVarStub */, 0,
    76                "display received pings", "" ),
     118               "display received pings", "" );
    77119
    78120  OWLVAR_BOOL( "txping" /* %OwlVarStub */, 1,
    79                "send pings", "" ),
     121               "send pings", "" );
    80122
    81123  OWLVAR_BOOL( "sepbar_disable" /* %OwlVarStub */, 0,
    82                "disable printing information in the separator bar", "" ),
     124               "disable printing information in the separator bar", "" );
    83125
    84126  OWLVAR_BOOL( "smartstrip" /* %OwlVarStub */, 1,
    85                "strip kerberos instance for reply", ""),
     127               "strip kerberos instance for reply", "");
    86128
    87129  OWLVAR_BOOL( "newlinestrip" /* %OwlVarStub */, 1,
    88                "strip leading and trailing newlines", ""),
     130               "strip leading and trailing newlines", "");
    89131
    90132  OWLVAR_BOOL( "displayoutgoing" /* %OwlVarStub */, 1,
    91                "display outgoing messages", "" ),
     133               "display outgoing messages", "" );
    92134
    93135  OWLVAR_BOOL( "loginsubs" /* %OwlVarStub */, 1,
    94                "load logins from .anyone on startup", "" ),
     136               "load logins from .anyone on startup", "" );
    95137
    96138  OWLVAR_BOOL( "logging" /* %OwlVarStub */, 0,
     
    99141               "logged in the directory specified\n"
    100142               "by the 'logpath' variable.  The filename in that\n"
    101                "directory is derived from the sender of the message.\n" ),
     143               "directory is derived from the sender of the message.\n" );
    102144
    103145  OWLVAR_BOOL( "classlogging" /* %OwlVarStub */, 0,
     
    107149               "by the 'classlogpath' variable.\n"
    108150               "The filename in that directory is derived from\n"
    109                "the name of the class to which the message was sent.\n" ),
     151               "the name of the class to which the message was sent.\n" );
    110152
    111153  OWLVAR_ENUM( "loggingdirection" /* %OwlVarStub */, OWL_LOGGING_DIRECTION_BOTH,
     
    116158               "is selected both incoming and outgoing messages are\n"
    117159               "logged.",
    118                "both,in,out"),
    119 
    120   OWLVAR_BOOL( "colorztext" /* %OwlVarStub */, 1,
    121                "allow @color() in zephyrs to change color",
    122                "Note that only messages received after this variable\n"
    123                "is set will be affected." ),
     160               "both,in,out");
     161
     162  OWLVAR_BOOL_FULL( "colorztext" /* %OwlVarStub */, 1,
     163                    "allow @color() in zephyrs to change color",
     164                    NULL, NULL, owl_variable_colorztext_set, NULL);
    124165
    125166  OWLVAR_BOOL( "fancylines" /* %OwlVarStub */, 1,
     
    127168               "If turned off, dashes, pipes and pluses will be used\n"
    128169               "to draw lines on the screen.  Useful when the terminal\n"
    129                "is causing problems" ),
     170               "is causing problems" );
    130171
    131172  OWLVAR_BOOL( "zcrypt" /* %OwlVarStub */, 1,
    132173               "Do automatic zcrypt processing",
    133                "" ),
     174               "" );
    134175
    135176  OWLVAR_BOOL_FULL( "pseudologins" /* %OwlVarStub */, 0,
    136177                    "Enable zephyr pseudo logins",
    137                     "When this is enabled, Owl will periodically check the zephyr\n"
     178                    "When this is enabled, BarnOwl will periodically check the zephyr\n"
    138179                    "location of users in your .anyone file.  If a user is present\n"
    139180                    "but sent no login message, or a user is not present that sent no\n"
    140181                    "logout message, a pseudo login or logout message will be created\n",
    141                     NULL, owl_variable_pseudologins_set, NULL),
     182                    NULL, owl_variable_pseudologins_set, NULL);
    142183
    143184  OWLVAR_BOOL( "ignorelogins" /* %OwlVarStub */, 0,
    144185               "Enable printing of login notifications",
    145                "When this is enabled, Owl will print login and logout notifications\n"
    146                "for AIM, zephyr, or other protocols.  If disabled Owl will not print\n"
    147                "login or logout notifications.\n"),
     186               "When this is enabled, BarnOwl will print login and logout notifications\n"
     187               "for AIM, zephyr, or other protocols.  If disabled BarnOwl will not print\n"
     188               "login or logout notifications.\n");
    148189
    149190  OWLVAR_STRING( "logfilter" /* %OwlVarStub */, "",
     
    154195                 "variables like logging, classlogging, loglogins, loggingdirection,\n"
    155196                 "etc.  If you want this variable to control all logging, make sure\n"
    156                  "all other logging variables are in their default state.\n"),
     197                 "all other logging variables are in their default state.\n");
    157198
    158199  OWLVAR_BOOL( "loglogins" /* %OwlVarStub */, 0,
    159200               "Enable logging of login notifications",
    160                "When this is enabled, Owl will login login and logout notifications\n"
    161                "for AIM, zephyr, or other protocols.  If disabled Owl will not print\n"
    162                "login or logout notifications.\n"),
     201               "When this is enabled, BarnOwl will log login and logout notifications\n"
     202               "for AIM, zephyr, or other protocols.  If disabled BarnOwl will not print\n"
     203               "login or logout notifications.\n");
    163204
    164205  OWLVAR_ENUM_FULL( "disable-ctrl-d" /* %OwlVarStub:lockout_ctrld */, 1,
    165206                    "don't send zephyrs on C-d",
    166                     "If set to 'off', C-d won't send a zephyr from the edit\n"
    167                     "window.  If set to 'on', C-d will always send a zephyr\n"
     207                    "If set to 'on', C-d won't send a zephyr from the edit\n"
     208                    "window.  If set to 'off', C-d will always send a zephyr\n"
    168209                    "being composed in the edit window.  If set to 'middle',\n"
    169210                    "C-d will only ever send a zephyr if the cursor is at\n"
     
    172213                    "in the editmulti keymap.\n",
    173214                    "off,middle,on",
    174                     NULL, owl_variable_disable_ctrl_d_set, NULL),
     215                    NULL, owl_variable_disable_ctrl_d_set, NULL);
    175216
    176217  OWLVAR_PATH( "logpath" /* %OwlVarStub */, "~/zlog/people",
    177218               "path for logging personal zephyrs",
    178219               "Specifies a directory which must exist.\n"
    179                "Files will be created in the directory for each sender.\n"),
     220               "Files will be created in the directory for each sender.\n");
    180221
    181222  OWLVAR_PATH( "classlogpath" /* %OwlVarStub:classlogpath */, "~/zlog/class",
    182223               "path for logging class zephyrs",
    183224               "Specifies a directory which must exist.\n"
    184                "Files will be created in the directory for each class.\n"),
     225               "Files will be created in the directory for each class.\n");
    185226
    186227  OWLVAR_PATH( "debug_file" /* %OwlVarStub */, OWL_DEBUG_FILE,
    187228               "path for logging debug messages when debugging is enabled",
    188229               "This file will be logged to if 'debug' is set to 'on'.\n"
    189                "BarnOwl will append a dot and the current process's pid to the filename."),
     230               "BarnOwl will append a dot and the current process's pid to the filename.");
    190231 
    191232  OWLVAR_PATH( "zsigproc" /* %OwlVarStub:zsigproc */, NULL,
     
    195236               "See the documentation for 'zsig' for more information about\n"
    196237               "how the outgoing zsig is chosen."
    197                ),
     238               );
    198239
    199240  OWLVAR_PATH( "newmsgproc" /* %OwlVarStub:newmsgproc */, NULL,
    200241               "name of a program to run when new messages are present",
    201                "The named program will be run when owl receives new\n"
     242               "The named program will be run when BarnOwl receives new\n"
    202243               "messages.  It will not be run again until the first\n"
    203                "instance exits"),
     244               "instance exits");
    204245
    205246  OWLVAR_STRING( "zsender" /* %OwlVarStub */, "",
     
    208249         "zephyrs.  If this is unset, it will use your Kerberos\n"
    209250         "principal. Note that customizing the sender name will\n"
    210          "cause your zephyrs to be sent unauthenticated."),
     251         "cause your zephyrs to be sent unauthenticated.");
    211252
    212253  OWLVAR_STRING( "zsigfunc" /* %OwlVarStub */, "BarnOwl::default_zephyr_signature()",
     
    215256                 "explicit zsig.  The default setting implements the policy\n"
    216257                 "described in the documentation for the 'zsig' variable.\n"
    217                  "See also BarnOwl::random_zephyr_signature().\n"),
     258                 "See also BarnOwl::random_zephyr_signature().\n");
    218259
    219260  OWLVAR_STRING( "zsig" /* %OwlVarStub */, "",
     
    222263                 "unset, 'zsigproc' will be run to generate a zsig. If that is\n"
    223264                 "also unset, the 'zwrite-signature' zephyr variable will be\n"
    224                  "used instead.\n"),
     265                 "used instead.\n");
    225266
    226267  OWLVAR_STRING( "appendtosepbar" /* %OwlVarStub */, "",
    227268                 "string to append to the end of the sepbar",
    228269                 "The sepbar is the bar separating the top and bottom\n"
    229                  "of the owl screen.  Any string specified here will\n"
    230                  "be displayed on the right of the sepbar\n"),
     270                 "of the BarnOwl screen.  Any string specified here will\n"
     271                 "be displayed on the right of the sepbar\n");
    231272
    232273  OWLVAR_BOOL( "zaway" /* %OwlVarStub */, 0,
    233                "turn zaway on or off", "" ),
     274               "turn zaway on or off", "" );
    234275
    235276  OWLVAR_STRING( "zaway_msg" /* %OwlVarStub */,
    236277                 OWL_DEFAULT_ZAWAYMSG,
    237                  "zaway msg for responding to zephyrs when away", "" ),
     278                 "zaway msg for responding to zephyrs when away", "" );
    238279
    239280  OWLVAR_STRING( "zaway_msg_default" /* %OwlVarStub */,
    240281                 OWL_DEFAULT_ZAWAYMSG,
    241                  "default zaway message", "" ),
     282                 "default zaway message", "" );
    242283
    243284  OWLVAR_BOOL_FULL( "aaway" /* %OwlVarStub */, 0,
    244285                    "Set AIM away status",
    245286                    "",
    246                     NULL, owl_variable_aaway_set, NULL),
     287                    NULL, owl_variable_aaway_set, NULL);
    247288
    248289  OWLVAR_STRING( "aaway_msg" /* %OwlVarStub */,
    249290                 OWL_DEFAULT_AAWAYMSG,
    250                  "AIM away msg for responding when away", "" ),
     291                 "AIM away msg for responding when away", "" );
    251292
    252293  OWLVAR_STRING( "aaway_msg_default" /* %OwlVarStub */,
    253294                 OWL_DEFAULT_AAWAYMSG,
    254                  "default AIM away message", "" ),
     295                 "default AIM away message", "" );
    255296
    256297  OWLVAR_STRING( "view_home" /* %OwlVarStub */, "all",
    257298                 "home view to switch to after 'X' and 'V'",
    258                  "SEE ALSO: view, filter\n" ),
     299                 "SEE ALSO: view, filter\n" );
    259300
    260301  OWLVAR_STRING( "alert_filter" /* %OwlVarStub */, "none",
    261302                 "filter on which to trigger alert actions",
    262                  "" ),
     303                 "" );
    263304
    264305  OWLVAR_STRING( "alert_action" /* %OwlVarStub */, "nop",
    265                  "owl command to execute for alert actions",
    266                  "" ),
     306                 "BarnOwl command to execute for alert actions",
     307                 "" );
    267308
    268309  OWLVAR_STRING_FULL( "tty" /* %OwlVarStub */, "", "<string>", "tty name for zephyr location", "",
    269                       NULL, owl_variable_tty_set, NULL),
     310                      NULL, owl_variable_tty_set, NULL);
    270311
    271312  OWLVAR_STRING( "default_style" /* %OwlVarStub */, "default",
     
    274315                 "Styles may be created with the 'style' command.\n"
    275316                 "Some built-in styles include:\n"
    276                  "   default  - the default owl formatting\n"
     317                 "   default  - the default BarnOwl formatting\n"
    277318                 "   oneline  - one line per-message\n"
    278319                 "   perl     - legacy perl interface\n"
    279320                 "\nSEE ALSO: style, show styles, view -s <style>\n"
    280                  ),
     321                 );
    281322
    282323
     
    285326                 "This specifies the maximum number of columns for M-q to fill text\n"
    286327                 "to.  If set to 0, M-q will wrap to the width of the window, and\n"
    287                  "values less than 0 disable M-q entirely.\n"),
     328                 "values less than 0 disable M-q entirely.\n");
    288329
    289330  OWLVAR_INT(    "edit:maxwrapcols" /* %OwlVarStub:edit_maxwrapcols */, 70,
     
    294335                 "\n"
    295336                 "As a courtesy to recipients, it is recommended that outgoing\n"
    296                  "Zephyr messages be no wider than 70 columns.\n"),
     337                 "Zephyr messages be no wider than 70 columns.\n");
    297338
    298339  OWLVAR_INT( "aim_ignorelogin_timer" /* %OwlVarStub */, 15,
     
    301342              "AIM login before allowing the receipt of AIM login notifications.\n"
    302343              "By default this is set to 15.  If you would like to view login\n"
    303               "notifications of buddies as soon as you login, set it to 0 instead."),
     344              "notifications of buddies as soon as you login, set it to 0 instead.");
    304345
    305346             
     
    314355                   owl_variable_typewinsize_set,
    315356                   NULL /* use default for get */
    316                    ),
     357                   );
    317358
    318359  OWLVAR_INT( "typewindelta" /* %OwlVarStub */, 0,
     
    324365           "typewinsize to 1.\n\n"
    325366           "This works a lot better with a non-default scrollmode;\n"
    326            "try :set scrollmode pagedcenter.\n"),
     367           "try :set scrollmode pagedcenter.\n");
    327368
    328369  OWLVAR_ENUM( "scrollmode" /* %OwlVarStub */, OWL_SCROLLMODE_NORMAL,
     
    331372               "cursor moves between messages being displayed.\n"
    332373               "The following modes are supported:\n\n"
    333                "   normal      - This is the owl default.  Scrolling happens\n"
     374               "   normal      - This is the BarnOwl default.  Scrolling happens\n"
    334375               "                 when it needs to, and an attempt is made to\n"
    335376               "                 keep the current message roughly near\n"
     
    353394               "                 the screen will be paged up or down and\n"
    354395               "                 the cursor will be near the center.\n",
    355                "normal,top,neartop,center,paged,pagedcenter" ),
     396               "normal,top,neartop,center,paged,pagedcenter" );
    356397
    357398  OWLVAR_BOOL( "narrow-related" /* %OwlVarStub:narrow_related */, 1,
    358399               "Make smartnarrow use broader filters",
    359                "Causes smartfiler to narrow to messages \"related\" to \n"
     400               "Causes smartfilter to narrow to messages \"related\" to \n"
    360401               "the current message, as well as ones to the same place.\n\n"
    361402               "for Zephyr, this controls whether to narrow to e.g. class-help or\n"
    362403               "class-help.d alone, or to related-class-help, which includes\n"
    363                "help, unhelp, help.d, etc.\n\nDefault is true (include unclasses, etc.).\n" ),
     404               "help, unhelp, help.d, etc.\n\nDefault is true (include unclasses, etc.).\n" );
    364405
    365406  OWLVAR_BOOL( "_followlast" /* %OwlVarStub */, 0,
     
    368409               "continue to follow the last message if this is set.\n"
    369410               "Note that this is currently risky as you might accidentally\n"
    370                "delete a message right as it came in.\n" ),
     411               "delete a message right as it came in.\n" );
    371412
    372413  OWLVAR_STRING_FULL( "default_exposure" /* %OwlVarStub */, "",
     
    377418                      "~/.zephyr.vars.\n"
    378419                      "See the description of exposure for the values this can be.",
    379                       NULL, owl_variable_default_exposure_set, owl_variable_default_exposure_get ),
     420                      NULL, owl_variable_default_exposure_set, owl_variable_default_exposure_get );
    380421
    381422  OWLVAR_STRING_FULL( "exposure" /* %OwlVarStub */, "",
     
    433474                      "                     personal subscriptions will be entered for the\n"
    434475                      "                     user.\n",
    435                       NULL, owl_variable_exposure_set, NULL /* use default for get */ ),
    436 
    437   /* This MUST be last... */
    438   { NULL, 0, NULL, 0, NULL, NULL, NULL, NULL,
    439     NULL, NULL, NULL, NULL, NULL, NULL }
    440 
    441 };
     476                      NULL, owl_variable_exposure_set, NULL /* use default for get */ );
     477}
    442478
    443479/**************************************************************************/
     
    448484/* commonly useful */
    449485
    450 int owl_variable_int_validate_gt0(const owl_variable *v, const void *newval)
    451 {
    452   if (newval == NULL) return(0);
    453   else if (*(const int*)newval < 1) return(0);
    454   else return (1);
    455 }
    456 
    457 int owl_variable_int_validate_positive(const owl_variable *v, const void *newval)
    458 {
    459   if (newval == NULL) return(0);
    460   else if (*(const int*)newval < 0) return(0);
    461   else return (1);
     486int owl_variable_int_validate_gt0(const owl_variable *v, int newval)
     487{
     488  return !(newval < 1);
     489}
     490
     491int owl_variable_int_validate_positive(const owl_variable *v, int newval)
     492{
     493  return !(newval < 0);
    462494}
    463495
    464496/* typewinsize */
    465 int owl_variable_typewinsize_set(owl_variable *v, const void *newval)
     497int owl_variable_typewinsize_set(owl_variable *v, int newval)
    466498{
    467499  int rv;
     
    472504
    473505/* debug (cache value in g->debug) */
    474 int owl_variable_debug_set(owl_variable *v, const void *newval)
    475 {
    476   if (newval && (*(const int*)newval == 1 || *(const int*)newval == 0)) {
    477     g.debug = *(const int*)newval;
     506int owl_variable_debug_set(owl_variable *v, bool newval)
     507{
     508  g.debug = newval;
     509  return owl_variable_bool_set_default(v, newval);
     510}
     511
     512/* When 'aaway' is changed, need to notify the AIM server */
     513int owl_variable_aaway_set(owl_variable *v, bool newval)
     514{
     515  if (newval) {
     516    owl_aim_set_awaymsg(owl_global_get_aaway_msg(&g));
     517  } else {
     518    owl_aim_set_awaymsg("");
    478519  }
    479520  return owl_variable_bool_set_default(v, newval);
    480521}
    481522
    482 /* When 'aaway' is changed, need to notify the AIM server */
    483 int owl_variable_aaway_set(owl_variable *v, const void *newval)
    484 {
     523int owl_variable_colorztext_set(owl_variable *v, bool newval)
     524{
     525  int ret = owl_variable_bool_set_default(v, newval);
     526  /* flush the format cache so that we see the update, but only if we're done initializing BarnOwl */
     527  if (owl_global_get_msglist(&g) != NULL)
     528    owl_messagelist_invalidate_formats(owl_global_get_msglist(&g));
     529  if (owl_global_get_mainwin(&g) != NULL) {
     530    owl_function_calculate_topmsg(OWL_DIRECTION_DOWNWARDS);
     531    owl_mainwin_redisplay(owl_global_get_mainwin(&g));
     532  }
     533  return ret;
     534}
     535
     536int owl_variable_pseudologins_set(owl_variable *v, bool newval)
     537{
     538  static guint timer = 0;
    485539  if (newval) {
    486     if (*(const int*)newval == 1) {
    487       owl_aim_set_awaymsg(owl_global_get_aaway_msg(&g));
    488     } else if (*(const int*)newval == 0) {
    489       owl_aim_set_awaymsg("");
     540    owl_function_zephyr_buddy_check(0);
     541    if (timer == 0) {
     542      timer = g_timeout_add_seconds(180, owl_zephyr_buddycheck_timer, NULL);
     543    }
     544  } else {
     545    if (timer != 0) {
     546      g_source_remove(timer);
     547      timer = 0;
    490548    }
    491549  }
     
    493551}
    494552
    495 int owl_variable_pseudologins_set(owl_variable *v, const void *newval)
    496 {
    497   static owl_timer *timer = NULL;
    498   if (newval) {
    499     if (*(const int*)newval == 1) {
    500       owl_function_zephyr_buddy_check(0);
    501       if (timer == NULL) {
    502         timer = owl_select_add_timer("owl_zephyr_buddycheck_timer",
    503                                      180, 180, owl_zephyr_buddycheck_timer, NULL, NULL);
    504       }
    505     } else {
    506       if (timer != NULL) {
    507         owl_select_remove_timer(timer);
    508         timer = NULL;
    509       }
    510     }
    511   }
    512   return owl_variable_bool_set_default(v, newval);
    513 }
    514 
    515553/* note that changing the value of this will clobber
    516554 * any user setting of this */
    517 int owl_variable_disable_ctrl_d_set(owl_variable *v, const void *newval)
    518 {
    519   if (newval && !owl_context_is_startup(owl_global_get_context(&g))) {
    520     if (*(const int*)newval == 2) {
     555int owl_variable_disable_ctrl_d_set(owl_variable *v, int newval)
     556{
     557  if (!owl_context_is_startup(owl_global_get_context(&g))) {
     558    if (newval == 2) {
    521559      owl_function_command_norv("bindkey editmulti C-d command edit:delete-next-char");
    522     } else if (*(const int*)newval == 1) {
     560    } else if (newval == 1) {
    523561      owl_function_command_norv("bindkey editmulti C-d command edit:done-or-delete");
    524562    } else {
     
    526564    }
    527565  } 
    528   return owl_variable_int_set_default(v, newval); 
    529 }
    530 
    531 int owl_variable_tty_set(owl_variable *v, const void *newval)
     566  return owl_variable_int_set_default(v, newval);
     567}
     568
     569int owl_variable_tty_set(owl_variable *v, const char *newval)
    532570{
    533571  owl_zephyr_set_locationinfo(g_get_host_name(), newval);
    534   return(owl_variable_string_set_default(v, newval));
    535 }
    536 
    537 int owl_variable_default_exposure_set(owl_variable *v, const void *newval)
     572  return owl_variable_string_set_default(v, newval);
     573}
     574
     575int owl_variable_default_exposure_set(owl_variable *v, const char *newval)
    538576{
    539577  return owl_zephyr_set_default_exposure(newval);
    540578}
    541579
    542 const void *owl_variable_default_exposure_get(const owl_variable *v)
     580const char *owl_variable_default_exposure_get(const owl_variable *v)
    543581{
    544582  return owl_zephyr_get_default_exposure();
    545583}
    546584
    547 int owl_variable_exposure_set(owl_variable *v, const void *newval)
     585int owl_variable_exposure_set(owl_variable *v, const char *newval)
    548586{
    549587  int ret = owl_zephyr_set_exposure(newval);
     
    557595/**************************************************************************/
    558596
    559 int owl_variable_dict_setup(owl_vardict *vd) {
    560   owl_variable *var, *cur;
     597void owl_variable_dict_setup(owl_vardict *vd) {
    561598  owl_dict_create(vd);
    562   for (var = variables_to_init; var->name != NULL; var++) {
    563     cur = g_new(owl_variable, 1);
    564     *cur = *var;
    565     /* strdup all the strings so we can delete them consistently. */
    566     cur->name = g_strdup(var->name);
    567     cur->summary = g_strdup(var->summary);
    568     cur->description = g_strdup(var->description);
    569     switch (cur->type) {
    570     case OWL_VARIABLE_OTHER:
    571       cur->set_fn(cur, cur->pval_default);
    572       break;
    573     case OWL_VARIABLE_STRING:
    574       if (!cur->validate_fn)
    575         cur->validate_fn = owl_variable_string_validate_default;
    576       if (!cur->set_fn)
    577         cur->set_fn = owl_variable_string_set_default;
    578       if (!cur->set_fromstring_fn)
    579         cur->set_fromstring_fn = owl_variable_string_set_fromstring_default;
    580       if (!cur->get_fn)
    581         cur->get_fn = owl_variable_get_default;
    582       if (!cur->get_tostring_fn)
    583         cur->get_tostring_fn = owl_variable_string_get_tostring_default;     
    584       if (!cur->delete_fn)
    585         cur->delete_fn = owl_variable_delete_default;
    586       cur->set_fn(cur, cur->pval_default);
    587       break;
    588     case OWL_VARIABLE_BOOL:
    589       if (!cur->validate_fn)
    590         cur->validate_fn = owl_variable_bool_validate_default;
    591       if (!cur->set_fn)
    592         cur->set_fn = owl_variable_bool_set_default;
    593       if (!cur->set_fromstring_fn)
    594         cur->set_fromstring_fn = owl_variable_bool_set_fromstring_default;
    595       if (!cur->get_fn)
    596         cur->get_fn = owl_variable_get_default;
    597       if (!cur->get_tostring_fn)
    598         cur->get_tostring_fn = owl_variable_bool_get_tostring_default;     
    599       if (!cur->delete_fn)
    600         cur->delete_fn = owl_variable_delete_default;
    601       cur->val = g_new(int, 1);
    602       cur->set_fn(cur, &cur->ival_default);
    603       break;
    604     case OWL_VARIABLE_INT:
    605       if (!cur->validate_fn)
    606         cur->validate_fn = owl_variable_int_validate_default;
    607       if (!cur->set_fn)
    608         cur->set_fn = owl_variable_int_set_default;
    609       if (!cur->set_fromstring_fn)
    610         cur->set_fromstring_fn = owl_variable_int_set_fromstring_default;
    611       if (!cur->get_fn)
    612         cur->get_fn = owl_variable_get_default;
    613       if (!cur->get_tostring_fn)
    614         cur->get_tostring_fn = owl_variable_int_get_tostring_default;     
    615       if (!cur->delete_fn)
    616         cur->delete_fn = owl_variable_delete_default;
    617       cur->val = g_new(int, 1);
    618       cur->set_fn(cur, &cur->ival_default);
    619       break;
    620     default:
    621       fprintf(stderr, "owl_variable_setup: invalid variable type\n");
    622       return(-2);
    623     }
    624     owl_dict_insert_element(vd, cur->name, cur, NULL);
    625   }
    626   return 0;
     599  owl_variable_add_defaults(vd);
     600}
     601
     602CALLER_OWN GClosure *owl_variable_make_closure(owl_variable *v,
     603                                               GCallback fn,
     604                                               GClosureMarshal marshal) {
     605  GClosure *closure = g_cclosure_new_swap(fn, v, NULL);
     606  g_closure_set_marshal(closure,marshal);
     607  g_closure_ref(closure);
     608  g_closure_sink(closure);
     609  return closure;
    627610}
    628611
    629612void owl_variable_dict_add_variable(owl_vardict * vardict,
    630613                                    owl_variable * var) {
     614  char *oldvalue = NULL;
     615  owl_variable *oldvar = owl_variable_get_var(vardict, var->name);
     616  /* Save the old value as a string. */
     617  if (oldvar) {
     618    oldvalue = owl_variable_get_tostring(oldvar);
     619  }
    631620  owl_dict_insert_element(vardict, var->name, var, (void (*)(void *))owl_variable_delete);
    632 }
    633 
    634 owl_variable * owl_variable_newvar(const char *name, const char *summary, const char * description) {
    635   owl_variable * var = g_new0(owl_variable, 1);
     621  /* Restore the old value. */
     622  if (oldvalue) {
     623    owl_variable_set_fromstring(var, oldvalue, 0);
     624    g_free(oldvalue);
     625  }
     626}
     627
     628static owl_variable *owl_variable_newvar(int type, const char *name, const char *summary, const char *description, const char *validsettings) {
     629  owl_variable *var = g_new0(owl_variable, 1);
     630  var->type = type;
    636631  var->name = g_strdup(name);
    637632  var->summary = g_strdup(summary);
    638633  var->description = g_strdup(description);
     634  var->validsettings = g_strdup(validsettings);
    639635  return var;
    640636}
    641637
    642 void owl_variable_update(owl_variable *var, const char *summary, const char *desc) {
    643   g_free(var->summary);
    644   var->summary = g_strdup(summary);
    645   g_free(var->description);
    646   var->description = g_strdup(desc);
    647 }
    648 
    649 void owl_variable_dict_newvar_string(owl_vardict * vd, const char *name, const char *summ, const char * desc, const char * initval) {
    650   owl_variable *old = owl_variable_get_var(vd, name, OWL_VARIABLE_STRING);
    651   if(old) {
    652     owl_variable_update(old, summ, desc);
    653     g_free(old->pval_default);
    654     old->pval_default = g_strdup(initval);
    655   } else {
    656     owl_variable * var = owl_variable_newvar(name, summ, desc);
    657     var->type = OWL_VARIABLE_STRING;
    658     var->pval_default = g_strdup(initval);
    659     var->set_fn = owl_variable_string_set_default;
    660     var->set_fromstring_fn = owl_variable_string_set_fromstring_default;
    661     var->get_fn = owl_variable_get_default;
    662     var->get_tostring_fn = owl_variable_string_get_tostring_default;
    663     var->delete_fn = owl_variable_delete_default;
    664     var->set_fn(var, initval);
    665     owl_variable_dict_add_variable(vd, var);
    666   }
    667 }
    668 
    669 void owl_variable_dict_newvar_int(owl_vardict * vd, const char *name, const char *summ, const char * desc, int initval) {
    670   owl_variable *old = owl_variable_get_var(vd, name, OWL_VARIABLE_INT);
    671   if(old) {
    672     owl_variable_update(old, summ, desc);
    673     old->ival_default = initval;
    674   } else {
    675     owl_variable * var = owl_variable_newvar(name, summ, desc);
    676     var->type = OWL_VARIABLE_INT;
    677     var->ival_default = initval;
    678     var->validate_fn = owl_variable_int_validate_default;
    679     var->set_fn = owl_variable_int_set_default;
    680     var->set_fromstring_fn = owl_variable_int_set_fromstring_default;
    681     var->get_fn = owl_variable_get_default;
    682     var->get_tostring_fn = owl_variable_int_get_tostring_default;
    683     var->delete_fn = owl_variable_delete_default;
    684     var->val = g_new(int, 1);
    685     var->set_fn(var, &initval);
    686     owl_variable_dict_add_variable(vd, var);
    687   }
    688 }
    689 
    690 void owl_variable_dict_newvar_bool(owl_vardict * vd, const char *name, const char *summ, const char * desc, int initval) {
    691   owl_variable *old = owl_variable_get_var(vd, name, OWL_VARIABLE_BOOL);
    692   if(old) {
    693     owl_variable_update(old, summ, desc);
    694     old->ival_default = initval;
    695   } else {
    696     owl_variable * var = owl_variable_newvar(name, summ, desc);
    697     var->type = OWL_VARIABLE_BOOL;
    698     var->ival_default = initval;
    699     var->validate_fn = owl_variable_bool_validate_default;
    700     var->set_fn = owl_variable_bool_set_default;
    701     var->set_fromstring_fn = owl_variable_bool_set_fromstring_default;
    702     var->get_fn = owl_variable_get_default;
    703     var->get_tostring_fn = owl_variable_bool_get_tostring_default;
    704     var->delete_fn = owl_variable_delete_default;
    705     var->val = g_new(int, 1);
    706     var->set_fn(var, &initval);
    707     owl_variable_dict_add_variable(vd, var);
    708   }
     638static void owl_variable_dict_newvar_int_full(owl_vardict *vd, const char *name, int default_val, const char *summary, const char *description, const char *validsettings, validate_int_t validate_fn, set_int_t set_fn, get_int_t get_fn)
     639{
     640  owl_variable *var = owl_variable_newvar(OWL_VARIABLE_INT, name, summary,
     641                                          description, validsettings);
     642  var->takes_on_off = false;
     643  var->get_fn = G_CALLBACK(get_fn ? get_fn : owl_variable_int_get_default);
     644  var->set_fn = G_CALLBACK(set_fn ? set_fn : owl_variable_int_set_default);
     645  var->validate_fn = G_CALLBACK(validate_fn ? validate_fn : owl_variable_int_validate_default);
     646
     647  var->get_tostring_fn = owl_variable_make_closure(
     648      var, G_CALLBACK(owl_variable_int_get_tostring_default),
     649      g_cclosure_user_marshal_STRING__VOID);
     650  var->set_fromstring_fn = owl_variable_make_closure(
     651      var, G_CALLBACK(owl_variable_int_set_fromstring_default),
     652      g_cclosure_user_marshal_INT__STRING);
     653
     654  g_value_init(&var->val, G_TYPE_INT);
     655  owl_variable_set_int(var, default_val);
     656
     657  var->default_str = owl_variable_get_tostring(var);
     658  owl_variable_dict_add_variable(vd, var);
     659}
     660
     661void owl_variable_dict_newvar_int(owl_vardict *vd, const char *name, int default_val, const char *summary, const char *description) {
     662  owl_variable_dict_newvar_int_full(vd, name, default_val, summary, description,
     663                                    "<int>", NULL, NULL, NULL);
     664}
     665
     666static void owl_variable_dict_newvar_bool_full(owl_vardict *vd, const char *name, bool default_val, const char *summary, const char *description, validate_bool_t validate_fn, set_bool_t set_fn, get_bool_t get_fn)
     667{
     668  owl_variable *var = owl_variable_newvar(OWL_VARIABLE_BOOL, name, summary,
     669                                          description, "on,off");
     670  var->takes_on_off = true;
     671  var->get_fn = G_CALLBACK(get_fn ? get_fn : owl_variable_bool_get_default);
     672  var->set_fn = G_CALLBACK(set_fn ? set_fn : owl_variable_bool_set_default);
     673  var->validate_fn = G_CALLBACK(validate_fn ? validate_fn : owl_variable_bool_validate_default);
     674
     675  var->get_tostring_fn = owl_variable_make_closure(
     676      var, G_CALLBACK(owl_variable_bool_get_tostring_default),
     677      g_cclosure_user_marshal_STRING__VOID);
     678  var->set_fromstring_fn = owl_variable_make_closure(
     679      var, G_CALLBACK(owl_variable_bool_set_fromstring_default),
     680      g_cclosure_user_marshal_INT__STRING);
     681
     682  g_value_init(&var->val, G_TYPE_BOOLEAN);
     683  owl_variable_set_bool(var, default_val);
     684
     685  var->default_str = owl_variable_get_tostring(var);
     686  owl_variable_dict_add_variable(vd, var);
     687}
     688
     689void owl_variable_dict_newvar_bool(owl_vardict *vd, const char *name, bool default_val, const char *summary, const char *description) {
     690  owl_variable_dict_newvar_bool_full(vd, name, default_val, summary, description,
     691                                     NULL, NULL, NULL);
     692}
     693
     694static void owl_variable_dict_newvar_string_full(owl_vardict *vd, const char *name, const char *default_val, const char *summary, const char *description, const char *validsettings, validate_string_t validate_fn, set_string_t set_fn, get_string_t get_fn)
     695{
     696  owl_variable *var = owl_variable_newvar(OWL_VARIABLE_STRING, name, summary,
     697                                          description, validsettings);
     698  var->takes_on_off = false;
     699  var->get_fn = G_CALLBACK(get_fn ? get_fn : owl_variable_string_get_default);
     700  var->set_fn = G_CALLBACK(set_fn ? set_fn : owl_variable_string_set_default);
     701  var->validate_fn = G_CALLBACK(validate_fn ? validate_fn : owl_variable_string_validate_default);
     702
     703  var->get_tostring_fn = owl_variable_make_closure(
     704      var, G_CALLBACK(owl_variable_string_get_tostring_default),
     705      g_cclosure_user_marshal_STRING__VOID);
     706  var->set_fromstring_fn = owl_variable_make_closure(
     707      var, G_CALLBACK(owl_variable_string_set_fromstring_default),
     708      g_cclosure_user_marshal_INT__STRING);
     709
     710  g_value_init(&var->val, G_TYPE_STRING);
     711  owl_variable_set_string(var, default_val);
     712
     713  var->default_str = owl_variable_get_tostring(var);
     714  owl_variable_dict_add_variable(vd, var);
     715}
     716
     717void owl_variable_dict_newvar_string(owl_vardict *vd, const char *name, const char *default_val, const char *summary, const char *description) {
     718  owl_variable_dict_newvar_string_full(vd, name, default_val, summary, description,
     719                                       "<string>", NULL, NULL, NULL);
     720}
     721
     722void owl_variable_dict_newvar_path(owl_vardict *vd, const char *name, const char *default_val, const char *summary, const char *description) {
     723  owl_variable_dict_newvar_string_full(vd, name, default_val, summary, description,
     724                                       "<path>", NULL, NULL, NULL);
     725}
     726
     727static void owl_variable_dict_newvar_enum_full(owl_vardict *vd, const char *name, int default_val, const char *summary, const char *description, const char *validsettings, validate_int_t validate_fn, set_int_t set_fn, get_int_t get_fn)
     728{
     729  owl_variable *var = owl_variable_newvar(OWL_VARIABLE_INT, name, summary,
     730                                          description, validsettings);
     731  var->takes_on_off = false;
     732  var->get_fn = G_CALLBACK(get_fn ? get_fn : owl_variable_int_get_default);
     733  var->set_fn = G_CALLBACK(set_fn ? set_fn : owl_variable_int_set_default);
     734  var->validate_fn = G_CALLBACK(validate_fn ? validate_fn : owl_variable_enum_validate);
     735
     736  var->get_tostring_fn = owl_variable_make_closure(
     737      var, G_CALLBACK(owl_variable_enum_get_tostring),
     738      g_cclosure_user_marshal_STRING__VOID);
     739  var->set_fromstring_fn = owl_variable_make_closure(
     740      var, G_CALLBACK(owl_variable_enum_set_fromstring),
     741      g_cclosure_user_marshal_INT__STRING);
     742
     743  g_value_init(&var->val, G_TYPE_INT);
     744  owl_variable_set_int(var, default_val);
     745
     746  var->default_str = owl_variable_get_tostring(var);
     747  owl_variable_dict_add_variable(vd, var);
     748}
     749
     750void owl_variable_dict_newvar_enum(owl_vardict *vd, const char *name, int default_val, const char *summary, const char *description, const char *validset) {
     751  owl_variable_dict_newvar_enum_full(vd, name, default_val, summary, description,
     752                                     validset, NULL, NULL, NULL);
     753}
     754
     755void owl_variable_dict_newvar_other(owl_vardict *vd, const char *name, const char *summary, const char *description, const char *validsettings, bool takes_on_off, GClosure *get_tostring_fn, GClosure *set_fromstring_fn)
     756{
     757  owl_variable *var = owl_variable_newvar(OWL_VARIABLE_OTHER, name, summary,
     758                                          description, validsettings);
     759  var->takes_on_off = takes_on_off;
     760
     761  var->get_tostring_fn = g_closure_ref(get_tostring_fn);
     762  g_closure_sink(get_tostring_fn);
     763
     764  var->set_fromstring_fn = g_closure_ref(set_fromstring_fn);
     765  g_closure_sink(set_fromstring_fn);
     766
     767  var->default_str = owl_variable_get_tostring(var);
     768
     769  /* Note: this'll overwrite any existing variable of that name, even a C one,
     770     but it's consistent with previous behavior and commands. */
     771  owl_variable_dict_add_variable(vd, var);
    709772}
    710773
     
    714777}
    715778
    716 void owl_variable_dict_get_names(const owl_vardict *d, owl_list *l) {
    717   owl_dict_get_keys(d, l);
     779CALLER_OWN GPtrArray *owl_variable_dict_get_names(const owl_vardict *d) {
     780  return owl_dict_get_keys(d);
    718781}
    719782
    720783void owl_variable_delete(owl_variable *v)
    721784{
    722   if (v->delete_fn) v->delete_fn(v);
    723785  g_free(v->name);
    724786  g_free(v->summary);
    725787  g_free(v->description);
     788  g_free(v->default_str);
     789  g_free(v->validsettings);
     790  if (v->type != OWL_VARIABLE_OTHER)
     791    g_value_unset(&(v->val));
     792  g_closure_unref(v->get_tostring_fn);
     793  g_closure_unref(v->set_fromstring_fn);
     794
    726795  g_free(v);
    727796}
    728797
     798
     799const char *owl_variable_get_name(const owl_variable *v)
     800{
     801  return v->name;
     802}
    729803
    730804const char *owl_variable_get_description(const owl_variable *v) {
     
    737811
    738812const char *owl_variable_get_validsettings(const owl_variable *v) {
    739   if (v->validsettings) {
    740     return v->validsettings;
    741   } else {
    742     return "";
     813  return v->validsettings;
     814}
     815
     816int owl_variable_get_type(const owl_variable *v)
     817{
     818  return v->type;
     819}
     820
     821/* returns 0 on success, prints a status msg if msg is true */
     822int owl_variable_set_fromstring(owl_variable *v, const char *value, int msg) {
     823  char *tostring;
     824  GValue values[] = {G_VALUE_INIT, G_VALUE_INIT};
     825  GValue return_box = G_VALUE_INIT;
     826  int set_successfully;
     827
     828  g_value_init(&values[0], G_TYPE_POINTER);
     829  g_value_set_pointer(&values[0], NULL);
     830  g_value_init(&values[1], G_TYPE_STRING);
     831  g_value_set_static_string(&values[1], value);
     832  g_value_init(&return_box, G_TYPE_INT);
     833  g_closure_invoke(v->set_fromstring_fn, &return_box, 2, values, NULL);
     834
     835  set_successfully = g_value_get_int(&return_box);
     836  if (0 != set_successfully) {
     837    if (msg) owl_function_error("Unable to set %s (must be %s)", owl_variable_get_name(v),
     838                                owl_variable_get_validsettings(v));
     839  } else if (msg) {
     840    tostring = owl_variable_get_tostring(v);
     841    if (tostring) {
     842      owl_function_makemsg("%s = '%s'", owl_variable_get_name(v), tostring);
     843    } else {
     844      owl_function_makemsg("%s = <null>", owl_variable_get_name(v));
     845    }
     846    g_free(tostring);
    743847  }
    744 }
    745 
    746 /* functions for getting and setting variable values */
    747 
    748 /* returns 0 on success, prints a status msg if msg is true */
    749 int owl_variable_set_fromstring(owl_vardict *d, const char *name, const char *value, int msg, int requirebool) {
    750   owl_variable *v;
     848
     849  g_value_unset(&return_box);
     850  g_value_unset(&values[1]);
     851  g_value_unset(&values[0]);
     852  return set_successfully;
     853}
     854 
     855int owl_variable_set_string(owl_variable *v, const char *newval)
     856{
     857  g_return_val_if_fail(v->type == OWL_VARIABLE_STRING, -1);
     858
     859  set_string_t cb = (set_string_t) v->set_fn;
     860  return cb(v, newval);
     861}
     862
     863int owl_variable_set_int(owl_variable *v, int newval)
     864{
     865  g_return_val_if_fail(v->type == OWL_VARIABLE_INT, -1);
     866
     867  set_int_t cb = (set_int_t) v->set_fn;
     868  return cb(v, newval);
     869}
     870
     871int owl_variable_set_bool(owl_variable *v, bool newval) {
     872  g_return_val_if_fail(v->type == OWL_VARIABLE_BOOL, -1);
     873
     874  set_bool_t cb = (set_bool_t) v->set_fn;
     875  return cb(v, newval);
     876}
     877
     878int owl_variable_set_bool_on(owl_variable *v)
     879{
     880  if (v->type != OWL_VARIABLE_BOOL) return -1;
     881  return owl_variable_set_bool(v, true);
     882}
     883
     884int owl_variable_set_bool_off(owl_variable *v)
     885{
     886  if (v->type != OWL_VARIABLE_BOOL) return -1;
     887  return owl_variable_set_bool(v, false);
     888}
     889
     890CALLER_OWN char *owl_variable_get_tostring(const owl_variable *v)
     891{
     892  GValue instance = G_VALUE_INIT;
     893  GValue tostring_box = G_VALUE_INIT;
     894  char *ret = NULL;
     895
     896  g_value_init(&instance, G_TYPE_POINTER);
     897  g_value_set_pointer(&instance, NULL);
     898  g_value_init(&tostring_box, G_TYPE_STRING);
     899  g_closure_invoke(v->get_tostring_fn, &tostring_box, 1, &instance, NULL);
     900
     901  ret = g_value_dup_string(&tostring_box);
     902
     903  g_value_unset(&tostring_box);
     904  g_value_unset(&instance);
     905  return ret;
     906}
     907
     908const char *owl_variable_get_default_tostring(const owl_variable *v)
     909{
     910  return v->default_str;
     911}
     912
     913owl_variable *owl_variable_get_var(const owl_vardict *d, const char *name)
     914{
     915  return owl_dict_find_element(d, name);
     916}
     917
     918const char *owl_variable_get_string(const owl_variable *v)
     919{
     920  g_return_val_if_fail(v->type == OWL_VARIABLE_STRING, NULL);
     921
     922  get_string_t cb = (get_string_t) v->get_fn;
     923  return cb(v);
     924}
     925
     926int owl_variable_get_int(const owl_variable *v)
     927{
     928  g_return_val_if_fail(v->type == OWL_VARIABLE_INT, 0);
     929
     930  get_int_t cb = (get_int_t) v->get_fn;
     931  return cb(v);
     932}
     933
     934bool owl_variable_get_bool(const owl_variable *v)
     935{
     936  g_return_val_if_fail(v->type == OWL_VARIABLE_BOOL, FALSE);
     937
     938  get_bool_t cb = (get_bool_t) v->get_fn;
     939  return cb(v);
     940}
     941
     942void owl_variable_describe(const owl_variable *v, owl_fmtext *fm)
     943{
     944  const char *default_str = owl_variable_get_default_tostring(v);
     945  char *default_buf;
     946
     947  if (default_str)
     948    default_buf = g_strdup_printf("'%s'", default_str);
     949  else
     950    default_buf = g_strdup("<null>");
     951  owl_fmtext_appendf_normal(fm, OWL_TABSTR "%-20s - %s (default: %s)\n",
     952                            owl_variable_get_name(v),
     953                            owl_variable_get_summary(v), default_buf);
     954  g_free(default_buf);
     955}
     956
     957void owl_variable_get_help(const owl_variable *v, owl_fmtext *fm) {
    751958  char *tostring;
    752   if (!name) return(-1);
    753   v = owl_dict_find_element(d, name);
    754   if (v == NULL) {
    755     if (msg) owl_function_error("Unknown variable %s", name);
    756     return -1;
    757   }
    758   if (!v->set_fromstring_fn) {
    759     if (msg) owl_function_error("Variable %s is read-only", name);
    760     return -1;   
    761   }
    762   if (requirebool && v->type!=OWL_VARIABLE_BOOL) {
    763     if (msg) owl_function_error("Variable %s is not a boolean", name);
    764     return -1;   
    765   }
    766   if (0 != v->set_fromstring_fn(v, value)) {
    767     if (msg) owl_function_error("Unable to set %s (must be %s)", name,
    768                                   owl_variable_get_validsettings(v));
    769     return -1;
    770   }
    771   if (msg && v->get_tostring_fn) {
    772     tostring = v->get_tostring_fn(v, v->get_fn(v));
    773     owl_function_makemsg("%s = '%s'", name, tostring);
    774     g_free(tostring);
    775   }   
    776   return 0;
    777 }
    778  
    779 int owl_variable_set_string(owl_vardict *d, const char *name, const char *newval) {
    780   owl_variable *v;
    781   if (!name) return(-1);
    782   v = owl_dict_find_element(d, name);
    783   if (v == NULL || !v->set_fn) return(-1);
    784   if (v->type!=OWL_VARIABLE_STRING) return(-1);
    785   return v->set_fn(v, newval);
    786 }
    787  
    788 int owl_variable_set_int(owl_vardict *d, const char *name, int newval) {
    789   owl_variable *v;
    790   if (!name) return(-1);
    791   v = owl_dict_find_element(d, name);
    792   if (v == NULL || !v->set_fn) return(-1);
    793   if (v->type!=OWL_VARIABLE_INT && v->type!=OWL_VARIABLE_BOOL) return(-1);
    794   return v->set_fn(v, &newval);
    795 }
    796  
    797 int owl_variable_set_bool_on(owl_vardict *d, const char *name) {
    798   return owl_variable_set_int(d,name,1);
    799 }
    800 
    801 int owl_variable_set_bool_off(owl_vardict *d, const char *name) {
    802   return owl_variable_set_int(d,name,0);
    803 }
    804 
    805 char *owl_variable_get_tostring(const owl_vardict *d, const char *name) {
    806   owl_variable *v;
    807   if (!name) return NULL;
    808   v = owl_dict_find_element(d, name);
    809   if (v == NULL || !v->get_tostring_fn) return NULL;
    810   return v->get_tostring_fn(v, v->get_fn(v));
    811 }
    812 
    813 char *owl_variable_get_default_tostring(const owl_vardict *d, const char *name) {
    814   owl_variable *v;
    815   if (!name) return NULL;
    816   v = owl_dict_find_element(d, name);
    817   if (v == NULL || !v->get_tostring_fn) return NULL;
    818   if (v->type == OWL_VARIABLE_INT || v->type == OWL_VARIABLE_BOOL) {
    819     return v->get_tostring_fn(v, &(v->ival_default));
    820   } else {
    821     return v->get_tostring_fn(v, v->pval_default);
    822   }
    823 }
    824 
    825 owl_variable *owl_variable_get_var(const owl_vardict *d, const char *name, int require_type) {
    826   owl_variable *v;
    827   if (!name) return(NULL);
    828   v = owl_dict_find_element(d, name);
    829   if (v == NULL || !v->get_fn || v->type != require_type) return(NULL);
    830   return v;
    831 }
    832 
    833 /* returns a reference */
    834 const void *owl_variable_get(const owl_vardict *d, const char *name, int require_type) {
    835   owl_variable *v = owl_variable_get_var(d, name, require_type);
    836   if(v == NULL) return NULL;
    837   return v->get_fn(v);
    838 }
    839 
    840 /* returns a reference */
    841 const char *owl_variable_get_string(const owl_vardict *d, const char *name) {
    842   return owl_variable_get(d,name, OWL_VARIABLE_STRING);
    843 }
    844 
    845 /* returns a reference */
    846 const void *owl_variable_get_other(const owl_vardict *d, const char *name) {
    847   return owl_variable_get(d,name, OWL_VARIABLE_OTHER);
    848 }
    849 
    850 int owl_variable_get_int(const owl_vardict *d, const char *name) {
    851   const int *pi;
    852   pi = owl_variable_get(d,name,OWL_VARIABLE_INT);
    853   if (!pi) return(-1);
    854   return(*pi);
    855 }
    856 
    857 int owl_variable_get_bool(const owl_vardict *d, const char *name) {
    858   const int *pi;
    859   pi = owl_variable_get(d,name,OWL_VARIABLE_BOOL);
    860   if (!pi) return(-1);
    861   return(*pi);
    862 }
    863 
    864 void owl_variable_describe(const owl_vardict *d, const char *name, owl_fmtext *fm) {
    865   char *default_buf;
    866   owl_variable *v;
    867 
    868   if (!name
    869       || (v = owl_dict_find_element(d, name)) == NULL
    870       || !v->get_fn) {
    871     owl_fmtext_appendf_normal(fm, "     No such variable '%s'\n", name);
    872     return;
    873   }
    874   if (v->type == OWL_VARIABLE_INT || v->type == OWL_VARIABLE_BOOL) {
    875     default_buf = v->get_tostring_fn(v, &(v->ival_default));
    876   } else {
    877     default_buf = v->get_tostring_fn(v, v->pval_default);
    878   }
    879   owl_fmtext_appendf_normal(fm, OWL_TABSTR "%-20s - %s (default: '%s')\n",
    880                             v->name,
    881                             owl_variable_get_summary(v), default_buf);
    882   g_free(default_buf);
    883 }
    884 
    885 void owl_variable_get_help(const owl_vardict *d, const char *name, owl_fmtext *fm) {
    886   char *tostring;
    887   owl_variable *v;
    888 
    889   if (!name
    890       || (v = owl_dict_find_element(d, name)) == NULL
    891       || !v->get_fn) {
    892     owl_fmtext_append_normal(fm, "No such variable...\n");
    893     return;
    894   }
     959  const char *default_str;
    895960
    896961  owl_fmtext_append_bold(fm, "OWL VARIABLE\n\n");
    897962  owl_fmtext_append_normal(fm, OWL_TABSTR);
    898   owl_fmtext_append_normal(fm, name);
     963  owl_fmtext_append_normal(fm, owl_variable_get_name(v));
    899964  owl_fmtext_append_normal(fm, " - ");
    900   owl_fmtext_append_normal(fm, v->summary);
     965  owl_fmtext_append_normal(fm, owl_variable_get_summary(v));
    901966  owl_fmtext_append_normal(fm, "\n\n");
    902967
    903968  owl_fmtext_append_normal(fm, "Current:        ");
    904   tostring = owl_variable_get_tostring(d, name);
    905   owl_fmtext_append_normal(fm, tostring);
     969  tostring = owl_variable_get_tostring(v);
     970  owl_fmtext_append_normal(fm, (tostring ? tostring : "<null>"));
    906971  g_free(tostring);
    907972  owl_fmtext_append_normal(fm, "\n\n");
    908973
    909 
    910   if (v->type == OWL_VARIABLE_INT || v->type == OWL_VARIABLE_BOOL) {
    911     tostring = v->get_tostring_fn(v, &(v->ival_default));
    912   } else {
    913     tostring = v->get_tostring_fn(v, v->pval_default);
    914   }
     974  default_str = owl_variable_get_default_tostring(v);
    915975  owl_fmtext_append_normal(fm, "Default:        ");
    916   owl_fmtext_append_normal(fm, tostring);
     976  owl_fmtext_append_normal(fm, (default_str ? default_str : "<null>"));
    917977  owl_fmtext_append_normal(fm, "\n\n");
    918978
     
    926986    owl_fmtext_append_normal(fm, "\n\n");
    927987  }
    928   g_free(tostring);
    929988}
    930989
     
    938997/* default common functions */
    939998
    940 const void *owl_variable_get_default(const owl_variable *v) {
    941   return v->val;
    942 }
    943 
    944 void owl_variable_delete_default(owl_variable *v)
    945 {
    946   g_free(v->val);
     999const char *owl_variable_string_get_default(const owl_variable *v) {
     1000  return g_value_get_string(&(v->val));
     1001}
     1002
     1003int owl_variable_int_get_default(const owl_variable *v) {
     1004  return g_value_get_int(&(v->val));
     1005}
     1006
     1007bool owl_variable_bool_get_default(const owl_variable *v) {
     1008  return g_value_get_boolean(&(v->val));
    9471009}
    9481010
    9491011/* default functions for booleans */
    9501012
    951 int owl_variable_bool_validate_default(const owl_variable *v, const void *newval) {
    952   if (newval == NULL) return(0);
    953   else if (*(const int*)newval==1 || *(const int*)newval==0) return(1);
    954   else return (0);
    955 }
    956 
    957 int owl_variable_bool_set_default(owl_variable *v, const void *newval) {
    958   if (v->validate_fn) {
    959     if (!v->validate_fn(v, newval)) return(-1);
     1013int owl_variable_bool_validate_default(const owl_variable *v, bool newval) {
     1014  return (newval == 1) || (newval == 0);
     1015}
     1016
     1017int owl_variable_bool_set_default(owl_variable *v, bool newval) {
     1018  if (!((validate_bool_t)v->validate_fn)(v, newval))
     1019    return -1;
     1020
     1021  g_value_set_boolean(&(v->val), newval);
     1022  return(0);
     1023}
     1024
     1025int owl_variable_bool_set_fromstring_default(owl_variable *v, const char *newval, void *dummy) {
     1026  bool i;
     1027  if (!strcmp(newval, "on")) {
     1028    i = true;
     1029  } else if (!strcmp(newval, "off")) {
     1030    i = false;
     1031  } else {
     1032    return(-1);
    9601033  }
    961   *(int*)v->val = *(const int*)newval;
    962   return(0);
    963 }
    964 
    965 int owl_variable_bool_set_fromstring_default(owl_variable *v, const char *newval) {
    966   int i;
    967   if (!strcmp(newval, "on")) i=1;
    968   else if (!strcmp(newval, "off")) i=0;
    969   else return(-1);
    970   return (v->set_fn(v, &i));
    971 }
    972 
    973 char *owl_variable_bool_get_tostring_default(const owl_variable *v, const void *val) {
    974   if (val == NULL) {
    975     return g_strdup("<null>");
    976   } else if (*(const int*)val == 0) {
     1034
     1035  return owl_variable_set_bool(v, i);
     1036}
     1037
     1038CALLER_OWN char *owl_variable_bool_get_tostring_default(const owl_variable *v, void *dummy)
     1039{
     1040  bool val = owl_variable_get_bool(v);
     1041  if (val == 0) {
    9771042    return g_strdup("off");
    978   } else if (*(const int*)val == 1) {
     1043  } else if (val == 1) {
    9791044    return g_strdup("on");
    9801045  } else {
     
    9851050/* default functions for integers */
    9861051
    987 int owl_variable_int_validate_default(const owl_variable *v, const void *newval) {
    988   if (newval == NULL) return(0);
    989   else return (1);
    990 }
    991 
    992 int owl_variable_int_set_default(owl_variable *v, const void *newval) {
    993   if (v->validate_fn) {
    994     if (!v->validate_fn(v, newval)) return(-1);
    995   }
    996   *(int*)v->val = *(const int*)newval;
     1052int owl_variable_int_validate_default(const owl_variable *v, int newval)
     1053{
     1054  return (1);
     1055}
     1056
     1057int owl_variable_int_set_default(owl_variable *v, int newval) {
     1058  if (!((validate_int_t)v->validate_fn)(v, newval))
     1059    return -1;
     1060
     1061  g_value_set_int(&(v->val), newval);
    9971062  return(0);
    9981063}
    9991064
    1000 int owl_variable_int_set_fromstring_default(owl_variable *v, const char *newval) {
     1065int owl_variable_int_set_fromstring_default(owl_variable *v, const char *newval, void *dummy) {
    10011066  int i;
    10021067  char *ep;
    10031068  i = strtol(newval, &ep, 10);
    10041069  if (*ep || ep==newval) return(-1);
    1005   return (v->set_fn(v, &i));
    1006 }
    1007 
    1008 char *owl_variable_int_get_tostring_default(const owl_variable *v, const void *val) {
    1009   if (val == NULL) {
    1010     return g_strdup("<null>");
    1011   } else {
    1012     return g_strdup_printf("%d", *(const int*)val);
    1013   }
     1070  return owl_variable_set_int(v, i);
     1071}
     1072
     1073CALLER_OWN char *owl_variable_int_get_tostring_default(const owl_variable *v, void *dummy)
     1074{
     1075  return g_strdup_printf("%d", owl_variable_get_int(v));
    10141076}
    10151077
    10161078/* default functions for enums (a variant of integers) */
    10171079
    1018 int owl_variable_enum_validate(const owl_variable *v, const void *newval) { 
     1080int owl_variable_enum_validate(const owl_variable *v, int newval) {
    10191081  char **enums;
    10201082  int nenums, val;
    1021   if (newval == NULL) return(0);
    10221083  enums = g_strsplit_set(v->validsettings, ",", 0);
    10231084  nenums = g_strv_length(enums);
    10241085  g_strfreev(enums);
    1025   val = *(const int*)newval;
     1086  val = newval;
    10261087  if (val < 0 || val >= nenums) {
    10271088    return(0);
     
    10301091}
    10311092
    1032 int owl_variable_enum_set_fromstring(owl_variable *v, const char *newval) {
     1093int owl_variable_enum_set_fromstring(owl_variable *v, const char *newval, void *dummy) {
    10331094  char **enums;
    10341095  int i, val=-1;
     
    10421103  g_strfreev(enums);
    10431104  if (val == -1) return(-1);
    1044   return (v->set_fn(v, &val));
    1045 }
    1046 
    1047 char *owl_variable_enum_get_tostring(const owl_variable *v, const void *val) {
     1105  return owl_variable_set_int(v, val);
     1106}
     1107
     1108CALLER_OWN char *owl_variable_enum_get_tostring(const owl_variable *v, void *dummy)
     1109{
    10481110  char **enums;
    10491111  int nenums, i;
    10501112  char *tostring;
    10511113
    1052   if (val == NULL) {
    1053     return g_strdup("<null>");
    1054   }
    10551114  enums = g_strsplit_set(v->validsettings, ",", 0);
    10561115  nenums = g_strv_length(enums);
    1057   i = *(const int*)val;
     1116  i = owl_variable_get_int(v);
    10581117  if (i<0 || i>=nenums) {
    10591118    g_strfreev(enums);
     
    10671126/* default functions for stringeans */
    10681127
    1069 int owl_variable_string_validate_default(const struct _owl_variable *v, const void *newval) {
     1128int owl_variable_string_validate_default(const owl_variable *v, const char *newval) {
    10701129  if (newval == NULL) return(0);
    10711130  else return (1);
    10721131}
    10731132
    1074 int owl_variable_string_set_default(owl_variable *v, const void *newval) {
    1075   if (v->validate_fn) {
    1076     if (!v->validate_fn(v, newval)) return(-1);
    1077   }
    1078   g_free(v->val);
    1079   v->val = g_strdup(newval);
     1133int owl_variable_string_set_default(owl_variable *v, const char *newval) {
     1134  if (!((validate_string_t)v->validate_fn)(v, newval))
     1135    return -1;
     1136
     1137  g_value_set_string(&(v->val), newval);
    10801138  return(0);
    10811139}
    10821140
    1083 int owl_variable_string_set_fromstring_default(owl_variable *v, const char *newval) {
    1084   return (v->set_fn(v, newval));
    1085 }
    1086 
    1087 char *owl_variable_string_get_tostring_default(const owl_variable *v, const void *val) {
    1088   if (val == NULL) {
    1089     return g_strdup("<null>");
    1090   } else {
    1091     return g_strdup((const char*)val);
    1092   }
    1093 }
    1094 
     1141int owl_variable_string_set_fromstring_default(owl_variable *v, const char *newval, void *dummy)
     1142{
     1143  return owl_variable_set_string(v, newval);
     1144}
     1145
     1146CALLER_OWN char *owl_variable_string_get_tostring_default(const owl_variable *v, void *dummy)
     1147{
     1148  return g_strdup(owl_variable_get_string(v));
     1149}
     1150
  • view.c

    r3b8a563 r219f52c  
    1 #include <stdlib.h>
    21#include "owl.h"
    32
     
    76  v->filter=f;
    87  v->style=s;
    9   owl_messagelist_create(&(v->ml));
     8  v->ml = owl_messagelist_new();
    109  owl_view_recalculate(v);
    1110}
     
    2019{
    2120  if (owl_filter_message_match(v->filter, m)) {
    22     owl_messagelist_append_element(&(v->ml), m);
     21    owl_messagelist_append_element(v->ml, m);
    2322  }
    2423}
     
    3130  int i, j;
    3231  const owl_messagelist *gml;
    33   owl_messagelist *ml;
    3432  owl_message *m;
    3533
    3634  gml=owl_global_get_msglist(&g);
    37   ml=&(v->ml);
    3835
    39   /* nuke the old list */
    40   owl_list_cleanup(&ml->list, NULL);
    41   owl_messagelist_create(&(v->ml));
     36  /* nuke the old list, don't free the messages */
     37  owl_messagelist_delete(v->ml, false);
     38  v->ml = owl_messagelist_new();
    4239
    4340  /* find all the messages we want */
     
    4643    m=owl_messagelist_get_element(gml, i);
    4744    if (owl_filter_message_match(v->filter, m)) {
    48       owl_messagelist_append_element(ml, m);
     45      owl_messagelist_append_element(v->ml, m);
    4946    }
    5047  }
     
    7370owl_message *owl_view_get_element(const owl_view *v, int index)
    7471{
    75   return(owl_messagelist_get_element(&(v->ml), index));
     72  return owl_messagelist_get_element(v->ml, index);
    7673}
    7774
    7875void owl_view_delete_element(owl_view *v, int index)
    7976{
    80   owl_messagelist_delete_element(&(v->ml), index);
     77  owl_messagelist_delete_element(v->ml, index);
    8178}
    8279
    8380void owl_view_undelete_element(owl_view *v, int index)
    8481{
    85   owl_messagelist_undelete_element(&(v->ml), index);
     82  owl_messagelist_undelete_element(v->ml, index);
    8683}
    8784
    8885int owl_view_get_size(const owl_view *v)
    8986{
    90   return(owl_messagelist_get_size(&(v->ml)));
     87  return owl_messagelist_get_size(v->ml);
    9188}
    9289
     
    159156void owl_view_cleanup(owl_view *v)
    160157{
    161   owl_list_cleanup(&v->ml.list, NULL);
     158  owl_messagelist_delete(v->ml, false);
    162159  g_free(v->name);
    163160}
  • viewwin.c

    r4fd211f r7803326  
    1 #include <string.h>
    21#include "owl.h"
    32
     
    1211 * will be used by the viewwin
    1312 */
    14 owl_viewwin *owl_viewwin_new_text(owl_window *win, const char *text)
     13CALLER_OWN owl_viewwin *owl_viewwin_new_text(owl_window *win, const char *text)
    1514{
    1615  owl_viewwin *v = g_new0(owl_viewwin, 1);
     
    3433 * will be used by the viewwin
    3534 */
    36 owl_viewwin *owl_viewwin_new_fmtext(owl_window *win, const owl_fmtext *fmtext)
     35CALLER_OWN owl_viewwin *owl_viewwin_new_fmtext(owl_window *win, const owl_fmtext *fmtext)
    3736{
    3837  char *text;
     
    159158} owl_viewwin_search_data;
    160159
    161 static void owl_viewwin_callback_search(owl_editwin *e)
    162 {
     160static void owl_viewwin_callback_search(owl_editwin *e, bool success)
     161{
     162  if (!success) return;
    163163  int consider_current = false;
    164164  const char *line = owl_editwin_get_text(e);
     
    237237}
    238238
    239 owl_editwin *owl_viewwin_set_typwin_active(owl_viewwin *v, owl_history *hist) {
     239CALLER_OWN owl_editwin *owl_viewwin_set_typwin_active(owl_viewwin *v, owl_history *hist) {
    240240  int lines, cols;
    241241  owl_editwin *cmdline;
  • window.c

    rf97c1a6 r3442788  
    11#include "owl.h"
    2 
    3 #include <assert.h>
    42
    53struct _owl_window { /*noproto*/
     
    399397}
    400398
    401 static owl_window *_get_cursor(void)
    402 {
     399static owl_window *_get_cursor(bool *is_default)
     400{
     401  *is_default = false;
    403402  if (cursor_owner && owl_window_is_realized(cursor_owner))
    404403    return cursor_owner;
     404  *is_default = true;
    405405  if (default_cursor && owl_window_is_realized(default_cursor))
    406406    return default_cursor;
     
    443443}
    444444
     445static bool _owl_window_is_subtree_dirty(owl_window *w)
     446{
     447  owl_window *child;
     448
     449  if (w->dirty)
     450    return true;
     451  for (child = w->child;
     452       child != NULL;
     453       child = child->next) {
     454    if (child->dirty_subtree)
     455      return true;
     456  }
     457  return false;
     458}
     459
    445460static void _owl_window_redraw_subtree(owl_window *w)
    446461{
    447462  FuncOneArg ptr = (FuncOneArg)_owl_window_redraw_subtree;
     463
    448464  if (!w->dirty_subtree)
    449465    return;
     466
    450467  _owl_window_redraw(w);
    451468  owl_window_children_foreach(w, first_arg_only, &ptr);
    452   w->dirty_subtree = 0;
     469
     470  /* Clear the dirty_subtree bit, unless a child doesn't have it
     471   * cleared because we dirtied a window in redraw. Dirtying a
     472   * non-descendant window during a redraw handler is
     473   * discouraged. Redraw will not break, but it is undefined whether
     474   * the dirty is delayed to the next event loop iteration. */
     475  if (_owl_window_is_subtree_dirty(w)) {
     476    owl_function_debugmsg("subtree still dirty after one iteration!");
     477  } else {
     478    w->dirty_subtree = 0;
     479  }
    453480}
    454481
     
    461488  owl_window *cursor;
    462489  owl_window *screen = owl_window_get_screen();
     490  bool default_cursor;
    463491
    464492  if (!screen->dirty_subtree)
     
    466494  _owl_window_redraw_subtree(screen);
    467495  update_panels();
    468   cursor = _get_cursor();
     496  cursor = _get_cursor(&default_cursor);
    469497  if (cursor && cursor->win) {
     498    /* If supported, hide the default cursor. */
     499    curs_set(default_cursor ? 0 : 1);
    470500    /* untouch it to avoid drawing; window should be clean now, but we must
    471501     * clean up in case there was junk left over on a subwin (cleaning up after
     
    569599};
    570600
    571 GSource *owl_window_redraw_source_new(void) {
     601CALLER_OWN GSource *owl_window_redraw_source_new(void)
     602{
    572603  GSource *source;
    573604  source = g_source_new(&redraw_funcs, sizeof(GSource));
  • window.h

    r4cc49bc rfe73d0c  
    55#include <glib-object.h>
    66
    7 #ifdef HAVE_STDBOOL_H
    87#include <stdbool.h>
    9 #else
    10 #ifndef HAVE__BOOL
    11 #define _Bool signed char
    12 #endif
    13 #define bool _Bool
    14 #define false 0
    15 #define true 1
    16 #define __bool_true_false_are_defined 1
    17 #endif  /* HAVE_STDBOOL_H */
    188
    199G_BEGIN_DECLS
  • zbuddylist.c

    rddbbcffa r7ed9bc6  
    33void owl_zbuddylist_create(owl_zbuddylist *zb)
    44{
    5   owl_list_create(&(zb->zusers));
     5  zb->zusers = g_ptr_array_new();
    66}
    77
    88int owl_zbuddylist_adduser(owl_zbuddylist *zb, const char *name)
    99{
    10   int i, j;
     10  int i;
    1111  char *user;
    1212
    1313  user=long_zuser(name);
    1414
    15   j=owl_list_get_size(&(zb->zusers));
    16   for (i=0; i<j; i++) {
    17     if (!strcasecmp(user, owl_list_get_element(&(zb->zusers), i))) {
     15  for (i = 0; i < zb->zusers->len; i++) {
     16    if (!strcasecmp(user, zb->zusers->pdata[i])) {
    1817      g_free(user);
    1918      return(-1);
    2019    }
    2120  }
    22   owl_list_append_element(&(zb->zusers), user);
     21  g_ptr_array_add(zb->zusers, user);
    2322  return(0);
    2423}
     
    2625int owl_zbuddylist_deluser(owl_zbuddylist *zb, const char *name)
    2726{
    28   int i, j;
    29   char *user, *ptr;
     27  int i;
     28  char *user;
    3029
    3130  user=long_zuser(name);
    3231
    33   j=owl_list_get_size(&(zb->zusers));
    34   for (i=0; i<j; i++) {
    35     ptr=owl_list_get_element(&(zb->zusers), i);
    36     if (!strcasecmp(user, ptr)) {
    37       owl_list_remove_element(&(zb->zusers), i);
    38       g_free(ptr);
     32  for (i = 0; i < zb->zusers->len; i++) {
     33    if (!strcasecmp(user, zb->zusers->pdata[i])) {
     34      g_free(g_ptr_array_remove_index(zb->zusers, i));
    3935      g_free(user);
    4036      return(0);
     
    4743int owl_zbuddylist_contains_user(const owl_zbuddylist *zb, const char *name)
    4844{
    49   int i, j;
     45  int i;
    5046  char *user;
    5147
    5248  user=long_zuser(name);
    5349
    54   j=owl_list_get_size(&(zb->zusers));
    55   for (i=0; i<j; i++) {
    56     if (!strcasecmp(user, owl_list_get_element(&(zb->zusers), i))) {
     50  for (i = 0; i < zb->zusers->len; i++) {
     51    if (!strcasecmp(user, zb->zusers->pdata[i])) {
    5752      g_free(user);
    5853      return(1);
  • zcrypt.c

    r7f86e3d r8f335a8  
    1616#include <sys/wait.h>
    1717#include <ctype.h>
    18 
    19 #include "config.h"
     18#include <limits.h>
     19#include <getopt.h>
     20
     21#include <config.h>
    2022
    2123#ifdef HAVE_KERBEROS_IV
     
    2628
    2729#include "filterproc.h"
     30
     31#ifndef OWL_VERSION_STRING
     32#ifdef  GIT_VERSION
     33#define stringify(x)       __stringify(x)
     34#define __stringify(x)     #x
     35#define OWL_VERSION_STRING stringify(GIT_VERSION)
     36#else
     37#define OWL_VERSION_STRING PACKAGE_VERSION
     38#endif
     39#endif /* !OWL_VERSION_STRING */
     40
     41/* Annotate functions in which the caller owns the return value and is
     42 * responsible for ensuring it is freed. */
     43#define CALLER_OWN G_GNUC_WARN_UNUSED_RESULT
    2844
    2945#define MAX_KEY      128
     
    5369} ZWRITEOPTIONS;
    5470
    55 char *GetZephyrVarKeyFile(const char *whoami, const char *class, const char *instance);
     71CALLER_OWN char *GetZephyrVarKeyFile(const char *whoami, const char *class, const char *instance);
    5672int ParseCryptSpec(const char *spec, const char **keyfile);
    57 char *BuildArgString(char **argv, int start, int end);
    58 char *read_keystring(const char *keyfile);
     73CALLER_OWN char *BuildArgString(char **argv, int start, int end);
     74CALLER_OWN char *read_keystring(const char *keyfile);
    5975
    6076int do_encrypt(int zephyr, const char *class, const char *instance,
     
    100116  des_string_to_key(keystring, key);
    101117  des_key_sched(key, *schedule);
     118}
     119
     120void usage(FILE *file, const char *progname)
     121{
     122  fprintf(file, "Usage: %s [-Z|-D|-E|-R|-S] [-F Keyfile] [-c class] [-i instance]\n", progname);
     123  fprintf(file, "       [-advqtluon] [-s signature] [-f arg] [-m message]\n");
     124  fprintf(file, "  One or more of class, instance, and keyfile must be specified.\n");
    102125}
    103126
     
    112135  int mode = M_NONE;
    113136
    114   char c;
     137  int c;
    115138
    116139  int messageflag = FALSE;
     
    118141  zoptions.flags = 0;
    119142
    120   while ((c = getopt(argc, argv, "ZDERSF:c:i:advqtluons:f:m")) != (char)EOF)
     143  enum {
     144    OPT_VERSION = CHAR_MAX + 1,
     145    OPT_HELP,
     146  };
     147  static const struct option options[] = {
     148    {"version", no_argument, NULL, OPT_VERSION},
     149    {"help", no_argument, NULL, OPT_HELP},
     150    {NULL, 0, NULL, 0}
     151  };
     152
     153  while ((c = getopt_long(argc, argv, "ZDERSF:c:i:advqtluons:f:m", options, NULL)) != -1)
    121154  {
    122155    switch(c)
    123156    {
     157      case OPT_VERSION:
     158        /* Version */
     159        printf("This is zcrypt version %s\n", OWL_VERSION_STRING);
     160        exit(0);
     161      case OPT_HELP:
     162        /* Help */
     163        usage(stdout, argv[0]);
     164        exit(0);
    124165      case 'Z':
    125166        /* Zephyr encrypt */
     
    253294  if (error || !cryptspec)
    254295  {
    255     fprintf(stderr, "Usage: %s [-Z|-D|-E|-R|-S] [-F Keyfile] [-c class] [-i instance]\n", argv[0]);
    256     fprintf(stderr, "       [-advqtluon] [-s signature] [-f arg] [-m message]\n");
    257     fprintf(stderr, "  One or more of class, instance, and keyfile must be specified.\n");
     296    usage(stderr, argv[0]);
    258297    exit(1);
    259298  }
     
    364403/* Build a space-separated string from argv from elements between start  *
    365404 * and end - 1.  malloc()'s the returned string. */
    366 char *BuildArgString(char **argv, int start, int end)
     405CALLER_OWN char *BuildArgString(char **argv, int start, int end)
    367406{
    368407  int len = 1;
     
    401440#define MAX_SEARCH 3
    402441/* Find the class/instance in the .crypt-table */
    403 char *GetZephyrVarKeyFile(const char *whoami, const char *class, const char *instance)
     442CALLER_OWN char *GetZephyrVarKeyFile(const char *whoami, const char *class, const char *instance)
    404443{
    405444  char *keyfile = NULL;
     
    407446  int length[MAX_SEARCH], i;
    408447  char buffer[MAX_BUFF];
     448  const char *home;
    409449  char *filename;
    410450  char result[MAX_SEARCH][MAX_BUFF];
     
    429469
    430470  /* Open~/.crypt-table */
    431   filename = g_strdup_printf("%s/.crypt-table", getenv("HOME"));
     471  home = getenv("HOME");
     472  if (home == NULL)
     473    home = g_get_home_dir();
     474  filename = g_build_filename(home, ".crypt-table", NULL);
    432475  fsearch = fopen(filename, "r");
    433476  if (fsearch)
     
    579622}
    580623
    581 char *slurp_stdin(int ignoredot, int *length) {
     624CALLER_OWN char *slurp_stdin(int ignoredot, int *length) {
    582625  char *buf;
    583626  char *inptr;
     
    611654}
    612655
    613 char *GetInputBuffer(ZWRITEOPTIONS *zoptions, int *length) {
     656CALLER_OWN char *GetInputBuffer(ZWRITEOPTIONS *zoptions, int *length) {
    614657  char *buf;
    615658
     
    637680}
    638681
    639 char *read_keystring(const char *keyfile) {
     682CALLER_OWN char *read_keystring(const char *keyfile) {
    640683  char *keystring;
    641684  FILE *fkey = fopen(keyfile, "r");
     
    758801    "gpg",
    759802    "--symmetric",
     803    "--no-options",
     804    "--no-default-keyring",
     805    "--keyring", "/dev/null",
     806    "--secret-keyring", "/dev/null",
    760807    "--batch",
    761808    "--quiet",
     
    766813    NULL
    767814  };
    768   err = call_filter("gpg", argv, in, &out, &status);
     815  err = call_filter(argv, in, &out, &status);
    769816  if(err || status) {
    770817    g_free(out);
     
    838885    "gpg",
    839886    "--decrypt",
     887    "--no-options",
     888    "--no-default-keyring",
     889    "--keyring", "/dev/null",
     890    "--secret-keyring", "/dev/null",
    840891    "--batch",
    841892    "--no-use-agent",
     
    849900  if(!in) return FALSE;
    850901
    851   err = call_filter("gpg", argv, in, &out, &status);
     902  err = call_filter(argv, in, &out, &status);
     903  free(in);
    852904  if(err || status) {
    853905    g_free(out);
  • zephyr.c

    rb848e30 r80d7b44  
    1 #include <stdlib.h>
    2 #include <unistd.h>
    3 #include <sys/types.h>
    4 #include <sys/wait.h>
     1#include "owl.h"
     2#include <stdio.h>
    53#include <sys/stat.h>
    6 #include <string.h>
    7 #include "owl.h"
    84
    95#ifdef HAVE_LIBZEPHYR
     
    3329#define HM_SVC_FALLBACK         htons((unsigned short) 2104)
    3430
    35 static char *owl_zephyr_dotfile(const char *name, const char *input)
     31static CALLER_OWN char *owl_zephyr_dotfile(const char *name, const char *input)
    3632{
    3733  if (input != NULL)
    3834    return g_strdup(input);
    3935  else
    40     return g_strdup_printf("%s/%s", owl_global_get_homedir(&g), name);
     36    return g_build_filename(owl_global_get_homedir(&g), name, NULL);
    4137}
    4238
     
    4844  struct sockaddr_in sin;
    4945  ZNotice_t req;
     46  GIOChannel *channel;
    5047
    5148  /*
     
    9188  }
    9289
    93   owl_select_add_io_dispatch(ZGetFD(), OWL_IO_READ|OWL_IO_EXCEPT, &owl_zephyr_finish_initialization, NULL, NULL);
    94 }
    95 
    96 void owl_zephyr_finish_initialization(const owl_io_dispatch *d, void *data) {
     90  channel = g_io_channel_unix_new(ZGetFD());
     91  g_io_add_watch(channel, G_IO_IN | G_IO_ERR | G_IO_HUP,
     92                 &owl_zephyr_finish_initialization, NULL);
     93  g_io_channel_unref(channel);
     94}
     95
     96gboolean owl_zephyr_finish_initialization(GIOChannel *source, GIOCondition condition, void *data) {
    9797  Code_t code;
    9898  char *perl;
    9999  GSource *event_source;
    100100
    101   owl_select_remove_io_dispatch(d);
    102 
    103101  ZClosePort();
    104102
    105103  if ((code = ZInitialize()) != ZERR_NONE) {
    106104    owl_function_error("Initializing Zephyr: %s", error_message(code));
    107     return;
     105    return FALSE;
    108106  }
    109107
    110108  if ((code = ZOpenPort(NULL)) != ZERR_NONE) {
    111109    owl_function_error("Initializing Zephyr: %s", error_message(code));
    112     return;
     110    return FALSE;
    113111  }
    114112
     
    143141  perl = owl_perlconfig_execute("BarnOwl::Zephyr::_zephyr_startup()");
    144142  g_free(perl);
     143  return FALSE;
    145144}
    146145
     
    292291  struct stat statbuff;
    293292
    294   subs = g_new(ZSubscription_t, subSize);
    295293  subsfile = owl_zephyr_dotfile(".zephyr.subs", filename);
    296294
     
    308306  if (!file)
    309307    return -1;
     308
     309  subs = g_new(ZSubscription_t, subSize);
    310310  while (owl_getline(&buffer, file)) {
    311311    if (buffer[0] == '#' || buffer[0] == '\n')
     
    455455}
    456456
    457 void unsuball(void)
     457bool unsuball(void)
    458458{
    459459#if HAVE_LIBZEPHYR
     
    465465    owl_function_error("Zephyr: Cancelling subscriptions: %s",
    466466                       error_message(ret));
    467 #endif
     467  return (ret == ZERR_NONE);
     468#endif
     469  return true;
    468470}
    469471
     
    517519}
    518520
    519 /* return a pointer to the data in the Jth field, (NULL terminated by
    520  * definition).  Caller must free the return.
    521  */
    522 #ifdef HAVE_LIBZEPHYR
    523 char *owl_zephyr_get_field(const ZNotice_t *n, int j)
    524 {
    525   int i, count, save;
    526 
    527   /* If there's no message here, just run along now */
     521#ifdef HAVE_LIBZEPHYR
     522const char *owl_zephyr_first_raw_field(const ZNotice_t *n)
     523{
    528524  if (n->z_message_len == 0)
    529     return(g_strdup(""));
    530 
    531   count=save=0;
    532   for (i=0; i<n->z_message_len; i++) {
    533     if (n->z_message[i]=='\0') {
    534       count++;
    535       if (count==j) {
    536         /* just found the end of the field we're looking for */
    537         return(g_strdup(n->z_message+save));
    538       } else {
    539         save=i+1;
    540       }
    541     }
    542   }
    543   /* catch the last field, which might not be null terminated */
    544   if (count==j-1) {
    545     return g_strndup(n->z_message + save, n->z_message_len - save);
    546   }
    547 
    548   return(g_strdup(""));
    549 }
    550 
    551 char *owl_zephyr_get_field_as_utf8(const ZNotice_t *n, int j)
    552 {
    553   int i, count, save;
    554 
    555   /* If there's no message here, just run along now */
    556   if (n->z_message_len == 0)
    557     return(g_strdup(""));
    558 
    559   count=save=0;
    560   for (i = 0; i < n->z_message_len; i++) {
    561     if (n->z_message[i]=='\0') {
    562       count++;
    563       if (count == j) {
    564         /* just found the end of the field we're looking for */
    565         return(owl_validate_or_convert(n->z_message + save));
    566       } else {
    567         save = i + 1;
    568       }
    569     }
    570   }
    571   /* catch the last field, which might not be null terminated */
    572   if (count == j - 1) {
    573     char *tmp, *out;
    574     tmp = g_strndup(n->z_message + save, n->z_message_len - save);
    575     out = owl_validate_or_convert(tmp);
    576     g_free(tmp);
    577     return out;
    578   }
    579 
    580   return(g_strdup(""));
    581 }
    582 #else
    583 char *owl_zephyr_get_field(void *n, int j)
    584 {
    585   return(g_strdup(""));
    586 }
    587 char *owl_zephyr_get_field_as_utf8(void *n, int j)
    588 {
    589   return owl_zephyr_get_field(n, j);
     525    return NULL;
     526  return n->z_message;
     527}
     528
     529const char *owl_zephyr_next_raw_field(const ZNotice_t *n, const char *f)
     530{
     531  const char *end = n->z_message + n->z_message_len;
     532  f = memchr(f, '\0', end - f);
     533  if (f == NULL)
     534    return NULL;
     535  return f + 1;
     536}
     537
     538const char *owl_zephyr_get_raw_field(const ZNotice_t *n, int j)
     539{
     540  int i;
     541  const char *f;
     542  for (i = 1, f = owl_zephyr_first_raw_field(n); i < j && f != NULL;
     543       i++, f = owl_zephyr_next_raw_field(n, f))
     544    ;
     545  return f;
     546}
     547
     548CALLER_OWN char *owl_zephyr_field(const ZNotice_t *n, const char *f)
     549{
     550  if (f == NULL)
     551    return g_strdup("");
     552  return g_strndup(f, n->z_message + n->z_message_len - f);
     553}
     554
     555CALLER_OWN char *owl_zephyr_field_as_utf8(const ZNotice_t *n, const char *f)
     556{
     557  char *tmp = owl_zephyr_field(n, f);
     558  char *out = owl_validate_or_convert(tmp);
     559  g_free(tmp);
     560  return out;
     561}
     562
     563CALLER_OWN char *owl_zephyr_get_field(const ZNotice_t *n, int j)
     564{
     565  return owl_zephyr_field(n, owl_zephyr_get_raw_field(n, j));
     566}
     567
     568CALLER_OWN char *owl_zephyr_get_field_as_utf8(const ZNotice_t *n, int j)
     569{
     570  return owl_zephyr_field_as_utf8(n, owl_zephyr_get_raw_field(n, j));
     571}
     572#else
     573const char *owl_zephyr_first_raw_field(const void *n)
     574{
     575  return NULL;
     576}
     577
     578const char *owl_zephyr_next_raw_field(const void *n, const char *f)
     579{
     580  return NULL;
     581}
     582
     583const char *owl_zephyr_get_raw_field(const void *n, int j)
     584{
     585  return NULL;
     586}
     587
     588CALLER_OWN char *owl_zephyr_field(const void *n, const char *f)
     589{
     590  return g_strdup("");
     591}
     592
     593CALLER_OWN char *owl_zephyr_field_as_utf8(const void *n, const char *f)
     594{
     595  return g_strdup("");
     596}
     597
     598CALLER_OWN char *owl_zephyr_get_field(const void *n, int j)
     599{
     600  return g_strdup("");
     601}
     602
     603CALLER_OWN char *owl_zephyr_get_field_as_utf8(const void *n, int j)
     604{
     605  return owl_zephyr_field(n, owl_zephyr_get_raw_field(n, j));
    590606}
    591607#endif
     
    595611int owl_zephyr_get_num_fields(const ZNotice_t *n)
    596612{
    597   int i, fields;
    598 
    599   if(n->z_message_len == 0)
    600     return 0;
    601 
    602   fields=1;
    603   for (i=0; i<n->z_message_len; i++) {
    604     if (n->z_message[i]=='\0') fields++;
    605   }
    606  
    607   return(fields);
     613  int i;
     614  const char *f;
     615  for (i = 0, f = owl_zephyr_first_raw_field(n); f != NULL;
     616       i++, f = owl_zephyr_next_raw_field(n, f))
     617    ;
     618  return i;
    608619}
    609620#else
     
    618629 * caller must free the return
    619630 */
    620 char *owl_zephyr_get_message(const ZNotice_t *n, const owl_message *m)
     631CALLER_OWN char *owl_zephyr_get_message(const ZNotice_t *n, const owl_message *m)
    621632{
    622633#define OWL_NFIELDS     5
     
    698709  Code_t ret;
    699710  ZNotice_t notice;
     711  char *zsender = NULL;
    700712   
    701713  memset(&notice, 0, sizeof(notice));
     
    707719  notice.z_kind=ACKED;
    708720  notice.z_port=0;
     721#ifdef ZCHARSET_UTF_8
     722  notice.z_charset = ZCHARSET_UTF_8;
     723#endif
    709724  notice.z_class=zstr(class);
    710725  notice.z_class_inst=zstr(instance);
    711   notice.z_sender=NULL;
    712   if (!strcmp(recipient, "*") || !strcmp(recipient, "@")) {
     726  if (!strcmp(recipient, "@")) {
    713727    notice.z_recipient=zstr("");
    714     if (*owl_global_get_zsender(&g))
    715         notice.z_sender=zstr(owl_global_get_zsender(&g));
    716728  } else {
    717729    notice.z_recipient=zstr(recipient);
    718730  }
    719   notice.z_default_format=zstr("Class $class, Instance $instance:\nTo: @bold($recipient) at $time $date\nFrom: @bold{$1 <$sender>}\n\n$2");
     731  if (!owl_zwrite_recip_is_personal(recipient) && *owl_global_get_zsender(&g))
     732    notice.z_sender = zsender = long_zuser(owl_global_get_zsender(&g));
     733  notice.z_default_format=zstr(ZEPHYR_DEFAULT_FORMAT);
    720734  if (opcode) notice.z_opcode=zstr(opcode);
    721735
     
    730744  /* free then check the return */
    731745  g_free(notice.z_message);
    732   ZFreeNotice(&notice);
     746  g_free(zsender);
    733747  if (ret != ZERR_NONE) {
    734748    owl_function_error("Error sending zephyr: %s", error_message(ret));
     
    790804  } else if (!strcmp(retnotice->z_message, ZSRVACK_NOTSENT)) {
    791805    if (retnotice->z_recipient == NULL
    792         || *retnotice->z_recipient == 0
    793         || *retnotice->z_recipient == '@') {
     806        || !owl_zwrite_recip_is_personal(retnotice->z_recipient)) {
    794807      char *buff;
    795808      owl_function_error("No one subscribed to class %s", retnotice->z_class);
     
    835848      zw.opcode = g_strdup(retnotice->z_opcode);
    836849      zw.zsig   = g_strdup("");
    837       owl_list_create(&(zw.recips));
    838       owl_list_append_element(&(zw.recips), g_strdup(retnotice->z_recipient));
     850      zw.recips = g_ptr_array_new();
     851      g_ptr_array_add(zw.recips, g_strdup(retnotice->z_recipient));
    839852
    840853      owl_log_outgoing_zephyr_error(&zw, buff);
     
    910923  g_free(to);
    911924
    912   z = owl_zwrite_new(tmpbuff);
     925  z = owl_zwrite_new_from_line(tmpbuff);
    913926  g_free(tmpbuff);
    914927  if (z == NULL) {
     
    939952#endif
    940953
    941 char *owl_zephyr_zlocate(const char *user, int auth)
     954CALLER_OWN char *owl_zephyr_zlocate(const char *user, int auth)
    942955{
    943956#ifdef HAVE_LIBZEPHYR
     
    10121025  }
    10131026
     1027  g_free(subsfile);
    10141028  g_free(line);
    10151029#endif
     
    10391053
    10401054/* caller must free the return */
    1041 char *owl_zephyr_makesubline(const char *class, const char *inst, const char *recip)
     1055CALLER_OWN char *owl_zephyr_makesubline(const char *class, const char *inst, const char *recip)
    10421056{
    10431057  return g_strdup_printf("%s,%s,%s\n", class, inst, !strcmp(recip, "") ? "*" : recip);
     
    11191133 * free the return.
    11201134 */
    1121 char *owl_zephyr_getsubs(void)
     1135CALLER_OWN char *owl_zephyr_getsubs(void)
    11221136{
    11231137#ifdef HAVE_LIBZEPHYR
     
    12281242    return -1;
    12291243  ret = ZSetLocation(zstr(exposure));
    1230   if (ret != ZERR_NONE) {
     1244  if (ret != ZERR_NONE
     1245#ifdef ZCONST
     1246      /* Before zephyr 3.0, ZSetLocation had a bug where, if you were subscribed
     1247       * to your own logins, it could wait for the wrong notice and return
     1248       * ZERR_INTERNAL when found neither SERVACK nor SERVNAK. Suppress it when
     1249       * building against the old ABI. */
     1250      && ret != ZERR_INTERNAL
     1251#endif
     1252     ) {
    12311253    owl_function_error("Unable to set exposure level: %s.", error_message(ret));
    12321254    return -1;
     
    12391261 * The caller must free the return
    12401262 */
    1241 char *short_zuser(const char *in)
     1263CALLER_OWN char *short_zuser(const char *in)
    12421264{
    12431265  char *ptr = strrchr(in, '@');
     
    12511273 * The caller must free the return.
    12521274 */
    1253 char *long_zuser(const char *in)
     1275CALLER_OWN char *long_zuser(const char *in)
    12541276{
    12551277  char *ptr = strrchr(in, '@');
     
    12791301 * caller must free the return.
    12801302 */
    1281 char *owl_zephyr_smartstripped_user(const char *in)
     1303CALLER_OWN char *owl_zephyr_smartstripped_user(const char *in)
    12821304{
    12831305  char *slash, *dot, *realm, *out;
     
    13211343}
    13221344
    1323 /* read the list of users in 'filename' as a .anyone file, and put the
    1324  * names of the zephyr users in the list 'in'.  If 'filename' is NULL,
    1325  * use the default .anyone file in the users home directory.  Returns
    1326  * -1 on failure, 0 on success.
     1345/* Read the list of users in 'filename' as a .anyone file, and return as a
     1346 * GPtrArray of strings.  If 'filename' is NULL, use the default .anyone file
     1347 * in the users home directory.  Returns NULL on failure.
    13271348 */
    1328 int owl_zephyr_get_anyone_list(owl_list *in, const char *filename)
     1349GPtrArray *owl_zephyr_get_anyone_list(const char *filename)
    13291350{
    13301351#ifdef HAVE_LIBZEPHYR
    13311352  char *ourfile, *tmp, *s = NULL;
    13321353  FILE *f;
     1354  GPtrArray *list;
    13331355
    13341356  ourfile = owl_zephyr_dotfile(".anyone", filename);
     
    13381360    owl_function_error("Error opening file %s: %s", ourfile, strerror(errno) ? strerror(errno) : "");
    13391361    g_free(ourfile);
    1340     return -1;
     1362    return NULL;
    13411363  }
    13421364  g_free(ourfile);
    13431365
     1366  list = g_ptr_array_new();
    13441367  while (owl_getline_chomp(&s, f)) {
    13451368    /* ignore comments, blank lines etc. */
     
    13571380      tmp[0] = '\0';
    13581381
    1359     owl_list_append_element(in, long_zuser(s));
     1382    g_ptr_array_add(list, long_zuser(s));
    13601383  }
    13611384  g_free(s);
    13621385  fclose(f);
    1363   return 0;
    1364 #else
    1365   return -1;
     1386  return list;
     1387#else
     1388  return NULL;
    13661389#endif
    13671390}
     
    14321455#endif
    14331456
    1434 void owl_zephyr_buddycheck_timer(owl_timer *t, void *data)
     1457gboolean owl_zephyr_buddycheck_timer(void *data)
    14351458{
    14361459  if (owl_global_is_pseudologins(&g)) {
     
    14401463    owl_function_debugmsg("Warning: owl_zephyr_buddycheck_timer call pointless; timer should have been disabled");
    14411464  }
     1465  return TRUE;
    14421466}
    14431467
     
    15101534  event_source = (owl_zephyr_event_source*) source;
    15111535  event_source->poll_fd.fd = fd;
    1512   event_source->poll_fd.events = G_IO_IN | G_IO_HUP | G_IO_PRI | G_IO_ERR;
     1536  event_source->poll_fd.events = G_IO_IN | G_IO_HUP | G_IO_ERR;
    15131537  g_source_add_poll(source, &event_source->poll_fd);
    15141538
  • zwrite.c

    r3b8a563 r919cbf2  
    1 #include <string.h>
    2 #include <pwd.h>
    3 #include <sys/types.h>
    4 #include <unistd.h>
    51#include "owl.h"
    62
    7 owl_zwrite *owl_zwrite_new(const char *line)
     3CALLER_OWN owl_zwrite *owl_zwrite_new_from_line(const char *line)
    84{
    95  owl_zwrite *z = g_new(owl_zwrite, 1);
    10   if (owl_zwrite_create_from_line(z, line) < 0) {
    11     owl_zwrite_delete(z);
     6  if (owl_zwrite_create_from_line(z, line) != 0) {
     7    g_free(z);
    128    return NULL;
    139  }
     
    1511}
    1612
    17 int owl_zwrite_create_from_line(owl_zwrite *z, const char *line)
    18 {
    19   int argc, badargs, myargc;
     13CALLER_OWN owl_zwrite *owl_zwrite_new(int argc, const char *const *argv)
     14{
     15  owl_zwrite *z = g_new(owl_zwrite, 1);
     16  if (owl_zwrite_create(z, argc, argv) != 0) {
     17    g_free(z);
     18    return NULL;
     19  }
     20  return z;
     21}
     22
     23G_GNUC_WARN_UNUSED_RESULT int owl_zwrite_create_from_line(owl_zwrite *z, const char *line)
     24{
     25  int argc;
    2026  char **argv;
    21   const char *const *myargv;
     27  int ret;
     28
     29  /* parse the command line for options */
     30  argv = owl_parseline(line, &argc);
     31  if (argc < 0) {
     32    owl_function_error("Unbalanced quotes in zwrite");
     33    return -1;
     34  }
     35  ret = owl_zwrite_create(z, argc, strs(argv));
     36  g_strfreev(argv);
     37  return ret;
     38}
     39
     40G_GNUC_WARN_UNUSED_RESULT int owl_zwrite_create(owl_zwrite *z, int argc, const char *const *argv)
     41{
     42  int badargs = 0;
    2243  char *msg = NULL;
    23 
    24   badargs=0;
    2544 
    2645  /* start with null entries */
     
    3453  z->cc=0;
    3554  z->noping=0;
    36   owl_list_create(&(z->recips));
    37   z->zwriteline = g_strdup(line);
    38 
    39   /* parse the command line for options */
    40   argv=owl_parseline(line, &argc);
    41   myargv=strs(argv);
    42   if (argc<0) {
    43     owl_function_error("Unbalanced quotes in zwrite");
    44     return(-1);
    45   }
    46   myargc=argc;
    47   if (myargc && *(myargv[0])!='-') {
    48     z->cmd=g_strdup(myargv[0]);
    49     myargc--;
    50     myargv++;
    51   }
    52   while (myargc) {
    53     if (!strcmp(myargv[0], "-c")) {
    54       if (myargc<2) {
    55         badargs=1;
    56         break;
    57       }
    58       z->class=owl_validate_utf8(myargv[1]);
    59       myargv+=2;
    60       myargc-=2;
    61     } else if (!strcmp(myargv[0], "-i")) {
    62       if (myargc<2) {
    63         badargs=1;
    64         break;
    65       }
    66       z->inst=owl_validate_utf8(myargv[1]);
    67       myargv+=2;
    68       myargc-=2;
    69     } else if (!strcmp(myargv[0], "-r")) {
    70       if (myargc<2) {
    71         badargs=1;
    72         break;
    73       }
    74       z->realm=owl_validate_utf8(myargv[1]);
    75       myargv+=2;
    76       myargc-=2;
    77     } else if (!strcmp(myargv[0], "-s")) {
    78       if (myargc<2) {
    79         badargs=1;
    80         break;
    81       }
    82       z->zsig=owl_validate_utf8(myargv[1]);
    83       myargv+=2;
    84       myargc-=2;
    85     } else if (!strcmp(myargv[0], "-O")) {
    86       if (myargc<2) {
    87         badargs=1;
    88         break;
    89       }
    90       z->opcode=owl_validate_utf8(myargv[1]);
    91       myargv+=2;
    92       myargc-=2;
    93     } else if (!strcmp(myargv[0], "-m")) {
    94       if (myargc<2) {
     55  z->recips = g_ptr_array_new();
     56  z->zwriteline = owl_argv_quote(argc, argv);
     57
     58  if (argc && *(argv[0])!='-') {
     59    z->cmd=g_strdup(argv[0]);
     60    argc--;
     61    argv++;
     62  }
     63  while (argc) {
     64    if (!strcmp(argv[0], "-c")) {
     65      if (argc<2) {
     66        badargs=1;
     67        break;
     68      }
     69      z->class=owl_validate_utf8(argv[1]);
     70      argv+=2;
     71      argc-=2;
     72    } else if (!strcmp(argv[0], "-i")) {
     73      if (argc<2) {
     74        badargs=1;
     75        break;
     76      }
     77      z->inst=owl_validate_utf8(argv[1]);
     78      argv+=2;
     79      argc-=2;
     80    } else if (!strcmp(argv[0], "-r")) {
     81      if (argc<2) {
     82        badargs=1;
     83        break;
     84      }
     85      z->realm=owl_validate_utf8(argv[1]);
     86      argv+=2;
     87      argc-=2;
     88    } else if (!strcmp(argv[0], "-s")) {
     89      if (argc<2) {
     90        badargs=1;
     91        break;
     92      }
     93      z->zsig=owl_validate_utf8(argv[1]);
     94      argv+=2;
     95      argc-=2;
     96    } else if (!strcmp(argv[0], "-O")) {
     97      if (argc<2) {
     98        badargs=1;
     99        break;
     100      }
     101      z->opcode=owl_validate_utf8(argv[1]);
     102      argv+=2;
     103      argc-=2;
     104    } else if (!strcmp(argv[0], "-m")) {
     105      if (argc<2) {
    95106        badargs=1;
    96107        break;
    97108      }
    98109      /* we must already have users or a class or an instance */
    99       if (owl_list_get_size(&(z->recips))<1 && (!z->class) && (!z->inst)) {
     110      if (z->recips->len < 1 && (!z->class) && (!z->inst)) {
    100111        badargs=1;
    101112        break;
     
    103114
    104115      /* Once we have -m, gobble up everything else on the line */
    105       myargv++;
    106       myargc--;
    107       msg = g_strjoinv(" ", (char**)myargv);
     116      argv++;
     117      argc--;
     118      msg = g_strjoinv(" ", (char**)argv);
    108119      break;
    109     } else if (!strcmp(myargv[0], "-C")) {
     120    } else if (!strcmp(argv[0], "-C")) {
    110121      z->cc=1;
    111       myargv++;
    112       myargc--;
    113     } else if (!strcmp(myargv[0], "-n")) {
     122      argv++;
     123      argc--;
     124    } else if (!strcmp(argv[0], "-n")) {
    114125      z->noping=1;
    115       myargv++;
    116       myargc--;
     126      argv++;
     127      argc--;
    117128    } else {
    118129      /* anything unattached is a recipient */
    119       owl_list_append_element(&(z->recips), owl_validate_utf8(myargv[0]));
    120       myargv++;
    121       myargc--;
     130      g_ptr_array_add(z->recips, owl_validate_utf8(argv[0]));
     131      argv++;
     132      argc--;
    122133    }
    123134  }
    124135
    125   g_strfreev(argv);
    126 
    127136  if (badargs) {
     137    owl_zwrite_cleanup(z);
    128138    return(-1);
    129139  }
     
    131141  if (z->class == NULL &&
    132142      z->inst == NULL &&
    133       owl_list_get_size(&(z->recips))==0) {
     143      z->recips->len == 0) {
    134144    owl_function_error("You must specify a recipient for zwrite");
     145    owl_zwrite_cleanup(z);
    135146    return(-1);
    136147  }
     
    162173void owl_zwrite_send_ping(const owl_zwrite *z)
    163174{
    164   int i, j;
     175  int i;
    165176  char *to;
    166177
     
    171182  }
    172183
    173   /* if there are no recipients we won't send a ping, which
    174      is what we want */
    175   j=owl_list_get_size(&(z->recips));
    176   for (i=0; i<j; i++) {
     184  for (i = 0; i < z->recips->len; i++) {
    177185    to = owl_zwrite_get_recip_n_with_realm(z, i);
    178     send_ping(to, z->class, z->inst);
     186    if (owl_zwrite_recip_is_personal(to))
     187      send_ping(to, z->class, z->inst);
    179188    g_free(to);
    180189  }
     
    191200void owl_zwrite_set_message(owl_zwrite *z, const char *msg)
    192201{
    193   int i, j;
     202  int i;
    194203  GString *message;
    195204  char *tmp = NULL, *tmp2;
     
    197206  g_free(z->message);
    198207
    199   j=owl_list_get_size(&(z->recips));
    200   if (j>0 && z->cc) {
     208  if (z->cc && owl_zwrite_is_personal(z)) {
    201209    message = g_string_new("CC: ");
    202     for (i=0; i<j; i++) {
     210    for (i = 0; i < z->recips->len; i++) {
    203211      tmp = owl_zwrite_get_recip_n_with_realm(z, i);
    204212      g_string_append_printf(message, "%s ", tmp);
     
    233241int owl_zwrite_send_message(const owl_zwrite *z)
    234242{
    235   int i, j, ret = 0;
     243  int i, ret = 0;
    236244  char *to = NULL;
    237245
    238246  if (z->message==NULL) return(-1);
    239247
    240   j=owl_list_get_size(&(z->recips));
    241   if (j>0) {
    242     for (i=0; i<j; i++) {
     248  if (z->recips->len > 0) {
     249    for (i = 0; i < z->recips->len; i++) {
    243250      to = owl_zwrite_get_recip_n_with_realm(z, i);
    244251      ret = send_zephyr(z->opcode, z->zsig, z->class, z->inst, to, z->message);
     
    261268  owl_zwrite z;
    262269  int rv;
    263   rv=owl_zwrite_create_from_line(&z, cmd);
    264   if (rv) return(rv);
     270  rv = owl_zwrite_create_from_line(&z, cmd);
     271  if (rv != 0) return rv;
    265272  if (!owl_zwrite_is_message_set(&z)) {
    266273    owl_zwrite_set_message(&z, msg);
     
    312319int owl_zwrite_get_numrecips(const owl_zwrite *z)
    313320{
    314   return(owl_list_get_size(&(z->recips)));
     321  return z->recips->len;
    315322}
    316323
    317324const char *owl_zwrite_get_recip_n(const owl_zwrite *z, int n)
    318325{
    319   return(owl_list_get_element(&(z->recips), n));
     326  return z->recips->pdata[n];
    320327}
    321328
    322329/* Caller must free the result. */
    323 char *owl_zwrite_get_recip_n_with_realm(const owl_zwrite *z, int n)
     330CALLER_OWN char *owl_zwrite_get_recip_n_with_realm(const owl_zwrite *z, int n)
    324331{
    325332  if (z->realm[0]) {
     
    330337}
    331338
    332 int owl_zwrite_is_personal(const owl_zwrite *z)
     339bool owl_zwrite_recip_is_personal(const char *recipient)
     340{
     341  return recipient[0] && recipient[0] != '@';
     342}
     343
     344bool owl_zwrite_is_personal(const owl_zwrite *z)
    333345{
    334346  /* return true if at least one of the recipients is personal */
    335   int i, j;
    336   char *foo;
    337 
    338   j=owl_list_get_size(&(z->recips));
    339   for (i=0; i<j; i++) {
    340     foo=owl_list_get_element(&(z->recips), i);
    341     if (foo[0]!='@') return(1);
    342   }
    343   return(0);
     347  int i;
     348
     349  for (i = 0; i < z->recips->len; i++)
     350    if (owl_zwrite_recip_is_personal(z->recips->pdata[i]))
     351      return true;
     352  return false;
    344353}
    345354
     
    352361void owl_zwrite_cleanup(owl_zwrite *z)
    353362{
    354   owl_list_cleanup(&(z->recips), &g_free);
     363  owl_ptr_array_free(z->recips, g_free);
    355364  g_free(z->cmd);
    356365  g_free(z->zwriteline);
     
    370379 * If not a CC, only the recip_index'th user will be replied to.
    371380 */
    372 char *owl_zwrite_get_replyline(const owl_zwrite *z, int recip_index)
     381CALLER_OWN char *owl_zwrite_get_replyline(const owl_zwrite *z, int recip_index)
    373382{
    374383  /* Match ordering in zwrite help. */
     
    403412  }
    404413  if (z->cc) {
    405     for (i = 0; i < owl_list_get_size(&(z->recips)); i++) {
     414    for (i = 0; i < z->recips->len; i++) {
    406415      g_string_append_c(buf, ' ');
    407       owl_string_append_quoted_arg(buf, owl_list_get_element(&(z->recips), i));
     416      owl_string_append_quoted_arg(buf, z->recips->pdata[i]);
    408417    }
    409   } else if (recip_index < owl_list_get_size(&(z->recips))) {
     418  } else if (recip_index < z->recips->len) {
    410419    g_string_append_c(buf, ' ');
    411     owl_string_append_quoted_arg(buf, owl_list_get_element(&(z->recips), recip_index));
     420    owl_string_append_quoted_arg(buf, z->recips->pdata[recip_index]);
    412421  }
    413422
Note: See TracChangeset for help on using the changeset viewer.