Changes in / [416a7e5:7aa6811]


Ignore:
Files:
8 added
47 deleted
61 edited

Legend:

Unmodified
Added
Removed
  • .gitignore

    r1c22155 r7834bb5  
     1# Generated by autoreconf
     2Makefile.in
     3/aclocal.m4
     4/autom4te.cache/
     5/compile
     6/config.h.in
     7/config.h.in~
     8/configure
     9/depcomp
     10/install-sh
     11/missing
     12/test-driver
     13
     14# Generated by configure
     15Makefile
     16.deps/
     17/config.cache
     18/config.h
     19/config.log
     20/config.status
     21/stamp-h1
     22
     23# Generated by make
     24*.o
    125*.a
    2 *.o
    3 *.par
    4 .deps
     26/BUILD_VERSION.mk
     27/barnowl
    528/bin/
    6 META.yml
    7 MYMETA.yml
    8 Makefile
    9 Makefile.in
    10 Makefile.old
     29/gmarshal_funcs.c
     30/gmarshal_funcs.h
     31/owl_prototypes.h
     32/owl_prototypes.h.new
     33/perlglue.c
     34/varstubs.c
     35/version.c
     36/version.c.new
     37/zcrypt
     38
     39# Generated by make check
     40/runtests.sh.log
     41/runtests.sh.trs
     42/test-suite.log
     43/tester
     44
     45# Generated by make tags et al.
     46ID
    1147TAGS
    12 aclocal.m4
    13 autom4te.cache
    14 barnowl
    15 blib
    16 config.cache
    17 config.h
    18 config.h.in
    19 config.h.in~
    20 config.log
    21 config.status
    22 configure
    23 core
    24 depcomp
    25 gmarshal_funcs.c
    26 gmarshal_funcs.h
    27 inc/
    28 install-sh
    29 jabber.log
    30 missing
    31 owl_prototypes.h
    32 owl_prototypes.h.new
    33 perlglue.c
    34 pm_to_blib
    35 runtests.sh.log
    36 runtests.sh.trs
    37 stamp-h1
    38 test-driver
    39 test-suite.log
    40 tester
    41 varstubs.c
    42 zcrypt
     48tags
     49/GPATH
     50/GRTAGS
     51/GSYMS
     52/GTAGS
     53/cscope.files
     54/cscope.in.out
     55/cscope.out
     56/cscope.po.out
  • .travis.yml

    r48c09d4 rbecd617  
    11language: perl
     2sudo: false
    23compiler:
    34  - clang
     
    910  - "5.16"
    1011  - "5.18"
    11   - "5.19"
    12 install:
    13   - sudo apt-get update -q
    14 # we actually want debhelper >= 7, libperl-dev >= 5.10.1-8, libzephyr-dev >= 3.0~beta
    15   - sudo apt-get install -q autoconf autotools-dev debhelper dh-autoreconf libglib2.0-dev libkrb5-dev libncurses5-dev libncursesw5-dev libssl-dev libzephyr-dev pkg-config zip
     12  - "5.20"
     13addons:
     14  apt:
     15    # we actually want debhelper >= 7, libperl-dev >= 5.10.1-8, libzephyr-dev >= 3.0~beta
     16    packages:
     17    - autoconf
     18    - autotools-dev
     19    - debhelper
     20    - dh-autoreconf
     21    - libglib2.0-dev
     22    - libkrb5-dev
     23    - libncurses5-dev
     24    - libncursesw5-dev
     25    - libssl-dev
     26    - libzephyr-dev
     27    - pkg-config
     28    - zip
    1629# perl things
    1730# In lp:~barnowl/barnowl/packaging, we use apt-get.  Here, we use cpanm.
    1831#  - sudo apt-get install libanyevent-perl libclass-accessor-perl libextutils-depends-perl libglib-perl libmodule-install-perl libnet-twitter-lite-perl libpar-perl libperl-dev
    19   - cpanm AnyEvent Class::Accessor ExtUtils::Depends Glib Module::Install Net::Twitter::Lite PAR
    20 script: "./autogen.sh && ./configure && make distcheck"
     32# It's taken care of by the default install script
     33script: ./autogen.sh && ./configure && make distcheck
  • ChangeLog

    r1b17f50 r678a7650  
     11.10
     2 * No changes above what's already in 1.10rc1
     3
     41.10rc1
     5 * Numerous autotools/build machinery fixes -andersk@mit.edu
     6 * Numerous code correctness and simplification/cleanup fixes -andersk@mit.edu
     7 * Add and use a cpanfile documenting perl module dependencies -jgross@mit.edu
     8 * Add Travis configuration -jgross@mit.edu
     9 * Avoid strchrnul -andersk@mit.edu
     10 * Numerous IRC fixes -jgross@mit.edu
     11 * Improve smartnarrow and smartfilter documentation -jgross@mit.edu
     12 * filterproc: Rewrite using GIOChannel -andersk@mit.edu
     13 * Implement :twitter-favorite -nelhage@nelhage.com
     14 * Kill the client-side tweet length check. -nelhage@nelhage.com
     15 * squelch the Twitter legacy_list_api warnings -nelhage@nelhage.com
     16 * Use SSL for Twitter by default -adehnert@mit.edu
     17 * Humanize zsigs -andersk@mit.edu
     18 * Show Zephyr charset in info popup -andersk@mit.edu
     19 * Fix Jabber SRV record support (at one point fixed connecting via jabber to google talk or facebook) -james2vegas@aim.com
     20 * fix cmd_join in BarnOwl/Module/IRC.pm -james2vegas@aim.com
     21 * Add a ~/.owl/ircchannels file, persist channels -jgross@mit.edu
     22 * Added hooks for user going idle or active. -jgross@mit.edu
     23 * Support channel-or-user IRC commands, and setup irc-msg to use it. -ezyang@mit.edu
     24 * Refactor perl calls through a single method -jgross@mit.edu
     25 * Really support building Perl modules from a separate builddir -andersk@mit.edu
     26 * Get rid of all our embedded copies of Module::Install -andersk@mit.edu
     27 * Don't let new_variable_* overriding previously set values -rnjacobs@mit.edu
     28 * Messages sent to 'class messages' are not personal -jgross@mit.edu
     29 * Expose message_matches_filter to perl -jgross@mit.edu
     30 * Fail fast on -c filsrv, which most people won't have permission to send to -rnjacobs@mit.edu
     31 * zcrypt: Use getopt_long for argument parsing -andersk@mit.edu
     32 * zcrypt: Accept -help and --version -andersk@mit.edu
     33 * barnowl --help: Write to stdout and exit successfully -andersk@mit.edu
     34 * Don't swallow errors in :unsuball -davidben@mit.edu
     35 * Allow testing in a separate build directory -andersk@mit.edu
     36 * Add support for arbitrary Perl subs for getters and setters for barnowl variables -glasgall@mit.edu
     37 * owl_zephyr_loadsubs: Don’t leak memory on error opening ~/.zephyr.subs -andersk@mit.edu
     38 * Make :loadsubs reload instanced personals too -davidben@mit.edu
     39 * Fix some undefined behavior in filter.c, caught by clang scan-build -jgross@mit.edu
     40 * Die on a failed zephyr_zwrite; don't silently ignore it -jgross@mit.edu
     41 * Fix a memory leak in zcrypt.c, caught by clang scan-build -jgross@mit.edu
     42 * zcrypt: Make gpg stop messing around in ~/.gnupg -andersk@mit.edu
     43 * Fix display of pseudologins -davidben@mit.edu
     44 * Unbundle random Facebook module libraries -davidben@mit.edu
     45 * Replace deprecated GLib < 2.31.0 APIs -andersk@mit.edu
     46 * Abstract g->interrupt_lock -andersk@mit.edu
     47 * zephyr: Replace outgoing default format with a small URL -geofft@mit.edu
     48
    1491.9
     50 * Update Jabber module for Net::DNS changes -james2vegas@aim.com
     51 * Update and make configurable the Zephyr default format -adehnert@mit.edu
     52 * Fix a crash when zcrypt fails -andersk@mit.edu
     53 * Fix building with OpenSSL before 0.9.8 -andersk@mit.edu
     54 * Make :loadsubs reload instanced personals too -davidben@mit.edu
     55 * Make Perl zephyr_zwrite call die() when it fails -jgross@mit.edu
     56 * Tell gpg calls from zcrypt to ignore ~/.gnupg -andersk@mit.edu
     57 * Replace outgoing zephyr default format with a small URL -geofft@mit.edu
    258 * Add getnumlines() to perl interface -asedeno@mit.edu
    359 * Include names of invalid filters on filter errors -adehnert@mit.edu
     
    321377 * Support --program-{prefix,suffix,transform}. -nelhage
    322378 * Send instanced pings and give useful error messages -adehnert
    323  * Add <message,*,%me%> to default Barnowl subs. -adehnert
     379 * Add <message,*,%me%> to default BarnOwl subs. -adehnert
    324380 * Maintain instance when using shift-R on personals -adehnert
    325381 * Improve handling of outgoing instanced personals -adehnert
  • Makefile.am

    ra223b6b r4fd3c04  
    11ACLOCAL_AMFLAGS = -I m4
    22
    3 GIT_DESCRIPTION := $(if $(wildcard .git),$(shell git describe --match='barnowl-*' HEAD 2>/dev/null))
    4 GIT_FLAGS := $(if $(GIT_DESCRIPTION),-DGIT_VERSION=$(GIT_DESCRIPTION:barnowl-%=%))
     3GIT_DESCRIPTION := $(if $(wildcard $(srcdir)/.git),$(shell cd $(srcdir) && git describe --match='barnowl-*' HEAD 2>/dev/null))
     4VERSION = $(if $(GIT_DESCRIPTION),$(GIT_DESCRIPTION:barnowl-%=%),$(DIST_VERSION))
     5DIST_VERSION = @VERSION@
     6-include $(srcdir)/DIST_VERSION.mk BUILD_VERSION.mk
     7
     8FORCE:
     9BUILD_VERSION.mk: $(if $(filter-out $(BUILD_VERSION),$(VERSION)),FORCE)
     10        echo 'BUILD_VERSION = $(VERSION)' > $@
     11dist-hook:: $(if $(filter-out @VERSION@,$(VERSION)),dist-hook-version)
     12dist-hook-version:
     13        echo 'DIST_VERSION = $(VERSION)' > $(distdir)/DIST_VERSION.mk
    514
    615bin_PROGRAMS = bin/barnowl
     
    1019
    1120zcrypt_SOURCES = zcrypt.c filterproc.c
     21nodist_zcrypt_SOURCES = version.c
    1222
    1323check_PROGRAMS = bin/tester
     
    3343dist_doc_DATA = doc/intro.txt doc/advanced.txt
    3444
    35 bin_barnowl_LDADD = compat/libcompat.a libfaim/libfaim.a
     45bin_barnowl_LDADD = compat/libcompat.a
    3646
    3747bin_tester_SOURCES = $(BASE_SRCS) \
     
    4050nodist_bin_tester_SOURCES = $(GEN_C) $(GEN_H)
    4151
    42 bin_tester_LDADD = compat/libcompat.a libfaim/libfaim.a
     52bin_tester_LDADD = compat/libcompat.a
    4353
    4454TESTS=runtests.sh
    4555
    4656AM_CPPFLAGS = \
    47            -I$(top_srcdir)/libfaim/ \
    4857           -DDATADIR='"$(pkgdatadir)"' \
    49            -DBINDIR='"$(bindir)"' \
    50            $(GIT_FLAGS)
     58           -DBINDIR='"$(bindir)"'
    5159
    5260CODELIST_SRCS=message.c mainwin.c popwin.c zephyr.c messagelist.c \
     
    5664     regex.c history.c view.c dict.c variable.c filterelement.c pair.c \
    5765     keypress.c keymap.c keybinding.c cmd.c context.c \
    58      aim.c buddy.c buddylist.c style.c errqueue.c \
     66     style.c errqueue.c \
    5967     zbuddylist.c popexec.c select.c wcwidth.c \
    6068     mainpanel.c msgwin.c sepbar.c editcontext.c signal.c closures.c
     
    6472BASE_SRCS = $(CODELIST_SRCS) $(NORMAL_SRCS)
    6573
    66 GEN_C = varstubs.c perlglue.c gmarshal_funcs.c
     74GEN_C = varstubs.c perlglue.c gmarshal_funcs.c version.c version.c.new
    6775GEN_H = owl_prototypes.h owl_prototypes.h.new gmarshal_funcs.h
    6876
    69 BUILT_SOURCES = $(GEN_C) $(GEN_H)
     77BUILT_SOURCES = $(GEN_H)
    7078
    7179# Only copy file into place if file.new is different
    72 %: %.new
     80owl_prototypes.h version.c: %: %.new
    7381        @diff -U0 $@ $< || { \
    7482         test -f $@ && echo '$@ changed!'; \
     
    8795        $(AM_V_GEN)perl $< $(sort $(filter-out $<,$+)) > $@
    8896
     97version.c.new: Makefile BUILD_VERSION.mk
     98        $(AM_V_GEN)echo 'const char *version = "$(VERSION)";' > $@
     99
    89100gmarshal_funcs.h: marshal_types
    90101        glib-genmarshal --header $< > $@
     
    96107        $(COMPILE) -Wall -Wextra -pedantic -fsyntax-only $(CHK_SOURCES)
    97108
    98 CLEANFILES = $(BUILT_SOURCES) $(noinst_SCRIPTS) $(check_SCRIPTS)
     109CLEANFILES = $(BUILT_SOURCES) $(GEN_C) $(noinst_SCRIPTS) $(check_SCRIPTS) BUILD_VERSION.mk
     110MAINTAINERCLEANFILES = DIST_VERSION.mk
    99111EXTRA_DIST = \
    100112    autogen.sh \
     
    109121    scripts \
    110122    stubgen.pl \
    111     typemap
     123    typemap \
     124    cpanfile
    112125
    113 SUBDIRS = compat libfaim perl
     126SUBDIRS = compat perl
  • cmd.c

    rf271129 r7dcef03  
    3535void owl_cmddict_add_alias(owl_cmddict *cd, const char *alias_from, const char *alias_to) {
    3636  owl_cmd *cmd;
    37   cmd = g_new(owl_cmd, 1);
     37  cmd = g_slice_new(owl_cmd);
    3838  owl_cmd_create_alias(cmd, alias_from, alias_to);
    3939  owl_perlconfig_new_command(cmd->name);
     
    4242
    4343int owl_cmddict_add_cmd(owl_cmddict *cd, const owl_cmd * cmd) {
    44   owl_cmd * newcmd = g_new(owl_cmd, 1);
     44  owl_cmd * newcmd = g_slice_new(owl_cmd);
    4545  if(owl_cmd_create_from_template(newcmd, cmd) < 0) {
    46     g_free(newcmd);
     46    g_slice_free(owl_cmd, newcmd);
    4747    return -1;
    4848  }
     
    141141{
    142142  owl_cmd_cleanup(cmd);
    143   g_free(cmd);
     143  g_slice_free(owl_cmd, cmd);
    144144}
    145145
  • codelist.pl

    r06adc25 r4fd3c04  
    1818            && !/^XS/
    1919            && !/\/\*/
    20             && !/ZWRITEOPTIONS/
    21             && !/owlfaim_priv/)
     20            && !/ZWRITEOPTIONS/)
    2221        {
    2322
  • commands.c

    ra38becd r4fd3c04  
    122122              "      Send to the specified opcode\n"),
    123123
    124   OWLCMD_ARGS("aimwrite", owl_command_aimwrite, OWL_CTX_INTERACTIVE,
    125               "send an AIM message",
    126               "aimwrite <user> [-m <message...>]",
    127               "Send an aim message to a user.\n\n"
    128               "The following options are available:\n\n"
    129               "-m    Specifies a message to send without prompting.\n"),
    130 
    131124  OWLCMD_ARGS("loopwrite", owl_command_loopwrite, OWL_CTX_INTERACTIVE,
    132125              "send a loopback message",
     
    153146  OWLCMD_ARGS("set", owl_command_set, OWL_CTX_ANY,
    154147              "set a variable value",
    155               "set [-q] [<variable>] [<value>]\n"
     148              "set [-q] <variable> [<value>]\n"
    156149              "set",
    157150              "Set the named variable to the specified value.  If no\n"
     
    234227              "Execute the BarnOwl commands in <filename>.\n"),
    235228
    236   OWLCMD_ARGS("aim", owl_command_aim, OWL_CTX_INTERACTIVE,
    237               "AIM specific commands",
    238               "aim search <email>",
    239               ""),
    240 
    241229  OWLCMD_ARGS("addbuddy", owl_command_addbuddy, OWL_CTX_INTERACTIVE,
    242230              "add a buddy to a buddylist",
    243231              "addbuddy <protocol> <screenname>",
    244               "Add the named buddy to your buddylist.  <protocol> can be aim or zephyr\n"),
     232              "Add the named buddy to your buddylist.  <protocol> must be zephyr\n"),
    245233
    246234  OWLCMD_ARGS("delbuddy", owl_command_delbuddy, OWL_CTX_INTERACTIVE,
    247235              "delete a buddy from a buddylist",
    248236              "delbuddy <protocol> <screenname>",
    249               "Delete the named buddy from your buddylist.  <protocol> can be aim or zephyr\n"),
    250 
    251   OWLCMD_ARGS("join", owl_command_join, OWL_CTX_INTERACTIVE,
    252               "join a chat group",
    253               "join aim <groupname> [exchange]",
    254               "Join the AIM chatroom with 'groupname'.\n"),
     237              "Delete the named buddy from your buddylist.  <protocol> must be zephyr\n"),
    255238
    256239  OWLCMD_ARGS("smartzpunt", owl_command_smartzpunt, OWL_CTX_INTERACTIVE,
     
    308291              "znol [-f file]",
    309292              "Print a znol-style listing of users logged in"),
    310 
    311   OWLCMD_VOID("alist", owl_command_alist, OWL_CTX_INTERACTIVE,
    312               "List AIM users logged in",
    313               "alist",
    314               "Print a listing of AIM users logged in"),
    315293
    316294  OWLCMD_VOID("blist", owl_command_blist, OWL_CTX_INTERACTIVE,
     
    470448              "use the default.\n"),
    471449
    472   OWLCMD_ARGS("aaway", owl_command_aaway, OWL_CTX_INTERACTIVE,
    473               "Set, enable or disable AIM away message",
    474               "aaway [ on | off | toggle ]\n"
    475               "aaway <message>",
    476               "Turn on or off the AIM away message.  If 'message' is\n"
    477               "specified turn on aaway with that message, otherwise\n"
    478               "use the default.\n"),
    479 
    480450  OWLCMD_ARGS("away", owl_command_away, OWL_CTX_INTERACTIVE,
    481451              "Set, enable or disable all away messages",
     
    486456              "otherwise use the default.\n"
    487457              "\n"
    488               "SEE ALSO: aaway, zaway"),
     458              "SEE ALSO: zaway"),
     459
     460  OWLCMD_ARGS("flush-logs", owl_command_flushlogs, OWL_CTX_ANY,
     461              "flush the queue of messages waiting to be logged",
     462              "flush-logs [-f | --force] [-q | --quiet]",
     463              "If BarnOwl failed to log a file, this command tells\n"
     464              "BarnOwl to try logging the messages that have since\n"
     465              "come in, and to resume logging normally.\n"
     466              "\n"
     467              "Normally, if logging any of these messages fails,\n"
     468              "that message is added to the queue of messages waiting\n"
     469              "to be logged, and any new messages are deferred until\n"
     470              "the next :flush-logs.  If the --force flag is passed,\n"
     471              "any messages on the queue which cannot successfully be\n"
     472              "logged are dropped, and BarnOwl will resume logging\n"
     473              "normally.\n"
     474              "\n"
     475              "Unless --quiet is passed, a message is printed about\n"
     476              "how many logs there are to flush."),
    489477
    490478  OWLCMD_ARGS("load-subs", owl_command_loadsubs, OWL_CTX_ANY,
     
    530518              "    body       -  message body\n"
    531519              "    hostname   -  hostname of sending host\n"
    532               "    type       -  message type (zephyr, aim, admin)\n"
     520              "    type       -  message type (zephyr, admin)\n"
    533521              "    direction  -  either 'in' 'out' or 'none'\n"
    534522              "    login      -  either 'login' 'logout' or 'none'\n"
     
    548536              "optional color arguments are used they specifies the colors that\n"
    549537              "messages matching this filter should be displayed in.\n\n"
    550               "SEE ALSO: view, viewclass, viewuser\n"),
     538              "SEE ALSO: smartfilter, smartnarrow, view, viewclass, viewuser\n"),
    551539
    552540  OWLCMD_ARGS("colorview", owl_command_colorview, OWL_CTX_INTERACTIVE,
     
    585573              "filter expression that will be dynamically created by BarnOwl and then\n"
    586574              "applied as the view's filter\n"
    587               "SEE ALSO: filter, viewclass, viewuser\n"),
     575              "SEE ALSO: filter, smartfilter, smartnarrow, viewclass, viewuser\n"),
    588576
    589577  OWLCMD_ARGS("smartnarrow", owl_command_smartnarrow, OWL_CTX_INTERACTIVE,
     
    599587              "    then narrow to the class and instance.\n"
    600588              "If '-r' or '--related' is specified, behave as though the\n"
    601               "    'narrow-related' variable was inverted."),
     589              "    'narrow-related' variable was inverted.\n\n"
     590              "SEE ALSO: filter, smartfilter, view, viewclass, viewuser\n"),
    602591
    603592  OWLCMD_ARGS("smartfilter", owl_command_smartfilter, OWL_CTX_INTERACTIVE,
     
    610599              "If the curmsg is a class message, the filter is that class.\n"
    611600              "If the curmsg is a class message and '-i' is specified\n"
    612               "    the filter is to that class and instance.\n"),
     601              "    the filter is to that class and instance.\n\n"
     602              "SEE ALSO: filter, smartnarrow, view, viewclass, viewuser\n"),
    613603
    614604  OWLCMD_ARGS("viewclass", owl_command_viewclass, OWL_CTX_INTERACTIVE,
     
    618608              "matching the specified class and switch the current view\n"
    619609              "to it.\n\n"
    620               "SEE ALSO: filter, view, viewuser\n"),
     610              "SEE ALSO: filter, smartfilter, smartnarrow, view, viewuser\n"),
    621611  OWLCMD_ALIAS("vc", "viewclass"),
    622612
     
    627617              "matching the specified user and switch the current\n"
    628618              "view to it.\n\n"
    629               "SEE ALSO: filter, view, viewclass\n"),
     619              "SEE ALSO: filter, smartfilter, smartnarrow, view, viewclass\n"),
    630620  OWLCMD_ALIAS("vu", "viewuser"),
    631621  OWLCMD_ALIAS("viewperson", "viewuser"),
     
    752742          "no argument, it makes search highlighting inactive."),
    753743
    754   OWLCMD_ARGS("aimlogin", owl_command_aimlogin, OWL_CTX_ANY,
    755               "login to an AIM account",
    756               "aimlogin <screenname> [<password>]\n",
    757               ""),
    758 
    759   OWLCMD_ARGS("aimlogout", owl_command_aimlogout, OWL_CTX_ANY,
    760               "logout from AIM",
    761               "aimlogout\n",
    762               ""),
    763 
    764744  OWLCMD_ARGS("error", owl_command_error, OWL_CTX_ANY,
    765745              "Display an error message",
     
    10881068    }
    10891069  }
    1090   owl_function_buddylist(0, 1, file);
     1070  owl_function_buddylist(1, file);
    10911071  return(NULL);
    10921072}
    10931073
    1094 void owl_command_alist(void)
    1095 {
    1096   owl_function_buddylist(1, 0, NULL);
    1097 }
    1098 
    10991074void owl_command_blist(void)
    11001075{
    1101   owl_function_buddylist(1, 1, NULL);
     1076  owl_function_buddylist(1, NULL);
    11021077}
    11031078
     
    11141089void owl_command_version(void)
    11151090{
    1116   owl_function_makemsg("BarnOwl version %s", OWL_VERSION_STRING);
    1117 }
    1118 
    1119 char *owl_command_aim(int argc, const char *const *argv, const char *buff)
    1120 {
    1121   if (argc<2) {
    1122     owl_function_makemsg("not enough arguments to aim command");
    1123     return(NULL);
    1124   }
    1125 
    1126   if (!strcmp(argv[1], "search")) {
    1127     if (argc!=3) {
    1128       owl_function_makemsg("not enough arguments to aim search command");
    1129       return(NULL);
    1130     }
    1131     owl_aim_search(argv[2]);
    1132   } else {
    1133     owl_function_makemsg("unknown subcommand '%s' for aim command", argv[1]);
    1134     return(NULL);
    1135   }
    1136   return(NULL);
     1091  owl_function_makemsg("BarnOwl version %s", version);
    11371092}
    11381093
     
    11441099  }
    11451100
    1146   if (!strcasecmp(argv[1], "aim")) {
    1147     if (!owl_global_is_aimloggedin(&g)) {
    1148       owl_function_makemsg("addbuddy: You must be logged into aim to use this command.");
    1149       return(NULL);
    1150     }
    1151     /*
    1152     owl_function_makemsg("This function is not yet operational.  Stay tuned.");
    1153     return(NULL);
    1154     */
    1155     owl_aim_addbuddy(argv[2]);
    1156     owl_function_makemsg("%s added as AIM buddy for %s", argv[2], owl_global_get_aim_screenname(&g));
    1157   } else if (!strcasecmp(argv[1], "zephyr")) {
     1101  if (!strcasecmp(argv[1], "zephyr")) {
    11581102    owl_zephyr_addbuddy(argv[2]);
    11591103    owl_function_makemsg("%s added as zephyr buddy", argv[2]);
    11601104  } else {
    1161     owl_function_makemsg("addbuddy: currently the only supported protocols are 'zephyr' and 'aim'");
     1105    owl_function_makemsg("addbuddy: currently the only supported protocol is 'zephyr'");
    11621106  }
    11631107
     
    11721116  }
    11731117
    1174   if (!strcasecmp(argv[1], "aim")) {
    1175     if (!owl_global_is_aimloggedin(&g)) {
    1176       owl_function_makemsg("delbuddy: You must be logged into aim to use this command.");
    1177       return(NULL);
    1178     }
    1179     owl_aim_delbuddy(argv[2]);
    1180     owl_function_makemsg("%s deleted as AIM buddy for %s", argv[2], owl_global_get_aim_screenname(&g));
    1181   } else if (!strcasecmp(argv[1], "zephyr")) {
     1118  if (!strcasecmp(argv[1], "zephyr")) {
    11821119    owl_zephyr_delbuddy(argv[2]);
    11831120    owl_function_makemsg("%s deleted as zephyr buddy", argv[2]);
    11841121  } else {
    1185     owl_function_makemsg("delbuddy: currently the only supported protocols are 'zephyr' and 'aim'");
    1186   }
    1187 
    1188   return(NULL);
    1189 }
    1190 
    1191 char *owl_command_join(int argc, const char *const *argv, const char *buff)
    1192 {
    1193   if (argc!=3 && argc!=4) {
    1194     owl_function_makemsg("usage: join <protocol> <buddyname> [exchange]");
    1195     return(NULL);
    1196   }
    1197 
    1198   if (!strcasecmp(argv[1], "aim")) {
    1199     if (!owl_global_is_aimloggedin(&g)) {
    1200       owl_function_makemsg("join aim: You must be logged into aim to use this command.");
    1201       return(NULL);
    1202     }
    1203     if (argc==3) {
    1204       owl_aim_chat_join(argv[2], 4);
    1205     } else {
    1206       owl_aim_chat_join(argv[2], atoi(argv[3]));
    1207     }
    1208     /* owl_function_makemsg("%s deleted as AIM buddy for %s", argv[2], owl_global_get_aim_screenname(&g)); */
    1209   } else {
    1210     owl_function_makemsg("join: currently the only supported protocol is 'aim'");
    1211   }
     1122    owl_function_makemsg("delbuddy: currently the only supported protocol is 'zephyr'");
     1123  }
     1124
    12121125  return(NULL);
    12131126}
     
    14351348}
    14361349
     1350char *owl_command_flushlogs(int argc, const char *const *argv, const char *buff)
     1351{
     1352  bool force = false;
     1353  bool quiet = false;
     1354  int i;
     1355
     1356  for (i = 1; i < argc; i++) {
     1357    if (!strcmp(argv[i], "-f") || !strcmp(argv[i], "--force")) {
     1358      force = true;
     1359    } else if (!strcmp(argv[i], "-q") || !strcmp(argv[i], "--quiet")) {
     1360      quiet = true;
     1361    } else {
     1362      owl_function_makemsg("Invalid flag to flush-logs: %s", argv[i]);
     1363    }
     1364  }
     1365  owl_log_flush_logs(force, quiet);
     1366  return NULL;
     1367}
     1368
    14371369char *owl_command_loadsubs(int argc, const char *const *argv, const char *buff)
    14381370{
     
    15001432
    15011433
    1502 char *owl_command_aaway(int argc, const char *const *argv, const char *buff)
    1503 {
    1504   if ((argc==1) ||
    1505       ((argc==2) && !strcmp(argv[1], "on"))) {
    1506     owl_global_set_aaway_msg(&g, owl_global_get_aaway_msg_default(&g));
    1507     owl_function_aaway_on();
    1508     return NULL;
    1509   }
    1510 
    1511   if (argc==2 && !strcmp(argv[1], "off")) {
    1512     owl_function_aaway_off();
    1513     return NULL;
    1514   }
    1515 
    1516   if (argc==2 && !strcmp(argv[1], "toggle")) {
    1517     owl_function_aaway_toggle();
    1518     return NULL;
    1519   }
    1520 
    1521   buff = skiptokens(buff, 1);
    1522   owl_global_set_aaway_msg(&g, buff);
    1523   owl_function_aaway_on();
    1524   return NULL;
    1525 }
    1526 
    1527 
    15281434char *owl_command_away(int argc, const char *const *argv, const char *buff)
    15291435{
     
    15341440      (argc == 2 && !strcmp(argv[1], "on"))) {
    15351441    away_off = false;
    1536     owl_global_set_aaway_msg(&g, owl_global_get_aaway_msg_default(&g));
    15371442    owl_global_set_zaway_msg(&g, owl_global_get_zaway_msg_default(&g));
    15381443  } else if (argc == 2 && !strcmp(argv[1], "off")) {
     
    15461451
    15471452  if (away_off) {
    1548     owl_function_aaway_off();
    15491453    owl_function_zaway_off();
    15501454    owl_perlconfig_perl_call_norv("BarnOwl::Hooks::_away_off", 0, NULL);
    15511455    owl_function_makemsg("Away messages off.");
    15521456  } else if (message != NULL) {
    1553     owl_global_set_aaway_msg(&g, message);
    15541457    owl_global_set_zaway_msg(&g, message);
    1555     owl_function_aaway_on();
    15561458    owl_function_zaway_on();
    15571459    owl_perlconfig_perl_call_norv("BarnOwl::Hooks::_away_on", 1, &message);
    15581460    owl_function_makemsg("Away messages set (%s).", message);
    15591461  } else {
    1560     owl_function_aaway_on();
    15611462    owl_function_zaway_on();
    15621463    owl_perlconfig_perl_call_norv("BarnOwl::Hooks::_away_on", 0, NULL);
     
    19991900  }
    20001901  return(NULL);
    2001 }
    2002 
    2003 char *owl_command_aimwrite(int argc, const char *const *argv, const char *buff)
    2004 {
    2005   char *message = NULL;
    2006   GString *recip = g_string_new("");
    2007   const char *const *myargv;
    2008   int myargc;
    2009  
    2010   if (!owl_global_is_aimloggedin(&g)) {
    2011     owl_function_error("You are not logged in to AIM.");
    2012     goto err;
    2013   }
    2014 
    2015   /* Skip argv[0]. */
    2016   myargv = argv+1;
    2017   myargc = argc-1;
    2018   while (myargc) {
    2019     if (!strcmp(myargv[0], "-m")) {
    2020       if (myargc <= 1) {
    2021         owl_function_error("No message specified.");
    2022         goto err;
    2023       }
    2024       /* Once we have -m, gobble up everything else on the line */
    2025       myargv++;
    2026       myargc--;
    2027       message = g_strjoinv(" ", (char**)myargv);
    2028       break;
    2029     } else {
    2030       /* squish arguments together to make one screenname w/o spaces for now */
    2031       g_string_append(recip, myargv[0]);
    2032       myargv++;
    2033       myargc--;
    2034     }
    2035   }
    2036 
    2037   if (recip->str[0] == '\0') {
    2038     owl_function_error("No recipient specified");
    2039     goto err;
    2040   }
    2041 
    2042   if (message != NULL)
    2043     owl_function_aimwrite(recip->str, message, false);
    2044   else
    2045     owl_function_aimwrite_setup(recip->str);
    2046  err:
    2047   g_string_free(recip, true);
    2048   g_free(message);
    2049   return NULL;
    20501902}
    20511903
     
    26152467}
    26162468
    2617 char *owl_command_aimlogin(int argc, const char *const *argv, const char *buff)
    2618 {
    2619   if ((argc<2) || (argc>3)) {
    2620     owl_function_makemsg("Wrong number of arguments to aimlogin command");
    2621     return(NULL);
    2622   }
    2623 
    2624   /* if we get two arguments, ask for the password */
    2625   if (argc==2) {
    2626     owl_editwin *e = owl_function_start_password("AIM Password: ");
    2627     owl_editwin_set_cbdata(e, g_strdup(argv[1]), g_free);
    2628     owl_editwin_set_callback(e, owl_callback_aimlogin);
    2629     return(NULL);
    2630   } else {
    2631     owl_function_aimlogin(argv[1], argv[2]);
    2632   }
    2633 
    2634   /* this is a test */
    2635   return(NULL);
    2636 }
    2637 
    2638 char *owl_command_aimlogout(int argc, const char *const *argv, const char *buff)
    2639 {
    2640   /* clear the buddylist */
    2641   owl_buddylist_clear(owl_global_get_buddylist(&g));
    2642 
    2643   owl_aim_logout();
    2644   return(NULL);
    2645 }
    2646 
    26472469CALLER_OWN char *owl_command_getstyle(int argc, const char *const *argv, const char *buff)
    26482470{
  • configure.ac

    r77dfeb1 r9a0d25d  
    11dnl Process this file with autoconf to produce a configure script.
    2 AC_INIT([BarnOwl],[1.10dev],[bug-barnowl@mit.edu])
     2AC_INIT([BarnOwl],[1.11dev],[bug-barnowl@mit.edu])
    33AM_INIT_AUTOMAKE([1.7.0 foreign std-options -Wall -Wno-portability])
    44AM_MAINTAINER_MODE([enable])
     
    5454  [with_zephyr=check])
    5555
    56 AC_ARG_WITH([krb4],
    57   AS_HELP_STRING([--with-krb4],
    58                  [Build with kerberos IV]))
    59 
    6056AS_IF([test "x$with_zephyr" != xno],
    61   [have_krb4=no
    62 
    63    AS_IF([test "x$with_krb4" != "xno"],
    64    [AC_MSG_CHECKING([for Kerberos IV])
    65     AS_IF([krb5-config krb4 --libs >/dev/null 2>&1],
    66       [AC_MSG_RESULT([yes])
    67        have_krb4=yes
    68        AC_DEFINE([HAVE_KERBEROS_IV], [1], [Define if you have kerberos IV])
    69        AM_CFLAGS="${AM_CFLAGS} `krb5-config krb4 --cflags`"
    70        LIBS="${LIBS} `krb5-config krb4 --libs`"
    71       ],
    72       [AC_MSG_RESULT([no])
    73        AS_IF([test "x$with_krb4" = "xyes"],
    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            ])])])
     57  [PKG_CHECK_MODULES([LIBCRYPTO], [libcrypto],
     58     [AM_CFLAGS="${AM_CFLAGS} ${LIBCRYPTO_CFLAGS}"
     59      LIBS="${LIBS} ${LIBCRYPTO_LIBS}"
     60     ],
     61     [PKG_CHECK_MODULES([OPENSSL], [openssl],
     62        [AM_CFLAGS="${AM_CFLAGS} ${OPENSSL_CFLAGS}"
     63         LIBS="${LIBS} ${OPENSSL_LIBS}"
     64        ])])
    8565
    8666   AC_CHECK_LIB([zephyr], [ZGetSender],
     
    10282AC_CHECK_FUNCS([use_default_colors])
    10383AC_CHECK_FUNCS([resizeterm], [], [AC_MSG_ERROR([No resizeterm found])])
    104 AC_CHECK_FUNCS([des_string_to_key DES_string_to_key], [HAVE_DES_STRING_TO_KEY=1])
    105 AC_CHECK_FUNCS([des_ecb_encrypt DES_ecb_encrypt], [HAVE_DES_ECB_ENCRYPT=1])
    106 AC_CHECK_FUNCS([des_key_sched DES_key_sched], [HAVE_DES_KEY_SCHED=1])
     84AC_CHECK_FUNCS([DES_string_to_key], [HAVE_DES_STRING_TO_KEY=1])
     85AC_CHECK_FUNCS([DES_ecb_encrypt], [HAVE_DES_ECB_ENCRYPT=1])
     86AC_CHECK_FUNCS([DES_key_sched], [HAVE_DES_KEY_SCHED=1])
    10787
    10888dnl Checks for header files.
     
    176156AX_APPEND_COMPILE_FLAGS([-Wno-format-zero-length],[AM_CFLAGS])
    177157
    178 AX_APPEND_COMPILE_FLAGS([-Wno-pointer-sign -Wno-empty-body -Wno-unused-value],[LIBFAIM_CFLAGS])
    179 
    180158AM_CONDITIONAL([ENABLE_ZCRYPT], [test "$HAVE_DES_STRING_TO_KEY" && dnl
    181159                                 test "$HAVE_DES_KEY_SCHED" && dnl
     
    183161
    184162AM_CFLAGS="$AM_CFLAGS -D_XOPEN_SOURCE=600"
    185 dnl Define _BSD_SOURCE because zephyr needs caddr_t.
    186 AM_CFLAGS="$AM_CFLAGS -D_BSD_SOURCE"
     163dnl Define _BSD_SOURCE/_DEFAULT_SOURCE because zephyr needs caddr_t.
     164AM_CFLAGS="$AM_CFLAGS -D_BSD_SOURCE -D_DEFAULT_SOURCE"
    187165dnl Define __EXTENSIONS__ for strcasecmp on Solaris.
    188166AM_CFLAGS="$AM_CFLAGS -D__EXTENSIONS__"
     
    194172
    195173AC_SUBST([AM_CFLAGS])
    196 AC_SUBST([LIBFAIM_CFLAGS])
    197174
    198175AC_SUBST(XSUBPPDIR)
     
    213190AC_SUBST([abs_srcdir])
    214191
    215 AC_CONFIG_FILES([Makefile compat/Makefile libfaim/Makefile perl/Makefile perl/modules/Makefile])
     192AC_CONFIG_FILES([Makefile compat/Makefile perl/Makefile perl/modules/Makefile])
    216193AC_OUTPUT
  • context.c

    rf271129 r7dcef03  
    1010  if (!(mode & OWL_CTX_MODE_BITS))
    1111    mode |= OWL_CTX_INTERACTIVE;
    12   c = g_new0(owl_context, 1);
     12  c = g_slice_new0(owl_context);
    1313  c->mode = mode;
    1414  c->data = data;
     
    7171  if (ctx->delete_cb)
    7272    ctx->delete_cb(ctx);
    73   g_free(ctx);
     73  g_slice_free(owl_context, ctx);
    7474}
  • doc/advanced.txt

    rc82b055 r4fd3c04  
    4242     realm         zephyr realm
    4343     body          message body
    44      type          message type ('zephyr', 'aim', 'admin')
     44     type          message type ('zephyr', 'admin')
    4545     direction     either 'in' 'out' or 'none'\n"
    4646     login         either 'login' 'logout' or 'none'\n"
     
    103103All owl::Message objects contain the following methods:
    104104
    105     type      - returns the type of the message ("zephyr", "aim", "admin")
     105    type      - returns the type of the message ("zephyr", "admin")
    106106    direction - returns "in" or "out" for incoming or outgoing messages
    107107    time      - returns a string of the time when the message showed up
     
    126126
    127127    header      - returns the admin message header line  (admin)
    128     is_personal - returns true if this is a personal message (aim,zephyr)
     128    is_personal - returns true if this is a personal message (zephyr)
    129129    is_private  - returns true if this was a private message (zephyr)
    130130    login_tty   - returns the login tty for login messages (zephyr)
  • doc/intro.txt

    rd7cc50b r4fd3c04  
    88
    99Owl is a tty, curses-based instant messaging client.  This is a quick
    10 guide to learning how to use it.  Currently Owl supports AIM & zephyr,
     10guide to learning how to use it.  Currently Owl supports zephyr,
    1111but other messaging protocols, including Jabber, are on the way.  Some
    1212major features of owl include:
     
    7373If you wish to send to a class/instance pair simply supply -c and -i
    7474arguments to the zwrite command as you normally would.
    75 
    76 Sending an AIM message
    77 ----------------------
    78 
    79 Before sending an AIM message you must login to AOL Instant Messenger.
    80 Use the 'aimlogin' command, with your screenname as an argument:
    81 
    82      aimlogin <screenname>
    83 
    84 You will be prompted for your password, which you must enter.  Once
    85 you are successfully logged in you can send an AIM message by pressing
    86 the 'a' key, which will bring up an 'aimwrite' command:
    87 
    88      aimwrite <screenname>
    89 
    90 Supply the screen name you wish to write to as an argument and then
    91 send the message just as you would send a zephyr, as described above.
    9275
    9376Manipulating Messages
     
    256239     auto             Messages generated by automated programs
    257240     out              Messages sent from you to another user
    258      aim              AIM messages
    259241     zephyr           Zephyr messages
    260242     trash            "Trash" messages
  • editwin.c

    r8258ea5 r7dcef03  
    6868static CALLER_OWN owl_editwin *owl_editwin_allocate(void)
    6969{
    70   owl_editwin *e = g_new0(owl_editwin, 1);
     70  owl_editwin *e = g_slice_new0(owl_editwin);
    7171  e->refcount = 1;
    7272  return e;
     
    8787  oe_destroy_cbdata(e);
    8888
    89   g_free(e);
     89  g_slice_free(owl_editwin, e);
    9090}
    9191
     
    373373owl_editwin_excursion *owl_editwin_begin_excursion(owl_editwin *e)
    374374{
    375   owl_editwin_excursion *x = g_new(owl_editwin_excursion, 1);
     375  owl_editwin_excursion *x = g_slice_new(owl_editwin_excursion);
    376376  oe_save_excursion(e, x);
    377377  return x;
     
    381381{
    382382  oe_restore_excursion(e, x);
    383   g_free(x);
     383  g_slice_free(owl_editwin_excursion, x);
    384384}
    385385
  • filter.c

    rc068c03 r9e596f5  
    1616owl_filter *owl_filter_new(const char *name, int argc, const char *const *argv)
    1717{
     18  return owl_filter_new_colored(name, argc, argv, OWL_COLOR_DEFAULT, OWL_COLOR_DEFAULT);
     19}
     20
     21owl_filter *owl_filter_new_colored(const char *name, int argc, const char *const *argv, int fgcolor, int bgcolor)
     22{
    1823  owl_filter *f;
    1924
    20   f = g_new(owl_filter, 1);
     25  f = g_slice_new(owl_filter);
    2126
    2227  f->name=g_strdup(name);
    23   f->fgcolor=OWL_COLOR_DEFAULT;
    24   f->bgcolor=OWL_COLOR_DEFAULT;
    25 
    26   /* first take arguments that have to come first */
    27   /* set the color */
    28   while ( argc>=2 && ( !strcmp(argv[0], "-c") ||
    29                        !strcmp(argv[0], "-b") ) ) {
    30     if (owl_util_string_to_color(argv[1])==OWL_COLOR_INVALID) {
    31       owl_function_error("The color '%s' is not available, using default.", argv[1]);
    32     } else {
    33       switch (argv[0][1]) {
    34       case 'c':
    35         f->fgcolor=owl_util_string_to_color(argv[1]);
    36         break;
    37       case 'b':
    38         f->bgcolor=owl_util_string_to_color(argv[1]);
    39         break;
    40       }
    41     }
    42     argc-=2;
    43     argv+=2;
    44   }
     28  f->fgcolor = fgcolor;
     29  f->bgcolor = bgcolor;
    4530
    4631  if (!(f->root = owl_filter_parse_expression(argc, argv, NULL))) {
     
    6954  if(!argc) return NULL;
    7055
    71   fe = g_new(owl_filterelement, 1);
     56  fe = g_slice_new(owl_filterelement);
    7257  owl_filterelement_create(fe);
    7358
     
    11499err:
    115100  owl_filterelement_cleanup(fe);
    116   g_free(fe);
     101  g_slice_free(owl_filterelement, fe);
    117102  return NULL;
    118103}
     
    132117    op2 = owl_filter_parse_primitive_expression(argc-i-1, argv+i+1, &skip);
    133118    if(!op2) goto err;
    134     tmp = g_new(owl_filterelement, 1);
     119    tmp = g_slice_new(owl_filterelement);
    135120    if(!strcasecmp(argv[i], "and")) {
    136121      owl_filterelement_create_and(tmp, op1, op2);
     
    152137  if(op1) {
    153138    owl_filterelement_cleanup(op1);
    154     g_free(op1);
     139    g_slice_free(owl_filterelement, op1);
    155140  }
    156141  return NULL;
     
    262247  if (f->root) {
    263248    owl_filterelement_cleanup(f->root);
    264     g_free(f->root);
     249    g_slice_free(owl_filterelement, f->root);
    265250  }
    266251  if (f->name)
    267252    g_free(f->name);
    268   g_free(f);
    269 }
     253  g_slice_free(owl_filter, f);
     254}
  • filterelement.c

    r7756dde r7dcef03  
    328328  if (fe->left) {
    329329    owl_filterelement_cleanup(fe->left);
    330     g_free(fe->left);
     330    g_slice_free(owl_filterelement, fe->left);
    331331  }
    332332  if (fe->right) {
    333333    owl_filterelement_cleanup(fe->right);
    334     g_free(fe->right);
     334    g_slice_free(owl_filterelement, fe->right);
    335335  }
    336336  owl_regex_cleanup(&(fe->re));
  • filterproc.c

    r7155955 re8db357  
    11#include "filterproc.h"
    22#include <sys/wait.h>
    3 #include <fcntl.h>
     3#include <string.h>
    44#include <glib.h>
    5 #include <poll.h>
    6 #include <string.h>
    7 #include <unistd.h>
    85
    9 /* Even in case of error, send_receive is responsible for closing wfd
    10  * (to EOF the child) and rfd (for consistency). */
    11 static int send_receive(int rfd, int wfd, const char *out, char **in)
     6struct filter_data {
     7  const char **in;
     8  const char *in_end;
     9  GString *out_str;
     10  GMainLoop *loop;
     11  int err;
     12};
     13
     14static gboolean filter_stdin(GIOChannel *channel, GIOCondition condition, gpointer data_)
    1215{
    13   GString *str = g_string_new("");
    14   char buf[1024];
    15   nfds_t nfds;
    16   int err = 0;
    17   struct pollfd fds[2];
     16  struct filter_data *data = data_;
     17  gboolean done = condition & (G_IO_ERR | G_IO_HUP);
    1818
    19   fcntl(rfd, F_SETFL, O_NONBLOCK | fcntl(rfd, F_GETFL));
    20   fcntl(wfd, F_SETFL, O_NONBLOCK | fcntl(wfd, F_GETFL));
    21 
    22   fds[0].fd = rfd;
    23   fds[0].events = POLLIN;
    24   fds[1].fd = wfd;
    25   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;
     19  if (condition & G_IO_OUT) {
     20    gsize n;
     21    GIOStatus ret = g_io_channel_write_chars(channel, *data->in, data->in_end - *data->in, &n, NULL);
     22    *data->in += n;
     23    if (ret == G_IO_STATUS_ERROR)
     24      data->err = 1;
     25    if (ret == G_IO_STATUS_ERROR || *data->in == data->in_end)
     26      done = TRUE;
    3127  }
    3228
    33   while(1) {
    34     if(out && *out) {
    35       nfds = 2;
    36     } else {
    37       nfds = 1;
    38     }
    39     err = poll(fds, nfds, -1);
    40     if(err < 0) {
    41       break;
    42     }
    43     if(out && *out) {
    44       if(fds[1].revents & POLLOUT) {
    45         err = write(wfd, out, strlen(out));
    46         if(err > 0) {
    47           out += err;
    48         }
    49         if(err < 0) {
    50           out = NULL;
    51         }
    52       }
    53       if(!out || !*out || fds[1].revents & (POLLERR | POLLHUP)) {
    54         close(wfd); wfd = -1;
    55         out = NULL;
    56       }
    57     }
    58     if(fds[0].revents & POLLIN) {
    59       err = read(rfd, buf, sizeof(buf));
    60       if(err <= 0) {
    61         break;
    62       }
    63       g_string_append_len(str, buf, err);
    64     } else if(fds[0].revents & (POLLHUP | POLLERR)) {
    65       err = 0;
    66       break;
     29  if (condition & G_IO_ERR)
     30    data->err = 1;
     31
     32  if (done)
     33    g_io_channel_shutdown(channel, TRUE, NULL);
     34  return !done;
     35}
     36
     37static gboolean filter_stdout(GIOChannel *channel, GIOCondition condition, gpointer data_)
     38{
     39  struct filter_data *data = data_;
     40  gboolean done = condition & (G_IO_ERR | G_IO_HUP);
     41
     42  if (condition & (G_IO_IN | G_IO_HUP)) {
     43    gchar *buf;
     44    gsize n;
     45    GIOStatus ret = g_io_channel_read_to_end(channel, &buf, &n, NULL);
     46    g_string_append_len(data->out_str, buf, n);
     47    g_free(buf);
     48    if (ret == G_IO_STATUS_ERROR) {
     49      data->err = 1;
     50      done = TRUE;
    6751    }
    6852  }
    6953
    70   if (wfd >= 0) close(wfd);
    71   close(rfd);
    72   *in = g_string_free(str, err < 0);
    73   return err;
     54  if (condition & G_IO_ERR)
     55    data->err = 1;
     56
     57  if (done) {
     58    g_io_channel_shutdown(channel, TRUE, NULL);
     59    g_main_loop_quit(data->loop);
     60  }
     61  return !done;
    7462}
    7563
    7664int call_filter(const char *const *argv, const char *in, char **out, int *status)
    7765{
    78   int err;
    7966  GPid child_pid;
    8067  int child_stdin, child_stdout;
     
    8976  }
    9077
    91   err = send_receive(child_stdout, child_stdin, in, out);
    92   if (err == 0) {
    93     waitpid(child_pid, status, 0);
    94   }
    95   return err;
     78  if (in == NULL) in = "";
     79  GMainContext *context = g_main_context_new();
     80  struct filter_data data = {&in, in + strlen(in), g_string_new(""), g_main_loop_new(context, FALSE), 0};
     81
     82  GIOChannel *channel = g_io_channel_unix_new(child_stdin);
     83  g_io_channel_set_encoding(channel, NULL, NULL);
     84  g_io_channel_set_flags(channel, g_io_channel_get_flags(channel) | G_IO_FLAG_NONBLOCK, NULL);
     85  GSource *source = g_io_create_watch(channel, G_IO_OUT | G_IO_ERR | G_IO_HUP);
     86  g_io_channel_unref(channel);
     87  g_source_set_callback(source, (GSourceFunc)filter_stdin, &data, NULL);
     88  g_source_attach(source, context);
     89  g_source_unref(source);
     90
     91  channel = g_io_channel_unix_new(child_stdout);
     92  g_io_channel_set_encoding(channel, NULL, NULL);
     93  g_io_channel_set_flags(channel, g_io_channel_get_flags(channel) | G_IO_FLAG_NONBLOCK, NULL);
     94  source = g_io_create_watch(channel, G_IO_IN | G_IO_ERR | G_IO_HUP);
     95  g_io_channel_unref(channel);
     96  g_source_set_callback(source, (GSourceFunc)filter_stdout, &data, NULL);
     97  g_source_attach(source, context);
     98  g_source_unref(source);
     99
     100  g_main_loop_run(data.loop);
     101
     102  g_main_loop_unref(data.loop);
     103  g_main_context_unref(context);
     104
     105  waitpid(child_pid, status, 0);
     106  g_spawn_close_pid(child_pid);
     107  *out = g_string_free(data.out_str, data.err);
     108  return data.err;
    96109}
  • functions.c

    ra38becd r9e596f5  
    115115void owl_function_show_license(void)
    116116{
    117   const char *text;
    118 
    119   text=""
    120     "BarnOwl version " OWL_VERSION_STRING "\n"
     117  char *text = g_strdup_printf(
     118    "BarnOwl version %s\n"
    121119    "Copyright (c) 2006-2011 The BarnOwl Developers. All rights reserved.\n"
    122120    "Copyright (c) 2004 James Kretchmar. All rights reserved.\n"
     
    155153    "WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\n"
    156154    "OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN\n"
    157     "IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n";
     155    "IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n",
     156    version);
    158157  owl_function_popless_text(text);
     158  g_free(text);
    159159}
    160160
     
    170170    "':sub @b(class)', and then type ':zwrite -c @b(class)' to send.\n\n"
    171171#endif
    172     "@b(AIM:)\n"
    173     "Log in to AIM with ':aimlogin @b(screenname)'. Use ':aimwrite @b(screenname)',\n"
    174     "or 'a' and then the screen name, to send someone a message.\n\n"
    175172    ;
    176173
     
    196193  owl_message *m;
    197194
    198   m=g_new(owl_message, 1);
     195  m=g_slice_new(owl_message);
    199196  owl_message_create_admin(m, header, body);
    200197 
     
    218215  if (z->cc && owl_zwrite_is_personal(z)) {
    219216    /* create the message */
    220     owl_message *m = g_new(owl_message, 1);
     217    owl_message *m = g_slice_new(owl_message);
    221218    owl_message_create_from_zwrite(m, z, owl_zwrite_get_message(z), 0);
    222219
     
    231228
    232229      /* create the message */
    233       m = g_new(owl_message, 1);
     230      m = g_slice_new(owl_message);
    234231      owl_message_create_from_zwrite(m, z, owl_zwrite_get_message(z), i);
    235232
     
    237234    }
    238235  }
    239 }
    240 
    241 /* Create an outgoing AIM message, returns a pointer to the created
    242  * message or NULL if we're not logged into AIM (and thus unable to
    243  * create the message).  Does not put it on the global queue.  Use
    244  * owl_global_messagequeue_addmsg() for that.
    245  */
    246 CALLER_OWN owl_message *owl_function_make_outgoing_aim(const char *body, const char *to)
    247 {
    248   owl_message *m;
    249 
    250   /* error if we're not logged into aim */
    251   if (!owl_global_is_aimloggedin(&g)) return(NULL);
    252  
    253   m=g_new(owl_message, 1);
    254   owl_message_create_aim(m,
    255                          owl_global_get_aim_screenname(&g),
    256                          to,
    257                          body,
    258                          OWL_MESSAGE_DIRECTION_OUT,
    259                          0);
    260   return(m);
    261236}
    262237
     
    270245
    271246  /* create the message */
    272   m=g_new(owl_message, 1);
     247  m=g_slice_new(owl_message);
    273248  owl_message_create_loopback(m, body);
    274249  owl_message_set_direction_out(m);
     
    325300}
    326301
    327 void owl_function_aimwrite_setup(const char *to)
    328 {
    329   owl_editwin *e;
    330   /* TODO: We probably actually want an owl_aimwrite object like
    331    * owl_zwrite. */
    332   char *line = g_strdup_printf("aimwrite %s", to);
    333   owl_function_write_setup("message");
    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);
    337   g_free(line);
    338 }
    339 
    340302void owl_function_loopwrite_setup(void)
    341303{
     
    438400}
    439401
    440 void owl_callback_aimwrite(owl_editwin *e, bool success)
    441 {
    442   if (!success) return;
    443   char *to = owl_editwin_get_cbdata(e);
    444   owl_function_aimwrite(to, owl_editwin_get_text(e), true);
    445 }
    446 
    447 void owl_function_aimwrite(const char *to, const char *msg, bool unwrap)
    448 {
    449   int ret;
    450   char *format_msg;
    451   owl_message *m;
    452 
    453   /* make a formatted copy of the message */
    454   format_msg = g_strdup(msg);
    455   if (unwrap)
    456     owl_text_wordunwrap(format_msg);
    457  
    458   /* send the message */
    459   ret=owl_aim_send_im(to, format_msg);
    460   if (!ret) {
    461     owl_function_makemsg("AIM message sent.");
    462   } else {
    463     owl_function_error("Could not send AIM message.");
    464   }
    465 
    466   /* create the outgoing message */
    467   m=owl_function_make_outgoing_aim(msg, to);
    468 
    469   if (m) {
    470     owl_global_messagequeue_addmsg(&g, m);
    471   } else {
    472     owl_function_error("Could not create outgoing AIM message");
    473   }
    474 
    475   g_free(format_msg);
    476 }
    477 
    478 void owl_function_send_aimawymsg(const char *to, const char *msg)
    479 {
    480   int ret;
    481   char *format_msg;
    482   owl_message *m;
    483 
    484   /* make a formatted copy of the message */
    485   format_msg=g_strdup(msg);
    486   owl_text_wordunwrap(format_msg);
    487  
    488   /* send the message */
    489   ret=owl_aim_send_awaymsg(to, format_msg);
    490   if (!ret) {
    491     /* owl_function_makemsg("AIM message sent."); */
    492   } else {
    493     owl_function_error("Could not send AIM message.");
    494   }
    495 
    496   /* create the message */
    497   m=owl_function_make_outgoing_aim(msg, to);
    498   if (m) {
    499     owl_global_messagequeue_addmsg(&g, m);
    500   } else {
    501     owl_function_error("Could not create AIM message");
    502   }
    503   g_free(format_msg);
    504 }
    505 
    506402void owl_callback_loopwrite(owl_editwin *e, bool success)
    507403{
     
    516412  /* create a message and put it on the message queue.  This simulates
    517413   * an incoming message */
    518   min=g_new(owl_message, 1);
     414  min=g_slice_new(owl_message);
    519415  mout=owl_function_make_outgoing_loopback(msg);
    520416
     
    918814}
    919815
    920 void owl_callback_aimlogin(owl_editwin *e, bool success)
    921 {
    922   if (!success) return;
    923   char *user = owl_editwin_get_cbdata(e);
    924   owl_function_aimlogin(user,
    925                         owl_editwin_get_text(e));
    926 }
    927 
    928 void owl_function_aimlogin(const char *user, const char *passwd) {
    929   int ret;
    930 
    931   /* clear the buddylist */
    932   owl_buddylist_clear(owl_global_get_buddylist(&g));
    933 
    934   /* try to login */
    935   ret=owl_aim_login(user, passwd);
    936   if (ret) owl_function_makemsg("Warning: login for %s failed.\n", user);
    937 }
    938 
    939816void owl_function_suspend(void)
    940817{
     
    969846}
    970847
    971 void owl_function_aaway_toggle(void)
    972 {
    973   if (!owl_global_is_aaway(&g)) {
    974     owl_global_set_aaway_msg(&g, owl_global_get_aaway_msg_default(&g));
    975     owl_function_aaway_on();
    976   } else {
    977     owl_function_aaway_off();
    978   }
    979 }
    980 
    981 void owl_function_aaway_on(void)
    982 {
    983   owl_global_set_aaway_on(&g);
    984   /* owl_aim_set_awaymsg(owl_global_get_zaway_msg(&g)); */
    985   owl_function_makemsg("AIM away set (%s)", owl_global_get_aaway_msg(&g));
    986 }
    987 
    988 void owl_function_aaway_off(void)
    989 {
    990   owl_global_set_aaway_off(&g);
    991   /* owl_aim_set_awaymsg(""); */
    992   owl_function_makemsg("AIM away off");
    993 }
    994 
    995848bool owl_function_is_away(void)
    996849{
    997850  return owl_global_is_zaway(&g) ||
    998          owl_global_is_aaway(&g) ||
    999851         owl_perlconfig_perl_call_bool("BarnOwl::Hooks::_get_is_away", 0, NULL);
    1000852}
     
    1017869  if (owl_global_get_newmsgproc_pid(&g)) {
    1018870    kill(owl_global_get_newmsgproc_pid(&g), SIGHUP);
    1019   }
    1020  
    1021   /* Quit AIM */
    1022   if (owl_global_is_aimloggedin(&g)) {
    1023     owl_aim_logout();
    1024871  }
    1025872
     
    12261073  FILE *file;
    12271074  time_t now;
     1075  struct tm tm;
    12281076  va_list ap;
    1229   va_start(ap, fmt);
    12301077
    12311078  if (!owl_global_is_debug_fast(&g))
     
    12381085  now = time(NULL);
    12391086
    1240   tmpbuff = owl_util_format_time(localtime(&now));
     1087  tmpbuff = owl_util_format_time(localtime_r(&now, &tm));
    12411088  fprintf(file, "[%d -  %s - %lds]: ",
    12421089          (int) getpid(), tmpbuff, now - owl_global_get_starttime(&g));
    12431090  g_free(tmpbuff);
     1091
     1092  va_start(ap, fmt);
    12441093  vfprintf(file, fmt, ap);
     1094  va_end(ap);
     1095
    12451096  putc('\n', file);
    12461097  fflush(file);
    1247 
    1248   va_end(ap);
    12491098}
    12501099
     
    13591208void owl_function_about(void)
    13601209{
    1361   owl_function_popless_text(
    1362     "This is BarnOwl version " OWL_VERSION_STRING ".\n\n"
     1210  char *text = g_strdup_printf(
     1211    "This is BarnOwl version %s.\n\n"
    13631212    "BarnOwl is a fork of the Owl zephyr client, written and\n"
    13641213    "maintained by Alejandro Sedeno and Nelson Elhage at the\n"
     
    13791228    "This program is free software. You can redistribute it and/or\n"
    13801229    "modify under the terms of the Sleepycat License. Use the \n"
    1381     "':show license' command to display the full license\n"
    1382   );
     1230      "':show license' command to display the full license\n",
     1231      version);
     1232  owl_function_popless_text(text);
     1233  g_free(text);
    13831234}
    13841235
     
    14701321        owl_fmtext_append_normal(&fm, "\n");
    14711322        owl_fmtext_appendf_normal(&fm, "  Port      : %i\n", ntohs(n->z_port));
     1323        owl_fmtext_appendf_normal(&fm, "  Charset   : %s\n", owl_zephyr_get_charsetstr(n));
    14721324        owl_fmtext_appendf_normal(&fm, "  Auth      : %s\n", owl_zephyr_get_authstr(n));
    14731325
     
    17711623  char buff[MAXPATHLEN+1];
    17721624  time_t start;
     1625  struct tm tm;
    17731626  int up, days, hours, minutes;
    17741627  owl_fmtext fm;
     
    17811634
    17821635  owl_fmtext_append_normal(&fm, "  Version: ");
    1783   owl_fmtext_append_normal(&fm, OWL_VERSION_STRING);
     1636  owl_fmtext_append_normal(&fm, version);
    17841637  owl_fmtext_append_normal(&fm, "\n");
    17851638
     
    17961649  owl_fmtext_append_normal(&fm, "\n");
    17971650
    1798   tmpbuff = owl_util_format_time(localtime(&start));
     1651  tmpbuff = owl_util_format_time(localtime_r(&start, &tm));
    17991652  owl_fmtext_appendf_normal(&fm, "  Startup Time: %s\n", tmpbuff);
    18001653  g_free(tmpbuff);
     
    18161669    owl_fmtext_append_normal(&fm, "no\n");
    18171670  }
    1818   owl_fmtext_append_normal(&fm, "  AIM included       : yes\n");
    18191671  owl_fmtext_append_normal(&fm, "  Loopback included  : yes\n");
    18201672
     
    18271679  owl_fmtext_append_normal(&fm, "no\n");
    18281680#endif
    1829  
    1830 
    1831   owl_fmtext_append_normal(&fm, "\nAIM Status:\n");
    1832   owl_fmtext_append_normal(&fm, "  Logged in: ");
    1833   if (owl_global_is_aimloggedin(&g)) {
    1834     owl_fmtext_append_normal(&fm, owl_global_get_aim_screenname(&g));
    1835     owl_fmtext_append_normal(&fm, "\n");
    1836   } else {
    1837     owl_fmtext_append_normal(&fm, "(not logged in)\n");
    1838   }
    1839 
    1840   owl_fmtext_append_normal(&fm, "  Processing events: ");
    1841   if (owl_global_is_doaimevents(&g)) {
    1842     owl_fmtext_append_normal(&fm, "yes\n");
    1843   } else {
    1844     owl_fmtext_append_normal(&fm, "no\n");
    1845   }
    18461681
    18471682  owl_function_popless_fmtext(&fm);
     
    21451980  const owl_view *v;
    21461981  int inuse = 0;
     1982  int i = 2;
     1983  int fgcolor = OWL_COLOR_DEFAULT;
     1984  bool set_fgcolor = false;
     1985  int bgcolor = OWL_COLOR_DEFAULT;
     1986  bool set_bgcolor = false;
    21471987
    21481988  if (argc < 2) {
     
    21612001  }
    21622002
    2163   /* deal with the case of trying change the filter color */
    2164   if (argc==4 && !strcmp(argv[2], "-c")) {
     2003  /* set the color */
     2004  while (i + 2 <= argc && (!strcmp(argv[i], "-c") ||
     2005                           !strcmp(argv[i], "-b"))) {
     2006    int color = owl_util_string_to_color(argv[i + 1]);
     2007    if (color == OWL_COLOR_INVALID) {
     2008      owl_function_error("The color '%s' is not available.", argv[i + 1]);
     2009    } else if (argv[i][1] == 'c') {
     2010      fgcolor = color;
     2011      set_fgcolor = true;
     2012    } else {
     2013      bgcolor = color;
     2014      set_bgcolor = true;
     2015    }
     2016    i += 2;
     2017  }
     2018
     2019  if (i > 2 && i == argc) {
    21652020    f=owl_global_get_filter(&g, argv[1]);
    21662021    if (!f) {
     
    21682023      return false;
    21692024    }
    2170     if (owl_util_string_to_color(argv[3])==OWL_COLOR_INVALID) {
    2171       owl_function_error("The color '%s' is not available.", argv[3]);
     2025    if (!set_fgcolor && !set_bgcolor)
    21722026      return false;
    2173     }
    2174     owl_filter_set_fgcolor(f, owl_util_string_to_color(argv[3]));
    2175     owl_mainwin_redisplay(owl_global_get_mainwin(&g));
    2176     return false;
    2177   }
    2178   if (argc==4 && !strcmp(argv[2], "-b")) {
    2179     f=owl_global_get_filter(&g, argv[1]);
    2180     if (!f) {
    2181       owl_function_error("The filter '%s' does not exist.", argv[1]);
    2182       return false;
    2183     }
    2184     if (owl_util_string_to_color(argv[3])==OWL_COLOR_INVALID) {
    2185       owl_function_error("The color '%s' is not available.", argv[3]);
    2186       return false;
    2187     }
    2188     owl_filter_set_bgcolor(f, owl_util_string_to_color(argv[3]));
     2027    if (set_fgcolor)
     2028      owl_filter_set_fgcolor(f, fgcolor);
     2029    if (set_bgcolor)
     2030      owl_filter_set_bgcolor(f, bgcolor);
    21892031    owl_mainwin_redisplay(owl_global_get_mainwin(&g));
    21902032    return true;
     
    21922034
    21932035  /* create the filter and check for errors */
    2194   f = owl_filter_new(argv[1], argc-2, argv+2);
     2036  f = owl_filter_new_colored(argv[1], argc - i, argv + i, fgcolor, bgcolor);
    21952037  if (f == NULL) {
    21962038    owl_function_error("Invalid filter: %s", argv[1]);
     
    24402282  if (f == NULL) {
    24412283    /* Couldn't make a filter for some reason. Return NULL. */
    2442     owl_function_error("Error creating filter '%s'", filtname);
    2443     g_free(filtname);
    2444     return NULL;
    2445   }
    2446 
    2447   /* add it to the global list */
    2448   owl_global_add_filter(&g, f);
    2449 
    2450   return(filtname);
    2451 }
    2452 
    2453 /* Create a filter for AIM IM messages to or from the specified
    2454  * screenname.  The name of the filter will be 'aimuser-<user>'.  If a
    2455  * filter already exists with this name, no new filter will be
    2456  * created.  This allows the configuration to override this function.
    2457  * Returns the name of the filter, which the caller must free.
    2458  */
    2459 CALLER_OWN char *owl_function_aimuserfilt(const char *user)
    2460 {
    2461   owl_filter *f;
    2462   char *argbuff, *filtname;
    2463   char *escuser;
    2464 
    2465   /* name for the filter */
    2466   filtname=g_strdup_printf("aimuser-%s", user);
    2467 
    2468   /* if it already exists then go with it.  This lets users override */
    2469   if (owl_global_get_filter(&g, filtname)) {
    2470     return filtname;
    2471   }
    2472 
    2473   /* create the new-internal filter */
    2474   escuser = owl_text_quote(user, OWL_REGEX_QUOTECHARS, OWL_REGEX_QUOTEWITH);
    2475 
    2476   argbuff = g_strdup_printf(
    2477       "( type ^aim$ and ( ( sender ^%1$s$ and recipient ^%2$s$ ) or "
    2478       "( sender ^%2$s$ and recipient ^%1$s$ ) ) )",
    2479       escuser, owl_global_get_aim_screenname_for_filters(&g));
    2480   g_free(escuser);
    2481 
    2482   f = owl_filter_new_fromstring(filtname, argbuff);
    2483   g_free(argbuff);
    2484 
    2485   if (f == NULL) {
    24862284    owl_function_error("Error creating filter '%s'", filtname);
    24872285    g_free(filtname);
     
    26002398 * If the curmsg is a zephyr class message and type==1 then
    26012399 *    return a filter name for the class and instance.
    2602  * If the curmsg is a personal AIM message returna  filter
    2603  *    name to the AIM conversation with that user
    26042400 */
    26052401CALLER_OWN char *owl_function_smartfilter(int type, int invert_related)
     
    26272423  if (owl_message_is_type_loopback(m)) {
    26282424    return(owl_function_typefilt("loopback"));
    2629   }
    2630 
    2631   /* aim messages */
    2632   if (owl_message_is_type_aim(m)) {
    2633     if (owl_message_is_direction_in(m)) {
    2634       filtname=owl_function_aimuserfilt(owl_message_get_sender(m));
    2635     } else if (owl_message_is_direction_out(m)) {
    2636       filtname=owl_function_aimuserfilt(owl_message_get_recipient(m));
    2637     }
    2638     return(filtname);
    26392425  }
    26402426
     
    30642850
    30652851/* Popup a buddylisting.  If filename is NULL use the default .anyone */
    3066 void owl_function_buddylist(int aim, int zephyr, const char *filename)
    3067 {
    3068   int i, j, idle;
     2852void owl_function_buddylist(int zephyr, const char *filename)
     2853{
     2854  int i;
    30692855  int interrupted = 0;
    30702856  owl_fmtext fm;
    3071   const owl_buddylist *bl;
    3072   const owl_buddy *b;
    3073   char *timestr;
    30742857#ifdef HAVE_LIBZEPHYR
    30752858  int x;
     
    30822865
    30832866  owl_fmtext_init_null(&fm);
    3084 
    3085   /* AIM first */
    3086   if (aim && owl_global_is_aimloggedin(&g)) {
    3087     bl=owl_global_get_buddylist(&g);
    3088 
    3089     owl_fmtext_append_bold(&fm, "AIM users logged in:\n");
    3090     /* we're assuming AIM for now */
    3091     j=owl_buddylist_get_size(bl);
    3092     for (i=0; i<j; i++) {
    3093       b=owl_buddylist_get_buddy_n(bl, i);
    3094       idle=owl_buddy_get_idle_time(b);
    3095       if (idle!=0) {
    3096         timestr=owl_util_format_minutes(idle);
    3097       } else {
    3098         timestr=g_strdup("");
    3099       }
    3100       owl_fmtext_appendf_normal(&fm, "  %-20.20s %-12.12s\n", owl_buddy_get_name(b), timestr);
    3101       g_free(timestr);
    3102     }
    3103   }
    31042867
    31052868#ifdef HAVE_LIBZEPHYR
     
    31582921#endif
    31592922
    3160   if (aim && zephyr) {
     2923  if (zephyr) {
    31612924    if (owl_perlconfig_is_function("BarnOwl::Hooks::_get_blist")) {
    31622925      char * perlblist = owl_perlconfig_execute("BarnOwl::Hooks::_get_blist()");
     
    34203183  char *date;
    34213184  time_t now;
     3185  struct tm tm;
    34223186  char *buff;
    34233187
    34243188  now = time(NULL);
    3425   date = owl_util_format_time(localtime(&now));
     3189  date = owl_util_format_time(localtime_r(&now, &tm));
    34263190
    34273191  buff = g_strdup_printf("%s %s", date, string);
     
    34793243  while (zaldptr) {
    34803244    ZFreeALD(zaldptr->data);
    3481     g_free(zaldptr->data);
     3245    g_slice_free(ZAsyncLocateData_t, zaldptr->data);
    34823246    zaldptr = g_list_next(zaldptr);
    34833247  }
     
    34893253    for (i = 0; i < anyone->len; i++) {
    34903254      user = anyone->pdata[i];
    3491       zald = g_new(ZAsyncLocateData_t, 1);
     3255      zald = g_slice_new(ZAsyncLocateData_t);
    34923256      if (ZRequestLocations(zstr(user), zald, UNACKED, ZAUTH) == ZERR_NONE) {
    34933257        *zaldlist = g_list_append(*zaldlist, zald);
    34943258      } else {
    3495         g_free(zald);
     3259        g_slice_free(ZAsyncLocateData_t, zald);
    34963260      }
    34973261    }
     
    34993263  }
    35003264#endif
    3501 }
    3502 
    3503 void owl_function_aimsearch_results(const char *email, GPtrArray *namelist)
    3504 {
    3505   owl_fmtext fm;
    3506   int i;
    3507 
    3508   owl_fmtext_init_null(&fm);
    3509   owl_fmtext_append_normal(&fm, "AIM screennames associated with ");
    3510   owl_fmtext_append_normal(&fm, email);
    3511   owl_fmtext_append_normal(&fm, ":\n");
    3512 
    3513   for (i = 0; i < namelist->len; i++) {
    3514     owl_fmtext_append_normal(&fm, "  ");
    3515     owl_fmtext_append_normal(&fm, namelist->pdata[i]);
    3516     owl_fmtext_append_normal(&fm, "\n");
    3517   }
    3518 
    3519   owl_function_popless_fmtext(&fm);
    3520   owl_fmtext_cleanup(&fm);
    35213265}
    35223266
  • global.c

    r120dac7 r4fd3c04  
    8484  _owl_global_init_windows(g);
    8585
    86   g->aim_screenname=NULL;
    87   g->aim_screenname_for_filters=NULL;
    88   g->aim_loggedin=0;
    89   owl_buddylist_init(&(g->buddylist));
    90 
    9186  g->havezephyr=0;
    92   g->haveaim=0;
    93   g->ignoreaimlogin=0;
    94   owl_global_set_no_doaimevents(g);
    9587
    9688  owl_errqueue_init(&(g->errqueue));
     
    553545  e->g->filterlist = g_list_remove(e->g->filterlist, e->f);
    554546  owl_filter_delete(e->f);
    555   g_free(e);
     547  g_slice_free(owl_global_filter_ent, e);
    556548}
    557549
    558550void owl_global_add_filter(owl_global *g, owl_filter *f) {
    559   owl_global_filter_ent *e = g_new(owl_global_filter_ent, 1);
     551  owl_global_filter_ent *e = g_slice_new(owl_global_filter_ent);
    560552  e->g = g;
    561553  e->f = f;
     
    646638}
    647639
    648 /* AIM stuff */
    649 
    650 int owl_global_is_aimloggedin(const owl_global *g)
    651 {
    652   if (g->aim_loggedin) return(1);
    653   return(0);
    654 }
    655 
    656 const char *owl_global_get_aim_screenname(const owl_global *g)
    657 {
    658   if (owl_global_is_aimloggedin(g)) {
    659     return (g->aim_screenname);
    660   }
    661   return("");
    662 }
    663 
    664 const char *owl_global_get_aim_screenname_for_filters(const owl_global *g)
    665 {
    666   if (owl_global_is_aimloggedin(g)) {
    667     return (g->aim_screenname_for_filters);
    668   }
    669   return("");
    670 }
    671 
    672 void owl_global_set_aimloggedin(owl_global *g, const char *screenname)
    673 {
    674   char *sn_escaped;
    675   g->aim_loggedin=1;
    676   if (g->aim_screenname) g_free(g->aim_screenname);
    677   if (g->aim_screenname_for_filters) g_free(g->aim_screenname_for_filters);
    678   g->aim_screenname=g_strdup(screenname);
    679   sn_escaped = owl_text_quote(screenname, OWL_REGEX_QUOTECHARS, OWL_REGEX_QUOTEWITH);
    680   g->aim_screenname_for_filters = owl_arg_quote(sn_escaped);
    681   g_free(sn_escaped);
    682 }
    683 
    684 void owl_global_set_aimnologgedin(owl_global *g)
    685 {
    686   g->aim_loggedin=0;
    687 }
    688 
    689 bool owl_global_is_doaimevents(const owl_global *g)
    690 {
    691   return g->aim_event_source != NULL;
    692 }
    693 
    694 void owl_global_set_doaimevents(owl_global *g)
    695 {
    696   if (g->aim_event_source)
    697     return;
    698   g->aim_event_source = owl_aim_event_source_new(owl_global_get_aimsess(g));
    699   g_source_attach(g->aim_event_source, NULL);
    700 }
    701 
    702 void owl_global_set_no_doaimevents(owl_global *g)
    703 {
    704   if (!g->aim_event_source)
    705     return;
    706   g_source_destroy(g->aim_event_source);
    707   g_source_unref(g->aim_event_source);
    708   g->aim_event_source = NULL;
    709 }
    710 
    711 aim_session_t *owl_global_get_aimsess(owl_global *g)
    712 {
    713   return(&(g->aimsess));
    714 }
    715 
    716 aim_conn_t *owl_global_get_bosconn(owl_global *g)
    717 {
    718   return(&(g->bosconn));
    719 }
    720 
    721 void owl_global_set_bossconn(owl_global *g, aim_conn_t *conn)
    722 {
    723   g->bosconn=*conn;
    724 }
    725 
    726640/* message queue */
    727641
     
    750664}
    751665
    752 owl_buddylist *owl_global_get_buddylist(owl_global *g)
    753 {
    754   return(&(g->buddylist));
    755 }
    756  
    757666/* style */
    758667
     
    781690  owl_dict_insert_element(&(g->styledict), owl_style_get_name(s),
    782691                          s, (void (*)(void *))owl_style_delete);
    783 }
    784 
    785 void owl_global_set_haveaim(owl_global *g)
    786 {
    787   g->haveaim=1;
    788 }
    789 
    790 int owl_global_is_haveaim(const owl_global *g)
    791 {
    792   if (g->haveaim) return(1);
    793   return(0);
    794 }
    795 
    796 void owl_global_set_ignore_aimlogin(owl_global *g)
    797 {
    798     g->ignoreaimlogin = 1;
    799 }
    800 
    801 void owl_global_unset_ignore_aimlogin(owl_global *g)
    802 {
    803     g->ignoreaimlogin = 0;
    804 }
    805 
    806 int owl_global_is_ignore_aimlogin(const owl_global *g)
    807 {
    808     return g->ignoreaimlogin;
    809692}
    810693
     
    867750    { "reply-lockout", "class ^mail$ or class ^filsrv$" },
    868751    { "out", "direction ^out$" },
    869     { "aim", "type ^aim$" },
    870752    { "zephyr", "type ^zephyr$" },
    871753    { "none", "false" },
  • help.c

    r8258ea5 r4fd3c04  
    5252     "\n"
    5353     "    z             Start a zwrite command\n"
    54      "    a             Start an aimwrite command\n"
    5554     "    r             Reply to the current message\n"
    5655     "    R             Reply to sender\n"
     
    6463     "    !             Invert the current view\n"
    6564     "\n"
    66      "    l             Print a zephyr/AIM buddy listing\n"
     65     "    l             Print a zephyr buddy listing\n"
    6766     "    A             Toggle away\n"
    6867     "    o             Toggle one-line display mode\n"
     
    8887     "\n"
    8988     "    zwrite        Send a zephyr\n"
    90      "    aimlogin      Login to AIM\n"
    91      "    aimwrite      Send an AIM message\n"
    9289     "\n"
    93      "    addbuddy      Add a zephyr or AIM buddy\n"
     90     "    addbuddy      Add a zephyr buddy\n"
    9491     "    zaway         Turn zaway on or off, or set the message\n"
    9592     "    zlocate       Locate a user\n"
    9693     "    subscribe     Subscribe to a zephyr class or instance\n"
    9794     "    unsubscribe   Unsubscribe to a zephyr class or instance\n"
    98      "    blist         Print a list of zephyr and AIM buddies logged in\n"
     95     "    blist         Print a list of zephyr buddies logged in\n"
    9996     "    search        Search for a text string\n"
    10097     "\n"
     
    110107     "    zlog          Send a login or logout notification\n"
    111108     "    zlist         Print a list of zephyr buddies logged in\n"
    112      "    alist         Print a list of AIM buddies logged in\n"
    113109     "    info          Print detailed information about the current message\n"
    114110     "    filter        Create a message filter\n"
  • keybinding.c

    rf271129 r7dcef03  
    1414CALLER_OWN owl_keybinding *owl_keybinding_new(const char *keyseq, const char *command, void (*function_fn)(void), const char *desc)
    1515{
    16   owl_keybinding *kb = g_new(owl_keybinding, 1);
     16  owl_keybinding *kb = g_slice_new(owl_keybinding);
    1717
    1818  owl_function_debugmsg("owl_keybinding_init: creating binding for <%s> with desc: <%s>", keyseq, desc);
    1919  if (command && function_fn) {
    20     g_free(kb);
     20    g_slice_free(owl_keybinding, kb);
    2121    return NULL;
    2222  } else if (command && !function_fn) {
     
    2929
    3030  if (owl_keybinding_make_keys(kb, keyseq) != 0) {
    31     g_free(kb);
     31    g_slice_free(owl_keybinding, kb);
    3232    return NULL;
    3333  }
     
    7070  g_free(kb->desc);
    7171  g_free(kb->command);
    72   g_free(kb);
     72  g_slice_free(owl_keybinding, kb);
    7373}
    7474
  • keymap.c

    rf271129 r7dcef03  
    189189{
    190190  owl_keymap *km;
    191   km = g_new(owl_keymap, 1);
     191  km = g_slice_new(owl_keymap);
    192192  owl_keymap_init(km, name, desc, default_fn, prealways_fn, postalways_fn);
    193193  owl_keyhandler_add_keymap(kh, km);
  • keys.c

    rdcd48ad r4fd3c04  
    4444  BIND_CMD("M-RIGHT",     "edit:move-next-word", "");
    4545  BIND_CMD("M-[ 1 ; 3 D", "edit:move-next-word", "");
     46  BIND_CMD("M-[ 1 ; 5 D", "edit:move-next-word", "");
    4647  BIND_CMD("M-b",         "edit:move-prev-word", "");
    4748  BIND_CMD("M-O 3 D",     "edit:move-prev-word", "");
    4849  BIND_CMD("M-LEFT",      "edit:move-prev-word", "");
    49   BIND_CMD("M-[ 1 ; 3 C", "edit:move-next-word", "");
     50  BIND_CMD("M-[ 1 ; 3 C", "edit:move-prev-word", "");
     51  BIND_CMD("M-[ 1 ; 5 C", "edit:move-prev-word", "");
    5052
    5153  BIND_CMD("LEFT",        "edit:move-left", "");
     
    315317
    316318  BIND_CMD("z",   "start-command zwrite ", "start a zwrite command");
    317   BIND_CMD("a",   "start-command aimwrite ", "start an aimwrite command");
    318319  BIND_CMD("r",   "reply",            "reply to the current message");
    319320  BIND_CMD("R",   "reply sender",     "reply to sender of the current message");
  • logging.c

    r0792d99 r0c059f0  
    77} owl_log_entry;
    88
     9typedef struct _owl_log_options { /* noproto */
     10  bool drop_failed_logs;
     11  bool display_initial_log_count;
     12} owl_log_options;
    913
    1014static GMainContext *log_context;
    1115static GMainLoop *log_loop;
    1216static GThread *logging_thread;
    13 
    14 /* This is now the one function that should be called to log a
    15  * message.  It will do all the work necessary by calling the other
    16  * functions in this file as necessary.
     17static bool defer_logs; /* to be accessed only on the disk-writing thread */
     18static GQueue *deferred_entry_queue;
     19
     20static void owl_log_error_main_thread(gpointer data)
     21{
     22  owl_function_error("%s", (const char*)data);
     23}
     24
     25static void owl_log_adminmsg_main_thread(gpointer data)
     26{
     27  owl_function_adminmsg("Logging", (const char*)data);
     28}
     29
     30static void owl_log_makemsg_main_thread(gpointer data)
     31{
     32  owl_function_makemsg("%s", (const char*)data);
     33}
     34
     35static void G_GNUC_PRINTF(1, 2) owl_log_error(const char *fmt, ...)
     36{
     37  va_list ap;
     38  char *data;
     39
     40  va_start(ap, fmt);
     41  data = g_strdup_vprintf(fmt, ap);
     42  va_end(ap);
     43
     44  owl_select_post_task(owl_log_error_main_thread,
     45                       data, g_free, g_main_context_default());
     46}
     47
     48static void G_GNUC_PRINTF(1, 2) owl_log_adminmsg(const char *fmt, ...)
     49{
     50  va_list ap;
     51  char *data;
     52
     53  va_start(ap, fmt);
     54  data = g_strdup_vprintf(fmt, ap);
     55  va_end(ap);
     56
     57  owl_select_post_task(owl_log_adminmsg_main_thread,
     58                       data, g_free, g_main_context_default());
     59}
     60
     61static void G_GNUC_PRINTF(1, 2) owl_log_makemsg(const char *fmt, ...)
     62{
     63  va_list ap;
     64  char *data;
     65
     66  va_start(ap, fmt);
     67  data = g_strdup_vprintf(fmt, ap);
     68  va_end(ap);
     69
     70  owl_select_post_task(owl_log_makemsg_main_thread,
     71                       data, g_free, g_main_context_default());
     72}
     73
     74static CALLER_OWN owl_log_entry *owl_log_new_entry(const char *buffer, const char *filename)
     75{
     76  owl_log_entry *log_msg = g_slice_new(owl_log_entry);
     77  log_msg->message = g_strdup(buffer);
     78  log_msg->filename = g_strdup(filename);
     79  return log_msg;
     80}
     81
     82static void owl_log_deferred_enqueue_message(const char *buffer, const char *filename)
     83{
     84  g_queue_push_tail(deferred_entry_queue, owl_log_new_entry(buffer, filename));
     85}
     86
     87static void owl_log_deferred_enqueue_first_message(const char *buffer, const char *filename)
     88{
     89  g_queue_push_head(deferred_entry_queue, owl_log_new_entry(buffer, filename));
     90}
     91
     92/* write out the entry if possible
     93 * return 0 on success, errno on failure to open
    1794 */
    18 void owl_log_message(const owl_message *m) {
    19   owl_function_debugmsg("owl_log_message: entering");
    20 
    21   if (m == NULL) {
    22     owl_function_debugmsg("owl_log_message: passed null message");
    23     return;
    24   }
    25 
    26   /* should we be logging this message? */
    27   if (!owl_log_shouldlog_message(m)) {
    28     owl_function_debugmsg("owl_log_message: not logging message");
    29     return;
    30   }
    31 
    32   /* handle incmoing messages */
    33   if (owl_message_is_direction_in(m)) {
    34     owl_log_incoming(m);
    35     owl_function_debugmsg("owl_log_message: leaving");
    36     return;
    37   }
    38 
    39   /* handle outgoing messages */
    40   owl_log_outgoing(m);
    41 
    42   owl_function_debugmsg("owl_log_message: leaving");
    43 }
    44 
    45 /* Return 1 if we should log the given message, otherwise return 0 */
    46 int owl_log_shouldlog_message(const owl_message *m) {
    47   const owl_filter *f;
    48 
    49   /* If there's a logfilter and this message matches it, log */
    50   f=owl_global_get_filter(&g, owl_global_get_logfilter(&g));
    51   if (f && owl_filter_message_match(f, m)) return(1);
    52 
    53   /* otherwise we do things based on the logging variables */
    54 
    55   /* skip login/logout messages if appropriate */
    56   if (!owl_global_is_loglogins(&g) && owl_message_is_loginout(m)) return(0);
    57      
    58   /* check direction */
    59   if ((owl_global_get_loggingdirection(&g)==OWL_LOGGING_DIRECTION_IN) && owl_message_is_direction_out(m)) {
    60     return(0);
    61   }
    62   if ((owl_global_get_loggingdirection(&g)==OWL_LOGGING_DIRECTION_OUT) && owl_message_is_direction_in(m)) {
    63     return(0);
    64   }
    65 
    66   if (owl_message_is_type_zephyr(m)) {
    67     if (owl_message_is_personal(m) && !owl_global_is_logging(&g)) return(0);
    68     if (!owl_message_is_personal(m) && !owl_global_is_classlogging(&g)) return(0);
    69   } else {
    70     if (owl_message_is_private(m) || owl_message_is_loginout(m)) {
    71       if (!owl_global_is_logging(&g)) return(0);
    72     } else {
    73       if (!owl_global_is_classlogging(&g)) return(0);
    74     }
    75   }
    76   return(1);
    77 }
    78 
    79 CALLER_OWN char *owl_log_zephyr(const owl_message *m)
    80 {
    81     char *tmp = NULL;
    82     GString *buffer = NULL;
    83     buffer = g_string_new("");
    84     tmp = short_zuser(owl_message_get_sender(m));
    85     g_string_append_printf(buffer, "Class: %s Instance: %s",
    86                            owl_message_get_class(m),
    87                            owl_message_get_instance(m));
    88     if (strcmp(owl_message_get_opcode(m), "")) {
    89       g_string_append_printf(buffer, " Opcode: %s",
    90                              owl_message_get_opcode(m));
    91     }
    92     g_string_append_printf(buffer, "\n");
    93     g_string_append_printf(buffer, "Time: %s Host: %s\n",
    94                            owl_message_get_timestr(m),
    95                            owl_message_get_hostname(m));
    96     g_string_append_printf(buffer, "From: %s <%s>\n\n",
    97                            owl_message_get_zsig(m), tmp);
    98     g_string_append_printf(buffer, "%s\n\n", owl_message_get_body(m));
    99     g_free(tmp);
    100     return g_string_free(buffer, FALSE);
    101 }
    102 
    103 CALLER_OWN char *owl_log_aim(const owl_message *m)
    104 {
    105     GString *buffer = NULL;
    106     buffer = g_string_new("");
    107     g_string_append_printf(buffer, "From: <%s> To: <%s>\n",
    108                            owl_message_get_sender(m), owl_message_get_recipient(m));
    109     g_string_append_printf(buffer, "Time: %s\n\n",
    110                            owl_message_get_timestr(m));
    111     if (owl_message_is_login(m)) {
    112         g_string_append_printf(buffer, "LOGIN\n\n");
    113     } else if (owl_message_is_logout(m)) {
    114         g_string_append_printf(buffer, "LOGOUT\n\n");
    115     } else {
    116         g_string_append_printf(buffer, "%s\n\n", owl_message_get_body(m));
    117     }
    118     return g_string_free(buffer, FALSE);
    119 }
    120 
    121 CALLER_OWN char *owl_log_jabber(const owl_message *m)
    122 {
    123     GString *buffer = NULL;
    124     buffer = g_string_new("");
    125     g_string_append_printf(buffer, "From: <%s> To: <%s>\n",
    126                            owl_message_get_sender(m),
    127                            owl_message_get_recipient(m));
    128     g_string_append_printf(buffer, "Time: %s\n\n",
    129                            owl_message_get_timestr(m));
    130     g_string_append_printf(buffer, "%s\n\n", owl_message_get_body(m));
    131     return g_string_free(buffer, FALSE);
    132 }
    133 
    134 CALLER_OWN char *owl_log_generic(const owl_message *m)
    135 {
    136     GString *buffer;
    137     buffer = g_string_new("");
    138     g_string_append_printf(buffer, "From: <%s> To: <%s>\n",
    139                            owl_message_get_sender(m),
    140                            owl_message_get_recipient(m));
    141     g_string_append_printf(buffer, "Time: %s\n\n",
    142                            owl_message_get_timestr(m));
    143     g_string_append_printf(buffer, "%s\n\n",
    144                            owl_message_get_body(m));
    145     return g_string_free(buffer, FALSE);
    146 }
    147 
    148 static void owl_log_error_main_thread(gpointer data)
    149 {
    150   owl_function_error("%s", (const char*)data);
    151 }
    152 
    153 static void owl_log_error(const char *message)
    154 {
    155   char *data = g_strdup(message);
    156   owl_select_post_task(owl_log_error_main_thread,
    157                        data, g_free, g_main_context_default());
    158 }
    159 
    160 static void owl_log_write_entry(gpointer data)
    161 {
    162   owl_log_entry *msg = (owl_log_entry*)data;
     95static int owl_log_try_write_entry(owl_log_entry *msg)
     96{
    16397  FILE *file = NULL;
    16498  file = fopen(msg->filename, "a");
    16599  if (!file) {
    166     owl_log_error("Unable to open file for logging");
    167     return;
     100    return errno;
    168101  }
    169102  fprintf(file, "%s", msg->message);
    170103  fclose(file);
    171 }
    172 
    173 static void owl_log_entry_free(void *data)
     104  return 0;
     105}
     106
     107static void owl_log_entry_delete(void *data)
    174108{
    175109  owl_log_entry *msg = (owl_log_entry*)data;
    176   if (msg) {
    177     g_free(msg->message);
    178     g_free(msg->filename);
    179     g_free(msg);
    180   }
     110  g_free(msg->message);
     111  g_free(msg->filename);
     112  g_slice_free(owl_log_entry, msg);
     113}
     114
     115#if GLIB_CHECK_VERSION(2, 32, 0)
     116#else
     117static void owl_log_entry_delete_gfunc(gpointer data, gpointer user_data)
     118{
     119  owl_log_entry_delete(data);
     120}
     121#endif
     122
     123static void owl_log_file_error(owl_log_entry *msg, int errnum)
     124{
     125  owl_log_error("Unable to open file for logging: %s (file %s)",
     126                g_strerror(errnum),
     127                msg->filename);
     128}
     129
     130/* If we are deferring log messages, enqueue this entry for writing.
     131 * Otherwise, try to write this log message, and, if it fails with
     132 * EPERM, EACCES, or ETIMEDOUT, go into deferred logging mode and
     133 * queue an admin message.  If it fails with anything else, display an
     134 * error message, drop the log message, and do not go into deferred
     135 * logging mode.
     136 *
     137 * N.B. This function is called only on the disk-writing thread. */
     138static void owl_log_eventually_write_entry(gpointer data)
     139{
     140  int ret;
     141  owl_log_entry *msg = (owl_log_entry*)data;
     142  if (defer_logs) {
     143    owl_log_deferred_enqueue_message(msg->message, msg->filename);
     144  } else {
     145    ret = owl_log_try_write_entry(msg);
     146    if (ret == EPERM || ret == EACCES || ret == ETIMEDOUT) {
     147      defer_logs = true;
     148      owl_log_error("Unable to open file for logging (%s): \n"
     149                    "%s.  \n"
     150                    "Consider renewing your tickets.  Logging has been \n"
     151                    "suspended, and your messages will be saved.  To \n"
     152                    "resume logging, use the command :flush-logs.\n\n",
     153                    msg->filename,
     154                    g_strerror(ret));
     155      /* If we were not in deferred logging mode, either the queue should be
     156       * empty, or we are attempting to log a message that we just popped off
     157       * the head of the queue.  Either way, we should enqueue this message as
     158       * the first message in the queue, rather than the last, so that we
     159       * preserve message ordering. */
     160      owl_log_deferred_enqueue_first_message(msg->message, msg->filename);
     161    } else if (ret != 0) {
     162      owl_log_file_error(msg, ret);
     163    }
     164  }
     165}
     166
     167/* tries to write the deferred log entries
     168 *
     169 * N.B. This function is called only on the disk-writing thread. */
     170static void owl_log_write_deferred_entries(gpointer data)
     171{
     172  owl_log_entry *entry;
     173  owl_log_options *opts = (owl_log_options *)data;
     174  int ret;
     175  int logged_message_count = 0;
     176  bool all_succeeded = true;
     177
     178  if (opts->display_initial_log_count) {
     179    if (g_queue_is_empty(deferred_entry_queue)) {
     180      owl_log_makemsg("There are no logs to flush.");
     181    } else {
     182      owl_log_makemsg("Attempting to flush %u logs...",
     183                      g_queue_get_length(deferred_entry_queue));
     184    }
     185  }
     186
     187  defer_logs = false;
     188  while (!g_queue_is_empty(deferred_entry_queue) && !defer_logs) {
     189    logged_message_count++;
     190    entry = (owl_log_entry*)g_queue_pop_head(deferred_entry_queue);
     191    if (!opts->drop_failed_logs) {
     192      /* Attempt to write the log entry.  If it fails, re-queue the entry at
     193       * the head of the queue. */
     194      owl_log_eventually_write_entry(entry);
     195    } else {
     196      /* Attempt to write the log entry. If it fails, print an error message,
     197       * drop the log, and keep going through the queue. */
     198      ret = owl_log_try_write_entry(entry);
     199      if (ret != 0) {
     200        all_succeeded = false;
     201        owl_log_file_error(entry, ret);
     202      }
     203    }
     204    owl_log_entry_delete(entry);
     205  }
     206  if (logged_message_count > 0) {
     207    if (opts->display_initial_log_count) {
     208      /* first clear the "attempting to flush" message from the status bar */
     209      owl_log_makemsg("");
     210    }
     211    if (!defer_logs) {
     212      if (all_succeeded) {
     213        owl_log_adminmsg("Flushed %d logs and resumed logging.",
     214                         logged_message_count);
     215      } else {
     216        owl_log_adminmsg("Flushed or dropped %d logs and resumed logging.",
     217                         logged_message_count);
     218      }
     219    } else {
     220      owl_log_error("Attempted to flush %d logs; %u deferred logs remain.",
     221                    logged_message_count, g_queue_get_length(deferred_entry_queue));
     222    }
     223  }
     224}
     225
     226void owl_log_flush_logs(bool drop_failed_logs, bool quiet)
     227{
     228  owl_log_options *data = g_new(owl_log_options, 1);
     229  data->drop_failed_logs = drop_failed_logs;
     230  data->display_initial_log_count = !quiet;
     231
     232  owl_select_post_task(owl_log_write_deferred_entries,
     233                       data,
     234                       g_free,
     235                       log_context);
    181236}
    182237
    183238void owl_log_enqueue_message(const char *buffer, const char *filename)
    184239{
    185   owl_log_entry *log_msg = NULL;
    186   log_msg = g_new(owl_log_entry,1);
    187   log_msg->message = g_strdup(buffer);
    188   log_msg->filename = g_strdup(filename);
    189   owl_select_post_task(owl_log_write_entry, log_msg,
    190                        owl_log_entry_free, log_context);
    191 }
    192 
    193 void owl_log_append(const owl_message *m, const char *filename) {
    194   char *buffer = NULL;
    195   if (owl_message_is_type_zephyr(m)) {
    196     buffer = owl_log_zephyr(m);
    197   } else if (owl_message_is_type_jabber(m)) {
    198     buffer = owl_log_jabber(m);
    199   } else if (owl_message_is_type_aim(m)) {
    200     buffer = owl_log_aim(m);
    201   } else {
    202     buffer = owl_log_generic(m);
    203   }
    204   owl_log_enqueue_message(buffer, filename);
    205   g_free(buffer);
    206 }
    207 
    208 void owl_log_outgoing(const owl_message *m)
    209 {
    210   char *filename, *logpath;
    211   char *to, *temp;
    212   GList *cc;
    213 
    214   /* expand ~ in path names */
    215   logpath = owl_util_makepath(owl_global_get_logpath(&g));
    216 
    217   /* Figure out what path to log to */
    218   if (owl_message_is_type_zephyr(m)) {
    219     /* If this has CC's, do all but the "recipient" which we'll do below */
    220     cc = owl_message_get_cc_without_recipient(m);
    221     while (cc != NULL) {
    222       temp = short_zuser(cc->data);
    223       filename = g_build_filename(logpath, temp, NULL);
    224       owl_log_append(m, filename);
    225 
    226       g_free(filename);
    227       g_free(temp);
    228       g_free(cc->data);
    229       cc = g_list_delete_link(cc, cc);
    230     }
    231 
    232     to = short_zuser(owl_message_get_recipient(m));
    233   } else if (owl_message_is_type_jabber(m)) {
    234     to = g_strdup_printf("jabber:%s", owl_message_get_recipient(m));
    235     g_strdelimit(to, "/", '_');
    236   } else if (owl_message_is_type_aim(m)) {
    237     char *temp2;
    238     temp = owl_aim_normalize_screenname(owl_message_get_recipient(m));
    239     temp2 = g_utf8_strdown(temp,-1);
    240     to = g_strdup_printf("aim:%s", temp2);
    241     g_free(temp2);
    242     g_free(temp);
    243   } else {
    244     to = g_strdup("loopback");
    245   }
    246 
    247   filename = g_build_filename(logpath, to, NULL);
    248   owl_log_append(m, filename);
    249   g_free(to);
    250   g_free(filename);
    251 
    252   filename = g_build_filename(logpath, "all", NULL);
    253   owl_log_append(m, filename);
    254   g_free(logpath);
    255   g_free(filename);
    256 }
    257 
     240  owl_log_entry *log_msg = owl_log_new_entry(buffer, filename);
     241  owl_select_post_task(owl_log_eventually_write_entry, log_msg,
     242                       owl_log_entry_delete, log_context);
     243}
    258244
    259245void owl_log_outgoing_zephyr_error(const owl_zwrite *zw, const char *text)
    260246{
    261   char *filename, *logpath;
    262   char *tobuff, *recip;
    263   owl_message *m;
    264   GString *msgbuf;
    265   /* create a present message so we can pass it to
    266    * owl_log_shouldlog_message(void)
    267    */
    268   m = g_new(owl_message, 1);
     247  owl_message *m = g_slice_new(owl_message);
    269248  /* recip_index = 0 because there can only be one recipient anyway */
    270249  owl_message_create_from_zwrite(m, zw, text, 0);
    271   if (!owl_log_shouldlog_message(m)) {
    272     owl_message_delete(m);
    273     return;
    274   }
     250  g_free(owl_perlconfig_call_with_message("BarnOwl::Logging::log_outgoing_error", m));
    275251  owl_message_delete(m);
    276 
    277   /* chop off a local realm */
    278   recip = owl_zwrite_get_recip_n_with_realm(zw, 0);
    279   tobuff = short_zuser(recip);
    280   g_free(recip);
    281 
    282   /* expand ~ in path names */
    283   logpath = owl_util_makepath(owl_global_get_logpath(&g));
    284   filename = g_build_filename(logpath, tobuff, NULL);
    285   msgbuf = g_string_new("");
    286   g_string_printf(msgbuf, "ERROR (owl): %s\n%s\n", tobuff, text);
    287   if (text[strlen(text)-1] != '\n') {
    288     g_string_append_printf(msgbuf, "\n");
    289   }
    290   owl_log_enqueue_message(msgbuf->str, filename);
    291   g_string_free(msgbuf, TRUE);
    292 
    293   filename = g_build_filename(logpath, "all", NULL);
    294   g_free(logpath);
    295   msgbuf = g_string_new("");
    296   g_string_printf(msgbuf, "ERROR (owl): %s\n%s\n", tobuff, text);
    297   if (text[strlen(text)-1] != '\n') {
    298     g_string_append_printf(msgbuf, "\n");
    299   }
    300   owl_log_enqueue_message(msgbuf->str, filename);
    301   g_string_free(msgbuf, TRUE);
    302 
    303   g_free(tobuff);
    304 }
    305 
    306 void owl_log_incoming(const owl_message *m)
    307 {
    308   char *filename, *allfilename, *logpath;
    309   const char *from=NULL;
    310   char *frombuff=NULL;
    311   int len, ch, i, personal;
    312 
    313   /* figure out if it's a "personal" message or not */
    314   if (owl_message_is_type_zephyr(m)) {
    315     if (owl_message_is_personal(m)) {
    316       personal = 1;
    317     } else {
    318       personal = 0;
    319     }
    320   } else if (owl_message_is_type_jabber(m)) {
    321     /* This needs to be fixed to handle groupchat */
    322     const char* msgtype = owl_message_get_attribute_value(m,"jtype");
    323     if (msgtype && !strcmp(msgtype,"groupchat")) {
    324       personal = 0;
    325     } else {
    326       personal = 1;
    327     }
    328   } else {
    329     if (owl_message_is_private(m) || owl_message_is_loginout(m)) {
    330       personal = 1;
    331     } else {
    332       personal = 0;
    333     }
    334   }
    335 
    336 
    337   if (owl_message_is_type_zephyr(m)) {
    338     if (personal) {
    339       from=frombuff=short_zuser(owl_message_get_sender(m));
    340     } else {
    341       from=frombuff=g_strdup(owl_message_get_class(m));
    342     }
    343   } else if (owl_message_is_type_aim(m)) {
    344     /* we do not yet handle chat rooms */
    345     char *normalto, *temp;
    346     temp = owl_aim_normalize_screenname(owl_message_get_sender(m));
    347     normalto = g_utf8_strdown(temp, -1);
    348     from=frombuff=g_strdup_printf("aim:%s", normalto);
    349     g_free(normalto);
    350     g_free(temp);
    351   } else if (owl_message_is_type_loopback(m)) {
    352     from=frombuff=g_strdup("loopback");
    353   } else if (owl_message_is_type_jabber(m)) {
    354     if (personal) {
    355       from=frombuff=g_strdup_printf("jabber:%s",
    356                                     owl_message_get_sender(m));
    357     } else {
    358       from=frombuff=g_strdup_printf("jabber:%s",
    359                                     owl_message_get_recipient(m));
    360     }
    361   } else {
    362     from=frombuff=g_strdup("unknown");
    363   }
    364  
    365   /* check for malicious sender formats */
    366   len=strlen(frombuff);
    367   if (len<1 || len>35) from="weird";
    368   if (strchr(frombuff, '/')) from="weird";
    369 
    370   ch=frombuff[0];
    371   if (!g_ascii_isalnum(ch)) from="weird";
    372 
    373   for (i=0; i<len; i++) {
    374     if (frombuff[i]<'!' || frombuff[i]>='~') from="weird";
    375   }
    376 
    377   if (!strcmp(frombuff, ".") || !strcasecmp(frombuff, "..")) from="weird";
    378 
    379   if (!personal) {
    380     if (strcmp(from, "weird")) {
    381       char* temp = g_utf8_strdown(frombuff, -1);
    382       if (temp) {
    383         g_free(frombuff);
    384         from = frombuff = temp;
    385       }
    386     }
    387   }
    388 
    389   /* create the filename (expanding ~ in path names) */
    390   if (personal) {
    391     logpath = owl_util_makepath(owl_global_get_logpath(&g));
    392     filename = g_build_filename(logpath, from, NULL);
    393     allfilename = g_build_filename(logpath, "all", NULL);
    394     owl_log_append(m, allfilename);
    395     g_free(allfilename);
    396   } else {
    397     logpath = owl_util_makepath(owl_global_get_classlogpath(&g));
    398     filename = g_build_filename(logpath, from, NULL);
    399   }
    400 
    401   owl_log_append(m, filename);
    402   g_free(filename);
    403 
    404   if (personal && owl_message_is_type_zephyr(m)) {
    405     /* We want to log to all of the CC'd people who were not us, or
    406      * the sender, as well.
    407      */
    408     char *temp;
    409     GList *cc;
    410     cc = owl_message_get_cc_without_recipient(m);
    411     while (cc != NULL) {
    412       temp = short_zuser(cc->data);
    413       if (strcasecmp(temp, frombuff) != 0) {
    414         filename = g_build_filename(logpath, temp, NULL);
    415         owl_log_append(m, filename);
    416         g_free(filename);
    417       }
    418 
    419       g_free(temp);
    420       g_free(cc->data);
    421       cc = g_list_delete_link(cc, cc);
    422     }
    423   }
    424 
    425   g_free(frombuff);
    426   g_free(logpath);
    427252}
    428253
    429254static gpointer owl_log_thread_func(gpointer data)
    430255{
     256  log_context = g_main_context_new();
    431257  log_loop = g_main_loop_new(log_context, FALSE);
    432258  g_main_loop_run(log_loop);
     
    434260}
    435261
    436 void owl_log_init(void) 
     262void owl_log_init(void)
    437263{
    438264  log_context = g_main_context_new();
     
    454280  }
    455281#endif
    456  
     282
     283  deferred_entry_queue = g_queue_new();
    457284}
    458285
    459286static void owl_log_quit_func(gpointer data)
    460287{
     288  /* flush the deferred logs queue, trying to write the
     289   * entries to the disk one last time.  Drop any failed
     290   * entries, and be quiet about it. */
     291  owl_log_options opts;
     292  opts.drop_failed_logs = true;
     293  opts.display_initial_log_count = false;
     294  owl_log_write_deferred_entries(&opts);
     295#if GLIB_CHECK_VERSION(2, 32, 0)
     296  g_queue_free_full(deferred_entry_queue, owl_log_entry_delete);
     297#else
     298  g_queue_foreach(deferred_entry_queue, owl_log_entry_delete_gfunc, NULL);
     299  g_queue_free(deferred_entry_queue);
     300#endif
     301
    461302  g_main_loop_quit(log_loop);
    462303}
  • mainwin.c

    rab88b05 r7dcef03  
    66CALLER_OWN owl_mainwin *owl_mainwin_new(owl_window *window)
    77{
    8   owl_mainwin *mw = g_new(owl_mainwin, 1);
     8  owl_mainwin *mw = g_slice_new(owl_mainwin);
    99  mw->curtruncated=0;
    1010  mw->lastdisplayed=-1;
  • message.c

    r2354e9a r4fd3c04  
    3030void owl_message_init(owl_message *m)
    3131{
     32  /* ctime_r requires a 26-byte buffer */
     33  char timestr[26];
     34
    3235  m->id=owl_global_get_nextmsgid(&g);
    3336  owl_message_set_direction_none(m);
     
    4346  /* save the time */
    4447  m->time = time(NULL);
    45   m->timestr = g_strdup(ctime(&m->time));
    46   m->timestr[strlen(m->timestr)-1] = '\0';
     48  ctime_r(&m->time, timestr);
     49  m->timestr = g_strndup(timestr, strlen(timestr) - 1);
    4750
    4851  m->fmtext = NULL;
     
    7073
    7174  if(pair ==  NULL) {
    72     pair = g_new(owl_pair, 1);
     75    pair = g_slice_new(owl_pair);
    7376    owl_pair_create(pair, attrname, NULL);
    7477    g_ptr_array_add(m->attributes, pair);
     
    349352CALLER_OWN char *owl_message_format_time(const owl_message *m)
    350353{
    351   return owl_util_format_time(localtime(&m->time));
     354  struct tm tm;
     355  return owl_util_format_time(localtime_r(&m->time, &tm));
    352356}
    353357
     
    365369{
    366370  owl_message_set_attribute(m, "type", "zephyr");
    367 }
    368 
    369 void owl_message_set_type_aim(owl_message *m)
    370 {
    371   owl_message_set_attribute(m, "type", "AIM");
    372371}
    373372
     
    391390{
    392391  return owl_message_is_type(m, "zephyr");
    393 }
    394 
    395 int owl_message_is_type_aim(const owl_message *m)
    396 {
    397   return owl_message_is_type(m, "aim");
    398 }
    399 
    400 /* XXX TODO: deprecate this */
    401 int owl_message_is_type_jabber(const owl_message *m)
    402 {
    403   return owl_message_is_type(m, "jabber");
    404392}
    405393
     
    599587CALLER_OWN GList *owl_message_get_cc_without_recipient(const owl_message *m)
    600588{
    601   char *cc, *shortuser, *recip;
     589  char *cc, *shortuser, *recip, *saveptr;
    602590  const char *user;
    603591  GList *out = NULL;
     
    609597  recip = short_zuser(owl_message_get_recipient(m));
    610598
    611   user = strtok(cc, " ");
     599  user = strtok_r(cc, " ", &saveptr);
    612600  while (user != NULL) {
    613601    shortuser = short_zuser(user);
     
    616604    }
    617605    g_free(shortuser);
    618     user = strtok(NULL, " ");
     606    user = strtok_r(NULL, " ", &saveptr);
    619607  }
    620608
     
    689677
    690678
    691 /* if loginout == -1 it's a logout message
    692  *                 0 it's not a login/logout message
    693  *                 1 it's a login message
    694  */
    695 void owl_message_create_aim(owl_message *m, const char *sender, const char *recipient, const char *text, int direction, int loginout)
    696 {
    697   owl_message_init(m);
    698   owl_message_set_body(m, text);
    699   owl_message_set_sender(m, sender);
    700   owl_message_set_recipient(m, recipient);
    701   owl_message_set_type_aim(m);
    702 
    703   if (direction==OWL_MESSAGE_DIRECTION_IN) {
    704     owl_message_set_direction_in(m);
    705   } else if (direction==OWL_MESSAGE_DIRECTION_OUT) {
    706     owl_message_set_direction_out(m);
    707   }
    708 
    709   /* for now all messages that aren't loginout are private */
    710   if (!loginout) {
    711     owl_message_set_isprivate(m);
    712   }
    713 
    714   if (loginout==-1) {
    715     owl_message_set_islogout(m);
    716   } else if (loginout==1) {
    717     owl_message_set_islogin(m);
    718   }
    719 }
    720 
    721679void owl_message_create_admin(owl_message *m, const char *header, const char *text)
    722680{
     
    781739  struct hostent *hent;
    782740#endif /* ZNOTICE_SOCKADDR */
    783   char *tmp, *tmp2;
     741  /* ctime_r requires a 26-byte buffer */
     742  char timestr[26], *tmp, *tmp2;
    784743  int len;
    785744
     
    799758  if (m->timestr) g_free(m->timestr);
    800759  m->time = n->z_time.tv_sec;
    801   m->timestr = g_strdup(ctime(&m->time));
    802   m->timestr[strlen(m->timestr)-1] = '\0';
     760  ctime_r(&m->time, timestr);
     761  m->timestr = g_strndup(timestr, strlen(timestr) - 1);
    803762
    804763  /* set other info */
     
    1019978    p = m->attributes->pdata[i];
    1020979    g_free(owl_pair_get_value(p));
    1021     g_free(p);
     980    g_slice_free(owl_pair, p);
    1022981  }
    1023982
     
    1030989{
    1031990  owl_message_cleanup(m);
    1032   g_free(m);
    1033 }
     991  g_slice_free(owl_message, m);
     992}
  • messagelist.c

    r219f52c r7dcef03  
    33CALLER_OWN owl_messagelist *owl_messagelist_new(void)
    44{
    5   owl_messagelist *ml = g_new(owl_messagelist, 1);
     5  owl_messagelist *ml = g_slice_new(owl_messagelist);
    66  ml->list = g_ptr_array_new();
    77  return ml;
     
    1313    g_ptr_array_foreach(ml->list, (GFunc)owl_message_delete, NULL);
    1414  g_ptr_array_free(ml->list, true);
    15   g_free(ml);
     15  g_slice_free(owl_messagelist, ml);
    1616}
    1717
  • owl.c

    r120dac7 r4fd3c04  
    3636void usage(FILE *file)
    3737{
    38   fprintf(file, "Barnowl version %s\n", OWL_VERSION_STRING);
     38  fprintf(file, "BarnOwl version %s\n", version);
    3939  fprintf(file, "Usage: barnowl [-n] [-d] [-D] [-v] [-h] [-c <configfile>] [-s <confdir>] [-t <ttyname>]\n");
    4040  fprintf(file, "  -n,--no-subs        don't load zephyr subscriptions\n");
    4141  fprintf(file, "  -d,--debug          enable debugging\n");
    42   fprintf(file, "  -v,--version        print the Barnowl version number and exit\n");
     42  fprintf(file, "  -v,--version        print the BarnOwl version number and exit\n");
    4343  fprintf(file, "  -h,--help           print this help message\n");
    4444  fprintf(file, "  -s,--config-dir     specify an alternate config dir (default ~/.owl)\n");
     
    8080      break;
    8181    case 'v':
    82       printf("This is BarnOwl version %s\n", OWL_VERSION_STRING);
     82      printf("This is BarnOwl version %s\n", version);
    8383      exit(0);
    8484    case 'h':
     
    187187      if (owl_message_is_type_zephyr(m)) {
    188188        owl_zephyr_zaway(m);
    189       } else if (owl_message_is_type_aim(m)) {
    190         if (owl_message_is_private(m)) {
    191           owl_function_send_aimawymsg(owl_message_get_sender(m), owl_global_get_zaway_msg(&g));
    192         }
    193189      }
    194190    }
     
    230226  /* let perl know about it */
    231227  owl_perlconfig_newmsg(m, NULL);
    232   /* log the message if we need to */
    233   owl_log_message(m);
    234228  /* redraw the sepbar; TODO: don't violate layering */
    235229  owl_global_sepbar_dirty(&g);
     
    506500  owl_global_set_startupargs(&g, argc_copy, argv_copy);
    507501  g_strfreev(argv_copy);
    508   owl_global_set_haveaim(&g);
    509502
    510503  owl_register_signal_handlers();
     
    567560                  owl_global_get_style_by_name(&g, "default"));
    568561
    569   /* AIM init */
    570   owl_function_debugmsg("startup: doing AIM initialization");
    571   owl_aim_init();
    572 
    573562  /* execute the startup function in the configfile */
    574563  owl_function_debugmsg("startup: executing perl startup, if applicable");
     
    578567  /* welcome message */
    579568  owl_function_debugmsg("startup: creating splash message");
    580   owl_function_adminmsg("",
     569  char *welcome = g_strdup_printf(
    581570    "-----------------------------------------------------------------------\n"
    582     "Welcome to BarnOwl version " OWL_VERSION_STRING ".\n"
     571    "Welcome to BarnOwl version %s.\n"
    583572    "To see a quick introduction, type ':show quickstart'.                  \n"
    584573    "Press 'h' for on-line help.                                            \n"
     
    588577    "                                                                 OvO   \n"
    589578    "Please report any bugs or suggestions to bug-barnowl@mit.edu    (   )  \n"
    590     "-----------------------------------------------------------------m-m---\n"
    591   );
     579    "-----------------------------------------------------------------m-m---\n",
     580    version);
     581  owl_function_adminmsg("", welcome);
     582  g_free(welcome);
    592583
    593584  owl_function_debugmsg("startup: setting context interactive");
  • owl.h

    r120dac7 r4fd3c04  
    3535#include <termios.h>
    3636#include <unistd.h>
    37 #include "libfaim/aim.h"
    3837#include <wchar.h>
    3938#include <glib.h>
     
    6463#include "window.h"
    6564
    66 #ifndef OWL_VERSION_STRING
    67 #ifdef  GIT_VERSION
    68 #define stringify(x)       __stringify(x)
    69 #define __stringify(x)     #x
    70 #define OWL_VERSION_STRING stringify(GIT_VERSION)
    71 #else
    72 #define OWL_VERSION_STRING PACKAGE_VERSION
    73 #endif
    74 #endif /* !OWL_VERSION_STRING */
     65extern const char *version;
    7566
    7667/* Feature that is being tested to redirect stderr through a pipe.
     
    116107#define OWL_EDITWIN_STYLE_MULTILINE 0
    117108#define OWL_EDITWIN_STYLE_ONELINE   1
    118 
    119 #define OWL_PROTOCOL_ZEPHYR         0
    120 #define OWL_PROTOCOL_AIM            1
    121 #define OWL_PROTOCOL_JABBER         2
    122 #define OWL_PROTOCOL_ICQ            3
    123 #define OWL_PROTOCOL_YAHOO          4
    124 #define OWL_PROTOCOL_MSN            5
    125109
    126110#define OWL_MESSAGE_DIRECTION_NONE  0
     
    186170
    187171#define OWL_DEFAULT_ZAWAYMSG    "I'm sorry, but I am currently away from the terminal and am\nnot able to receive your message.\n"
    188 #define OWL_DEFAULT_AAWAYMSG    "I'm sorry, but I am currently away from the terminal and am\nnot able to receive your message.\n"
    189172
    190173#define OWL_CMD_ALIAS_SUMMARY_PREFIX "command alias to: "
     
    500483  int       kpstackpos;         /* location in stack (-1 = none) */
    501484} owl_keyhandler;
    502 
    503 typedef struct _owl_buddy {
    504   int proto;
    505   char *name;
    506   int isidle;
    507   int idlesince;
    508 } owl_buddy;
    509 
    510 typedef struct _owl_buddylist {
    511   GPtrArray *buddies;
    512 } owl_buddylist;
    513485
    514486typedef struct _owl_zbuddylist {
     
    577549  pid_t newmsgproc_pid;
    578550  owl_regex search_re;
    579   aim_session_t aimsess;
    580   aim_conn_t bosconn;
    581   int aim_loggedin;         /* true if currently logged into AIM */
    582   GSource *aim_event_source; /* where we get our AIM events from */
    583   char *aim_screenname;     /* currently logged in AIM screen name */
    584   char *aim_screenname_for_filters;     /* currently logged in AIM screen name */
    585   owl_buddylist buddylist;  /* list of logged in AIM buddies */
    586   GQueue *messagequeue;     /* for queueing up aim and other messages */
     551  GQueue *messagequeue;     /* for queueing up messages */
    587552  owl_dict styledict;       /* global dictionary of available styles */
    588553  char *response;           /* response to the last question asked */
    589554  int havezephyr;
    590   int haveaim;
    591   int ignoreaimlogin;
    592555  owl_zbuddylist zbuddies;
    593556  GList *zaldlist;
    594557  int pseudologin_notify;
    595558  struct termios startup_tio;
    596   guint aim_nop_timer;
    597559  int load_initial_subs;
    598560  FILE *debug_file;
  • perl/Makefile.am

    ra870319 r4fd3c04  
    22nobase_dist_pkgdata_DATA = \
    33        lib/BarnOwl.pm \
    4         lib/BarnOwl/Complete/AIM.pm \
    54        lib/BarnOwl/Complete/Client.pm \
    65        lib/BarnOwl/Complete/Filter.pm \
     
    98        lib/BarnOwl/Completion/Context.pm \
    109        lib/BarnOwl/Completion/Util.pm \
     10        lib/BarnOwl/DeferredLogging.pm \
    1111        lib/BarnOwl/Editwin.pm \
    1212        lib/BarnOwl/Help.pm \
    1313        lib/BarnOwl/Hook.pm \
    1414        lib/BarnOwl/Hooks.pm \
     15        lib/BarnOwl/Logging.pm \
    1516        lib/BarnOwl/MainLoopCompatHook.pm \
    1617        lib/BarnOwl/Message.pm \
    17         lib/BarnOwl/Message/AIM.pm \
    1818        lib/BarnOwl/Message/Admin.pm \
    1919        lib/BarnOwl/Message/Generic.pm \
  • perl/lib/BarnOwl.pm

    recd4edf reea7bed4  
    1616                    create_style getnumcolors wordwrap
    1717                    message_matches_filter
     18                    get_variable_info
    1819                    add_dispatch remove_dispatch
    1920                    add_io_dispatch remove_io_dispatch
     
    3839use BarnOwl::Hook;
    3940use BarnOwl::Hooks;
     41use BarnOwl::Logging;
    4042use BarnOwl::Message;
    4143use BarnOwl::Style;
     
    4547use BarnOwl::Completion;
    4648use BarnOwl::Help;
     49use BarnOwl::DeferredLogging;
    4750
    4851use List::Util qw(max);
     
    249252C<QUIET> is false, this method displays an error message if
    250253if C<FILTER_NAME> does not name a valid filter.
     254
     255=head2 get_variable_info VARIABLE_NAME
     256
     257Returns a hash with the following keys, describing the variable named:
     258
     259=over
     260
     261=item name
     262
     263=item description
     264
     265=item summary
     266
     267=item validsettings
     268
     269=item takes_on_off
     270
     271=back
     272
     273Fails if C<VARIABLE_NAME> does not name a valid variable.
    251274
    252275=head2 add_dispatch FD CALLBACK
  • perl/lib/BarnOwl/Complete/Client.pm

    r4626016 r1f92f39  
    146146sub complete_set {
    147147    my $ctx = shift;
    148     return complete_flags($ctx,
    149         [qw(-q)],
    150         {
    151         },
    152          \&complete_set_args
    153         );
    154 }
    155 sub complete_set_args {
    156     my $ctx = shift;
    157     my $arg = shift;
    158     return if $arg;
    159     return complete_variable();
     148    my $is_unset = ($ctx->words->[0] eq "unset");
     149
     150    # Shift away the -q if seen.
     151    my $seen_q = 0;
     152    if ($ctx->word > 1 && $ctx->words->[1] eq "-q") {
     153        $seen_q = 1;
     154        $ctx = $ctx->shift_words(1);
     155    }
     156
     157    # First argument is the variable.
     158    if ($ctx->word == 1) {
     159        my @vars = complete_variable();
     160        if ($is_unset) {
     161            # Only complete the variables which are unsettable.
     162            @vars = grep { BarnOwl::get_variable_info($_)->{takes_on_off} } @vars;
     163        }
     164        unshift(@vars, "-q") unless $seen_q;
     165        return @vars;
     166    }
     167    # For set, second argument is the value.
     168    if (!$is_unset && $ctx->word == 2) {
     169        # Parse what we can out of validsettings.
     170        my $info;
     171        eval { $info = BarnOwl::get_variable_info($ctx->words->[1]) };
     172        return if $@;
     173        if ($info->{validsettings} eq "<path>") {
     174            return complete_file($ctx->words->[2]);
     175        } elsif ($info->{validsettings} !~ /^<.*>$/) {
     176            # Assume it's a comma-separated list of values;
     177            return split(",", $info->{validsettings});
     178        }
     179    }
     180    return;
    160181}
    161182
  • perl/lib/BarnOwl/Complete/Filter.pm

    r6dba228 r4fd3c04  
    3636    body      => undef,
    3737    hostname  => undef,
    38     type      => sub { qw(zephyr aim admin); },
     38    type      => sub { qw(zephyr admin); },
    3939    direction => sub { qw(in out none); },
    4040    login     => sub { qw(login logout none); },
  • perl/lib/BarnOwl/Message.pm

    r0adbce1 r4fd3c04  
    44package BarnOwl::Message;
    55
     6use File::Spec;
     7
    68use BarnOwl::Message::Admin;
    7 use BarnOwl::Message::AIM;
    89use BarnOwl::Message::Generic;
    910use BarnOwl::Message::Loopback;
     
    4142sub is_generic  { return (shift->{"type"} eq "generic"); }
    4243sub is_zephyr   { return (shift->{"type"} eq "zephyr"); }
    43 sub is_aim      { return (shift->{"type"} eq "AIM"); }
     44sub is_aim      { return ''; }
    4445sub is_jabber   { return (shift->{"type"} eq "jabber"); }
    4546sub is_icq      { return (shift->{"type"} eq "icq"); }
     
    115116    }
    116117    return $s;
     118}
     119
     120=head2 log MESSAGE
     121
     122Returns the text that should be written to a file to log C<MESSAGE>.
     123
     124=cut
     125
     126sub log {
     127    my ($m) = @_;
     128    return $m->log_header . "\n\n" . $m->log_body . "\n\n";
     129}
     130
     131=head2 log_header MESSAGE
     132
     133Returns the header of the message, for logging purposes.
     134If you override L<BarnOwl::Message::log>, this method is not called.
     135
     136=cut
     137
     138sub log_header {
     139    my ($m) = @_;
     140    my $sender = $m->sender;
     141    my $recipient = $m->recipient;
     142    my $timestr = $m->time;
     143    return "From: <$sender> To: <$recipient>\n"
     144         . "Time: $timestr";
     145}
     146
     147=head2 log_body MESSAGE
     148
     149Returns the body of the message, for logging purposes.
     150If you override L<BarnOwl::Message::log>, this method is not called.
     151
     152=cut
     153
     154sub log_body {
     155    my ($m) = @_;
     156    if ($m->is_loginout) {
     157        return uc($m->login)
     158            . $m->login_type
     159            . ($m->login_extra ? ' at ' . $m->login_extra : '');
     160    } else {
     161        return $m->body;
     162    }
     163}
     164
     165=head2 log_filenames MESSAGE
     166
     167Returns a list of filenames to which this message should be logged.
     168The filenames should be relative to the path returned by C<log_path>.
     169See L<BarnOwl::Logging::get_filenames> for the specification of valid
     170filenames, and for what happens if this method returns an invalid
     171filename.
     172
     173=cut
     174
     175sub log_filenames {
     176    my ($m) = @_;
     177    my $filename;
     178    if ($m->is_incoming) {
     179        $filename = $m->pretty_sender;
     180    } elsif ($m->is_outgoing) {
     181        $filename = $m->pretty_recipient;
     182    }
     183    $filename = "unknown" if !defined($filename) || $filename eq '';
     184    if (BarnOwl::getvar('log-to-subdirectories') eq 'on') {
     185        return ($filename);
     186    } else {
     187        return ($m->log_subfolder . ':' . $filename);
     188    }
     189}
     190
     191=head2 log_to_all_file MESSAGE
     192
     193There is an C<all> file.  This method determines if C<MESSAGE>
     194should get logged to it, in addition to any files returned by
     195C<log_filenames>.
     196
     197It defaults to returning true if and only if C<MESSAGE> is outgoing.
     198
     199=cut
     200
     201sub log_to_all_file {
     202    my ($m) = @_;
     203    return $m->is_outgoing;
     204}
     205
     206=head2 log_path MESSAGE
     207
     208Returns the folder in which all messages of this class get logged.
     209
     210Defaults to C<log_base_path/log_subfolder> if C<log-to-subdirectories>
     211is enabled, or to the C<logpath> BarnOwl variable if it is not.
     212
     213Most protocols should override C<log_subfolder> rather than
     214C<log_path>, in order to properly take into account the value of
     215C<log-to-subdirectories>.
     216
     217=cut
     218
     219sub log_path {
     220    my ($m) = @_;
     221    if (BarnOwl::getvar('log-to-subdirectories') eq 'on') {
     222        return File::Spec->catfile($m->log_base_path, $m->log_subfolder);
     223    } else {
     224        return BarnOwl::getvar('logpath');
     225    }
     226}
     227
     228=head2 log_base_path MESSAGE
     229
     230Returns the base path for logging.  See C<log_path> for more information.
     231
     232Defaults to the BarnOwl variable C<logbasepath>.
     233
     234=cut
     235
     236sub log_base_path {
     237    return BarnOwl::getvar('logbasepath');
     238}
     239
     240=head2 log_subfolder MESSAGE
     241
     242Returns the subfolder of C<log_base_path> to log messages in.
     243
     244Defaults to C<lc($m->type)>.
     245
     246=cut
     247
     248sub log_subfolder {
     249    return lc(shift->type);
     250}
     251
     252=head2 log_outgoing_error MESSAGE
     253
     254Returns the string that should be logged if there is an error sending
     255an outgoing message.
     256
     257=cut
     258
     259sub log_outgoing_error {
     260    my ($m) = @_;
     261    my $recipient = $m->pretty_recipient;
     262    my $body = $m->body;
     263    chomp $body;
     264    return "ERROR (BarnOwl): $recipient\n$body\n\n";
     265}
     266
     267=head2 should_log MESSAGE
     268
     269Returns true if we should log C<MESSAGE>.  This does not override
     270user settings; if the BarnOwl variable C<loggingdirection> is in,
     271and C<MESSAGE> is outgoing and does not match the C<logfilter>, it
     272will not get logged regardless of what this method returns.
     273
     274Note that this method I<does> override the BarnOwl C<logging>
     275variable; if a derived class overrides this method and does not
     276provide an alternative BarnOwl variable (such as C<classlogging>),
     277the overriding method should check the BarnOwl C<logging> variable.
     278
     279Defaults to returning the value of the BarnOwl variable C<logging>.
     280
     281=cut
     282
     283sub should_log {
     284    return BarnOwl::getvar('logging') eq 'on';
    117285}
    118286
  • perl/lib/BarnOwl/Message/Loopback.pm

    ree183be r8cec8f7  
    1414sub replysendercmd {return 'loopwrite';}
    1515
     16sub log_subfolder { return ''; }
     17sub log_filenames { return ('loopback'); }
    1618
    17191;
  • perl/lib/BarnOwl/Message/Zephyr.pm

    r0adbce1 r8f91a70  
    2121    my ($user, $realm) = split(/@/,$principal);
    2222    return $realm;
     23}
     24
     25sub casefold_principal {
     26    my $principal = shift;
     27    # split the principal right after the final @, without eating any
     28    # characters; this way, we always get at least '@' in $user
     29    my ($user, $realm) = split(/(?<=@)(?=[^@]+$)/, $principal);
     30    $user = '' if !defined $user;
     31    $user = lc($user);
     32    $user = $user . uc($realm) if defined $realm;
     33    return $user;
    2334}
    2435
     
    132143    return $1 if $self->body =~ /^\s*cc:\s+([^\n]+)/i;
    133144    return undef;
     145}
     146
     147# Note: This is the cc-line without the recipient; it does not include
     148# the sender.
     149sub zephyr_cc_without_recipient {
     150    my $self = shift;
     151    my $recipient = lc(strip_realm($self->recipient));
     152    my $cc = $self->zephyr_cc;
     153    return grep { lc(strip_realm($_)) ne $recipient } split(/\s+/, $cc) if defined $cc;
     154    return ();
    134155}
    135156
     
    223244}
    224245
     246# Logging
     247sub log_header {
     248    my ($m) = @_;
     249    my $class = $m->class;
     250    my $instance = $m->instance;
     251    my $opcode = $m->opcode;
     252    my $timestr = $m->time;
     253    my $host = $m->host;
     254    my $sender = $m->pretty_sender;
     255    my $zsig = $m->zsig;
     256    my $rtn = "Class: $class Instance: $instance";
     257    $rtn .= " Opcode: $opcode" unless !defined $opcode || $opcode eq '';
     258    $rtn .= "\nTime: $timestr Host: $host"
     259          . "\nFrom: $zsig <$sender>";
     260    return $rtn;
     261}
     262
     263sub log_filenames {
     264    my ($m) = @_;
     265    my @filenames = ();
     266    if ($m->is_personal) {
     267        # If this has CC's, add all but the "recipient" which we'll add below
     268        @filenames = $m->zephyr_cc_without_recipient;
     269    }
     270    if ($m->is_incoming) {
     271        if ($m->is_personal) {
     272            push @filenames, $m->sender;
     273        } else {
     274            my $realm = '';
     275            $realm .= '@' . $m->realm if $m->realm ne BarnOwl::zephyr_getrealm();
     276            return (BarnOwl::compat_casefold($m->class) . uc($realm));
     277        }
     278    } else {
     279        push @filenames, $m->recipient;
     280    }
     281    return map { casefold_principal(BarnOwl::zephyr_smartstrip_user(strip_realm($_))) } @filenames;
     282}
     283
     284sub log_to_class_file {
     285    my ($m) = @_;
     286    return !$m->is_personal;
     287}
     288
     289sub log_path {
     290    my ($m) = @_;
     291    if ($m->log_to_class_file) {
     292        return BarnOwl::getvar('classlogpath');
     293    } else {
     294        return BarnOwl::getvar('logpath');
     295    }
     296}
     297
     298sub should_log {
     299    my ($m) = @_;
     300    if ($m->log_to_class_file) {
     301        return BarnOwl::getvar('classlogging') eq 'on';
     302    } else {
     303        return BarnOwl::getvar('logging') eq 'on';
     304    }
     305}
    225306
    2263071;
  • perl/lib/BarnOwl/Style/Default.pm

    r732d5c0 rebc6f77  
    129129    my $self = shift;
    130130    my $m = shift;
    131     my $sender = $m->long_sender;
    132     $sender =~ s/\n.*$//s;
     131    my $sender = $self->humanize($m->long_sender, 1);
    133132    if (BarnOwl::getvar('colorztext') eq 'on') {
    134133      return "  (" . $sender . '@color[default]' . ")";
  • perl/modules/Facebook/README

    rf4037cf r441fd42  
    1414
    1515  This token will persist across BarnOwls until you change your
    16   Facebook password or you revoke permissions for Barnowl at:
     16  Facebook password or you revoke permissions for BarnOwl at:
    1717    http://www.facebook.com/settings/?tab=applications&app_id=235537266461636
    1818
    19   (3) Start receiving wall updates in Barnowl!
     19  (3) Start receiving wall updates in BarnOwl!
    2020  You can post updates with the ":facebook" command.
    2121
  • perl/modules/IRC/lib/BarnOwl/Message/IRC.pm

    r60b49a7 r3f0c209  
    9292}
    9393
     94# logging
     95sub log_filenames {
     96    my ($m) = @_;
     97    die "IRC should not be handling non-IRC messages" if lc($m->type) ne "irc";
     98    BarnOwl::error("IRC message without a network") if !defined($m->network) || $m->network eq '';
     99    my $filename = lc($m->network);
     100    # Note: Channel names generally start with '#', which
     101    # disambiguates channels from individuals; for example, personals
     102    # will look like, e.g., "~/zlog/irc/freenode:john-doe", whereas
     103    # channels will look like, e.g., "~/zlog/irc/freenode:#barnowl"
     104    if ($m->is_personal) {
     105        if ($m->is_incoming) {
     106            $filename .= ":" . $m->sender;
     107        } elsif ($m->is_outgoing) {
     108            $filename .= ":" . $m->recipient;
     109        }
     110    } else {
     111        $filename .= ":" . $m->channel;
     112    }
     113    return ($filename);
     114}
     115
     116sub log {
     117    my ($m) = @_;
     118    my $sender = $m->sender;
     119    my $timestr = $m->time;
     120    my $body = $m->body;
     121    if ($m->is_loginout) {
     122        return BarnOwl::Message::log($m);
     123    } else {
     124        return "[$timestr] <$sender> $body\n";
     125    }
     126}
     127
    941281;
  • perl/modules/IRC/lib/BarnOwl/Module/IRC.pm

    r4f7b1f4 rd4f33f1  
    2121
    2222use AnyEvent::IRC;
     23use Encode;
     24use File::Spec;
    2325use Getopt::Long;
    24 use Encode;
    2526use Text::Wrap;
    2627
    2728our $VERSION = 0.02;
     29
     30our $IRC_SUBS_FILENAME = "ircchannels";
    2831
    2932our $irc;
     
    169172            summary => 'Connect to an IRC server',
    170173            usage =>
    171 'irc-connect [-a ALIAS ] [-s] [-p PASSWORD] [-n NICK] SERVER [port]',
     174'irc-connect [-a ALIAS] [-s] [-p PASSWORD] [-n NICK] SERVER [port]',
    172175            description => <<END_DESCR
    173176Connect to an IRC server. Supported options are:
     
    230233        {
    231234            summary => 'Join an IRC channel',
    232             usage   => 'irc-join [-a ALIAS] #channel [KEY]',
    233 
    234             description => <<END_DESCR
    235 Join an IRC channel.
     235            usage   => 'irc-join [-a ALIAS] [-t] #channel [KEY]',
     236
     237            description => <<END_DESCR
     238Join an IRC channel.  If the -t option is present the subscription will only be
     239temporary, i.e., it will not be written to the subscription file and will
     240therefore not be present the next time BarnOwl is started, and will disappear
     241if the connection is lost.
    236242END_DESCR
    237243        }
     
    242248        {
    243249            summary => 'Leave an IRC channel',
    244             usage   => 'irc-part [-a ALIAS] #channel',
    245 
    246             description => <<END_DESCR
    247 Part from an IRC channel.
     250            usage   => 'irc-part [-a ALIAS] [-t] #channel',
     251
     252            description => <<END_DESCR
     253Part from an IRC channel.  If the -t option is present the unsubscription will
     254only be temporary, i.e., it will not be updated in the subscription file and
     255will therefore not be in effect the next time BarnOwl is started, or if the
     256connection is lost.
    248257END_DESCR
    249258        }
     
    342351This can be used to perform some operation not yet supported by
    343352BarnOwl, or to define new IRC commands.
     353END_DESCR
     354        }
     355    );
     356
     357    BarnOwl::new_command(
     358        'irc-loadchannels' => \&cmd_loadchannels,
     359        {
     360            summary => 'Reload persistent channels',
     361            usage   => 'irc-loadchannels [-a ALIAS] [<file>]',
     362
     363            description => <<END_DESCR
     364Load persistent channels from a file.  The file defaults to
     365\$HOME/.owl/$IRC_SUBS_FILENAME.  If the ALIAS is present, only channels
     366on the given alias are loaded.  The ALIAS is case-sensitive.
     367
     368Each line of the file should describe a single channel, in the format
     369'\$alias \$channel' (without quotes).
    344370END_DESCR
    345371        }
     
    356382######################## Owl command handlers ##################################
    357383################################################################################
     384
     385sub make_autoconnect_filename {
     386    # can't use ||, or else we'll treat '0' as invalid.  We could check for eq "" ...
     387    # TODO(jgross): When we move to requiring perl 5.10, combine the
     388    # following two lines using //
     389    my $filename = shift;
     390    $filename = File::Spec->catfile(BarnOwl::get_config_dir(), $IRC_SUBS_FILENAME) unless defined $filename;
     391    if (!File::Spec->file_name_is_absolute($filename)) {
     392        $filename = File::Spec->catfile($ENV{HOME}, $filename);
     393    }
     394    return $filename;
     395}
     396
     397sub _get_autoconnect_lines {
     398    my $filename = shift;
     399
     400    # TODO(jgross): Write a C-side function to do this, asynchronously;
     401    #               AIUI, perl doesn't do asynchronous I/O in any useful way
     402    if (open (my $subsfile, "<:encoding(UTF-8)", $filename)) {
     403        my @lines = <$subsfile>;
     404        close($subsfile);
     405
     406        # strip trailing newlines
     407        local $/ = "";
     408        chomp(@lines);
     409
     410        return @lines;
     411    }
     412
     413    return ();
     414}
     415
     416sub get_autoconnect_channels {
     417    my $filename = make_autoconnect_filename(shift);
     418    my %channel_hash = ();
     419
     420    # Load the subs from the file
     421    my @lines = _get_autoconnect_lines($filename);
     422
     423    foreach my $line (@lines) {
     424        my @parsed_args = split(' ', $line);
     425        if (scalar @parsed_args == 2) {
     426            push @{$channel_hash{$parsed_args[0]}}, $parsed_args[1];
     427        } else {
     428            warn "Trouble parsing irc configuration file '$filename' line '$line'; the format is '\$alias \$channel', with no spaces in either\n";
     429        }
     430    }
     431
     432    return %channel_hash;
     433}
     434
     435sub add_autoconnect_channel {
     436    my $conn = shift;
     437    my $channel = shift;
     438    my $alias = $conn->alias;
     439    my $filename = make_autoconnect_filename(shift);
     440
     441    # we already checked for spaces in $channel in cmd_join, but we still need
     442    # to check $alias
     443    die "Alias name '$alias' contains a space; parsing will fail.  Use the -t flag.\n" unless index($alias, " ") == -1;
     444
     445    my $line = "$alias $channel";
     446
     447    my @lines = _get_autoconnect_lines($filename);
     448
     449    # We don't want to be noisy about duplicated joins.  For example, some
     450    # people might have :irc-join in startup files, even though that doesn't
     451    # work correctly anymore because connect is asynchronous and so join on
     452    # startup races with connect.  Regardless, just fail silently if the line
     453    # already exists.
     454    return if grep { $_ eq $line } @lines;
     455
     456    open (my $subsfile, ">>:encoding(UTF-8)", make_autoconnect_filename($filename))
     457        or die "Cannot open $filename for writing: $!\n";
     458    local $, = "";
     459    local $/ = "";
     460    print $subsfile "$line\n";
     461    close($subsfile);
     462}
     463
     464sub remove_autoconnect_channel {
     465    my $conn = shift;
     466    my $channel = shift;
     467    my $alias = $conn->alias;
     468    my $filename = make_autoconnect_filename(shift);
     469
     470    BarnOwl::Internal::file_deleteline($filename, "$alias $channel", 1);
     471}
     472
     473sub cmd_loadchannels {
     474    my $cmd = shift;
     475    my $alias;
     476    my $getopt = Getopt::Long::Parser->new;
     477
     478    local @ARGV = @_;
     479    $getopt->configure(qw(pass_through permute no_getopt_compat prefix_pattern=-|--));
     480    $getopt->getoptions("alias=s" => \$alias);
     481
     482    my %channel_hash = get_autoconnect_channels(@ARGV);
     483
     484    my $aliases = (defined $alias) ? [$alias] : [keys %channel_hash];
     485
     486    foreach my $cur_alias (@$aliases) {
     487        # get_connection_by_alias might die, and we don't want to
     488        eval {
     489            my $conn = get_connection_by_alias($cur_alias, 1);
     490            my %existing_channels = map { $_ => 1 } @{$conn->autoconnect_channels}, @{$channel_hash{$cur_alias}};
     491            $conn->autoconnect_channels([keys %existing_channels]);
     492        };
     493        foreach my $channel (@{$channel_hash{$cur_alias}}) {
     494            if ($cur_alias eq "") {
     495                BarnOwl::command("irc-join", "-t", $channel);
     496            } else {
     497                BarnOwl::command("irc-join", "-t", "-a", $cur_alias, $channel);
     498            }
     499        }
     500    }
     501}
    358502
    359503sub cmd_connect {
     
    393537    }
    394538
     539    my %channel_hash = get_autoconnect_channels;
     540
    395541    my $conn = BarnOwl::Module::IRC::Connection->new($alias, $host, $port, {
    396         nick      => $nick,
    397         user      => $username,
    398         real      => $ircname,
    399         password  => $password,
    400         SSL       => $ssl,
    401         timeout   => sub {0}
     542        nick                 => $nick,
     543        user                 => $username,
     544        real                 => $ircname,
     545        password             => $password,
     546        SSL                  => $ssl,
     547        timeout              => sub {0},
     548        autoconnect_channels => $channel_hash{$alias}
    402549       });
    403550    $ircnets{$alias} = $conn;
     
    415562                               "[" . $conn->alias . "] Reconnect cancelled");
    416563        $conn->cancel_reconnect;
     564        delete $ircnets{$conn->alias};
     565    } elsif (exists $ircnets{$conn->alias}) { # inconsistent state; no socket, but not yet deleted
     566        BarnOwl::admin_message('IRC',
     567                               "[" . $conn->alias . "] Attempt to disconnect from a socketless connection; deleting it");
    417568        delete $ircnets{$conn->alias};
    418569    }
     
    486637sub cmd_join {
    487638    my $cmd = shift;
    488     my $conn = shift;
    489     my $chan = shift or die("Usage: $cmd channel\n");
    490     $conn->conn->send_msg(join => $chan, @_);
     639    my $is_temporary;
     640
     641    my $getopt = Getopt::Long::Parser->new;
     642
     643    local @ARGV = @_;
     644    $getopt->configure(qw(pass_through permute no_getopt_compat prefix_pattern=-|--));
     645    $getopt->getoptions("temporary" => \$is_temporary);
     646
     647    my $conn = shift @ARGV;
     648    my $chan = shift @ARGV or die("Usage: $cmd channel\n");
     649
     650    die "Channel name '$chan' contains a space.  As per RFC 2812, IRC channel names may not contain spaces.\n" unless index($chan, " ") == -1;
     651
     652    $conn->conn->send_msg(join => $chan, @ARGV);
     653
     654    # regardless of whether or not this is temporary, we want to persist it
     655    # across reconnects.
     656
     657    # check if the channel is already in the list
     658    if (!grep { $_ eq $chan } @{$conn->autoconnect_channels}) {
     659        push @{$conn->autoconnect_channels}, $chan;
     660    }
     661
     662    if (!$is_temporary) {
     663        # add the line to the subs file
     664        add_autoconnect_channel($conn, $chan);
     665    }
     666
    491667    return;
    492668}
     
    494670sub cmd_part {
    495671    my $cmd = shift;
    496     my $conn = shift;
    497     my $chan = shift;
     672    my $is_temporary;
     673
     674    my $getopt = Getopt::Long::Parser->new;
     675
     676    local @ARGV = @_;
     677    $getopt->configure(qw(pass_through permute no_getopt_compat prefix_pattern=-|--));
     678    $getopt->getoptions("temporary" => \$is_temporary);
     679
     680    my $conn = shift @ARGV;
     681    my $chan = shift @ARGV or die("Usage: $cmd channel\n");
     682
    498683    $conn->conn->send_msg(part => $chan);
     684
     685    # regardless of whether or not this is temporary, we want to persist it
     686    # across reconnects
     687    my %existing_channels = map { $_ => 1 } @{$conn->autoconnect_channels};
     688    delete $existing_channels{$chan};
     689    $conn->autoconnect_channels([keys %existing_channels]);
     690
     691    if (!$is_temporary) {
     692        # remove the line from the subs file
     693        remove_autoconnect_channel($conn, $chan);
     694    }
     695
    499696    return;
    500697}
     
    596793        my $alias;
    597794        my $channel;
     795        my $is_temporary;
    598796        my $getopt = Getopt::Long::Parser->new;
    599797        my $m = BarnOwl::getcurmsg();
     
    601799        local @ARGV = @_;
    602800        $getopt->configure(qw(pass_through permute no_getopt_compat prefix_pattern=-|--));
    603         $getopt->getoptions("alias=s" => \$alias);
     801        $getopt->getoptions("alias=s" => \$alias,
     802                            "temporary" => \$is_temporary);
    604803
    605804        if(defined($alias)) {
     
    640839            die("You must specify an IRC network using -a.\n");
    641840        }
     841        push @ARGV, "-t" if $is_temporary;
    642842        if($flags & CHANNEL_ARG) {
    643843            $sub->($cmd, $conn, $channel, @ARGV);
  • perl/modules/IRC/lib/BarnOwl/Module/IRC/Completion.pm

    rdace02a r76e80de  
    5757}
    5858
     59sub complete_irc_join_part {
     60    my $ctx = shift;
     61    return complete_flags($ctx,
     62        [qw(-t)],
     63        {
     64            "-a" => \&complete_networks,
     65        },
     66        \&complete_channels
     67       );
     68}
     69
    5970sub complete_irc_channel {
    6071    my $ctx = shift;
     
    95106BarnOwl::Completion::register_completer('irc-msg'        => \&complete_irc_dest);
    96107BarnOwl::Completion::register_completer('irc-mode'       => \&complete_irc_dest);
    97 BarnOwl::Completion::register_completer('irc-join'       => \&complete_irc_channel);
    98 BarnOwl::Completion::register_completer('irc-part'       => \&complete_irc_channel);
     108BarnOwl::Completion::register_completer('irc-join'       => \&complete_irc_join_part);
     109BarnOwl::Completion::register_completer('irc-part'       => \&complete_irc_join_part);
    99110BarnOwl::Completion::register_completer('irc-names'      => \&complete_irc_channel);
    100111BarnOwl::Completion::register_completer('irc-whois'      => \&complete_irc_nick);
  • perl/modules/IRC/lib/BarnOwl/Module/IRC/Connection.pm

    r13ee8f2 r4379288  
    3939    my $self = bless({}, $class);
    4040    $self->conn($conn);
    41     $self->autoconnect_channels([]);
     41    # TODO(jgross): use // when we move to requiring perl 5.10
     42    $self->autoconnect_channels(defined $args->{autoconnect_channels} ? $args->{autoconnect_channels} : []);
    4243    $self->alias($alias);
    4344    $self->server($host);
     
    412413        $self->{reconnect_timer}->stop;
    413414    }
    414     $self->{reconnect_timer} = 
     415    $self->{reconnect_timer} =
    415416        BarnOwl::Timer->new( {
    416417            name  => 'IRC (' . $self->alias . ') reconnect_timer',
     
    436437}
    437438
     439sub rejoin_channels {
     440    my $self = shift;
     441    my @channels = @_;
     442    # As reported in https://barnowl.mit.edu/ticket/274, if we reconnect to
     443    # too many at once, the server rejects us.  Empirically, this is about
     444    # 20-26, so we set the cap at 15, then delay further joins for 5 seconds.
     445    my $MAX_RECONNECT_CHANNELS = 15;
     446    my $DELAY = 5;
     447    foreach my $c (@channels[ 0 .. $MAX_RECONNECT_CHANNELS ]) {
     448        $self->conn->send_msg(join => $c);
     449    }
     450    if ($MAX_RECONNECT_CHANNELS < $#channels) {
     451        my $remaining = $#channels - $MAX_RECONNECT_CHANNELS;
     452        my $cur_alias = $self->alias;
     453        BarnOwl::admin_message('IRC', "[$cur_alias] Delaying $remaining autorejoins for $DELAY seconds");
     454        # if we don't assign the timer to anything, then it gets garbage
     455        # collected, and never runs
     456        $self->{autoconnect_channels_delay_timer} = BarnOwl::Timer->new({
     457            name  => "IRC rejoin overflow timer ($remaining remaining)",
     458            after => $DELAY,
     459            cb    => sub {
     460                rejoin_channels($self, @channels[ $MAX_RECONNECT_CHANNELS .. $#channels ]);
     461            }
     462        });
     463    }
     464}
     465
     466
    438467sub connected {
    439468    my $self = shift;
     
    442471    $self->cancel_reconnect;
    443472    if ($self->autoconnect_channels) {
    444         for my $c (@{$self->autoconnect_channels}) {
    445             $self->conn->send_msg(join => $c);
    446         }
    447         $self->autoconnect_channels([]);
     473        rejoin_channels($self, @{$self->autoconnect_channels});
    448474    }
    449475    $self->conn->enable_ping(60, sub {
     
    458484    my $backoff = $self->backoff;
    459485
    460     $self->autoconnect_channels([keys(%{$self->{channel_list}})]);
    461486    $self->conn->connect(@{$self->connect_args});
    462487}
  • perl/modules/Jabber/lib/BarnOwl/Message/Jabber.pm

    ra27acf7 rd2ba33c  
    172172}
    173173
     174sub log_filenames {
     175    return map { BarnOwl::compat_casefold($_) } BarnOwl::Message::log_filenames(@_);
     176}
     177
    174178=head1 SEE ALSO
    175179
  • perl/modules/Jabber/lib/BarnOwl/Module/Jabber.pm

    r416a7e5 r41064be  
    13601360    {
    13611361        my @answer = $packet->answer;
    1362         return $answer[0]{target}, $answer[0]{port};
     1362        return $answer[0]->target, $answer[0]->port if @answer;
    13631363    }
    13641364
  • perl/modules/Makefile.am

    re4b8f93 r268c7e8  
    1 MODULES = Jabber IRC WordWrap Twitter Facebook
     1MODULES = Jabber IRC WordWrap Twitter Facebook Kerberos
    22
    33EXTRA_DIST = $(MODULES:=/Makefile.PL) $(MODULES:=/lib)
  • perl/modules/Twitter/lib/BarnOwl/Module/Twitter.pm

    rb8a3e00 r140429f  
    137137        my $twitter_args = { username   => $cfg->{user},
    138138                             password   => $cfg->{password},
    139                              source     => 'barnowl',
     139                             source     => 'barnowl',
     140                             ssl        => 1,
     141                             legacy_lists_api => 0,
    140142                         };
    141143        if (defined $cfg->{service}) {
     
    274276);
    275277
     278BarnOwl::new_command( 'twitter-favorite' => sub { cmd_twitter_favorite(@_) },
     279    {
     280    summary     => 'Favorite the current Twitter message',
     281    usage       => 'twitter-favorite [ACCOUNT]',
     282    description => <<END_DESCRIPTION
     283Favorite the current Twitter message using ACCOUNT (defaults to the
     284account that received the tweet).
     285END_DESCRIPTION
     286    }
     287);
     288
    276289BarnOwl::new_command( 'twitter-follow' => sub { cmd_twitter_follow(@_); },
    277290    {
     
    355368    $account = $m->account unless defined($account);
    356369    find_account($account)->twitter_retweet($m);
     370    return;
     371}
     372
     373sub cmd_twitter_favorite {
     374    my $cmd = shift;
     375    my $account = shift;
     376    my $m = BarnOwl::getcurmsg();
     377    if(!$m || $m->type ne 'Twitter') {
     378        die("$cmd must be used with a Twitter message selected.\n");
     379    }
     380
     381    $account = $m->account unless defined($account);
     382    find_account($account)->twitter_favorite($m);
    357383    return;
    358384}
  • perl/modules/Twitter/lib/BarnOwl/Module/Twitter/Handle.pm

    r4ebbfbc r140429f  
    371371        $self->twitter_direct($1, $2);
    372372    } elsif(defined $self->{twitter}) {
    373         if(length($msg) > 140) {
    374             die("Twitter: Message over 140 characters long.\n");
    375         }
    376373        $self->twitter_command('update', {
    377374            status => $msg,
     
    432429}
    433430
     431sub twitter_favorite {
     432    my $self = shift;
     433    my $msg = shift;
     434
     435    if($msg->service ne $self->{cfg}->{service}) {
     436        die("Cannot favorite a message from a different service.\n");
     437    }
     438    $self->twitter_command(create_favorite => $msg->{status_id});
     439}
     440
     441
    434442sub twitter_follow {
    435443    my $self = shift;
  • perlconfig.c

    r96d80e9 r09530e6  
    188188  hash = (HV*)SvRV(msg);
    189189
    190   m = g_new(owl_message, 1);
     190  m = g_slice_new(owl_message);
    191191  owl_message_init(m);
    192192
     
    211211      g_free(m->timestr);
    212212      m->timestr = g_strdup(val);
     213      // FIXME: Daylight saving time will be guessed wrongly one hour per year!
     214      tm.tm_isdst = -1;
    213215      strptime(val, "%a %b %d %T %Y", &tm);
    214216      m->time = mktime(&tm);
     
    336338  }
    337339
    338   sv_setpv(get_sv("BarnOwl::VERSION", TRUE), OWL_VERSION_STRING);
     340  sv_setpv(get_sv("BarnOwl::VERSION", TRUE), version);
    339341
    340342  /* Add the system lib path to @INC */
  • perlglue.xs

    r1ced34f rd2ba33c  
    232232     CODE:
    233233        {
    234                 s = g_new(owl_style, 1);
     234                s = g_slice_new(owl_style);
    235235                owl_style_create_perl(s, name, newSVsv(object));
    236236                owl_global_add_style(&g, s);
     
    385385                RETVAL
    386386
     387SV *
     388get_variable_info(name)
     389        const char *name;
     390        PREINIT:
     391                owl_variable *var;
     392                HV *h;
     393        CODE:
     394                var = owl_variable_get_var(owl_global_get_vardict(&g), name);
     395                if (var == NULL) {
     396                        croak("No such variable");
     397                }
     398                h = newHV();
     399                (void)hv_store(h, "name", strlen("name"),
     400                               owl_new_sv(owl_variable_get_name(var)), 0);
     401                (void)hv_store(h, "description", strlen("description"),
     402                               owl_new_sv(owl_variable_get_description(var)),
     403                               0);
     404                (void)hv_store(h, "summary", strlen("summary"),
     405                               owl_new_sv(owl_variable_get_summary(var)), 0);
     406                (void)hv_store(h, "validsettings", strlen("validsettings"),
     407                               owl_new_sv(owl_variable_get_validsettings(var)),
     408                               0);
     409                (void)hv_store(h, "takes_on_off", strlen("takes_on_off"),
     410                               newSViv(owl_variable_takes_on_off(var)), 0);
     411                RETVAL = newRV_noinc((SV*)h);
     412        OUTPUT:
     413                RETVAL
     414
     415const utf8 *
     416compat_casefold(in)
     417        const char * in
     418        PREINIT:
     419                char *rv;
     420        CODE:
     421                rv = owl_util_compat_casefold(in);
     422                RETVAL = rv;
     423        OUTPUT:
     424                RETVAL
     425        CLEANUP:
     426                g_free(rv);
     427
    387428
    388429MODULE = BarnOwl                PACKAGE = BarnOwl::Zephyr
     
    397438MODULE = BarnOwl                PACKAGE = BarnOwl::Internal
    398439
     440
     441int
     442file_deleteline(filename, line, backup)
     443        const char *filename
     444        const char *line
     445        int backup
     446        CODE:
     447                RETVAL = owl_util_file_deleteline(filename, line, backup);
     448        OUTPUT:
     449                RETVAL
     450
     451const utf8 *
     452makepath(in)
     453        const char * in
     454        PREINIT:
     455                char *rv;
     456        CODE:
     457                rv = owl_util_makepath(in);
     458                RETVAL = rv;
     459        OUTPUT:
     460                RETVAL
     461        CLEANUP:
     462                g_free(rv);
    399463
    400464void
     
    632696        OUTPUT:
    633697                RETVAL
     698
     699MODULE = BarnOwl                PACKAGE = BarnOwl::Logging
     700
     701void
     702enqueue_text(log_text, filename)
     703        const char * log_text
     704        const char * filename
     705        CODE:
     706                owl_log_enqueue_message(log_text, filename);
  • popexec.c

    re146cd7 r7dcef03  
    2323  }
    2424
    25   pe = g_new(owl_popexec, 1);
     25  pe = g_slice_new(owl_popexec);
    2626  pe->winactive=0;
    2727  pe->pid=0;
     
    179179  if (pe->refcount<=0) {
    180180    owl_function_debugmsg("doing free of %p", pe);
    181     g_free(pe);
     181    g_slice_free(owl_popexec, pe);
    182182  }
    183183}
  • popwin.c

    r6829afc r7dcef03  
    33CALLER_OWN owl_popwin *owl_popwin_new(void)
    44{
    5   owl_popwin *pw = g_new0(owl_popwin, 1);
     5  owl_popwin *pw = g_slice_new0(owl_popwin);
    66
    77  pw->border = owl_window_new(NULL);
     
    9292  g_object_unref(pw->content);
    9393
    94   g_free(pw);
     94  g_slice_free(owl_popwin, pw);
    9595}
    9696
  • runtests.sh

    r5db8835 r7dcef03  
    11#!/bin/sh
     2export G_SLICE=debug-blocks
    23exec env HARNESS_PERL=./tester prove --failures "${srcdir:=$(dirname "$0")}/t/"
  • scripts/do-release

    rb8a3e00 rbc308eb  
    1 #!/bin/sh -e
     1#!/bin/bash
     2set -eu
    23
    34die() {
     
    5556fi
    5657
     58[ -e Makefile.in ] || autoreconf -fvi
     59[ -e config.status ] || ./configure
     60make -j4 distcheck VERSION="$VERS"
     61
     62echo 'Checking distributed files against Git:'
     63if comm -3 <(tar -tzf "$TAG.tar.gz" | grep -v '/$' | sed "s%^$TAG/%%" | sort) \
     64    <(git ls-files | sort) | grep -vxf scripts/dist-ignore; then
     65    echo
     66    echo 'Error: Please fix Makefile.am and/or scripts/dist-ignore.'
     67    exit 1
     68fi
     69echo 'ok'
     70
     71mv "$TAG.tar.gz" "$TGZ.tgz"
     72
    5773if ! [ "$no_tag" ]; then
    5874    if git cat-file -t "$TAG" > /dev/null 2>&1; then
     
    6581fi
    6682
    67 exittrap() { :; }
    68 for sig in 1 2 13 15; do trap "exit $(($sig + 128))" $sig; done
    69 trap 'exittrap' EXIT
    70 
    71 TMPDIR=$(mktemp -d /tmp/barnowl.XXXXXX)
    72 
    73 exittrap() { rm -rf "$TMPDIR"; }
    74 
    75 git archive --format=tar --prefix="$TGZ/" "$TAG" | tar -x -C "$TMPDIR"
    76 
    77 CODIR=$(pwd)
    78 cd "$TMPDIR/$TGZ"
    79 [ "$git" ] && perl -i -pe 's{^(AC_INIT\(\[[^\]]+\],\s*)\[([^\]]+)\]}{${1}['$VERS']}' configure.ac
    80 autoreconf -fvi
    81 rm -r autom4te.cache/
    82 cd "$TMPDIR"
    83 tar czvf "$TGZ.tgz" "$TGZ"
    84 cd "$CODIR"
    85 
    86 mv "$TMPDIR/$TGZ.tgz" .
    87 rm -rf "$TMPDIR"
    88 
    89 exittrap() { :; }
    90 
    91 echo "Created release tarball for BarnOwl $VERS in $(pwd)"
     83echo "Created release tarball for BarnOwl $VERS at $(pwd)/$TGZ.tgz"
    9284echo "Remember to bump OWL_VERSION_STRING for future development."
    9385
  • select.c

    r84a071f r7dcef03  
    4141  if (t->destroy_cbdata)
    4242    t->destroy_cbdata(t->cbdata);
    43   g_free(t);
     43  g_slice_free(owl_task, t);
    4444}
    4545
     
    4747{
    4848  GSource *source = g_idle_source_new();
    49   owl_task *t = g_new0(owl_task, 1);
     49  owl_task *t = g_slice_new0(owl_task);
    5050  t->cb = cb;
    5151  t->cbdata = cbdata;
  • style.c

    r92ffd89 r7dcef03  
    103103{
    104104  owl_style_cleanup(s);
    105   g_free(s);
     105  g_slice_free(owl_style, s);
    106106}
  • t/completion.t

    re59d775 r4fd3c04  
    66
    77use File::Basename;
    8 BEGIN {require (dirname($0) . "/mock.pl");};
     8use File::Spec;
     9BEGIN {require File::Spec->rel2abs("mock.pl", dirname($0));};
    910
    1011use BarnOwl::Complete::Filter qw(complete_filter_expr);
     
    292293
    293294test_complete('type ', '',
    294               [qw[admin aim zephyr]],
     295              [qw[admin zephyr]],
    295296              \&complete_filter_expr);
    296297
  • tester.c

    r6a8b519 ra882637  
    2525int owl_history_regtest(void);
    2626int call_filter_regtest(void);
     27int owl_smartstrip_regtest(void);
    2728
    2829extern void owl_perl_xs_init(pTHX);
     
    8182    sv_setpv(get_sv("main::test_prog", TRUE), argv[1]);
    8283
    83     eval_pv("do $main::test_prog; die($@) if($@)", true);
    84   }
    85 
    86   status = 0;
     84    eval_pv("use File::Spec; do File::Spec->rel2abs($main::test_prog); die($@) if($@)", true);
     85  }
    8786
    8887  FREETMPS;
     
    116115  numfailures += owl_history_regtest();
    117116  numfailures += call_filter_regtest();
     117  numfailures += owl_smartstrip_regtest();
    118118  if (numfailures) {
    119119      fprintf(stderr, "# *** WARNING: %d failures total\n", numfailures);
     
    355355
    356356
    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)));
     357  FAIL_UNLESS("get string var", NULL != (var = owl_variable_get_var(&vd, "personalbell")));
     358  FAIL_UNLESS("get string", 0 == strcmp("off", owl_variable_get_string(var)));
    359359  FAIL_UNLESS("set string 7", 0 == owl_variable_set_string(var, "whee"));
    360360  FAIL_UNLESS("get string", !strcmp("whee", owl_variable_get_string(var)));
     
    10181018  return numfailed;
    10191019}
     1020
     1021int owl_smartstrip_regtest(void)
     1022{
     1023  int numfailed = 0;
     1024
     1025  printf("# BEGIN testing owl_zephyr_smartstripped_user\n");
     1026
     1027#define CHECK_SMARTSTRIP(in, expected)                  \
     1028  do {                                                  \
     1029    char *__value = owl_zephyr_smartstripped_user(in);  \
     1030    FAIL_UNLESS("owl_zephyr_smartstripped_user " in,    \
     1031                strcmp((expected), __value) == 0);      \
     1032    g_free(__value);                                    \
     1033  } while (0)
     1034
     1035  CHECK_SMARTSTRIP("foo", "foo");
     1036  CHECK_SMARTSTRIP("foo.bar", "foo");
     1037  CHECK_SMARTSTRIP("foo/bar", "foo");
     1038  CHECK_SMARTSTRIP("host/bar", "host/bar");
     1039  CHECK_SMARTSTRIP("rcmd.bar", "rcmd.bar");
     1040  CHECK_SMARTSTRIP("daemon/bar", "daemon/bar");
     1041  CHECK_SMARTSTRIP("daemon.bar", "daemon.bar");
     1042
     1043  CHECK_SMARTSTRIP("foo@ATHENA.MIT.EDU", "foo@ATHENA.MIT.EDU");
     1044  CHECK_SMARTSTRIP("foo.bar@ATHENA.MIT.EDU", "foo@ATHENA.MIT.EDU");
     1045  CHECK_SMARTSTRIP("foo/bar@ATHENA.MIT.EDU", "foo@ATHENA.MIT.EDU");
     1046  CHECK_SMARTSTRIP("host/bar@ATHENA.MIT.EDU", "host/bar@ATHENA.MIT.EDU");
     1047  CHECK_SMARTSTRIP("rcmd.bar@ATHENA.MIT.EDU", "rcmd.bar@ATHENA.MIT.EDU");
     1048  CHECK_SMARTSTRIP("daemon/bar@ATHENA.MIT.EDU", "daemon/bar@ATHENA.MIT.EDU");
     1049  CHECK_SMARTSTRIP("daemon.bar@ATHENA.MIT.EDU", "daemon.bar@ATHENA.MIT.EDU");
     1050
     1051  printf("# END testing owl_zephyr_smartstripped_user\n");
     1052
     1053  return numfailed;
     1054}
  • util.c

    r7b89e8c rd2ba33c  
    468468  if (fstat(fileno(old), &st) != 0) {
    469469    owl_function_error("Cannot stat %s: %s", filename, strerror(errno));
     470    fclose(old);
    470471    return -1;
    471472  }
     
    473474  /* resolve symlinks, because link() fails on symlinks, at least on AFS */
    474475  actual_filename = owl_util_recursive_resolve_link(filename);
    475   if (actual_filename == NULL)
     476  if (actual_filename == NULL) {
     477    fclose(old);
    476478    return -1; /* resolving the symlink failed, but we already logged this error */
     479  }
    477480
    478481  newfile = g_strdup_printf("%s.new", actual_filename);
     
    640643}
    641644
     645CALLER_OWN char *owl_util_compat_casefold(const char *str)
     646{
     647  /*
     648   * Quoting Anders Kaseorg at https://github.com/barnowl/barnowl/pull/54#issuecomment-31452543:
     649   *
     650   * The Unicode specification calls this compatibility caseless matching, and
     651   * the correct transformation actually has five calls:
     652   * NFKC(toCasefold(NFKD(toCasefold(NFD(string))))) Zephyr’s current
     653   * implementation incorrectly omits the innermost NFD, but that difference
     654   * only matters for characters including U+0345 ◌ͅ COMBINING GREEK
     655   * YPOGEGRAMMENI. I think we should just write the correct version and get
     656   * Zephyr fixed.
     657   *
     658   * Neither of these operations should be called toNFKC_Casefold, because that
     659   * has slightly different behavior regarding Default_Ignorable_Code_Point. I
     660   * propose compat_casefold. And I guess if Jabber wants it too, we should
     661   * move it to util.c.
     662   */
     663  char *tmp0 = g_utf8_normalize(str, -1, G_NORMALIZE_NFD);
     664  char *tmp1 = g_utf8_casefold(tmp0, -1);
     665  char *tmp2 = g_utf8_normalize(tmp1, -1, G_NORMALIZE_NFKD);
     666  char *tmp3 = g_utf8_casefold(tmp2, -1);
     667  char *out = g_utf8_normalize(tmp3, -1, G_NORMALIZE_NFKC);
     668  g_free(tmp0);
     669  g_free(tmp1);
     670  g_free(tmp2);
     671  g_free(tmp3);
     672
     673  return out;
     674}
     675
    642676/* This is based on _extract() and _isCJ() from perl's Text::WrapI18N */
    643677int owl_util_can_break_after(gunichar c)
  • variable.c

    r9d4dfdc r4fd3c04  
    136136               "load logins from .anyone on startup", "" );
    137137
    138   OWLVAR_BOOL( "logging" /* %OwlVarStub */, 0,
    139                "turn personal logging on or off",
    140                "If this is set to on, personal messages are\n"
    141                "logged in the directory specified\n"
    142                "by the 'logpath' variable.  The filename in that\n"
    143                "directory is derived from the sender of the message.\n" );
    144 
    145   OWLVAR_BOOL( "classlogging" /* %OwlVarStub */, 0,
    146                "turn class logging on or off",
    147                "If this is set to on, class messages are\n"
    148                "logged in the directory specified\n"
    149                "by the 'classlogpath' variable.\n"
    150                "The filename in that directory is derived from\n"
    151                "the name of the class to which the message was sent.\n" );
    152 
    153   OWLVAR_ENUM( "loggingdirection" /* %OwlVarStub */, OWL_LOGGING_DIRECTION_BOTH,
    154                "specifies which kind of messages should be logged",
    155                "Can be one of 'both', 'in', or 'out'.  If 'in' is\n"
    156                "selected, only incoming messages are logged, if 'out'\n"
    157                "is selected only outgoing messages are logged.  If 'both'\n"
    158                "is selected both incoming and outgoing messages are\n"
    159                "logged.",
    160                "both,in,out");
    161 
    162138  OWLVAR_BOOL_FULL( "colorztext" /* %OwlVarStub */, 1,
    163139                    "allow @color() in zephyrs to change color",
    164                     NULL, NULL, owl_variable_colorztext_set, NULL);
     140                    "", NULL, owl_variable_colorztext_set, NULL);
    165141
    166142  OWLVAR_BOOL( "fancylines" /* %OwlVarStub */, 1,
     
    185161               "Enable printing of login notifications",
    186162               "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");
    189 
    190   OWLVAR_STRING( "logfilter" /* %OwlVarStub */, "",
    191                  "name of a filter controlling which messages to log",
    192 
    193                  "If non empty, any messages matching the given filter will be logged.\n"
    194                  "This is a completely separate mechanism from the other logging\n"
    195                  "variables like logging, classlogging, loglogins, loggingdirection,\n"
    196                  "etc.  If you want this variable to control all logging, make sure\n"
    197                  "all other logging variables are in their default state.\n");
    198 
    199   OWLVAR_BOOL( "loglogins" /* %OwlVarStub */, 0,
    200                "Enable logging of login notifications",
    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"
     163               "for zephyr or other protocols.  If disabled BarnOwl will not print\n"
    203164               "login or logout notifications.\n");
    204165
     
    214175                    "off,middle,on",
    215176                    NULL, owl_variable_disable_ctrl_d_set, NULL);
    216 
    217   OWLVAR_PATH( "logpath" /* %OwlVarStub */, "~/zlog/people",
    218                "path for logging personal zephyrs",
    219                "Specifies a directory which must exist.\n"
    220                "Files will be created in the directory for each sender.\n");
    221 
    222   OWLVAR_PATH( "classlogpath" /* %OwlVarStub:classlogpath */, "~/zlog/class",
    223                "path for logging class zephyrs",
    224                "Specifies a directory which must exist.\n"
    225                "Files will be created in the directory for each class.\n");
    226177
    227178  OWLVAR_PATH( "debug_file" /* %OwlVarStub */, OWL_DEBUG_FILE,
     
    282233                 "default zaway message", "" );
    283234
    284   OWLVAR_BOOL_FULL( "aaway" /* %OwlVarStub */, 0,
    285                     "Set AIM away status",
    286                     "",
    287                     NULL, owl_variable_aaway_set, NULL);
    288 
    289   OWLVAR_STRING( "aaway_msg" /* %OwlVarStub */,
    290                  OWL_DEFAULT_AAWAYMSG,
    291                  "AIM away msg for responding when away", "" );
    292 
    293   OWLVAR_STRING( "aaway_msg_default" /* %OwlVarStub */,
    294                  OWL_DEFAULT_AAWAYMSG,
    295                  "default AIM away message", "" );
    296 
    297235  OWLVAR_STRING( "view_home" /* %OwlVarStub */, "all",
    298236                 "home view to switch to after 'X' and 'V'",
     
    337275                 "Zephyr messages be no wider than 70 columns.\n");
    338276
    339   OWLVAR_INT( "aim_ignorelogin_timer" /* %OwlVarStub */, 15,
    340               "number of seconds after AIM login to ignore login messages",
    341               "This specifies the number of seconds to wait after an\n"
    342               "AIM login before allowing the receipt of AIM login notifications.\n"
    343               "By default this is set to 15.  If you would like to view login\n"
    344               "notifications of buddies as soon as you login, set it to 0 instead.");
    345 
    346              
    347277  OWLVAR_INT_FULL( "typewinsize" /* %OwlVarStub:typwin_lines */,
    348278                   OWL_TYPWIN_SIZE,
     
    510440}
    511441
    512 /* When 'aaway' is changed, need to notify the AIM server */
    513 int 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("");
    519   }
    520   return owl_variable_bool_set_default(v, newval);
    521 }
    522 
    523442int owl_variable_colorztext_set(owl_variable *v, bool newval)
    524443{
     
    627546
    628547static 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);
     548  owl_variable *var = g_slice_new0(owl_variable);
    630549  var->type = type;
    631550  var->name = g_strdup(name);
     
    793712  g_closure_unref(v->set_fromstring_fn);
    794713
    795   g_free(v);
     714  g_slice_free(owl_variable, v);
    796715}
    797716
     
    812731const char *owl_variable_get_validsettings(const owl_variable *v) {
    813732  return v->validsettings;
     733}
     734
     735bool owl_variable_takes_on_off(const owl_variable *v) {
     736  return v->takes_on_off;
    814737}
    815738
     
    1038961CALLER_OWN char *owl_variable_bool_get_tostring_default(const owl_variable *v, void *dummy)
    1039962{
    1040   bool val = owl_variable_get_bool(v);
    1041   if (val == 0) {
    1042     return g_strdup("off");
    1043   } else if (val == 1) {
    1044     return g_strdup("on");
    1045   } else {
    1046     return g_strdup("<invalid>");
    1047   }
     963  return g_strdup(owl_variable_get_bool(v) ? "on" : "off");
    1048964}
    1049965
  • viewwin.c

    r7803326 r7dcef03  
    1313CALLER_OWN owl_viewwin *owl_viewwin_new_text(owl_window *win, const char *text)
    1414{
    15   owl_viewwin *v = g_new0(owl_viewwin, 1);
     15  owl_viewwin *v = g_slice_new0(owl_viewwin);
    1616  owl_fmtext_init_null(&(v->fmtext));
    1717  if (text) {
     
    3636{
    3737  char *text;
    38   owl_viewwin *v = g_new0(owl_viewwin, 1);
     38  owl_viewwin *v = g_slice_new0(owl_viewwin);
    3939
    4040  owl_fmtext_copy(&(v->fmtext), fmtext);
     
    424424  g_object_unref(v->status);
    425425  owl_fmtext_cleanup(&(v->fmtext));
    426   g_free(v);
    427 }
     426  g_slice_free(owl_viewwin, v);
     427}
  • zcrypt.c

    r8f335a8 r9a0d25d  
    2121#include <config.h>
    2222
    23 #ifdef HAVE_KERBEROS_IV
    24 #include <kerberosIV/des.h>
    25 #else
    2623#include <openssl/des.h>
    27 #endif
    2824
    2925#include "filterproc.h"
    3026
    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 */
     27extern const char *version;
    4028
    4129/* Annotate functions in which the caller owns the return value and is
     
    10795};
    10896
    109 static void owl_zcrypt_string_to_schedule(char *keystring, des_key_schedule *schedule) {
    110 #ifdef HAVE_KERBEROS_IV
    111   des_cblock key;
    112 #else
    113   des_cblock _key, *key = &_key;
    114 #endif
    115 
    116   des_string_to_key(keystring, key);
    117   des_key_sched(key, *schedule);
     97static void owl_zcrypt_string_to_schedule(char *keystring, DES_key_schedule *schedule) {
     98  DES_cblock key;
     99
     100  DES_string_to_key(keystring, &key);
     101  DES_key_sched(&key, schedule);
    118102}
    119103
     
    157141      case OPT_VERSION:
    158142        /* Version */
    159         printf("This is zcrypt version %s\n", OWL_VERSION_STRING);
     143        printf("This is zcrypt version %s\n", version);
    160144        exit(0);
    161145      case OPT_HELP:
     
    736720int do_encrypt_des(const char *keyfile, const char *in, int length, FILE *outfile)
    737721{
    738   des_key_schedule schedule;
     722  DES_key_schedule schedule;
    739723  unsigned char input[8], output[8];
    740724  const char *inptr;
     
    782766
    783767    /* Encrypt and output the block */
    784     des_ecb_encrypt(&input, &output, schedule, TRUE);
     768    DES_ecb_encrypt(&input, &output, &schedule, TRUE);
    785769    block_to_ascii(output, outfile);
    786770
     
    798782  char *out;
    799783  int err, status;
     784  int tried_gpg1 = FALSE;
    800785  const char *argv[] = {
    801     "gpg",
     786    "gpg1",
    802787    "--symmetric",
    803788    "--no-options",
     
    813798    NULL
    814799  };
    815   err = call_filter(argv, in, &out, &status);
     800  while ((err = call_filter(argv, in, &out, &status)) && !out && !tried_gpg1) {
     801    tried_gpg1 = TRUE;
     802    argv[0] = "gpg";
     803  }
    816804  if(err || status) {
    817805    g_free(out);
     
    882870  char *in, *out;
    883871  int length;
     872  int tried_gpg1 = FALSE;
    884873  const char *argv[] = {
    885     "gpg",
     874    "gpg1",
    886875    "--decrypt",
    887876    "--no-options",
     
    900889  if(!in) return FALSE;
    901890
    902   err = call_filter(argv, in, &out, &status);
     891  while ((err = call_filter(argv, in, &out, &status)) && !out && !tried_gpg1) {
     892    tried_gpg1 = TRUE;
     893    argv[0] = "gpg";
     894  }
    903895  free(in);
    904896  if(err || status) {
     
    913905
    914906int do_decrypt_des(const char *keyfile) {
    915   des_key_schedule schedule;
     907  DES_key_schedule schedule;
    916908  unsigned char input[8], output[8];
    917909  char tmp[9];
     
    923915    have a NULL-terminated string we can call printf/strlen on.
    924916
    925     We don't pass 'tmp' to des_ecb_encrypt directly, because it's
     917    We don't pass 'tmp' to DES_ecb_encrypt directly, because it's
    926918    prototyped as taking 'unsigned char[8]', and this avoids a stupid
    927919    cast.
     
    941933  while (read_ascii_block(input))
    942934  {
    943     des_ecb_encrypt(&input, &output, schedule, FALSE);
     935    DES_ecb_encrypt(&input, &output, &schedule, FALSE);
    944936    memcpy(tmp, output, 8);
    945937    printf("%s", tmp);
  • zephyr.c

    r80d7b44 ree6b30f  
    125125    owl_zephyr_loadsubs_helper(subs->subs, subs->nsubs);
    126126    deferred_subs = g_list_delete_link(deferred_subs, deferred_subs);
    127     g_free(subs);
     127    g_slice_free(owl_sub_list, subs);
    128128  }
    129129
     
    152152  ret_sd = owl_zephyr_loaddefaultsubs();
    153153
    154   /* load Barnowl default subscriptions */
     154  /* load BarnOwl default subscriptions */
    155155  ret_bd = owl_zephyr_loadbarnowldefaultsubs();
    156156
     
    261261    g_free(subs);
    262262  } else {
    263     owl_sub_list *s = g_new(owl_sub_list, 1);
     263    owl_sub_list *s = g_slice_new(owl_sub_list);
    264264    s->subs = subs;
    265265    s->nsubs = count;
     
    283283#ifdef HAVE_LIBZEPHYR
    284284  FILE *file;
    285   char *tmp, *start;
     285  int fopen_errno;
     286  char *tmp, *start, *saveptr;
    286287  char *buffer = NULL;
    287288  char *subsfile;
     
    289290  int subSize = 1024;
    290291  int count;
    291   struct stat statbuff;
    292292
    293293  subsfile = owl_zephyr_dotfile(".zephyr.subs", filename);
    294294
    295   if (stat(subsfile, &statbuff) != 0) {
    296     g_free(subsfile);
    297     if (error_on_nofile == 1)
     295  count = 0;
     296  file = fopen(subsfile, "r");
     297  fopen_errno = errno;
     298  g_free(subsfile);
     299  if (!file) {
     300    if (error_on_nofile == 1 || fopen_errno != ENOENT)
    298301      return -1;
    299302    return 0;
    300303  }
    301 
    302   ZResetAuthentication();
    303   count = 0;
    304   file = fopen(subsfile, "r");
    305   g_free(subsfile);
    306   if (!file)
    307     return -1;
    308304
    309305  subs = g_new(ZSubscription_t, subSize);
     
    323319   
    324320    /* add it to the list of subs */
    325     if ((tmp = strtok(start, ",\n\r")) == NULL)
     321    if ((tmp = strtok_r(start, ",\n\r", &saveptr)) == NULL)
    326322      continue;
    327323    subs[count].zsub_class = g_strdup(tmp);
    328     if ((tmp=strtok(NULL, ",\n\r")) == NULL)
     324    if ((tmp = strtok_r(NULL, ",\n\r", &saveptr)) == NULL)
    329325      continue;
    330326    subs[count].zsub_classinst = g_strdup(tmp);
    331     if ((tmp = strtok(NULL, " \t\n\r")) == NULL)
     327    if ((tmp = strtok_r(NULL, " \t\n\r", &saveptr)) == NULL)
    332328      continue;
    333329    subs[count].zsub_recipient = g_strdup(tmp);
     
    348344    g_free(buffer);
    349345
     346  ZResetAuthentication();
    350347  return owl_zephyr_loadsubs_helper(subs, count);
    351348#else
     
    354351}
    355352
    356 /* Load default Barnowl subscriptions
     353/* Load default BarnOwl subscriptions
    357354 *
    358355 * Returns 0 on success.
     
    363360#ifdef HAVE_LIBZEPHYR
    364361  ZSubscription_t *subs;
    365   int subSize = 10; /* Max Barnowl default subs we allow */
     362  int subSize = 10; /* Max BarnOwl default subs we allow */
    366363  int count, ret;
    367364
     
    412409  char *buffer = NULL;
    413410  int count;
    414   struct stat statbuff;
    415411
    416412  subs = g_new(ZSubscription_t, numSubs);
    417413  subsfile = owl_zephyr_dotfile(".anyone", filename);
    418414
    419   if (stat(subsfile, &statbuff) == -1) {
    420     g_free(subs);
    421     g_free(subsfile);
    422     return 0;
    423   }
    424 
    425   ZResetAuthentication();
    426415  count = 0;
    427416  file = fopen(subsfile, "r");
     
    445434    fclose(file);
    446435  } else {
     436    g_free(subs);
    447437    return 0;
    448438  }
    449439  g_free(buffer);
    450440
     441  ZResetAuthentication();
    451442  return owl_zephyr_loadsubs_helper(subs, count);
    452443#else
     
    11061097}
    11071098
     1099#ifdef HAVE_LIBZEPHYR
     1100const char *owl_zephyr_get_charsetstr(const ZNotice_t *n)
     1101{
     1102#ifdef ZCHARSET_UTF_8
     1103  return ZCharsetToString(n->z_charset);
     1104#else
     1105  return "";
     1106#endif
     1107}
     1108#else
     1109const char *owl_zephyr_get_charsetstr(const void *n)
     1110{
     1111  return "";
     1112}
     1113#endif
     1114
    11081115/* return auth string */
    11091116#ifdef HAVE_LIBZEPHYR
     
    13031310CALLER_OWN char *owl_zephyr_smartstripped_user(const char *in)
    13041311{
    1305   char *slash, *dot, *realm, *out;
    1306 
    1307   out = g_strdup(in);
    1308 
    1309   /* bail immeaditly if we don't have to do any work */
    1310   slash = strchr(out, '/');
    1311   dot = strchr(out, '.');
    1312   if (!slash && !dot) {
    1313     return(out);
    1314   }
    1315 
    1316   if (!strncasecmp(out, OWL_ZEPHYR_NOSTRIP_HOST, strlen(OWL_ZEPHYR_NOSTRIP_HOST)) ||
    1317       !strncasecmp(out, OWL_ZEPHYR_NOSTRIP_RCMD, strlen(OWL_ZEPHYR_NOSTRIP_RCMD)) ||
    1318       !strncasecmp(out, OWL_ZEPHYR_NOSTRIP_DAEMON5, strlen(OWL_ZEPHYR_NOSTRIP_DAEMON5)) ||
    1319       !strncasecmp(out, OWL_ZEPHYR_NOSTRIP_DAEMON4, strlen(OWL_ZEPHYR_NOSTRIP_DAEMON4))) {
    1320     return(out);
    1321   }
    1322 
    1323   realm = strchr(out, '@');
    1324   if (!slash && dot && realm && (dot > realm)) {
    1325     /* There's no '/', and the first '.' is in the realm */
    1326     return(out);
    1327   }
    1328 
    1329   /* remove the realm from out, but hold on to it */
    1330   if (realm) realm[0]='\0';
    1331 
    1332   /* strip */
    1333   if (slash) slash[0] = '\0';  /* krb5 style user/instance */
    1334   else if (dot) dot[0] = '\0'; /* krb4 style user.instance */
    1335 
    1336   /* reattach the realm if we had one */
    1337   if (realm) {
    1338     strcat(out, "@");
    1339     strcat(out, realm+1);
    1340   }
    1341 
    1342   return(out);
     1312  int n = strcspn(in, "./");
     1313  const char *realm = strchr(in, '@');
     1314  if (realm == NULL)
     1315    realm = in + strlen(in);
     1316
     1317  if (in + n >= realm ||
     1318      g_str_has_prefix(in, OWL_ZEPHYR_NOSTRIP_HOST) ||
     1319      g_str_has_prefix(in, OWL_ZEPHYR_NOSTRIP_RCMD) ||
     1320      g_str_has_prefix(in, OWL_ZEPHYR_NOSTRIP_DAEMON5) ||
     1321      g_str_has_prefix(in, OWL_ZEPHYR_NOSTRIP_DAEMON4))
     1322    return g_strdup(in);
     1323  else
     1324    return g_strdup_printf("%.*s%s", n, in, realm);
    13431325}
    13441326
     
    14241406          if (ret == ZERR_NONE) {
    14251407            /* Send a PSEUDO LOGIN! */
    1426             m = g_new(owl_message, 1);
     1408            m = g_slice_new(owl_message);
    14271409            owl_message_create_pseudo_zlogin(m, 0, zald->user,
    14281410                                             location.host,
     
    14371419        /* Send a PSEUDO LOGOUT! */
    14381420        if (notify) {
    1439           m = g_new(owl_message, 1);
     1421          m = g_slice_new(owl_message);
    14401422          owl_message_create_pseudo_zlogin(m, 1, zald->user, "", "", "");
    14411423          owl_global_messagequeue_addmsg(&g, m);
     
    14461428    }
    14471429    ZFreeALD(zald);
    1448     g_free(zald);
     1430    g_slice_free(ZAsyncLocateData_t, zald);
    14491431  }
    14501432}
     
    15131495
    15141496      /* create the new message */
    1515       m=g_new(owl_message, 1);
     1497      m=g_slice_new(owl_message);
    15161498      owl_message_create_from_znotice(m, &notice);
    15171499
  • zwrite.c

    r919cbf2 r1958790  
    33CALLER_OWN owl_zwrite *owl_zwrite_new_from_line(const char *line)
    44{
    5   owl_zwrite *z = g_new(owl_zwrite, 1);
     5  owl_zwrite *z = g_slice_new(owl_zwrite);
    66  if (owl_zwrite_create_from_line(z, line) != 0) {
    7     g_free(z);
     7    g_slice_free(owl_zwrite, z);
    88    return NULL;
    99  }
     
    1313CALLER_OWN owl_zwrite *owl_zwrite_new(int argc, const char *const *argv)
    1414{
    15   owl_zwrite *z = g_new(owl_zwrite, 1);
     15  owl_zwrite *z = g_slice_new(owl_zwrite);
    1616  if (owl_zwrite_create(z, argc, argv) != 0) {
    17     g_free(z);
     17    g_slice_free(owl_zwrite, z);
    1818    return NULL;
    1919  }
     
    270270  rv = owl_zwrite_create_from_line(&z, cmd);
    271271  if (rv != 0) return rv;
    272   if (!owl_zwrite_is_message_set(&z)) {
    273     owl_zwrite_set_message(&z, msg);
    274   }
    275   owl_zwrite_populate_zsig(&z);
    276   owl_zwrite_send_message(&z);
     272  owl_function_zwrite(&z, msg);
    277273  owl_zwrite_cleanup(&z);
    278274  return(0);
     
    356352{
    357353  owl_zwrite_cleanup(z);
    358   g_free(z);
     354  g_slice_free(owl_zwrite, z);
    359355}
    360356
Note: See TracChangeset for help on using the changeset viewer.