source: owl.h @ 99c1f46

release-1.10release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 99c1f46 was 129e609, checked in by Nelson Elhage <nelhage@mit.edu>, 14 years ago
Use a owl_dict to store the list of filters. Cathy Zhang reported that narrowing to filters that reference other filters is significantly slower than narrowing to filters that don't. The culprit is almost certainly the linear lookup of filters by name, which we currently do on each filter evaluation. Switch to using an owl_dict, which will now do a binary search over the filter list. We could potentially get this even faster by caching the owl_filter itself inside the owl_filterelement, and invalidating it somehow on filter redefinition, but we can save that sort of cleverness for later, if necessary. We also store the filters in a linked list, in order to preserve the ability to traverse them in order, for ":show filters" and for coloring.
  • Property mode set to 100644
File size: 17.6 KB
Line 
1/*  Copyright (c) 2006-2009 The BarnOwl Developers. All rights reserved.
2 *  Copyright (c) 2004 James Kretchmar. All rights reserved.
3 *
4 *  This program is free software. You can redistribute it and/or
5 *  modify under the terms of the Sleepycat License. See the COPYING
6 *  file included with the distribution for more information.
7 */
8
9#ifndef INC_OWL_H
10#define INC_OWL_H
11
12#ifndef OWL_PERL
13#include <curses.h>
14#endif
15#include <sys/param.h>
16#include <EXTERN.h>
17#include <netdb.h>
18#include <regex.h>
19#include <time.h>
20#include <signal.h>
21#include <termios.h>
22#include "libfaim/aim.h"
23#include <wchar.h>
24#include "config.h"
25#include "glib.h"
26#ifdef HAVE_LIBZEPHYR
27#include <zephyr/zephyr.h>
28#endif
29#ifdef HAVE_COM_ERR_H
30#include <com_err.h>
31#endif
32
33/* Perl and curses don't play nice. */
34#ifdef OWL_PERL
35typedef void WINDOW;
36/* logout is defined in FreeBSD. */
37#define logout logout_
38/* aim.h defines bool */
39#define HAS_BOOL
40#include <perl.h>
41#include "owl_perl.h"
42#undef logout
43#include "XSUB.h"
44#else
45typedef void SV;
46typedef void AV;
47typedef void HV;
48#endif
49
50#ifdef  GIT_VERSION
51#define stringify(x)       __stringify(x)
52#define __stringify(x)     #x
53#define OWL_VERSION_STRING stringify(GIT_VERSION)
54#else
55#define OWL_VERSION_STRING PACKAGE_VERSION
56#endif
57
58/* Feature that is being tested to redirect stderr through a pipe.
59 * There may still be some portability problems with this. */
60#define OWL_STDERR_REDIR 1
61
62#define OWL_DEBUG 0
63#define OWL_DEBUG_FILE "/var/tmp/owldebug"
64
65#define OWL_CONFIG_DIR "/.owl"             /* this is relative to the user's home directory */
66#define OWL_STARTUP_FILE "/.owl/startup"   /* this is relative to the user's home directory */
67
68#define OWL_FMTEXT_ATTR_NONE      0
69#define OWL_FMTEXT_ATTR_BOLD      1
70#define OWL_FMTEXT_ATTR_REVERSE   2
71#define OWL_FMTEXT_ATTR_UNDERLINE 4
72
73#define OWL_FMTEXT_UC_BASE 0x100000 /* Unicode Plane 16 - Supplementary Private Use Area-B*/
74#define OWL_FMTEXT_UC_ATTR ( OWL_FMTEXT_UC_BASE | 0x800 )
75#define OWL_FMTEXT_UC_ATTR_MASK 0x7
76#define OWL_FMTEXT_UC_COLOR_BASE ( OWL_FMTEXT_UC_BASE | 0x400 )
77#define OWL_FMTEXT_UC_FGCOLOR OWL_FMTEXT_UC_COLOR_BASE
78#define OWL_FMTEXT_UC_BGCOLOR ( OWL_FMTEXT_UC_COLOR_BASE | 0x200 )
79#define OWL_FMTEXT_UC_DEFAULT_COLOR 0x100
80#define OWL_FMTEXT_UC_FGDEFAULT ( OWL_FMTEXT_UC_FGCOLOR | OWL_FMTEXT_UC_DEFAULT_COLOR )
81#define OWL_FMTEXT_UC_BGDEFAULT ( OWL_FMTEXT_UC_BGCOLOR | OWL_FMTEXT_UC_DEFAULT_COLOR )
82#define OWL_FMTEXT_UC_COLOR_MASK 0xFF
83#define OWL_FMTEXT_UC_ALLCOLOR_MASK ( OWL_FMTEXT_UC_COLOR_MASK | OWL_FMTEXT_UC_DEFAULT_COLOR | 0x200)
84#define OWL_FMTEXT_UC_STARTBYTE_UTF8 '\xf4'
85
86#define OWL_FMTEXT_UTF8_ATTR_NONE "\xf4\x80\xa0\x80"
87#define OWL_FMTEXT_UTF8_FGDEFAULT "\xf4\x80\x94\x80"
88#define OWL_FMTEXT_UTF8_BGDEFAULT "\xf4\x80\x9C\x80"
89
90#define OWL_COLOR_BLACK     0
91#define OWL_COLOR_RED       1
92#define OWL_COLOR_GREEN     2
93#define OWL_COLOR_YELLOW    3
94#define OWL_COLOR_BLUE      4
95#define OWL_COLOR_MAGENTA   5
96#define OWL_COLOR_CYAN      6
97#define OWL_COLOR_WHITE     7
98#define OWL_COLOR_DEFAULT   -1
99#define OWL_COLOR_INVALID   -2
100
101#define OWL_EDITWIN_STYLE_MULTILINE 0
102#define OWL_EDITWIN_STYLE_ONELINE   1
103
104#define OWL_PROTOCOL_ZEPHYR         0
105#define OWL_PROTOCOL_AIM            1
106#define OWL_PROTOCOL_JABBER         2
107#define OWL_PROTOCOL_ICQ            3
108#define OWL_PROTOCOL_YAHOO          4
109#define OWL_PROTOCOL_MSN            5
110
111#define OWL_MESSAGE_DIRECTION_NONE  0
112#define OWL_MESSAGE_DIRECTION_IN    1
113#define OWL_MESSAGE_DIRECTION_OUT   2
114
115#define OWL_IO_READ   1
116#define OWL_IO_WRITE  2
117#define OWL_IO_EXCEPT 4
118
119#define OWL_DIRECTION_NONE      0
120#define OWL_DIRECTION_DOWNWARDS 1
121#define OWL_DIRECTION_UPWARDS   2
122
123#define OWL_LOGGING_DIRECTION_BOTH 0
124#define OWL_LOGGING_DIRECTION_IN   1
125#define OWL_LOGGING_DIRECTION_OUT  2
126
127#define OWL_SCROLLMODE_NORMAL      0
128#define OWL_SCROLLMODE_TOP         1
129#define OWL_SCROLLMODE_NEARTOP     2
130#define OWL_SCROLLMODE_CENTER      3
131#define OWL_SCROLLMODE_PAGED       4
132#define OWL_SCROLLMODE_PAGEDCENTER 5
133
134#define OWL_TAB               3  /* This *HAS* to be the size of TABSTR below */
135#define OWL_TABSTR        "   "
136#define OWL_MSGTAB            7
137#define OWL_TYPWIN_SIZE       8
138#define OWL_HISTORYSIZE       50
139
140/* Indicate current state, as well as what is allowed */
141#define OWL_CTX_ANY          0xffff
142/* Only one of these may be active at a time... */
143#define OWL_CTX_MODE_BITS    0x000f
144#define OWL_CTX_STARTUP      0x0001
145#define OWL_CTX_READCONFIG   0x0002
146#define OWL_CTX_INTERACTIVE  0x0004
147/* Only one of these may be active at a time... */
148#define OWL_CTX_ACTIVE_BITS  0xfff0
149#define OWL_CTX_POPWIN       0x00f0
150#define OWL_CTX_POPLESS      0x0010
151#define OWL_CTX_RECWIN       0x0f00
152#define OWL_CTX_RECV         0x0100
153#define OWL_CTX_TYPWIN       0xf000
154#define OWL_CTX_EDIT         0x7000
155#define OWL_CTX_EDITLINE     0x1000
156#define OWL_CTX_EDITMULTI    0x2000
157#define OWL_CTX_EDITRESPONSE 0x4000
158
159#define OWL_USERCLUE_NONE       0
160#define OWL_USERCLUE_CLASSES    1
161#define OWL_USERCLUE_FOOBAR     2
162#define OWL_USERCLUE_BAZ        4
163
164#define OWL_WEBBROWSER_NONE     0
165#define OWL_WEBBROWSER_NETSCAPE 1
166#define OWL_WEBBROWSER_GALEON   2
167#define OWL_WEBBROWSER_OPERA    3
168
169#define OWL_VARIABLE_OTHER      0
170#define OWL_VARIABLE_INT        1
171#define OWL_VARIABLE_BOOL       2
172#define OWL_VARIABLE_STRING     3
173
174#define OWL_FILTER_MAX_DEPTH    300
175
176#define OWL_KEYMAP_MAXSTACK     20
177
178#define OWL_KEYBINDING_COMMAND  1   /* command string */
179#define OWL_KEYBINDING_FUNCTION 2   /* function taking no args */
180
181#define OWL_DEFAULT_ZAWAYMSG    "I'm sorry, but I am currently away from the terminal and am\nnot able to receive your message.\n"
182#define OWL_DEFAULT_AAWAYMSG    "I'm sorry, but I am currently away from the terminal and am\nnot able to receive your message.\n"
183
184#define OWL_CMD_ALIAS_SUMMARY_PREFIX "command alias to: "
185
186#define OWL_WEBZEPHYR_PRINCIPAL "daemon.webzephyr"
187#define OWL_WEBZEPHYR_CLASS     "webzephyr"
188#define OWL_WEBZEPHYR_OPCODE    "webzephyr"
189
190#define OWL_REGEX_QUOTECHARS    "+*.?[]^\\${}()"
191#define OWL_REGEX_QUOTEWITH     "\\"
192
193#if defined(HAVE_DES_STRING_TO_KEY) && defined(HAVE_DES_KEY_SCHED) && defined(HAVE_DES_ECB_ENCRYPT)
194#define OWL_ENABLE_ZCRYPT 1
195#endif
196
197#define OWL_META(key) ((key)|010000)
198/* OWL_CTRL is definied in kepress.c */
199
200#define LINE 2048
201
202#ifdef HAVE_LIBZEPHYR
203/* libzephyr doesn't use const, so we appease the type system with this kludge.
204 * This just casts const char * to char * in a way that doesn't yield a warning
205 * from gcc -Wcast-qual. */
206static inline char *zstr(const char *str)
207{
208  union { char *rw; const char *ro; } u;
209  u.ro = str;
210  return u.rw;
211}
212#endif
213
214/* Convert char *const * into const char *const *.  This conversion is safe,
215 * and implicit in C++ (conv.qual 4) but for some reason not in C. */
216static inline const char *const *strs(char *const *pstr)
217{
218  return (const char *const *)pstr;
219}
220
221typedef struct _owl_variable {
222  char *name;
223  int   type;  /* OWL_VARIABLE_* */
224  void *pval_default;  /* for types other and string */
225  int   ival_default;  /* for types int and bool     */
226  char *validsettings;          /* documentation of valid settings */
227  char *summary;                /* summary of usage */
228  char *description;            /* detailed description */
229  void *val;                    /* current value */
230  int  (*validate_fn)(const struct _owl_variable *v, const void *newval);
231                                /* returns 1 if newval is valid */
232  int  (*set_fn)(struct _owl_variable *v, const void *newval); 
233                                /* sets the variable to a value
234                                 * of the appropriate type.
235                                 * unless documented, this
236                                 * should make a copy.
237                                 * returns 0 on success. */
238  int  (*set_fromstring_fn)(struct _owl_variable *v, const char *newval);
239                                /* sets the variable to a value
240                                 * of the appropriate type.
241                                 * unless documented, this
242                                 * should make a copy.
243                                 * returns 0 on success. */
244  const void *(*get_fn)(const struct _owl_variable *v);
245                                /* returns a reference to the current value.
246                                 * WARNING:  this approach is hard to make
247                                 * thread-safe... */
248  int  (*get_tostring_fn)(const struct _owl_variable *v, 
249                          char *buf, int bufsize, const void *val); 
250                                /* converts val to a string
251                                 * and puts into buf */
252  void  (*free_fn)(struct _owl_variable *v);
253                                /* frees val as needed */
254} owl_variable;
255
256typedef struct _owl_input {
257  int ch;
258  gunichar uch;
259} owl_input;
260
261typedef struct _owl_fmtext {
262  int textlen;
263  int bufflen;
264  char *textbuff;
265  char default_attrs;
266  short default_fgcolor;
267  short default_bgcolor;
268} owl_fmtext;
269
270typedef struct _owl_list {
271  int size;
272  int avail;
273  void **list;
274} owl_list;
275
276typedef struct _owl_dict_el {
277  char *k;                      /* key   */
278  void *v;                      /* value */
279} owl_dict_el;
280
281typedef struct _owl_dict {
282  int size;
283  int avail;
284  owl_dict_el *els;             /* invariant: sorted by k */
285} owl_dict;
286typedef owl_dict owl_vardict;   /* dict of variables */
287typedef owl_dict owl_cmddict;   /* dict of commands */
288
289typedef struct _owl_context {
290  int   mode;
291  void *data;           /* determined by mode */
292} owl_context;
293
294typedef struct _owl_cmd {       /* command */
295  char *name;
296
297  char *summary;                /* one line summary of command */
298  char *usage;                  /* usage synopsis */
299  char *description;            /* long description of command */
300
301  int validctx;                 /* bitmask of valid contexts */
302
303  /* we should probably have a type here that says which of
304   * the following is valid, and maybe make the below into a union... */
305
306  /* Only one of these may be non-NULL ... */
307
308  char *cmd_aliased_to;         /* what this command is aliased to... */
309 
310  /* These don't take any context */
311  char *(*cmd_args_fn)(int argc, const char *const *argv, const char *buff); 
312                                /* takes argv and the full command as buff.
313                                 * caller must free return value if !NULL */
314  void (*cmd_v_fn)(void);       /* takes no args */
315  void (*cmd_i_fn)(int i);      /* takes an int as an arg */
316
317  /* The following also take the active context if it's valid */
318  char *(*cmd_ctxargs_fn)(void *ctx, int argc, const char *const *argv, const char *buff); 
319                                /* takes argv and the full command as buff.
320                                 * caller must free return value if !NULL */
321  void (*cmd_ctxv_fn)(void *ctx);               /* takes no args */
322  void (*cmd_ctxi_fn)(void *ctx, int i);        /* takes an int as an arg */
323  SV *cmd_perl;                                /* Perl closure that takes a list of args */
324} owl_cmd;
325
326
327typedef struct _owl_zwrite {
328  char *zwriteline;
329  char *class;
330  char *inst;
331  char *realm;
332  char *opcode;
333  char *zsig;
334  char *message;
335  owl_list recips;
336  int cc;
337  int noping;
338} owl_zwrite;
339
340typedef struct _owl_pair {
341  const char *key;
342  char *value;
343} owl_pair;
344
345struct _owl_fmtext_cache;
346
347typedef struct _owl_message {
348  int id;
349  int direction;
350#ifdef HAVE_LIBZEPHYR
351  ZNotice_t notice;
352#endif
353  struct _owl_fmtext_cache * fmtext;
354  int delete;
355  const char *hostname;
356  owl_list attributes;            /* this is a list of pairs */
357  char *timestr;
358  time_t time;
359} owl_message;
360
361#define OWL_FMTEXT_CACHE_SIZE 1000
362/* We cache the saved fmtexts for the last bunch of messages we
363   rendered */
364typedef struct _owl_fmtext_cache {
365    owl_message * message;
366    owl_fmtext fmtext;
367} owl_fmtext_cache;
368
369typedef struct _owl_style {
370  char *name;
371  SV *perlobj;
372} owl_style;
373
374typedef struct _owl_mainwin {
375  int curtruncated;
376  int lasttruncated;
377  int lastdisplayed;
378} owl_mainwin;
379
380typedef struct _owl_viewwin {
381  owl_fmtext fmtext;
382  int textlines;
383  int topline;
384  int rightshift;
385  int winlines, wincols;
386  WINDOW *curswin;
387  void (*onclose_hook) (struct _owl_viewwin *vwin, void *data);
388  void *onclose_hook_data;
389} owl_viewwin;
390 
391typedef struct _owl_popwin {
392  WINDOW *borderwin;
393  WINDOW *popwin;
394  int lines;
395  int cols;
396  int active;
397  int needsfirstrefresh;
398} owl_popwin;
399
400typedef struct _owl_messagelist {
401  owl_list list;
402} owl_messagelist;
403
404typedef struct _owl_regex {
405  int negate;
406  char *string;
407  regex_t re;
408} owl_regex;
409
410typedef struct _owl_filterelement {
411  int (*match_message)(const struct _owl_filterelement *fe, const owl_message *m);
412  /* Append a string representation of the filterelement onto buf*/
413  void (*print_elt)(const struct _owl_filterelement *fe, GString *buf);
414  /* Operands for and,or,not*/
415  struct _owl_filterelement *left, *right;
416  /* For regex filters*/
417  owl_regex re;
418  /* Used by regexes, filter references, and perl */
419  char *field;
420} owl_filterelement;
421
422typedef struct _owl_filter {
423  char *name;
424  owl_filterelement * root;
425  int fgcolor;
426  int bgcolor;
427  int cachedmsgid;  /* cached msgid: should move into view eventually */
428} owl_filter;
429
430typedef struct _owl_view {
431  char *name;
432  owl_filter *filter;
433  owl_messagelist ml;
434  const owl_style *style;
435} owl_view;
436
437typedef struct _owl_history {
438  owl_list hist;
439  int cur;
440  int touched;
441  int partial;
442  int repeats;
443} owl_history;
444
445typedef struct _owl_editwin owl_editwin;
446typedef struct _owl_editwin_excursion owl_editwin_excursion;
447
448typedef struct _owl_keybinding {
449  int  *keys;                   /* keypress stack */
450  int   len;                    /* length of stack */
451  int   type;                   /* command or function? */
452  char *desc;                   /* description (or "*user*") */
453  char *command;                /* command, if of type command */
454  void (*function_fn)(void);    /* function ptr, if of type function */
455} owl_keybinding;
456
457typedef struct _owl_keymap {
458  char     *name;               /* name of keymap */
459  char     *desc;               /* description */
460  owl_list  bindings;           /* key bindings */
461  const struct _owl_keymap *submap;     /* submap */
462  void (*default_fn)(owl_input j);      /* default action (takes a keypress) */
463  void (*prealways_fn)(owl_input  j);   /* always called before a keypress is received */
464  void (*postalways_fn)(owl_input  j);  /* always called after keypress is processed */
465} owl_keymap;
466
467typedef struct _owl_keyhandler {
468  owl_dict  keymaps;            /* dictionary of keymaps */
469  const owl_keymap *active;             /* currently active keymap */
470  int       in_esc;             /* escape pressed? */
471  int       kpstack[OWL_KEYMAP_MAXSTACK+1]; /* current stack of keypresses */
472  int       kpstackpos;         /* location in stack (-1 = none) */
473} owl_keyhandler;
474
475typedef struct _owl_buddy {
476  int proto;
477  char *name;
478  int isidle;
479  int idlesince;
480} owl_buddy;
481
482typedef struct _owl_buddylist {
483  owl_list buddies;
484} owl_buddylist;
485
486typedef struct _owl_zbuddylist {
487  owl_list zusers;
488} owl_zbuddylist;
489
490typedef struct _owl_timer {
491  time_t time;
492  int interval;
493  void (*callback)(struct _owl_timer *, void *);
494  void (*destroy)(struct _owl_timer *);
495  void *data;
496} owl_timer;
497
498typedef struct _owl_errqueue {
499  owl_list errlist;
500} owl_errqueue;
501
502typedef struct _owl_colorpair_mgr {
503  int next;
504  short **pairs;
505} owl_colorpair_mgr;
506
507typedef struct _owl_obarray {
508  owl_list strings;
509} owl_obarray;
510
511typedef struct _owl_io_dispatch {
512  int fd;                                     /* FD to watch for dispatch. */
513  int mode;
514  int needs_gc;
515  void (*callback)(const struct _owl_io_dispatch *, void *); /* C function to dispatch to. */
516  void (*destroy)(const struct _owl_io_dispatch *);  /* Destructor */
517  void *data;
518} owl_io_dispatch;
519
520typedef struct _owl_ps_action {
521  int needs_gc;
522  int (*callback)(struct _owl_ps_action *, void *);
523  void (*destroy)(struct _owl_ps_action *);
524  void *data;
525} owl_ps_action;
526
527typedef struct _owl_popexec {
528  int refcount;
529  owl_viewwin *vwin;
530  int winactive;
531  pid_t pid;                    /* or 0 if it has terminated */
532  const owl_io_dispatch *dispatch;
533} owl_popexec;
534
535typedef struct _owl_global {
536  owl_mainwin mw;
537  owl_popwin pw;
538  owl_history cmdhist;          /* command history */
539  owl_history msghist;          /* outgoing message history */
540  owl_keyhandler kh;
541  owl_dict filters;
542  GList *filterlist;
543  owl_list puntlist;
544  owl_vardict vars;
545  owl_cmddict cmds;
546  owl_context ctx;
547  owl_errqueue errqueue;
548  int lines, cols;
549  int curmsg, topmsg;
550  int markedmsgid;              /* for finding the marked message when it has moved. */
551  int curmsg_vert_offset;
552  owl_view current_view;
553  owl_messagelist msglist;
554  WINDOW *recwin, *sepwin, *msgwin, *typwin;
555  int needrefresh;
556  int rightshift;
557  int resizepending;
558  int recwinlines;
559  int typwinactive;
560  char *thishost;
561  char *homedir;
562  char *confdir;
563  char *startupfile;
564  int direction;
565  int zaway;
566  char *cur_zaway_msg;
567  int haveconfig;
568  int config_format;
569  void *buffercbdata;
570  owl_editwin *tw;
571  owl_viewwin vw;
572  void *perl;
573  int debug;
574  time_t starttime;
575  time_t lastinputtime;
576  char *startupargs;
577  int userclue;
578  int nextmsgid;
579  int hascolors;
580  int colorpairs;
581  owl_colorpair_mgr cpmgr;
582  pid_t newmsgproc_pid;
583  int malloced, freed;
584  owl_regex search_re;
585  aim_session_t aimsess;
586  aim_conn_t bosconn;
587  owl_timer aim_noop_timer;
588  owl_timer aim_ignorelogin_timer;
589  int aim_loggedin;         /* true if currently logged into AIM */
590  int aim_doprocessing;     /* true if we should process AIM events (like pending login) */
591  char *aim_screenname;     /* currently logged in AIM screen name */
592  char *aim_screenname_for_filters;     /* currently logged in AIM screen name */
593  owl_buddylist buddylist;  /* list of logged in AIM buddies */
594  owl_list messagequeue;    /* for queueing up aim and other messages */
595  owl_dict styledict;       /* global dictionary of available styles */
596  char *response;           /* response to the last question asked */
597  int havezephyr;
598  int haveaim;
599  int ignoreaimlogin;
600  int got_err_signal;       /* 1 if we got an unexpected signal */
601  siginfo_t err_signal_info;
602  owl_zbuddylist zbuddies;
603  owl_timer zephyr_buddycheck_timer;
604  struct termios startup_tio;
605  owl_obarray obarray;
606  owl_list io_dispatch_list;
607  owl_list psa_list;
608  GList *timerlist;
609  owl_timer *aim_nop_timer;
610  int load_initial_subs;
611  int interrupted;
612  int got_sigtstp;
613} owl_global;
614
615/* globals */
616extern owl_global g;
617
618#include "owl_prototypes.h"
619
620/* these are missing from the zephyr includes for some reason */
621#ifdef HAVE_LIBZEPHYR
622int ZGetSubscriptions(ZSubscription_t *, int *);
623int ZGetLocations(ZLocations_t *,int *);
624#endif
625
626#endif /* INC_OWL_H */
Note: See TracBrowser for help on using the repository browser.