source: owl.h @ 28da2da

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