source: owl.h @ 3535a6e

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