Changeset e488ec5


Ignore:
Timestamp:
Jul 27, 2010, 10:50:36 PM (11 years ago)
Author:
Nelson Elhage <nelhage@mit.edu>
Branches:
master, release-1.7, release-1.8, release-1.9
Children:
35a30f9
Parents:
f93cc34 (diff), 26ad412 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:
Merge branch 'security'
Files:
26 added
1 deleted
37 edited

Legend:

Unmodified
Added
Removed
  • aim.c

    r5e5f08f rc5873be  
    77
    88struct owlfaim_priv {
    9   char *aimbinarypath;
    109  char *screenname;
    1110  char *password;
     
    6564/* static int reportinterval(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs); */
    6665static int faimtest_parse_motd(aim_session_t *sess, aim_frame_t *fr, ...);
    67 static int getaimdata(aim_session_t *sess, unsigned char **bufret, int *buflenret, unsigned long offset, unsigned long len, const char *modname);
    68 static int faimtest_memrequest(aim_session_t *sess, aim_frame_t *fr, ...);
    6966/* static void printuserflags(fu16_t flags); */
    7067static int faimtest_parse_userinfo(aim_session_t *sess, aim_frame_t *fr, ...);
     
    517514  va_end(ap);
    518515
    519   owl_function_debugmsg("faimtest_parse_login: %s %s %s", priv->screenname, priv->password, key);
    520 
    521516  aim_send_login(sess, fr->conn, priv->screenname, priv->password, &info, key);
    522517 
     
    635630  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR,    faimtest_parse_connerr, 0);
    636631  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_RIGHTSINFO,         faimtest_locrights, 0);
    637   aim_conn_addhandler(sess, bosconn, 0x0001,         0x001f,                        faimtest_memrequest, 0);
    638632  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_ONCOMING,           faimtest_parse_oncoming, 0);
    639633  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_OFFGOING,           faimtest_parse_offgoing, 0);
     
    951945
    952946/*
    953  * This is a little more complicated than it looks.  The module
    954  * name (proto, boscore, etc) may or may not be given.  If it is
    955  * not given, then use aim.exe.  If it is given, put ".ocm" on the
    956  * end of it.
    957  *
    958  * Now, if the offset or length requested would cause a read past
    959  * the end of the file, then the request is considered invalid.  Invalid
    960  * requests are processed specially.  The value hashed is the
    961  * the request, put into little-endian (eight bytes: offset followed
    962  * by length). 
    963  *
    964  * Additionally, if the request is valid, the length is mod 4096.  It is
    965  * important that the length is checked for validity first before doing
    966  * the mod.
    967  *
    968  * Note to Bosco's Brigade: if you'd like to break this, put the
    969  * module name on an invalid request.
    970  *
    971  */
    972 static int getaimdata(aim_session_t *sess, unsigned char **bufret, int *buflenret, unsigned long offset, unsigned long len, const char *modname)
    973 {
    974   struct owlfaim_priv *priv = sess->aux_data;
    975   FILE *f;
    976   static const char defaultmod[] = "aim.exe";
    977   char *filename = NULL;
    978   struct stat st;
    979   unsigned char *buf;
    980   int invalid = 0;
    981  
    982   if (!bufret || !buflenret)
    983     return -1;
    984  
    985   if (modname) {
    986     filename = owl_sprintf("%s/%s.ocm", priv->aimbinarypath, modname);
    987   } else {
    988     filename = owl_sprintf("%s/%s", priv->aimbinarypath, defaultmod);
    989   }
    990  
    991   if (stat(filename, &st) == -1) {
    992     if (!modname) {
    993       /* perror("memrequest: stat"); */
    994       owl_free(filename);
    995       return -1;
    996     }
    997     invalid = 1;
    998   }
    999  
    1000   if (!invalid) {
    1001     if ((offset > st.st_size) || (len > st.st_size))
    1002       invalid = 1;
    1003     else if ((st.st_size - offset) < len)
    1004       len = st.st_size - offset;
    1005     else if ((st.st_size - len) < len)
    1006       len = st.st_size - len;
    1007   }
    1008  
    1009   if (!invalid && len) {
    1010     len %= 4096;
    1011   }
    1012  
    1013   if (invalid) {
    1014     int i;
    1015    
    1016     owl_free(filename); /* not needed */
    1017     owl_function_error("getaimdata memrequest: recieved invalid request for 0x%08lx bytes at 0x%08lx (file %s)\n", len, offset, modname);
    1018     i = 8;
    1019     if (modname) {
    1020       i+=strlen(modname);
    1021     }
    1022    
    1023     if (!(buf = owl_malloc(i))) {
    1024       return -1;
    1025     }
    1026    
    1027     i=0;
    1028    
    1029     if (modname) {
    1030       memcpy(buf, modname, strlen(modname));
    1031       i+=strlen(modname);
    1032     }
    1033    
    1034     /* Damn endianness. This must be little (LSB first) endian. */
    1035     buf[i++] = offset & 0xff;
    1036     buf[i++] = (offset >> 8) & 0xff;
    1037     buf[i++] = (offset >> 16) & 0xff;
    1038     buf[i++] = (offset >> 24) & 0xff;
    1039     buf[i++] = len & 0xff;
    1040     buf[i++] = (len >> 8) & 0xff;
    1041     buf[i++] = (len >> 16) & 0xff;
    1042     buf[i++] = (len >> 24) & 0xff;
    1043    
    1044     *bufret = buf;
    1045     *buflenret = i;
    1046   } else {
    1047     if (!(buf = owl_malloc(len))) {
    1048       owl_free(filename);
    1049       return -1;
    1050     }
    1051     /* printf("memrequest: loading %ld bytes from 0x%08lx in \"%s\"...\n", len, offset, filename); */
    1052     if (!(f = fopen(filename, "r"))) {
    1053       /* perror("memrequest: fopen"); */
    1054       owl_free(filename);
    1055       owl_free(buf);
    1056       return -1;
    1057     }
    1058    
    1059     owl_free(filename);
    1060    
    1061     if (fseek(f, offset, SEEK_SET) == -1) {
    1062       /* perror("memrequest: fseek"); */
    1063       fclose(f);
    1064       owl_free(buf);
    1065       return -1;
    1066     }
    1067    
    1068     if (fread(buf, len, 1, f) != 1) {
    1069       /* perror("memrequest: fread"); */
    1070       fclose(f);
    1071       owl_free(buf);
    1072       return -1;
    1073     }
    1074    
    1075     fclose(f);
    1076     *bufret = buf;
    1077     *buflenret = len;
    1078   }
    1079   return 0; /* success! */
    1080 }
    1081 
    1082 /*
    1083  * This will get an offset and a length.  The client should read this
    1084  * data out of whatever AIM.EXE binary the user has provided (hopefully
    1085  * it matches the client information thats sent at login) and pass a
    1086  * buffer back to libfaim so it can hash the data and send it to AOL for
    1087  * inspection by the client police.
    1088  */
    1089 static int faimtest_memrequest(aim_session_t *sess, aim_frame_t *fr, ...)
    1090 {
    1091   struct owlfaim_priv *priv = sess->aux_data;
    1092   va_list ap;
    1093   fu32_t offset, len;
    1094   const char *modname;
    1095   unsigned char *buf;
    1096   int buflen;
    1097  
    1098   va_start(ap, fr);
    1099   offset = va_arg(ap, fu32_t);
    1100   len = va_arg(ap, fu32_t);
    1101   modname = va_arg(ap, const char *);
    1102   va_end(ap);
    1103  
    1104   if (priv->aimbinarypath && (getaimdata(sess, &buf, &buflen, offset, len, modname) == 0)) {
    1105     aim_sendmemblock(sess, fr->conn, offset, buflen, buf, AIM_SENDMEMBLOCK_FLAG_ISREQUEST);
    1106     owl_free(buf);
    1107   } else {
    1108     owl_function_debugmsg("faimtest_memrequest: unable to use AIM binary (\"%s/%s\"), sending defaults...\n", priv->aimbinarypath, modname);
    1109     aim_sendmemblock(sess, fr->conn, offset, len, NULL, AIM_SENDMEMBLOCK_FLAG_ISREQUEST);
    1110   }
    1111   return 1;
    1112 }
    1113 
    1114 /*
    1115947static void printuserflags(fu16_t flags)
    1116948{
  • functions.c

    rd296c9a re488ec5  
    11771177    return;
    11781178
    1179   file = fopen(owl_global_get_debug_file(&g), "a");
     1179  file = owl_global_get_debug_file_handle(&g);
    11801180  if (!file) /* XXX should report this */
    11811181    return;
     
    11871187  vfprintf(file, fmt, ap);
    11881188  putc('\n', file);
    1189   fclose(file);
     1189  fflush(file);
    11901190
    11911191  va_end(ap);
  • global.c

    rd296c9a re488ec5  
    983983                                                       filters[i].desc));
    984984}
     985
     986FILE *owl_global_get_debug_file_handle(owl_global *g) {
     987  static char *open_file = NULL;
     988  const char *filename = owl_global_get_debug_file(g);
     989  if (g->debug_file == NULL ||
     990      (open_file && strcmp(filename, open_file) != 0)) {
     991    char *path;
     992    int fd;
     993
     994    if (g->debug_file)
     995      fclose(g->debug_file);
     996
     997    g->debug_file = NULL;
     998
     999    path = owl_sprintf("%s.%d", filename, getpid());
     1000    fd = open(path, O_CREAT|O_WRONLY|O_EXCL, 0600);
     1001    owl_free(path);
     1002
     1003    if (fd >= 0)
     1004      g->debug_file = fdopen(fd, "a");
     1005
     1006    owl_free(open_file);
     1007    open_file = owl_strdup(filename);
     1008  }
     1009  return g->debug_file;
     1010}
  • owl.c

    r205e164 re488ec5  
    457457  g.load_initial_subs = opts.load_initial_subs;
    458458
    459   owl_function_debugmsg("startup: Finished parsing arguments");
    460 
    461459  owl_register_signal_handlers();
    462460  owl_start_curses();
  • owl.h

    rd296c9a re488ec5  
    7676
    7777#define OWL_DEBUG 0
    78 #define OWL_DEBUG_FILE "/var/tmp/owldebug"
     78#define OWL_DEBUG_FILE "/var/tmp/barnowl-debug"
    7979
    8080#define OWL_CONFIG_DIR "/.owl"             /* this is relative to the user's home directory */
     
    643643  int load_initial_subs;
    644644  volatile sig_atomic_t interrupted;
     645  FILE *debug_file;
    645646} owl_global;
    646647
  • variable.c

    rf6fae8d re488ec5  
    186186  OWLVAR_PATH( "debug_file" /* %OwlVarStub */, OWL_DEBUG_FILE,
    187187               "path for logging debug messages when debugging is enabled",
    188                "This file will be logged to if 'debug' is set to 'on'.\n"),
     188               "This file will be logged to if 'debug' is set to 'on'.\n"
     189               "BarnOwl will append a dot and the current process's pid to the filename."),
    189190 
    190191  OWLVAR_PATH( "zsigproc" /* %OwlVarStub:zsigproc */, NULL,
  • zephyr.c

    r987cf3f re488ec5  
    179179{
    180180#ifdef HAVE_LIBZEPHYR
    181   if(owl_global_is_havezephyr(&g))
    182     return(ZPending());
     181  Code_t code;
     182  if(owl_global_is_havezephyr(&g)) {
     183    if((code = ZPending()) < 0) {
     184      owl_function_debugmsg("Error (%s) in ZPending()\n",
     185                            error_message(code));
     186      return 0;
     187    }
     188    return code;
     189  }
    183190#endif
    184191  return 0;
     
    13971404#ifdef HAVE_LIBZEPHYR
    13981405  ZNotice_t notice;
     1406  Code_t code;
    13991407  owl_message *m=NULL;
    14001408
    14011409  while(owl_zephyr_zpending() && zpendcount < OWL_MAX_ZEPHYRGRAMS_TO_PROCESS) {
    14021410    if (owl_zephyr_zpending()) {
    1403       ZReceiveNotice(&notice, NULL);
     1411      if ((code = ZReceiveNotice(&notice, NULL)) != ZERR_NONE) {
     1412        owl_function_debugmsg("Error: %s while calling ZReceiveNotice\n",
     1413                              error_message(code));
     1414        continue;
     1415      }
    14041416      zpendcount++;
    14051417
  • .gitignore

    rde18326 rf93cc34  
    1515autom4te.cache
    1616barnowl.bin
     17tester.bin
    1718zcrypt
    1819blib
     
    3031owl_prototypes.h
    3132owl_prototypes.h.new
    32 perl_tester
    3333perlglue.c
    3434perlwrap.c
  • Makefile.am

    r5aa33fd rd296c9a  
    11ACLOCAL_AMFLAGS = -I m4
     2CFLAGS += $(EXTRA_CFLAGS)
    23
    34GIT_DESCRIPTION := $(if $(wildcard .git),$(shell git describe --match='barnowl-*' HEAD 2>/dev/null))
     
    1819     $(GEN_C) $(GEN_H)
    1920
     21man_MANS = doc/barnowl.1
     22doc_DATA = doc/intro.txt doc/advanced.txt
     23
    2024barnowl_bin_LDADD = libfaim/libfaim.a
    2125
     
    3539           $(GIT_FLAGS)
    3640
    37 BASE_SRCS=list.c message.c mainwin.c popwin.c zephyr.c messagelist.c \
     41CODELIST_SRCS=list.c message.c mainwin.c popwin.c zephyr.c messagelist.c \
    3842     commands.c global.c text.c fmtext.c editwin.c util.c logging.c \
    3943     perlconfig.c keys.c functions.c zwrite.c viewwin.c help.c filter.c \
     
    4145     keypress.c keymap.c keybinding.c cmd.c context.c \
    4246     aim.c buddy.c buddylist.c style.c errqueue.c \
    43      zbuddylist.c popexec.c obarray.c select.c wcwidth.c \
    44      glib_compat.c filterproc.c
     47     zbuddylist.c popexec.c select.c wcwidth.c \
     48     glib_compat.c mainpanel.c msgwin.c sepbar.c
     49
     50NORMAL_SRCS = filterproc.c window.c windowcb.c
     51
     52BASE_SRCS = $(CODELIST_SRCS) $(NORMAL_SRCS)
    4553
    4654GEN_C = varstubs.c perlglue.c
     
    6472        $(AM_V_GEN)perl $< $(sort $(filter-out $<,$+)) > $@
    6573
    66 owl_prototypes.h.new: codelist.pl varstubs.c $(BASE_SRCS)
     74owl_prototypes.h.new: codelist.pl varstubs.c $(CODELIST_SRCS)
    6775        $(AM_V_GEN)perl $< $(sort $(filter-out $<,$+)) > $@
    6876
  • README

    r62c91c1 raeadc74  
    11BarnOwl - owl, with more ponies
    22
     3Source is freely available from http://github.com/barnowl/barnowl/
     4
    35Based on owl 2.1.11, by James Kretchmar (http://www.ktools.org)
    4 
    5 This project is a work in progress.
    6 We guarantee no stability of form or function.
    76
    87Notes:
  • cmd.c

    r8d4b521 rd296c9a  
    5252  cmd = owl_malloc(sizeof(owl_cmd));
    5353  owl_cmd_create_alias(cmd, alias_from, alias_to);
     54  owl_perlconfig_new_command(cmd->name);
    5455  owl_dict_insert_element(cd, cmd->name, cmd, (void (*)(void *))owl_cmd_delete);
    5556  return(0);
     
    7374  } else if (NULL != (cmd = owl_dict_find_element(cd, argv[0]))) {
    7475    retval = owl_cmd_execute(cmd, cd, ctx, argc, argv, buff);
     76    /* redraw the sepbar; TODO: don't violate layering */
     77    owl_global_sepbar_dirty(&g);
    7578  } else {
    7679    owl_function_makemsg("Unknown command '%s'.", buff);
     
    8992  if (argc < 0) {
    9093    owl_free(tmpbuff);
    91     sepbar(NULL);
    9294    owl_function_makemsg("Unbalanced quotes");
    9395    return NULL;
     
    104106  owl_parse_delete(argv, argc);
    105107  owl_free(tmpbuff);
    106   sepbar(NULL);
    107108  return retval;
    108109}
  • commands.c

    r7ba9e0de rd296c9a  
    106106  OWLCMD_ARGS("zwrite", owl_command_zwrite, OWL_CTX_INTERACTIVE,
    107107              "send a zephyr",
    108               "zwrite [-n] [-C] [-c class] [-i instance] [-r realm] [-O opcde] [<user> ...] [-m <message...>]",
     108              "zwrite [-n] [-C] [-c class] [-i instance] [-r realm] [-O opcode] [<user> ...] [-m <message...>]",
    109109              "Zwrite send a zephyr to the one or more users specified.\n\n"
    110110              "The following options are available:\n\n"
     
    136136              "Send a local message.\n"),
    137137
    138   OWLCMD_ARGS("zcrypt", owl_command_zcrypt, OWL_CTX_INTERACTIVE,
     138  OWLCMD_ARGS("zcrypt", owl_command_zwrite, OWL_CTX_INTERACTIVE,
    139139              "send an encrypted zephyr",
    140               "zcrypt [-n] [-C] [-c class] [-i instance] [-r realm] [-O opcde] [-m <message...>]\n",
     140              "zcrypt [-n] [-C] [-c class] [-i instance] [-r realm] [-O opcode] [-m <message...>]\n",
    141141              "Behaves like zwrite but uses encryption.  Not for use with\n"
    142142              "personal messages\n"),
     
    148148              "allow editing.\n\n"
    149149              "If 'sender' is specified, reply to the sender.\n\n"
    150               "If 'all' or no args are specified, reply publically to the\n"
     150              "If 'all' or no args are specified, reply publicly to the\n"
    151151              "same class/instance for non-personal messages and to the\n"
    152152              "sender for personal messages.\n\n"
     
    266266              "zpunt <class> <instance> [recipient]\n"
    267267              "zpunt <instance>",
    268               "The zpunt command will supress message to the specified\n"
     268              "The zpunt command will suppress messages to the specified\n"
    269269              "zephyr triplet.  In the second usage messages are suppressed\n"
    270270              "for class MESSAGE and the named instance.\n\n"
     
    283283              "punt <filter-text>",
    284284              "punt <filter-text (multiple words)>\n"
    285               "The punt command will supress message to the specified\n"
     285              "The punt command will suppress messages to the specified\n"
    286286              "filter\n\n"
    287287              "SEE ALSO:  unpunt, zpunt, show zpunts\n"),
     
    586586              "name style after the -s argument.\n"
    587587              "\n"
    588               "The other usages listed above are abbreivated forms that simply set\n"
     588              "The other usages listed above are abbreviated forms that simply set\n"
    589589              "the filter of the current view. The -d option allows you to write a\n"
    590590              "filter expression that will be dynamically created by owl and then\n"
     
    594594  OWLCMD_ARGS("smartnarrow", owl_command_smartnarrow, OWL_CTX_INTERACTIVE,
    595595              "view only messages similar to the current message",
    596               "smartnarrow [-i | --instance]  [-r | --relatde]",
     596              "smartnarrow [-i | --instance]  [-r | --related]",
    597597              "If the curmsg is a personal message narrow\n"
    598598              "   to the conversation with that user.\n"
     
    614614              "   message, the filter is to that instance.\n"
    615615              "If the curmsg is a class message, the filter is that class.\n"
    616               "If the curmsg is a class message and '-i' is specied\n"
     616              "If the curmsg is a class message and '-i' is specified\n"
    617617              "    the filter is to that class and instance.\n"),
    618618
     
    674674              "for formatting messages.\n\n"
    675675              "Show variables will list the names of all variables.\n\n"
    676               "Show errors will show a list of errors ecountered by Owl.\n\n"
     676              "Show errors will show a list of errors encountered by Owl.\n\n"
    677677              "SEE ALSO: filter, view, alias, bindkey, help\n"),
    678678 
     
    743743              "set the search highlight string without searching",
    744744              "setsearch <string>",
    745               "The setsearch command highlights all occurences of its\n"
     745              "The setsearch command highlights all occurrences of its\n"
    746746          "argument and makes it the default argument for future\n"
    747747          "search commands, but does not move the cursor.  With\n"
     
    13711371{
    13721372  owl_function_full_redisplay();
    1373   owl_global_set_needrefresh(&g);
    13741373}
    13751374
     
    13871386{
    13881387  owl_global_set_rightshift(&g, shift);
    1389   owl_mainwin_redisplay(owl_global_get_mainwin(&g));
    1390   owl_global_set_needrefresh(&g);
    13911388}
    13921389
     
    19141911char *owl_command_zwrite(int argc, const char *const *argv, const char *buff)
    19151912{
    1916   owl_zwrite z;
     1913  owl_zwrite *z;
    19171914
    19181915  if (!owl_global_is_havezephyr(&g)) {
     
    19211918  }
    19221919  /* check for a zwrite -m */
    1923   owl_zwrite_create_from_line(&z, buff);
    1924   if (owl_zwrite_is_message_set(&z)) {
    1925     owl_function_zwrite(buff, NULL);
    1926     owl_zwrite_cleanup(&z);
    1927     return (NULL);
    1928   }
    1929   owl_zwrite_cleanup(&z);
     1920  z = owl_zwrite_new(buff);
     1921  if (!z) {
     1922    owl_function_error("Error in zwrite arguments");
     1923    return NULL;
     1924  }
     1925
     1926  if (owl_zwrite_is_message_set(z)) {
     1927    owl_function_zwrite(z, NULL);
     1928    owl_zwrite_delete(z);
     1929    return NULL;
     1930  }
    19301931
    19311932  if (argc < 2) {
     1933    owl_zwrite_delete(z);
    19321934    owl_function_makemsg("Not enough arguments to the zwrite command.");
    19331935  } else {
    1934     owl_function_zwrite_setup(buff);
     1936    owl_function_zwrite_setup(z);
    19351937  }
    19361938  return(NULL);
     
    20222024}
    20232025
    2024 char *owl_command_zcrypt(int argc, const char *const *argv, const char *buff)
    2025 {
    2026   owl_zwrite z;
    2027 
    2028   if (!owl_global_is_havezephyr(&g)) {
    2029     owl_function_makemsg("Zephyr is not available");
    2030     return(NULL);
    2031   }
    2032   /* check for a zcrypt -m */
    2033   owl_zwrite_create_from_line(&z, buff);
    2034   if (owl_zwrite_is_message_set(&z)) {
    2035     owl_function_zcrypt(buff, NULL);
    2036     owl_zwrite_cleanup(&z);
    2037     return (NULL);
    2038   }
    2039   owl_zwrite_cleanup(&z);
    2040 
    2041   if (argc < 2) {
    2042     owl_function_makemsg("Not enough arguments to the zcrypt command.");
    2043   } else {
    2044     owl_function_zwrite_setup(buff);
    2045   }
    2046   return(NULL);
    2047 }
    2048 
    20492026char *owl_command_reply(int argc, const char *const *argv, const char *buff)
    20502027{
     
    21842161      argc--;
    21852162      argv++;
    2186     } else if (!strcmp(argv[0], "-r")) {
    2187       const char *foo;
    2188       foo=owl_function_create_negative_filter(owl_view_get_filtname(owl_global_get_current_view(&g)));
    2189       owl_function_change_currentview_filter(foo);
    21902163    } else if (!strcmp(argv[0], "-s")) {
    21912164      if (argc<2) {
     
    27172690  }
    27182691
    2719   owl_global_set_needrefresh(&g);
    27202692  owl_global_pop_context(&g);
    27212693
     
    27382710    owl_editwin_clear(e);
    27392711    owl_editwin_insert_string(e, ptr);
    2740     owl_editwin_redisplay(e);
    2741     owl_global_set_needrefresh(&g);
    27422712  } else {
    27432713    owl_function_beep();
     
    27552725    owl_editwin_clear(e);
    27562726    owl_editwin_insert_string(e, ptr);
    2757     owl_editwin_redisplay(e);
    2758     owl_global_set_needrefresh(&g);
    27592727  } else {
    27602728    owl_function_beep();
     
    27662734  buff = skiptokens(buff, 1);
    27672735  owl_editwin_insert_string(e, buff);
    2768   owl_editwin_redisplay(e);
    2769   owl_global_set_needrefresh(&g); 
    27702736  return NULL;
    27712737}
     
    27822748  owl_global_set_typwin_inactive(&g);
    27832749  owl_global_pop_context(&g);
    2784   owl_global_set_needrefresh(&g);
    27852750
    27862751  owl_editwin_do_callback(e);
     
    28042769void owl_command_popless_quit(owl_viewwin *vw)
    28052770{
     2771  owl_viewwin_cleanup(vw);
    28062772  owl_popwin_close(owl_global_get_popwin(&g));
    28072773  owl_global_pop_context(&g);
    2808   owl_viewwin_cleanup(vw);
    2809   owl_global_set_needrefresh(&g);
    2810 }
     2774}
  • configure.ac

    r263320f rd296c9a  
    3535  [with_zephyr=check])
    3636
     37AC_ARG_WITH([krb4],
     38  AS_HELP_STRING([--with-krb4],
     39                 [Build with kerberos IV]))
     40
    3741AS_IF([test "x$with_zephyr" != xno],
    38   [AC_MSG_CHECKING([for Kerberos IV])
    39    AS_IF([krb5-config krb4 --libs >/dev/null 2>&1],
    40      [AC_MSG_RESULT([yes])
    41       AC_DEFINE([HAVE_KERBEROS_IV], [1], [Define if you have kerberos IV])
    42       CFLAGS="${CFLAGS} `krb5-config krb4 --cflags`"
    43       LIBS="${LIBS} `krb5-config krb4 --libs`"
    44      ],
    45      [AC_MSG_RESULT([no])
    46       PKG_CHECK_MODULES([LIBCRYPTO], [libcrypto])
    47       CFLAGS="${CFLAGS} ${LIBCRYPTO_CFLAGS}"
    48       LIBS="${LIBS} ${LIBCRYPTO_LIBS}"
    49      ])
     42  [AS_IF([test "x$with_krb4" != "xno"],
     43   [AC_MSG_CHECKING([for Kerberos IV])
     44    AS_IF([krb5-config krb4 --libs >/dev/null 2>&1],
     45      [AC_MSG_RESULT([yes])
     46       AC_DEFINE([HAVE_KERBEROS_IV], [1], [Define if you have kerberos IV])
     47       CFLAGS="${CFLAGS} `krb5-config krb4 --cflags`"
     48       LIBS="${LIBS} `krb5-config krb4 --libs`"
     49      ],
     50      [AC_MSG_RESULT([no])
     51       AS_IF([test "x$with_krb4" = "xyes"],
     52             [AC_MSG_ERROR([Kerberos IV requested but not found])])
     53       PKG_CHECK_MODULES([LIBCRYPTO], [libcrypto])
     54       CFLAGS="${CFLAGS} ${LIBCRYPTO_CFLAGS}"
     55       LIBS="${LIBS} ${LIBCRYPTO_LIBS}"
     56     ])])
    5057   AC_CHECK_LIB([zephyr], [ZGetSender],
    5158   [LIBS="$LIBS -lzephyr"
     
    108115
    109116dnl Add CFLAGS and LDFLAGS for glib-2.0
    110 PKG_CHECK_MODULES(GLIB,glib-2.0)
     117PKG_CHECK_MODULES(GLIB,[glib-2.0 gobject-2.0])
    111118
    112119AC_MSG_NOTICE([Adding glib-2.0 CFLAGS ${GLIB_CFLAGS}])
     
    131138                                 test "$HAVE_DES_ECB_ENCRYPT"])
    132139
     140CFLAGS="$CFLAGS -D_XOPEN_SOURCE"
     141
    133142AC_SUBST([LIBFAIM_CFLAGS])
    134143
  • context.c

    r2a17b63 r07b59ea  
    99  ctx->mode = OWL_CTX_STARTUP;
    1010  ctx->data = NULL;
     11  ctx->cursor = NULL;
    1112  return 0;
    1213}
  • doc/code.txt

    r1286893 r44cc9ab  
    8686             Meta.  At any one time, there is exactly one active
    8787             keymap which determines where keybindings are looked for
    88              (along with its submaps).
     88             (along with its parents).
    8989
    9090list:        Simple list abstraction.  (Uses realloc to resize the list.)
  • editwin.c

    r9d7a720 r3f11c00  
    2828  int cursorx;
    2929  int winlines, wincols, fillcol, wrapcol;
    30   WINDOW *curswin;
     30  owl_window *win;
     31  gulong repaint_id;
     32  gulong resized_id;
    3133  int style;
    3234  int lock;
     
    4042};
    4143
     44static void oe_set_window(owl_editwin *e, owl_window *w, int winlines, int wincols);
     45static void oe_redraw(owl_window *win, WINDOW *curswin, void *user_data);
    4246static void oe_reframe(owl_editwin *e);
    4347static void oe_save_excursion(owl_editwin *e, oe_excursion *x);
     
    5862static char *oe_chunk(owl_editwin *e, int start, int end);
    5963static void oe_destroy_cbdata(owl_editwin *e);
     64static void oe_dirty(owl_editwin *e);
     65static void oe_window_resized(owl_window *w, owl_editwin *e);
    6066
    6167#define INCR 4096
     
    7379void owl_editwin_delete(owl_editwin *e)
    7480{
     81  if (e->win) {
     82    g_signal_handler_disconnect(e->win, e->repaint_id);
     83    g_signal_handler_disconnect(e->win, e->resized_id);
     84  }
    7585  owl_free(e->buff);
    7686  owl_free(e->killbuf);
     
    91101  }
    92102  e->index = index;
     103  oe_dirty(e);
    93104}
    94105
     
    105116
    106117static void _owl_editwin_init(owl_editwin *e,
    107                               WINDOW *win,
    108118                              int winlines,
    109119                              int wincols,
     
    130140    e->style=OWL_EDITWIN_STYLE_MULTILINE;
    131141  }
    132   owl_editwin_set_curswin(e, win, winlines, wincols);
    133142  e->lock=0;
    134143  e->dotsend=0;
    135144  e->echochar='\0';
    136 
    137   if (win) werase(win);
    138 }
    139 
    140 owl_editwin *owl_editwin_new(WINDOW *win, int winlines, int wincols, int style, owl_history *hist)
     145}
     146
     147owl_editwin *owl_editwin_new(owl_window *win, int winlines, int wincols, int style, owl_history *hist)
    141148{
    142149  owl_editwin *e = owl_editwin_allocate();
    143150
    144   _owl_editwin_init(e, win, winlines, wincols, style, hist);
     151  _owl_editwin_init(e, winlines, wincols, style, hist);
     152  oe_set_window(e, win, winlines, wincols);
    145153  return e;
    146154}
    147155
    148 void owl_editwin_set_curswin(owl_editwin *e, WINDOW *w, int winlines, int wincols)
    149 {
    150   e->curswin=w;
     156static void oe_window_resized(owl_window *w, owl_editwin *e)
     157{
     158  /* update the sizes */
     159  owl_window_get_position(w, &e->winlines, &e->wincols, NULL, NULL);
     160}
     161
     162static void oe_set_window(owl_editwin *e, owl_window *w, int winlines, int wincols)
     163{
     164  e->win=w;
    151165  e->winlines=winlines;
    152166  e->wincols=wincols;
     
    156170  else
    157171    e->wrapcol = 0;
     172  if (e->win) {
     173    e->repaint_id = g_signal_connect(w, "redraw", G_CALLBACK(oe_redraw), e);
     174    e->resized_id = g_signal_connect(w, "resized", G_CALLBACK(oe_window_resized), e);
     175    owl_window_dirty(e->win);
     176  }
    158177}
    159178
     
    165184{
    166185  e->echochar=ch;
    167 }
    168 
    169 WINDOW *owl_editwin_get_curswin(owl_editwin *e)
    170 {
    171   return(e->curswin);
     186  oe_dirty(e);
    172187}
    173188
     
    239254  e->lock=e->bufflen;
    240255  oe_set_index(e, e->lock);
    241   owl_editwin_redisplay(e);
     256  oe_dirty(e);
    242257}
    243258
     
    265280
    266281  owl_free(e->buff);
    267   _owl_editwin_init(e, e->curswin, e->winlines, e->wincols, e->style, e->hist);
     282  _owl_editwin_init(e, e->winlines, e->wincols, e->style, e->hist);
    268283
    269284  if (lock > 0) {
     
    286301{
    287302  e->topindex = -1;
     303  oe_dirty(e);
    288304}
    289305
     
    467483
    468484  oe_restore_excursion(e, &x);
    469 }
    470 
    471 static void oe_addnec(owl_editwin *e, int count)
     485  oe_dirty(e);
     486}
     487
     488static void oe_addnec(owl_editwin *e, WINDOW *curswin, int count)
    472489{
    473490  int i;
    474491
    475492  for (i = 0; i < count; i++)
    476     waddch(e->curswin, e->echochar);
    477 }
    478 
    479 static void oe_mvaddnec(owl_editwin *e, int y, int x, int count)
    480 {
    481   wmove(e->curswin, y, x);
    482   oe_addnec(e, count);
     493    waddch(curswin, e->echochar);
     494}
     495
     496static void oe_mvaddnec(owl_editwin *e, WINDOW *curswin, int y, int x, int count)
     497{
     498  wmove(curswin, y, x);
     499  oe_addnec(e, curswin, count);
    483500}
    484501
    485502/* regenerate the text on the curses window */
    486 void owl_editwin_redisplay(owl_editwin *e)
     503static void oe_redraw(owl_window *win, WINDOW *curswin, void *user_data)
    487504{
    488505  int x = -1, y = -1, t, hard;
    489506  int line, index, lineindex, times = 0;
     507  owl_editwin *e = user_data;
    490508
    491509  do {
    492     werase(e->curswin);
     510    werase(curswin);
    493511
    494512    if (e->topindex == -1 || e->index < e->topindex)
     
    505523      if (index - lineindex) {
    506524        if (!e->echochar)
    507           mvwaddnstr(e->curswin, line, 0,
     525          mvwaddnstr(curswin, line, 0,
    508526                     e->buff + lineindex,
    509527                     index - lineindex);
    510528        else {
    511529          if(lineindex < e->lock) {
    512             mvwaddnstr(e->curswin, line, 0,
     530            mvwaddnstr(curswin, line, 0,
    513531                       e->buff + lineindex,
    514532                       MIN(index - lineindex,
    515533                           e->lock - lineindex));
    516534            if (e->lock < index)
    517               oe_addnec(e,
     535              oe_addnec(e, curswin,
    518536                        oe_region_width(e, e->lock, index,
    519537                                        oe_region_width(e, lineindex, e->lock, 0)));
    520538          } else
    521             oe_mvaddnec(e, line, 0, oe_region_width(e, lineindex, index, 0));
     539            oe_mvaddnec(e, curswin, line, 0, oe_region_width(e, lineindex, index, 0));
    522540        }
    523541        if (!hard)
    524           waddch(e->curswin, '\\');
     542          waddch(curswin, '\\');
    525543      }
    526544      line++;
     
    531549  } while(x == -1 && times < 3);
    532550
    533   wmove(e->curswin, y, x);
     551  wmove(curswin, y, x);
    534552  e->cursorx = x;
    535553}
     
    624642  if (start <= e->topindex)
    625643    owl_editwin_recenter(e);
     644
     645  oe_dirty(e);
    626646
    627647  return change;
     
    857877
    858878  e->goal_column = goal_column;
     879  oe_dirty(e);
    859880
    860881  return distance;
     
    12111232    return;
    12121233  }
    1213   owl_editwin_redisplay(e);
    12141234}
    12151235
     
    13461366}
    13471367
     1368static void oe_dirty(owl_editwin *e)
     1369{
     1370  if (e->win) owl_window_dirty(e->win);
     1371}
     1372
    13481373
    13491374
  • keymap.c

    r8a921b5 r44cc9ab  
    11#include <string.h>
    22#include "owl.h"
     3
     4static void _owl_keymap_format_bindings(const owl_keymap *km, owl_fmtext *fm);
     5static void _owl_keymap_format_with_parents(const owl_keymap *km, owl_fmtext *fm);
    36
    47/* returns 0 on success */
     
    912  if ((km->desc = owl_strdup(desc)) == NULL) return(-1);
    1013  if (0 != owl_list_create(&km->bindings)) return(-1);
    11   km->submap = NULL;
     14  km->parent = NULL;
    1215  km->default_fn = default_fn;
    1316  km->prealways_fn = prealways_fn;
     
    2427}
    2528
    26 void owl_keymap_set_submap(owl_keymap *km, const owl_keymap *submap)
    27 {
    28   km->submap = submap;
     29void owl_keymap_set_parent(owl_keymap *km, const owl_keymap *parent)
     30{
     31  km->parent = parent;
    2932}
    3033
     
    8689
    8790/* Appends details about the keymap to fm */
    88 void owl_keymap_get_details(const owl_keymap *km, owl_fmtext *fm)
    89 {
    90   int i, nbindings;
    91   const owl_keybinding *kb;
    92  
     91void owl_keymap_get_details(const owl_keymap *km, owl_fmtext *fm, int recurse)
     92{
    9393  owl_fmtext_append_bold(fm, "KEYMAP - ");
    9494  owl_fmtext_append_bold(fm, km->name);
     
    9999    owl_fmtext_append_normal(fm, "\n");
    100100  }
    101   if (km->submap) {
    102     owl_fmtext_append_normal(fm, OWL_TABSTR "Has submap: ");
    103     owl_fmtext_append_normal(fm, km->submap->name);
     101  if (km->parent) {
     102    owl_fmtext_append_normal(fm, OWL_TABSTR "Has parent: ");
     103    owl_fmtext_append_normal(fm, km->parent->name);
    104104    owl_fmtext_append_normal(fm, "\n");
    105105  }
     
    119119
    120120  owl_fmtext_append_bold(fm, "\nKey bindings:\n\n"); 
     121  if (recurse) {
     122    _owl_keymap_format_with_parents(km, fm);
     123  } else {
     124    _owl_keymap_format_bindings(km, fm);
     125  }
     126}
     127
     128static void _owl_keymap_format_with_parents(const owl_keymap *km, owl_fmtext *fm)
     129{
     130  while (km) {
     131    _owl_keymap_format_bindings(km, fm);
     132    km = km->parent;
     133    if (km) {
     134      owl_fmtext_append_bold(fm, "\nInherited from ");
     135      owl_fmtext_append_bold(fm, km->name);
     136      owl_fmtext_append_bold(fm, ":\n\n");
     137    }
     138  }
     139}
     140
     141static void _owl_keymap_format_bindings(const owl_keymap *km, owl_fmtext *fm)
     142{
     143  int i, nbindings;
     144  const owl_keybinding *kb;
     145 
    121146  nbindings = owl_list_get_size(&km->bindings);
    122147  for (i=0; i<nbindings; i++) {
     
    248273  }
    249274
    250   /* deal with the always_fn for the map and submaps */
    251   for (km=kh->active; km; km=km->submap) {
     275  /* deal with the always_fn for the map and parents */
     276  for (km=kh->active; km; km=km->parent) {
    252277    if (km->prealways_fn) {
    253278      km->prealways_fn(j);
     
    256281
    257282  /* search for a match.  goes through active keymap and then
    258    * through submaps... TODO:  clean this up so we can pull
     283   * through parents... TODO:  clean this up so we can pull
    259284   * keyhandler and keymap apart.  */
    260   for (km=kh->active; km; km=km->submap) {
     285  for (km=kh->active; km; km=km->parent) {
    261286    for (i=owl_list_get_size(&km->bindings)-1; i>=0; i--) {
    262287      kb = owl_list_get_element(&km->bindings, i);
  • keys.c

    r8a5b5a1 r5cc7e5e  
    3030       "Text editing and command window",
    3131       owl_keys_editwin_default, NULL, owl_keys_editwin_postalways);
    32   owl_keymap_set_submap(km_editwin, km_global);
     32  owl_keymap_set_parent(km_editwin, km_global);
    3333  /*
    3434  BIND_CMD("F1",          "help",            "");
     
    9999       "Multi-line text editing",
    100100       owl_keys_editwin_default, NULL, owl_keys_editwin_postalways);
    101   owl_keymap_set_submap(km_ew_multi, km_editwin);
     101  owl_keymap_set_parent(km_ew_multi, km_editwin);
    102102
    103103  BIND_CMD("UP",      "edit:move-up-line", "");
     
    129129       "Single-line text editing",
    130130       owl_keys_editwin_default, NULL, owl_keys_editwin_postalways);
    131   owl_keymap_set_submap(km_ew_onel, km_editwin);
     131  owl_keymap_set_parent(km_ew_onel, km_editwin);
    132132
    133133  BIND_CMD("C-u",         "edit:delete-all", "Clears the entire line");
     
    154154       "Single-line response to question",
    155155       owl_keys_editwin_default, NULL, owl_keys_editwin_postalways);
    156   owl_keymap_set_submap(km_ew_onel, km_editwin);
     156  owl_keymap_set_parent(km_ew_onel, km_editwin);
    157157
    158158  BIND_CMD("C-u",         "edit:delete-all", "Clears the entire line");
     
    169169       "Pop-up window (eg, help)",
    170170       owl_keys_default_invalid, NULL, owl_keys_popless_postalways);
    171   owl_keymap_set_submap(km_viewwin, km_global);
     171  owl_keymap_set_parent(km_viewwin, km_global);
    172172
    173173  BIND_CMD("SPACE",       "popless:scroll-down-page", "");
     
    222222        "Main window / message list",
    223223        owl_keys_default_invalid, owl_keys_recwin_prealways, NULL);
    224   owl_keymap_set_submap(km_mainwin, km_global);
     224  owl_keymap_set_parent(km_mainwin, km_global);
    225225  BIND_CMD("C-x C-c", "start-command quit", "");
    226226  BIND_CMD("F1",      "help",           "");
     
    338338    owl_editwin_post_process_char(e, j);
    339339  }
    340   owl_global_set_needrefresh(&g);
    341340}
    342341
    343342void owl_keys_popless_postalways(owl_input j) {
    344   owl_viewwin *v = owl_global_get_viewwin(&g);
    345   const owl_popwin *pw = owl_global_get_popwin(&g);
    346 
    347   if (pw && owl_popwin_is_active(pw) && v) {
    348     owl_viewwin_redisplay(v);
    349     owl_global_set_needrefresh(&g);
    350   } 
    351343}
    352344
  • logging.c

    r91634ec r839697d  
    128128  char filename[MAXPATHLEN], *logpath;
    129129  char *to, *temp;
     130  GList *cc;
    130131
    131132  /* expand ~ in path names */
     
    135136  if (owl_message_is_type_zephyr(m)) {
    136137    /* If this has CC's, do all but the "recipient" which we'll do below */
    137     to = owl_message_get_cc_without_recipient(m);
    138     if (to != NULL) {
    139       temp = strtok(to, " ");
    140       while (temp != NULL) {
    141           temp = short_zuser(temp);
    142           snprintf(filename, MAXPATHLEN, "%s/%s", logpath, temp);
    143           owl_log_append(m, filename);
    144           temp = strtok(NULL, " ");
    145       }
    146       owl_free(to);
    147     }
     138    cc = owl_message_get_cc_without_recipient(m);
     139    while (cc != NULL) {
     140      temp = short_zuser(cc->data);
     141      snprintf(filename, MAXPATHLEN, "%s/%s", logpath, temp);
     142      owl_log_append(m, filename);
     143
     144      owl_free(cc->data);
     145      cc = g_list_delete_link(cc, cc);
     146    }
     147
    148148    to = short_zuser(owl_message_get_recipient(m));
    149149  } else if (owl_message_is_type_jabber(m)) {
     
    325325     * the sender, as well.
    326326     */
    327     char *cc, *temp;
     327    char *temp;
     328    GList *cc;
    328329    cc = owl_message_get_cc_without_recipient(m);
    329     if (cc != NULL) {
    330       temp = strtok(cc, " ");
    331       while (temp != NULL) {
    332         temp = short_zuser(temp);
    333         if (strcasecmp(temp, frombuff) != 0) {
    334           snprintf(filename, MAXPATHLEN, "%s/%s", logpath, temp);
    335           owl_log_append(m, filename);
    336         }
    337         temp = strtok(NULL, " ");
     330    while (cc != NULL) {
     331      temp = short_zuser(cc->data);
     332      if (strcasecmp(temp, frombuff) != 0) {
     333        snprintf(filename, MAXPATHLEN, "%s/%s", logpath, temp);
     334        owl_log_append(m, filename);
    338335      }
    339       owl_free(cc);
     336
     337      owl_free(cc->data);
     338      cc = g_list_delete_link(cc, cc);
    340339    }
    341340  }
  • mainwin.c

    rf449096 r5cc7e5e  
    11#include "owl.h"
    22
    3 void owl_mainwin_init(owl_mainwin *mw)
     3static void owl_mainwin_redraw(owl_window *w, WINDOW *recwin, void *user_data);
     4static void owl_mainwin_resized(owl_window *w, void *user_data);
     5
     6void owl_mainwin_init(owl_mainwin *mw, owl_window *window)
    47{
    58  mw->curtruncated=0;
    69  mw->lastdisplayed=-1;
     10  mw->window = g_object_ref(window);
     11  /* for now, just assume this object lasts forever */
     12  g_signal_connect(window, "redraw", G_CALLBACK(owl_mainwin_redraw), mw);
     13  g_signal_connect(window, "resized", G_CALLBACK(owl_mainwin_resized), mw);
     14  owl_window_dirty(window);
     15
     16  /* For now, we do not bother with connecting up dependencies; that'll be a
     17   * future refactor of the mainwin */
     18}
     19
     20static void owl_mainwin_resized(owl_window *w, void *user_data)
     21{
     22  owl_mainwin *mw = user_data;
     23
     24  /* in case any styles rely on the current width */
     25  owl_messagelist_invalidate_formats(owl_global_get_msglist(&g));
     26
     27  /* recalculate the topmsg to make sure the current message is on
     28   * screen */
     29  owl_function_calculate_topmsg(OWL_DIRECTION_NONE);
     30
     31  /* Schedule a redraw */
     32  owl_window_dirty(mw->window);
    733}
    834
    935void owl_mainwin_redisplay(owl_mainwin *mw)
     36{
     37  owl_window_dirty(mw->window);
     38}
     39
     40static void owl_mainwin_redraw(owl_window *w, WINDOW *recwin, void *user_data)
    1041{
    1142  owl_message *m;
     
    1344  int x, y, savey, recwinlines, start;
    1445  int topmsg, curmsg, markedmsgid, fgcolor, bgcolor;
    15   WINDOW *recwin;
    1646  const owl_view *v;
    1747  GList *fl;
    1848  const owl_filter *f;
     49  owl_mainwin *mw = user_data;
    1950
    20   recwin = owl_global_get_curs_recwin(&g);
    2151  topmsg = owl_global_get_topmsg(&g);
    2252  curmsg = owl_global_get_curmsg(&g);
     
    4373    mw->curtruncated=0;
    4474    mw->lastdisplayed=-1;
    45     owl_global_set_needrefresh(&g);
    4675    return;
    4776  }
     
    88117    if (y+lines > recwinlines-1) {
    89118      isfull=1;
    90       owl_message_curs_waddstr(m, owl_global_get_curs_recwin(&g),
     119      owl_message_curs_waddstr(m, recwin,
    91120                               start,
    92121                               start+recwinlines-y,
     
    96125    } else {
    97126      /* otherwise print the whole thing */
    98       owl_message_curs_waddstr(m, owl_global_get_curs_recwin(&g),
     127      owl_message_curs_waddstr(m, recwin,
    99128                               start,
    100129                               start+lines,
     
    139168  }
    140169  mw->lastdisplayed=i-1;
    141 
    142   owl_global_set_needrefresh(&g);
    143170}
    144171
  • message.c

    r9a7b4f2 r89ab5c8  
    6161  owl_pair *p = NULL, *pair = NULL;
    6262
     63  attrname = g_intern_string(attrname);
     64
    6365  /* look for an existing pair with this key, */
    6466  j=owl_list_get_size(&(m->attributes));
    6567  for (i=0; i<j; i++) {
    6668    p=owl_list_get_element(&(m->attributes), i);
    67     if (!strcmp(owl_pair_get_key(p), attrname)) {
     69    if (owl_pair_get_key(p) == attrname) {
    6870      owl_free(owl_pair_get_value(p));
    6971      pair = p;
     
    7476  if(pair ==  NULL) {
    7577    pair = owl_malloc(sizeof(owl_pair));
    76     owl_pair_create(pair, owl_global_intern(&g, attrname), NULL);
     78    owl_pair_create(pair, attrname, NULL);
    7779    owl_list_append_element(&(m->attributes), pair);
    7880  }
     
    8789  int i, j;
    8890  owl_pair *p;
     91  GQuark quark;
     92
     93  quark = g_quark_try_string(attrname);
     94  if (quark == 0)
     95    /* don't bother inserting into string table */
     96    return NULL;
     97  attrname = g_quark_to_string(quark);
    8998
    9099  j=owl_list_get_size(&(m->attributes));
    91100  for (i=0; i<j; i++) {
    92101    p=owl_list_get_element(&(m->attributes), i);
    93     if (!strcmp(owl_pair_get_key(p), attrname)) {
     102    if (owl_pair_get_key(p) == attrname) {
    94103      return(owl_pair_get_value(p));
    95104    }
     
    496505void owl_message_set_hostname(owl_message *m, const char *hostname)
    497506{
    498   m->hostname=owl_global_intern(&g, hostname);
     507  m->hostname = g_intern_string(hostname);
    499508}
    500509
     
    584593
    585594/* caller must free return value */
    586 char *owl_message_get_cc_without_recipient(const owl_message *m)
    587 {
    588   char *cc, *out, *end, *shortuser, *recip;
     595GList *owl_message_get_cc_without_recipient(const owl_message *m)
     596{
     597  char *cc, *shortuser, *recip;
    589598  const char *user;
     599  GList *out = NULL;
    590600
    591601  cc = owl_message_get_cc(m);
     
    594604
    595605  recip = short_zuser(owl_message_get_recipient(m));
    596   out = owl_malloc(strlen(cc) + 2);
    597   end = out;
    598606
    599607  user = strtok(cc, " ");
     
    601609    shortuser = short_zuser(user);
    602610    if (strcasecmp(shortuser, recip) != 0) {
    603       strcpy(end, user);
    604       end[strlen(user)] = ' ';
    605       end += strlen(user) + 1;
     611      out = g_list_prepend(out, owl_strdup(user));
    606612    }
    607613    owl_free(shortuser);
    608614    user = strtok(NULL, " ");
    609615  }
    610   end[0] = '\0';
    611616
    612617  owl_free(recip);
    613618  owl_free(cc);
    614 
    615   if (strlen(out) == 0) {
    616     owl_free(out);
    617     out = NULL;
    618   }
    619619
    620620  return(out);
     
    732732  owl_message_set_recipient(m, "looprecip");
    733733  owl_message_set_isprivate(m);
     734}
     735
     736void owl_message_save_ccs(owl_message *m) {
     737  GList *cc;
     738  char *tmp;
     739
     740  cc = owl_message_get_cc_without_recipient(m);
     741
     742  if (cc != NULL) {
     743    GString *recips = g_string_new("");
     744    cc = g_list_prepend(cc, short_zuser(owl_message_get_sender(m)));
     745    cc = g_list_prepend(cc, short_zuser(owl_message_get_recipient(m)));
     746    cc = g_list_sort(cc, (GCompareFunc)strcasecmp);
     747
     748    while(cc != NULL) {
     749      /* Collapse any identical entries */
     750      while (cc->next && strcasecmp(cc->data, cc->next->data) == 0) {
     751        owl_free(cc->data);
     752        cc = g_list_delete_link(cc, cc);
     753      }
     754
     755      tmp = short_zuser(cc->data);
     756      g_string_append(recips, tmp);
     757
     758      owl_free(tmp);
     759      owl_free(cc->data);
     760      cc = g_list_delete_link(cc, cc);
     761
     762      if (cc)
     763        g_string_append_c(recips, ' ');
     764    }
     765
     766    owl_message_set_attribute(m, "zephyr_ccs", recips->str);
     767    g_string_free(recips, true);
     768  }
    734769}
    735770
     
    869904    }
    870905  }
     906
     907  owl_message_save_ccs(m);
    871908}
    872909#else
     
    9631000    owl_message_set_isprivate(m);
    9641001  }
     1002
     1003  owl_message_save_ccs(m);
    9651004}
    9661005
  • perl/lib/BarnOwl/Hooks.pm

    rb30c256 r3aa0522  
    7979our %EXPORT_TAGS = (all => [@EXPORT_OK]);
    8080
     81use BarnOwl::MainLoopCompatHook;
     82
    8183our $startup = BarnOwl::Hook->new;
    8284our $shutdown = BarnOwl::Hook->new;
    8385our $receiveMessage = BarnOwl::Hook->new;
    8486our $newMessage = BarnOwl::Hook->new;
    85 our $mainLoop = BarnOwl::Hook->new;
     87our $mainLoop = BarnOwl::MainLoopCompatHook->new;
    8688our $getBuddyList = BarnOwl::Hook->new;
    8789our $getQuickstart = BarnOwl::Hook->new;
     
    162164    }
    163165   
     166    $mainLoop->check_owlconf();
    164167    $startup->run(0);
    165168    BarnOwl::startup() if *BarnOwl::startup{CODE};
     
    186189   
    187190    BarnOwl::new_msg($m) if *BarnOwl::new_msg{CODE};
    188 }
    189 
    190 sub _mainloop_hook {
    191     $mainLoop->run;
    192     BarnOwl::mainloop_hook() if *BarnOwl::mainloop_hook{CODE};
    193191}
    194192
  • perl/lib/BarnOwl/Message/Generic.pm

    ree183be r5d1324f  
    66use base qw( BarnOwl::Message );
    77
     8sub body { "" }
     9
    810
    9111;
  • perl/lib/BarnOwl/Style/Default.pm

    r0fe69d2 r08544e0  
    3232    my $m = shift;
    3333    return $m->is_personal && $m->direction eq "in";
     34}
     35
     36sub maybe {
     37    my $x = shift;
     38    return defined($x) ? $x : "";
    3439}
    3540
     
    99104            $header .= ' / ' . $self->humanize($m->subcontext, 1);
    100105        }
    101         $header .= ' / @b{' . $m->pretty_sender . '}';
     106        $header .= ' / @b{' . maybe($m->pretty_sender) . '}';
    102107    }
    103108
  • perl/lib/BarnOwl/Timer.pm

    ree183be r8d16e58  
    2121}
    2222
     23sub stop {
     24    my $self = shift;
     25    if(defined($self->{timer})) {
     26        BarnOwl::Internal::remove_timer($self->{timer});
     27        undef $self->{timer};
     28    }
     29}
     30
    2331sub do_callback {
    2432    my $self = shift;
     
    2836sub DESTROY {
    2937    my $self = shift;
    30     if(defined($self->{timer})) {
    31         BarnOwl::Internal::remove_timer($self->{timer});
    32     }
     38    $self->stop;
    3339}
    3440
  • perl/modules/Jabber/lib/BarnOwl/Message/Jabber.pm

    rc854e74 r2f25537  
    2020sub to { shift->{to} };
    2121sub room { shift->{room} };
     22sub nick { shift->{nick} };
    2223sub subject { shift->{subject} };
    2324sub status { shift->{status} }
     
    4142sub long_sender {
    4243    my $self = shift;
     44    if ($self->jtype eq 'groupchat' && $self->nick) {
     45        my $from_jid = Net::Jabber::JID->new($self->from);
     46        if ($from_jid->GetJID('base') eq $self->room &&
     47            $from_jid->GetResource() eq $self->nick) {
     48            return $self->nick;
     49        }
     50    }
    4351    return $self->from;
    4452}
     
    7785    } elsif ($self->jtype eq 'groupchat') {
    7886        my $room = $self->room;
    79         $filter = "jabber-room-$room";
    80         BarnOwl::command(qw[filter], $filter,
    81                          qw[type ^jabber$ and room], "^\Q$room\E\$");
     87        if ($inst) {
     88            my $subject = $self->subject;
     89            $filter = "jabber-room-$room-subject-$subject";
     90            BarnOwl::command(qw[filter], $filter,
     91                             qw[type ^jabber$ and room], "^\Q$room\E\$",
     92                             qw[and subject], "^\Q$subject\E\$");
     93        } else {
     94            $filter = "jabber-room-$room";
     95            BarnOwl::command(qw[filter], $filter,
     96                             qw[type ^jabber$ and room], "^\Q$room\E\$");
     97        }
    8298        return $filter;
    8399    } elsif ($self->login ne 'none') {
  • perl/modules/Jabber/lib/BarnOwl/Module/Jabber.pm

    r8789410 r2f25537  
    285285        {
    286286            summary => "Send a Jabber Message",
    287             usage   => "jwrite <jid> [-t <thread>] [-s <subject>] [-a <account>]"
     287            usage   => "jwrite <jid> [-t <thread>] [-s <subject>] [-a <account>] [-m <message>]"
    288288        }
    289289    );
     
    308308            description => "jmuc sends Jabber commands related to MUC.\n\n"
    309309              . "The following commands are available\n\n"
    310               . "join <muc>  Join a MUC.\n\n"
     310              . "join <muc>[/<nick>]\n"
     311              . "            Join a MUC (with a given nickname, or otherwise your JID).\n\n"
    311312              . "part <muc>  Part a MUC.\n"
    312313              . "            The MUC is taken from the current message if not supplied.\n\n"
     
    377378        my $cjidStr = $conn->baseJIDExists($jidStr);
    378379        if ($cjidStr) {
    379             BarnOwl::error("Already logged in as $cjidStr.");
    380             return;
     380            die("Already logged in as $cjidStr.\n");
    381381        }
    382382    }
     
    387387
    388388    if ( !$uid || !$componentname ) {
    389         BarnOwl::error("usage: $cmd JID");
    390         return;
     389        die("usage: $cmd JID\n");
    391390    }
    392391
    393392    if ( $conn->jidActive($jidStr) ) {
    394         BarnOwl::error("Already logged in as $jidStr.");
    395         return;
     393        die("Already logged in as $jidStr.\n");
    396394    } elsif ($conn->jidExists($jidStr)) {
    397395        return $conn->tryReconnect($jidStr, 1);
     
    526524sub cmd_jlist {
    527525    if ( !( scalar $conn->getJIDs() ) ) {
    528         BarnOwl::error("You are not logged in to Jabber.");
    529         return;
     526        die("You are not logged in to Jabber.\n");
    530527    }
    531528    BarnOwl::popless_ztext( onGetBuddyList() );
     
    534531sub cmd_jwrite {
    535532    if ( !$conn->connected() ) {
    536         BarnOwl::error("You are not logged in to Jabber.");
    537         return;
     533        die("You are not logged in to Jabber.\n");
    538534    }
    539535
     
    543539    my $jwrite_thread  = "";
    544540    my $jwrite_subject = "";
     541    my $jwrite_body;
    545542    my ($to, $from);
    546543    my $jwrite_type    = "chat";
     
    554551        'subject=s' => \$jwrite_subject,
    555552        'account=s' => \$from,
    556         'id=s'     =>  \$jwrite_sid,
     553        'id=s'      => \$jwrite_sid,
     554        'message=s' => \$jwrite_body,
    557555    ) or die("Usage: jwrite <jid> [-t <thread>] [-s <subject>] [-a <account>]\n");
    558556    $jwrite_type = 'groupchat' if $gc;
    559557
    560558    if ( scalar @ARGV != 1 ) {
    561         BarnOwl::error(
    562             "Usage: jwrite <jid> [-t <thread>] [-s <subject>] [-a <account>]");
    563         return;
     559        die("Usage: jwrite <jid> [-t <thread>] [-s <subject>] [-a <account>]\n");
    564560    }
    565561    else {
     
    570566
    571567    unless(scalar @candidates) {
    572         die("Unable to resolve JID $to");
     568        die("Unable to resolve JID $to\n");
    573569    }
    574570
     
    577573    unless(scalar @candidates) {
    578574        if(!$from) {
    579             die("You must specify an account with -a");
     575            die("You must specify an account with -a\n");
    580576        } else {
    581             die("Unable to resolve account $from");
     577            die("Unable to resolve account $from\n");
    582578        }
    583579    }
     
    594590        type    => $jwrite_type
    595591    };
     592
     593    if (defined($jwrite_body)) {
     594        process_owl_jwrite($jwrite_body);
     595        return;
     596    }
    596597
    597598    if(scalar @candidates > 1) {
     
    631632    my $func = $jmuc_commands{$cmd};
    632633    if ( !$func ) {
    633         BarnOwl::error("jmuc: Unknown command: $cmd");
    634         return;
     634        die("jmuc: Unknown command: $cmd\n");
    635635    }
    636636
     
    654654        }
    655655        else {
    656             BarnOwl::error('You must specify an account with -a <jid>');
     656            die("You must specify an account with -a <jid>\n");
    657657        }
    658658        return $func->( $jid, $muc, @ARGV );
     
    667667
    668668    $muc = shift @ARGV
    669       or die("Usage: jmuc join <muc> [-p <password>] [-a <account>]");
     669      or die("Usage: jmuc join <muc> [-p <password>] [-a <account>]\n");
    670670
    671671    die("Error: Must specify a fully-qualified MUC name (e.g. barnowl\@conference.mit.edu)\n")
     
    680680                                                   MaxChars => 0
    681681                                                  });
    682     $completion_jids{$muc} = 1;
     682    $completion_jids{$muc->GetJID('base')} = 1;
    683683    return;
    684684}
     
    688688
    689689    $muc = shift @args if scalar @args;
    690     die("Usage: jmuc part [<muc>] [-a <account>]") unless $muc;
     690    die("Usage: jmuc part [<muc>] [-a <account>]\n") unless $muc;
    691691
    692692    if($conn->getConnectionFromJID($jid)->MUCLeave(JID => $muc)) {
    693693        queue_admin_msg("$jid has left $muc.");
    694694    } else {
    695         die("Error: Not joined to $muc");
     695        die("Error: Not joined to $muc\n");
    696696    }
    697697}
     
    703703    $muc = shift @args if scalar @args;
    704704
    705     die('Usage: jmuc invite <jid> [<muc>] [-a <account>]')
     705    die("Usage: jmuc invite <jid> [<muc>] [-a <account>]\n")
    706706      unless $muc && $invite_jid;
    707707
     
    718718    my ( $jid, $muc, @args ) = @_;
    719719    $muc = shift @args if scalar @args;
    720     die("Usage: jmuc configure [<muc>]") unless $muc;
     720    die("Usage: jmuc configure [<muc>]\n") unless $muc;
    721721    my $iq = Net::Jabber::IQ->new();
    722722    $iq->SetTo($muc);
     
    759759
    760760    $muc = shift @args if scalar @args;
    761     die("Usage: jmuc presence [<muc>]") unless $muc;
     761    die("Usage: jmuc presence [<muc>]\n") unless $muc;
    762762
    763763    if ($muc eq '-a') {
     
    774774    else {
    775775        my $m = $conn->getConnectionFromJID($jid)->FindMUC(jid => $muc);
    776         die("No such muc: $muc") unless $m;
     776        die("No such muc: $muc\n") unless $m;
    777777        BarnOwl::popless_ztext(jmuc_presence_single($m));
    778778    }
     
    801801    my $func = $jroster_commands{$cmd};
    802802    if ( !$func ) {
    803         BarnOwl::error("jroster: Unknown command: $cmd");
    804         return;
     803        die("jroster: Unknown command: $cmd\n");
    805804    }
    806805
     
    825824        }
    826825        else {
    827             BarnOwl::error('You must specify an account with -a <jid>');
     826            die("You must specify an account with -a <jid>\n");
    828827        }
    829828        return $func->( $jid, $name, \@groups, $purgeGroups,  @ARGV );
     
    849848    }
    850849    else {
    851         BarnOwl::error('You must specify an account with -a <jid>');
     850        die("You must specify an account with -a <jid>\n");
    852851    }
    853852
     
    12341233        $completion_jids{$room} = 1;
    12351234
     1235        my $muc;
     1236        if ($dir eq 'in') {
     1237            my $connection = $conn->getConnectionFromSid($props{sid});
     1238            $muc = $connection->FindMUC(jid => $from);
     1239        } else {
     1240            my $connection = $conn->getConnectionFromJID($props{from});
     1241            $muc = $connection->FindMUC(jid => $to);
     1242        }
     1243        $props{from} = $muc->GetFullJID($from) || $props{from};
    12361244        $props{sender} = $nick || $room;
    12371245        $props{recipient} = $room;
     
    13311339        return $givenJIDStr if ($conn->jidExists($givenJIDStr) );
    13321340        return resolveConnectedJID($givenJID->GetJID('base')) if $loose;
    1333         die("Invalid account: $givenJIDStr");
     1341        die("Invalid account: $givenJIDStr\n");
    13341342    }
    13351343
     
    13841392        # Not one of ours.
    13851393        else {
    1386             die("Invalid account: $givenJIDStr");
     1394            die("Invalid account: $givenJIDStr\n");
    13871395        }
    13881396
     
    14301438    if($from) {
    14311439        $from_jid = resolveConnectedJID($from, 1);
    1432         die("Unable to resolve account $from") unless $from_jid;
     1440        die("Unable to resolve account $from\n") unless $from_jid;
    14331441        $to_jid = resolveDestJID($to, $from_jid);
    14341442        push @matches, [$from_jid, $to_jid] if $to_jid;
  • perl/modules/Makefile.am

    r636de2a r1fd469d4  
    1 MODULES = Jabber IRC WordWrap
     1MODULES = Jabber IRC WordWrap Twitter
    22
    33EXTRA_DIST = $(MODULES:=/Makefile.PL) $(MODULES:=/inc) $(MODULES:=/lib)
  • perlconfig.c

    r5aa33fd rdec60b4  
    584584}
    585585
    586 void owl_perlconfig_mainloop(owl_timer *t, void *data)
    587 {
    588   dSP;
    589   if (!owl_perlconfig_is_function("BarnOwl::Hooks::_mainloop_hook"))
    590     return;
    591   PUSHMARK(SP) ;
    592   call_pv("BarnOwl::Hooks::_mainloop_hook", G_DISCARD|G_EVAL);
    593   if(SvTRUE(ERRSV)) {
    594     owl_function_error("%s", SvPV_nolen(ERRSV));
    595   }
    596   return;
    597 }
    598 
    599586void owl_perlconfig_io_dispatch(const owl_io_dispatch *d, void *data)
    600587{
  • popexec.c

    r125fd21 r07b59ea  
    2727
    2828  owl_popwin_up(pw);
    29   owl_global_push_context(&g, OWL_CTX_POPLESS, v, "popless");
    30   owl_viewwin_init_text(v, owl_popwin_get_curswin(pw),
    31                         owl_popwin_get_lines(pw), owl_popwin_get_cols(pw),
    32                         "");
    33   owl_viewwin_redisplay(v);
    34   owl_global_set_needrefresh(&g);
     29  owl_global_push_context(&g, OWL_CTX_POPLESS, v, "popless", NULL);
     30  owl_viewwin_init_text(v, owl_popwin_get_content(pw), "");
    3531  owl_viewwin_set_onclose_hook(v, owl_popexec_viewwin_onclose, pe);
    3632  pe->refcount++;
     
    111107    if (pe->winactive) {
    112108      owl_viewwin_append_text(pe->vwin, "\n");
    113       owl_viewwin_redisplay(pe->vwin);
    114       owl_global_set_needrefresh(&g);
    115109    }
    116110    owl_select_remove_io_dispatch(d);
     
    139133  if (pe->winactive) {
    140134    owl_viewwin_append_text(pe->vwin, buf);
    141     owl_viewwin_redisplay(pe->vwin);
    142     owl_global_set_needrefresh(&g);
    143135  }
    144136  owl_free(buf);
  • popwin.c

    r0881cdd r05ca0d8  
    44{
    55  pw->active=0;
    6   pw->lines=0;
    7   pw->cols=0;
    86  return(0);
    97}
     
    119int owl_popwin_up(owl_popwin *pw)
    1210{
    13   int glines, gcols, startcol, startline;
    14   WINDOW *popwin, *borderwin;
     11  pw->border = owl_window_new(NULL);
     12  pw->content = owl_window_new(pw->border);
     13  g_signal_connect(pw->border, "redraw", G_CALLBACK(owl_popwin_draw_border), 0);
     14  owl_signal_connect_object(owl_window_get_screen(), "resized", G_CALLBACK(owl_popwin_size_border), pw->border, 0);
     15  owl_signal_connect_object(pw->border, "resized", G_CALLBACK(owl_popwin_size_content), pw->content, 0);
    1516
    16   /* calculate the size of the popwin */
    17   glines=owl_global_get_lines(&g);
    18   gcols=owl_global_get_cols(&g);
     17  /* bootstrap sizing */
     18  owl_popwin_size_border(owl_window_get_screen(), pw->border);
    1919
    20   pw->lines = owl_util_min(glines,24)*3/4 + owl_util_max(glines-24,0)/2;
    21   startline = (glines-pw->lines)/2;
     20  owl_window_show_all(pw->border);
    2221
    23   pw->cols = owl_util_min(gcols,90)*15/16 + owl_util_max(gcols-90,0)/2;
    24   startcol = (gcols-pw->cols)/2;
     22  pw->active=1;
     23  return(0);
     24}
    2525
    26   borderwin = newwin(pw->lines, pw->cols, startline, startcol);
    27   pw->borderpanel = new_panel(borderwin);
    28   popwin = newwin(pw->lines-2, pw->cols-2, startline+1, startcol+1);
    29   pw->poppanel = new_panel(popwin);
     26void owl_popwin_size_border(owl_window *parent, void *user_data)
     27{
     28  int lines, cols, startline, startcol;
     29  int glines, gcols;
     30  owl_window *border = user_data;
    3031
    31   werase(popwin);
    32   werase(borderwin);
     32  owl_window_get_position(parent, &glines, &gcols, 0, 0);
     33
     34  lines = owl_util_min(glines,24)*3/4 + owl_util_max(glines-24,0)/2;
     35  startline = (glines-lines)/2;
     36  cols = owl_util_min(gcols,90)*15/16 + owl_util_max(gcols-90,0)/2;
     37  startcol = (gcols-cols)/2;
     38
     39  owl_window_set_position(border, lines, cols, startline, startcol);
     40}
     41
     42void owl_popwin_size_content(owl_window *parent, void *user_data)
     43{
     44  int lines, cols;
     45  owl_window *content = user_data;
     46  owl_window_get_position(parent, &lines, &cols, 0, 0);
     47  owl_window_set_position(content, lines-2, cols-2, 1, 1);
     48}
     49
     50void owl_popwin_draw_border(owl_window *w, WINDOW *borderwin, void *user_data)
     51{
     52  int lines, cols;
     53  owl_window_get_position(w, &lines, &cols, 0, 0);
    3354  if (owl_global_is_fancylines(&g)) {
    3455    box(borderwin, 0, 0);
     
    3758    wmove(borderwin, 0, 0);
    3859    waddch(borderwin, '+');
    39     wmove(borderwin, pw->lines-1, 0);
     60    wmove(borderwin, lines-1, 0);
    4061    waddch(borderwin, '+');
    41     wmove(borderwin, pw->lines-1, pw->cols-1);
     62    wmove(borderwin, lines-1, cols-1);
    4263    waddch(borderwin, '+');
    43     wmove(borderwin, 0, pw->cols-1);
     64    wmove(borderwin, 0, cols-1);
    4465    waddch(borderwin, '+');
    4566  }
    46    
    47   owl_global_set_needrefresh(&g);
    48   pw->active=1;
    49   return(0);
    5067}
    5168
    5269int owl_popwin_close(owl_popwin *pw)
    5370{
    54   WINDOW *popwin, *borderwin;
     71  owl_window_unlink(pw->border);
     72  g_object_unref(pw->border);
     73  g_object_unref(pw->content);
    5574
    56   popwin = panel_window(pw->poppanel);
    57   borderwin = panel_window(pw->borderpanel);
    58 
    59   del_panel(pw->poppanel);
    60   del_panel(pw->borderpanel);
    61   delwin(popwin);
    62   delwin(borderwin);
    63 
     75  pw->border = 0;
     76  pw->content = 0;
    6477  pw->active=0;
    65   owl_global_set_needrefresh(&g);
    6678  return(0);
    6779}
     
    7284}
    7385
    74 WINDOW *owl_popwin_get_curswin(const owl_popwin *pw)
     86owl_window *owl_popwin_get_content(const owl_popwin *pw)
    7587{
    76   return panel_window(pw->poppanel);
     88  return pw->content;
    7789}
    78 
    79 int owl_popwin_get_lines(const owl_popwin *pw)
    80 {
    81   return(pw->lines-2);
    82 }
    83 
    84 int owl_popwin_get_cols(const owl_popwin *pw)
    85 {
    86   return(pw->cols-2);
    87 }
  • stubgen.pl

    rd7cc50b rea7daa8  
    1212    my $altvarname = $2;
    1313    $altvarname = $3 if ($3);
     14    my $detailname = $altvarname;
     15    $detailname =~ s/[^a-zA-Z0-9]/-/g;
     16    $detailname =~ s/^[^a-zA-Z]+//;
    1417    if ($vartype =~ /^BOOL/) {
    15         print "void owl_global_set_${altvarname}_on(owl_global *g) {\n";
    16         print "  owl_variable_set_bool_on(&g->vars, \"$varname\");\n}\n";
    17         print "void owl_global_set_${altvarname}_off(owl_global *g) {\n";
    18         print "  owl_variable_set_bool_off(&g->vars, \"$varname\");\n}\n";
    19         print "int owl_global_is_$altvarname(const owl_global *g) {\n";
    20         print "  return owl_variable_get_bool(&g->vars, \"$varname\");\n}\n";
     18        print <<EOT;
     19void owl_global_set_${altvarname}_on(owl_global *g) {
     20  owl_variable_set_bool_on(&g->vars, "$altvarname");
     21}
     22void owl_global_set_${altvarname}_off(owl_global *g) {
     23  owl_variable_set_bool_off(&g->vars, "$altvarname");
     24}
     25int owl_global_is_$altvarname(const owl_global *g) {
     26  return owl_variable_get_bool(&g->vars, "$varname");
     27}
     28EOT
    2129    } elsif ($vartype =~ /^PATH/ or $vartype =~ /^STRING/) {
    22         print "void owl_global_set_$altvarname(owl_global *g, const char *text) {\n";
    23         print "  owl_variable_set_string(&g->vars, \"$varname\", text);\n}\n";
    24         print "const char *owl_global_get_$altvarname(const owl_global *g) {\n";
    25         print "  return owl_variable_get_string(&g->vars, \"$varname\");\n}\n";
     30        print <<EOT;
     31void owl_global_set_${altvarname}(owl_global *g, const char *text) {
     32  owl_variable_set_string(&g->vars, "$altvarname", text);
     33}
     34const char *owl_global_get_$altvarname(const owl_global *g) {
     35  return owl_variable_get_string(&g->vars, "$varname");
     36}
     37EOT
    2638    } elsif ($vartype =~ /^INT/ or $vartype =~ /^ENUM/) {
    27         print "void owl_global_set_$altvarname(owl_global *g, int n) {\n";
    28         print "  owl_variable_set_int(&g->vars, \"$varname\", n);\n}\n";
    29         print "int owl_global_get_$altvarname(const owl_global *g) {\n";
    30         print "  return owl_variable_get_int(&g->vars, \"$varname\");\n}\n";
     39        print <<EOT;
     40void owl_global_set_${altvarname}(owl_global *g, int n) {
     41  owl_variable_set_int(&g->vars, "$altvarname", n);
     42}
     43int owl_global_get_$altvarname(const owl_global *g) {
     44  return owl_variable_get_int(&g->vars, "$varname");
     45}
     46EOT
    3147    }
    3248    }
  • tester.c

    r95414bf rdec60b4  
    105105  numfailures += owl_variable_regtest();
    106106  numfailures += owl_filter_regtest();
    107   numfailures += owl_obarray_regtest();
    108107  numfailures += owl_editwin_regtest();
    109108  if (numfailures) {
     
    368367}
    369368
    370 
    371 int owl_obarray_regtest(void) {
    372   int numfailed = 0;
    373   const char *p,*p2;
    374 
    375   owl_obarray oa;
    376   owl_obarray_init(&oa);
    377 
    378   printf("# BEGIN testing owl_obarray\n");
    379 
    380   p = owl_obarray_insert(&oa, "test");
    381   FAIL_UNLESS("returned string is equal", p && !strcmp(p, "test"));
    382   p2 = owl_obarray_insert(&oa, "test");
    383   FAIL_UNLESS("returned string is equal", p2 && !strcmp(p2, "test"));
    384   FAIL_UNLESS("returned the same string", p2 && p == p2);
    385 
    386   p = owl_obarray_insert(&oa, "test2");
    387   FAIL_UNLESS("returned string is equal", p && !strcmp(p, "test2"));
    388   p2 = owl_obarray_find(&oa, "test2");
    389   FAIL_UNLESS("returned the same string", p2 && !strcmp(p2, "test2"));
    390 
    391   p = owl_obarray_find(&oa, "nothere");
    392   FAIL_UNLESS("Didn't find a string that isn't there", p == NULL);
    393 
    394   printf("# END testing owl_obarray (%d failures)\n", numfailed);
    395 
    396   return numfailed;
    397 }
    398 
    399369int owl_editwin_regtest(void) {
    400370  int numfailed = 0;
  • util.c

    r9a7b4f2 rc1f1e1e  
    88#include <sys/types.h>
    99
    10 void sepbar(const char *in)
    11 {
    12   WINDOW *sepwin;
    13   const owl_messagelist *ml;
    14   const owl_view *v;
    15   int x, y, i;
    16   const char *foo, *appendtosepbar;
    17 
    18   sepwin=owl_global_get_curs_sepwin(&g);
    19   ml=owl_global_get_msglist(&g);
    20   v=owl_global_get_current_view(&g);
    21 
    22   werase(sepwin);
    23   wattron(sepwin, A_REVERSE);
    24   if (owl_global_is_fancylines(&g)) {
    25     whline(sepwin, ACS_HLINE, owl_global_get_cols(&g));
    26   } else {
    27     whline(sepwin, '-', owl_global_get_cols(&g));
    28   }
    29 
    30   if (owl_global_is_sepbar_disable(&g)) {
    31     getyx(sepwin, y, x);
    32     wmove(sepwin, y, owl_global_get_cols(&g)-1);
    33     return;
    34   }
    35 
    36   wmove(sepwin, 0, 2);
    37 
    38   if (owl_messagelist_get_size(ml) == 0)
    39     waddstr(sepwin, " (-/-) ");
    40   else
    41     wprintw(sepwin, " (%i/%i/%i) ", owl_global_get_curmsg(&g) + 1,
    42             owl_view_get_size(v),
    43             owl_messagelist_get_size(ml));
    44 
    45   foo=owl_view_get_filtname(v);
    46   if (strcmp(foo, owl_global_get_view_home(&g)))
    47       wattroff(sepwin, A_REVERSE);
    48   wprintw(sepwin, " %s ", owl_view_get_filtname(v));
    49   if (strcmp(foo, owl_global_get_view_home(&g)))
    50       wattron(sepwin, A_REVERSE);
    51 
    52   if (owl_mainwin_is_curmsg_truncated(owl_global_get_mainwin(&g))) {
    53     getyx(sepwin, y, x);
    54     wmove(sepwin, y, x+2);
    55     wattron(sepwin, A_BOLD);
    56     waddstr(sepwin, " <truncated> ");
    57     wattroff(sepwin, A_BOLD);
    58   }
    59 
    60   i=owl_mainwin_get_last_msg(owl_global_get_mainwin(&g));
    61   if ((i != -1) &&
    62       (i < owl_view_get_size(v)-1)) {
    63     getyx(sepwin, y, x);
    64     wmove(sepwin, y, x+2);
    65     wattron(sepwin, A_BOLD);
    66     waddstr(sepwin, " <more> ");
    67     wattroff(sepwin, A_BOLD);
    68   }
    69 
    70   if (owl_global_get_rightshift(&g)>0) {
    71     getyx(sepwin, y, x);
    72     wmove(sepwin, y, x+2);
    73     wprintw(sepwin, " right: %i ", owl_global_get_rightshift(&g));
    74   }
    75 
    76   if (owl_global_is_zaway(&g) || owl_global_is_aaway(&g)) {
    77     getyx(sepwin, y, x);
    78     wmove(sepwin, y, x+2);
    79     wattron(sepwin, A_BOLD);
    80     wattroff(sepwin, A_REVERSE);
    81     if (owl_global_is_zaway(&g) && owl_global_is_aaway(&g)) {
    82       waddstr(sepwin, " AWAY ");
    83     } else if (owl_global_is_zaway(&g)) {
    84       waddstr(sepwin, " Z-AWAY ");
    85     } else if (owl_global_is_aaway(&g)) {
    86       waddstr(sepwin, " A-AWAY ");
    87     }
    88     wattron(sepwin, A_REVERSE);
    89     wattroff(sepwin, A_BOLD);
    90   }
    91 
    92   if (owl_global_get_curmsg_vert_offset(&g)) {
    93     getyx(sepwin, y, x);
    94     wmove(sepwin, y, x+2);
    95     wattron(sepwin, A_BOLD);
    96     wattroff(sepwin, A_REVERSE);
    97     waddstr(sepwin, " SCROLL ");
    98     wattron(sepwin, A_REVERSE);
    99     wattroff(sepwin, A_BOLD);
    100   }
    101  
    102   if (in) {
    103     getyx(sepwin, y, x);
    104     wmove(sepwin, y, x+2);
    105     waddstr(sepwin, in);
    106   }
    107 
    108   appendtosepbar = owl_global_get_appendtosepbar(&g);
    109   if (appendtosepbar && *appendtosepbar) {
    110     getyx(sepwin, y, x);
    111     wmove(sepwin, y, x+2);
    112     waddstr(sepwin, " ");
    113     waddstr(sepwin, owl_global_get_appendtosepbar(&g));
    114     waddstr(sepwin, " ");
    115   }
    116 
    117   getyx(sepwin, y, x);
    118   wmove(sepwin, y, owl_global_get_cols(&g)-1);
    119    
    120   wattroff(sepwin, A_BOLD);
    121   wattroff(sepwin, A_REVERSE);
    122 }
     10#include <glib-object.h>
    12311
    12412char **atokenize(const char *buffer, const char *sep, int *i)
     
    786674  return buf;
    787675}
     676
     677gulong owl_dirty_window_on_signal(owl_window *w, gpointer sender, const gchar *detailed_signal)
     678{
     679  return owl_signal_connect_object(sender, detailed_signal, G_CALLBACK(owl_window_dirty), w, G_CONNECT_SWAPPED);
     680}
     681
     682typedef struct { /*noproto*/
     683  GObject  *sender;
     684  gulong    signal_id;
     685} SignalData;
     686
     687static void _closure_invalidated(gpointer data, GClosure *closure);
     688
     689/*
     690 * GObject's g_signal_connect_object has a documented bug. This function is
     691 * identical except it does not leak the signal handler.
     692 */
     693gulong owl_signal_connect_object(gpointer sender, const gchar *detailed_signal, GCallback c_handler, gpointer receiver, GConnectFlags connect_flags)
     694{
     695  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (sender), 0);
     696  g_return_val_if_fail (detailed_signal != NULL, 0);
     697  g_return_val_if_fail (c_handler != NULL, 0);
     698
     699  if (receiver) {
     700    SignalData *sdata;
     701    GClosure *closure;
     702    gulong signal_id;
     703
     704    g_return_val_if_fail (G_IS_OBJECT (receiver), 0);
     705
     706    closure = ((connect_flags & G_CONNECT_SWAPPED) ? g_cclosure_new_object_swap : g_cclosure_new_object) (c_handler, receiver);
     707    signal_id = g_signal_connect_closure (sender, detailed_signal, closure, connect_flags & G_CONNECT_AFTER);
     708
     709    /* Register the missing hooks */
     710    sdata = g_slice_new0(SignalData);
     711    sdata->sender = sender;
     712    sdata->signal_id = signal_id;
     713
     714    g_closure_add_invalidate_notifier(closure, sdata, _closure_invalidated);
     715
     716    return signal_id;
     717  } else {
     718    return g_signal_connect_data(sender, detailed_signal, c_handler, NULL, NULL, connect_flags);
     719  }
     720}
     721
     722/*
     723 * There are three ways the signal could come to an end:
     724 *
     725 * 1. The user explicitly disconnects it with the returned signal_id.
     726 *    - In that case, the disconnection unref's the closure, causing it
     727 *      to first be invalidated. The handler's already disconnected, so
     728 *      we have no work to do.
     729 * 2. The sender gets destroyed.
     730 *    - GObject will disconnect each signal which then goes into the above
     731 *      case. Our handler does no work.
     732 * 3. The receiver gets destroyed.
     733 *    - The GClosure was created by g_cclosure_new_object_{,swap} which gets
     734 *      invalidated when the receiver is destroyed. We then follow through case 1
     735 *      again, but *this* time, the handler has not been disconnected. We then
     736 *      clean up ourselves.
     737 *
     738 * We can't actually hook into this process earlier with weakrefs as GObject
     739 * will, on object dispose, first disconnect signals, then invalidate closures,
     740 * and notify weakrefs last.
     741 */
     742static void _closure_invalidated(gpointer data, GClosure *closure)
     743{
     744  SignalData *sdata = data;
     745  if (g_signal_handler_is_connected(sdata->sender, sdata->signal_id)) {
     746    g_signal_handler_disconnect(sdata->sender, sdata->signal_id);
     747  }
     748  g_slice_free(SignalData, sdata);
     749}
     750
  • viewwin.c

    rfe4c786 r0b9e607  
    44#define BOTTOM_OFFSET 1
    55
     6static void owl_viewwin_redraw(owl_window *w, WINDOW *curswin, void *user_data);
     7
    68/* initialize the viewwin e.  'win' is an already initialzed curses
    79 * window that will be used by viewwin
    810 */
    9 void owl_viewwin_init_text(owl_viewwin *v, WINDOW *win, int winlines, int wincols, const char *text)
     11void owl_viewwin_init_text(owl_viewwin *v, owl_window *win, const char *text)
    1012{
    1113  owl_fmtext_init_null(&(v->fmtext));
     
    1921  v->topline=0;
    2022  v->rightshift=0;
    21   v->winlines=winlines;
    22   v->wincols=wincols;
    23   v->curswin=win;
    2423  v->onclose_hook = NULL;
     24
     25  owl_viewwin_set_window(v, win);
    2526}
    2627
     
    2829    owl_fmtext_append_normal(&(v->fmtext), text);
    2930    v->textlines=owl_fmtext_num_lines(&(v->fmtext)); 
     31    owl_window_dirty(v->window);
    3032}
    3133
     
    3335 * window that will be used by viewwin
    3436 */
    35 void owl_viewwin_init_fmtext(owl_viewwin *v, WINDOW *win, int winlines, int wincols, const owl_fmtext *fmtext)
     37void owl_viewwin_init_fmtext(owl_viewwin *v, owl_window *win, const owl_fmtext *fmtext)
    3638{
    3739  char *text;
     
    4648  v->topline=0;
    4749  v->rightshift=0;
    48   v->winlines=winlines;
    49   v->wincols=wincols;
    50   v->curswin=win;
     50
     51  owl_viewwin_set_window(v, win);
    5152}
    5253
    53 void owl_viewwin_set_curswin(owl_viewwin *v, WINDOW *w, int winlines, int wincols)
     54void owl_viewwin_set_window(owl_viewwin *v, owl_window *w)
    5455{
    55   v->curswin=w;
    56   v->winlines=winlines;
    57   v->wincols=wincols;
     56  if (v->window) {
     57    g_signal_handler_disconnect(v->window, v->sig_redraw_id);
     58    g_object_unref(v->window);
     59  }
     60  v->window = w;
     61  if (w) {
     62    g_object_ref(v->window);
     63    v->sig_redraw_id = g_signal_connect(w, "redraw", G_CALLBACK(owl_viewwin_redraw), v);
     64  }
    5865}
    5966
     
    6471
    6572/* regenerate text on the curses window. */
    66 void owl_viewwin_redisplay(owl_viewwin *v)
     73static void owl_viewwin_redraw(owl_window *w, WINDOW *curswin, void *user_data)
    6774{
    6875  owl_fmtext fm1, fm2;
     76  owl_viewwin *v = user_data;
     77  int winlines, wincols;
    6978
    70   /* avoid segfault when screen too small to create curswin */
    71   if (v->curswin == NULL)
    72     return;
     79  owl_window_get_position(w, &winlines, &wincols, 0, 0);
    7380 
    74   werase(v->curswin);
    75   wmove(v->curswin, 0, 0);
     81  werase(curswin);
     82  wmove(curswin, 0, 0);
    7683
    7784  owl_fmtext_init_null(&fm1);
    7885  owl_fmtext_init_null(&fm2);
    7986 
    80   owl_fmtext_truncate_lines(&(v->fmtext), v->topline, v->winlines-BOTTOM_OFFSET, &fm1);
    81   owl_fmtext_truncate_cols(&fm1, v->rightshift, v->wincols-1+v->rightshift, &fm2);
     87  owl_fmtext_truncate_lines(&(v->fmtext), v->topline, winlines-BOTTOM_OFFSET, &fm1);
     88  owl_fmtext_truncate_cols(&fm1, v->rightshift, wincols-1+v->rightshift, &fm2);
    8289
    83   owl_fmtext_curs_waddstr_without_search(&fm2, v->curswin);
     90  owl_fmtext_curs_waddstr_without_search(&fm2, curswin);
    8491
    8592  /* print the message at the bottom */
    86   wmove(v->curswin, v->winlines-1, 0);
    87   wattrset(v->curswin, A_REVERSE);
    88   if (v->textlines - v->topline > v->winlines-BOTTOM_OFFSET) {
    89     waddstr(v->curswin, "--More-- (Space to see more, 'q' to quit)");
     93  wmove(curswin, winlines-1, 0);
     94  wattrset(curswin, A_REVERSE);
     95  if (v->textlines - v->topline > winlines-BOTTOM_OFFSET) {
     96    waddstr(curswin, "--More-- (Space to see more, 'q' to quit)");
    9097  } else {
    91     waddstr(v->curswin, "--End-- (Press 'q' to quit)");
     98    waddstr(curswin, "--End-- (Press 'q' to quit)");
    9299  }
    93   wattroff(v->curswin, A_REVERSE);
     100  wattroff(curswin, A_REVERSE);
    94101
    95102  owl_fmtext_cleanup(&fm1);
     
    99106void owl_viewwin_pagedown(owl_viewwin *v)
    100107{
    101   v->topline+=v->winlines - BOTTOM_OFFSET;
    102   if ( (v->topline+v->winlines-BOTTOM_OFFSET) > v->textlines) {
    103     v->topline = v->textlines - v->winlines + BOTTOM_OFFSET;
     108  int winlines;
     109  owl_window_get_position(v->window, &winlines, 0, 0, 0);
     110  v->topline+=winlines - BOTTOM_OFFSET;
     111  if ( (v->topline+winlines-BOTTOM_OFFSET) > v->textlines) {
     112    v->topline = v->textlines - winlines + BOTTOM_OFFSET;
    104113  }
     114  owl_window_dirty(v->window);
    105115}
    106116
    107117void owl_viewwin_linedown(owl_viewwin *v)
    108118{
     119  int winlines;
     120  owl_window_get_position(v->window, &winlines, 0, 0, 0);
    109121  v->topline++;
    110   if ( (v->topline+v->winlines-BOTTOM_OFFSET) > v->textlines) {
    111     v->topline = v->textlines - v->winlines + BOTTOM_OFFSET;
     122  if ( (v->topline+winlines-BOTTOM_OFFSET) > v->textlines) {
     123    v->topline = v->textlines - winlines + BOTTOM_OFFSET;
    112124  }
     125  owl_window_dirty(v->window);
    113126}
    114127
    115128void owl_viewwin_pageup(owl_viewwin *v)
    116129{
    117   v->topline-=v->winlines;
     130  int winlines;
     131  owl_window_get_position(v->window, &winlines, 0, 0, 0);
     132  v->topline-=winlines;
    118133  if (v->topline<0) v->topline=0;
     134  owl_window_dirty(v->window);
    119135}
    120136
     
    123139  v->topline--;
    124140  if (v->topline<0) v->topline=0;
     141  owl_window_dirty(v->window);
    125142}
    126143
     
    128145{
    129146  v->rightshift+=n;
     147  owl_window_dirty(v->window);
    130148}
    131149
     
    134152  v->rightshift-=n;
    135153  if (v->rightshift<0) v->rightshift=0;
     154  owl_window_dirty(v->window);
    136155}
    137156
     
    140159  v->topline=0;
    141160  v->rightshift=0;
     161  owl_window_dirty(v->window);
    142162}
    143163
    144164void owl_viewwin_bottom(owl_viewwin *v)
    145165{
    146   v->topline = v->textlines - v->winlines + BOTTOM_OFFSET;
     166  int winlines;
     167  owl_window_get_position(v->window, &winlines, 0, 0, 0);
     168  v->topline = v->textlines - winlines + BOTTOM_OFFSET;
     169  owl_window_dirty(v->window);
    147170}
    148171
    149172void owl_viewwin_cleanup(owl_viewwin *v)
    150173{
     174  owl_viewwin_set_window(v, NULL);
    151175  if (v->onclose_hook) {
    152176    v->onclose_hook(v, v->onclose_hook_data);
  • zcrypt.c

    r60fcd71 r3c2c7fc  
    8888
    8989cipher_pair ciphers[NCIPHER] = {
    90   [CIPHER_DES] { do_encrypt_des, do_decrypt_des},
    91   [CIPHER_AES] { do_encrypt_aes, do_decrypt_aes},
     90  [CIPHER_DES] = { do_encrypt_des, do_decrypt_des},
     91  [CIPHER_AES] = { do_encrypt_aes, do_decrypt_aes},
    9292};
    9393
     
    113113  int mode = M_NONE;
    114114
    115   extern int optind, opterr;
    116   extern char *optarg;
    117115  char c;
    118116
  • zwrite.c

    rc230bc1 r7bfc613  
    55#include "owl.h"
    66
     7owl_zwrite *owl_zwrite_new(const char *line)
     8{
     9  owl_zwrite *z = owl_malloc(sizeof *z);
     10  if (owl_zwrite_create_from_line(z, line) < 0) {
     11    owl_zwrite_delete(z);
     12    return NULL;
     13  }
     14  return z;
     15}
     16
    717int owl_zwrite_create_from_line(owl_zwrite *z, const char *line)
    818{
     
    1525 
    1626  /* start with null entries */
     27  z->cmd=NULL;
    1728  z->realm=NULL;
    1829  z->class=NULL;
     
    3546  myargc=argc;
    3647  if (myargc && *(myargv[0])!='-') {
     48    z->cmd=owl_strdup(myargv[0]);
    3749    myargc--;
    3850    myargv++;
     
    187199}
    188200
     201/* Set the message with no post-processing*/
     202void owl_zwrite_set_message_raw(owl_zwrite *z, const char *msg)
     203{
     204  if (z->message) owl_free(z->message);
     205  z->message = owl_validate_utf8(msg);
     206}
     207
    189208void owl_zwrite_set_message(owl_zwrite *z, const char *msg)
    190209{
     
    350369}
    351370
     371void owl_zwrite_delete(owl_zwrite *z)
     372{
     373  owl_zwrite_cleanup(z);
     374  owl_free(z);
     375}
     376
    352377void owl_zwrite_cleanup(owl_zwrite *z)
    353378{
Note: See TracChangeset for help on using the changeset viewer.