source: owl.c @ 45cf49f

debianrelease-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 45cf49f was 45cf49f, checked in by Nelson Elhage <nelhage@mit.edu>, 12 years ago
Don't send stderr to admin messages. We've been getting a lot of complaints about 'uninitialized use of ...' errors and of spew from buggy zsig randomizers. In both cases, this was an effect of the way we were sending stderr to error messages, and those error messages went to admin messages because of a change in 1.0.5. We still send stderr to the error message log, but text there will no longer show up anywhere by default.
  • Property mode set to 100644
File size: 22.7 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#include <stdio.h>
10#include <unistd.h>
11#include <stdlib.h>
12#include <string.h>
13#include <signal.h>
14#include <time.h>
15#include <sys/param.h>
16#include <sys/types.h>
17#include <sys/time.h>
18#include <termios.h>
19#include <sys/stat.h>
20#include <locale.h>
21#include "owl.h"
22
23
24#if OWL_STDERR_REDIR
25#ifdef HAVE_SYS_IOCTL_H
26#include <sys/ioctl.h>
27#endif
28#ifdef HAVE_SYS_FILIO_H
29#include <sys/filio.h>
30#endif
31int stderr_replace(void);
32#endif
33
34#define STDIN 0
35
36static const char fileIdent[] = "$Id$";
37
38owl_global g;
39
40int main(int argc, char **argv, char **env)
41{
42  WINDOW *recwin, *sepwin, *typwin, *msgwin;
43  owl_editwin *tw;
44  owl_popwin *pw;
45  int ret, debug, argcsave, followlast;
46  int newmsgs, nexttimediff;
47  struct sigaction sigact;
48  char *configfile, *tty, *perlout, *perlerr, **argvsave;
49  char *confdir;
50  owl_filter *f;
51  owl_style *s;
52  time_t nexttime, now;
53  struct tm *today;
54  char *dir;
55  struct termios tio;
56  owl_message *m;
57
58  if (!GLIB_CHECK_VERSION (2, 12, 0))
59    g_error ("GLib version 2.12.0 or above is needed.");
60
61  argcsave=argc;
62  argvsave=argv;
63  configfile=NULL;
64  confdir = NULL;
65  tty=NULL;
66  debug=0;
67  g.load_initial_subs = 1;
68
69  setlocale(LC_ALL, "");
70 
71  if (argc>0) {
72    argv++;
73    argc--;
74  }
75  while (argc>0) {
76    if (!strcmp(argv[0], "-n")) {
77      g.load_initial_subs = 0;
78      argv++;
79      argc--;
80    } else if (!strcmp(argv[0], "-c")) {
81      if (argc<2) {
82        fprintf(stderr, "Too few arguments to -c\n");
83        usage();
84        exit(1);
85      }
86      configfile=argv[1];
87      argv+=2;
88      argc-=2;
89    } else if (!strcmp(argv[0], "-t")) {
90      if (argc<2) {
91        fprintf(stderr, "Too few arguments to -t\n");
92        usage();
93        exit(1);
94      }
95      tty=argv[1];
96      argv+=2;
97      argc-=2;
98    } else if (!strcmp(argv[0], "-s")){
99      if (argc<2) {
100        fprintf(stderr, "Too few arguments to -s\n");
101        usage();
102        exit(1);
103      }
104      confdir = argv[1];
105      argv+=2;
106      argc-=2;
107    } else if (!strcmp(argv[0], "-d")) {
108      debug=1;
109      argv++;
110      argc--;
111    } else if (!strcmp(argv[0], "-D")) {
112      debug=1;
113      unlink(OWL_DEBUG_FILE);
114      argv++;
115      argc--;
116    } else if (!strcmp(argv[0], "-v")) {
117      printf("This is barnowl version %s\n", OWL_VERSION_STRING);
118      exit(0);
119    } else {
120      fprintf(stderr, "Unknown argument\n");
121      usage();       
122      exit(1);
123    }
124  }
125
126  owl_function_debugmsg("startup: Finished parsing arguments");
127
128  /* signal handler */
129  /*sigact.sa_handler=sig_handler;*/
130  sigact.sa_sigaction=sig_handler;
131  sigemptyset(&sigact.sa_mask);
132  sigact.sa_flags=SA_SIGINFO;
133  sigaction(SIGWINCH, &sigact, NULL);
134  sigaction(SIGALRM, &sigact, NULL);
135  sigaction(SIGPIPE, &sigact, NULL);
136  sigaction(SIGTERM, &sigact, NULL);
137  sigaction(SIGHUP, &sigact, NULL);
138
139  /* save initial terminal settings */
140  tcgetattr(0, owl_global_get_startup_tio(&g));
141
142  /* turn ISTRIP off */
143  tcgetattr(0, &tio);
144  tio.c_iflag &= ~ISTRIP;
145  tcsetattr(0, TCSAFLUSH, &tio);
146
147  /* screen init */
148  if (!getenv("TERMINFO")) {
149    owl_function_debugmsg("startup: Not setting TERMINFO");
150  } else {
151    owl_function_debugmsg("startup: leaving TERMINFO as %s from envrionment", getenv("TERMINFO"));
152  }
153  initscr();
154  start_color();
155#ifdef HAVE_USE_DEFAULT_COLORS
156  use_default_colors();
157#endif
158  raw();
159  noecho();
160
161  /* define simple color pairs */
162  if (has_colors() && COLOR_PAIRS>=8) {
163    int bg = COLOR_BLACK;
164#ifdef HAVE_USE_DEFAULT_COLORS
165    bg = -1;
166#endif
167    init_pair(OWL_COLOR_BLACK,   COLOR_BLACK,   bg);
168    init_pair(OWL_COLOR_RED,     COLOR_RED,     bg);
169    init_pair(OWL_COLOR_GREEN,   COLOR_GREEN,   bg);
170    init_pair(OWL_COLOR_YELLOW,  COLOR_YELLOW,  bg);
171    init_pair(OWL_COLOR_BLUE,    COLOR_BLUE,    bg);
172    init_pair(OWL_COLOR_MAGENTA, COLOR_MAGENTA, bg);
173    init_pair(OWL_COLOR_CYAN,    COLOR_CYAN,    bg);
174    init_pair(OWL_COLOR_WHITE,   COLOR_WHITE,   bg);
175  }
176
177  /* owl global init */
178  owl_global_init(&g);
179  if (debug) owl_global_set_debug_on(&g);
180  if (confdir) owl_global_set_confdir(&g, confdir);
181  owl_function_debugmsg("startup: first available debugging message");
182  owl_global_set_startupargs(&g, argcsave, argvsave);
183  owl_global_set_haveaim(&g);
184
185  /* prepare stdin dispatch */
186  {
187    owl_dispatch *d = owl_malloc(sizeof(owl_dispatch));
188    d->fd = STDIN;
189    d->cfunc = &owl_process_input;
190    d->destroy = NULL;
191    owl_select_add_dispatch(d);
192  }
193
194  owl_zephyr_initialize();
195
196#if OWL_STDERR_REDIR
197  /* Do this only after we've started curses up... */
198  {
199    owl_dispatch *d = owl_malloc(sizeof(owl_dispatch));
200    owl_function_debugmsg("startup: doing stderr redirection");
201    d->fd = stderr_replace();
202    d->cfunc = stderr_redirect_handler;
203    d->destroy = NULL;
204    owl_select_add_dispatch(d);
205  }
206#endif
207
208  /* create the owl directory, in case it does not exist */
209  owl_function_debugmsg("startup: creating owl directory, if not present");
210  dir=owl_global_get_confdir(&g);
211  mkdir(dir, S_IRWXU);
212
213  /* set the tty, either from the command line, or by figuring it out */
214  owl_function_debugmsg("startup: setting tty name");
215  if (tty) {
216    owl_global_set_tty(&g, tty);
217  } else {
218    owl_global_set_tty(&g, owl_util_get_default_tty());
219  }
220
221  /* Initialize perl */
222  owl_function_debugmsg("startup: processing config file");
223  owl_context_set_readconfig(owl_global_get_context(&g));
224  perlerr=owl_perlconfig_initperl(configfile, &argc, &argv, &env);
225  if (perlerr) {
226    endwin();
227    owl_function_error("Internal perl error: %s\n", perlerr);
228    fprintf(stderr, "Internal perl error: %s\n", perlerr);
229    fflush(stderr);
230    printf("Internal perl error: %s\n", perlerr);
231    fflush(stdout);
232    exit(1);
233  }
234
235  /* setup the default filters */
236  /* the personal filter will need to change again when AIM chat's are
237   *  included.  Also, there should be an %aimme% */
238  owl_function_debugmsg("startup: creating default filters");
239  f=owl_malloc(sizeof(owl_filter));
240  owl_filter_init_fromstring(f, "personal", "isprivate ^true$ and ( not type ^zephyr$"
241                             " or ( class ^message and"
242                             " ( instance ^personal$ or instance ^urgent$ ) ) )");
243  owl_list_append_element(owl_global_get_filterlist(&g), f);
244
245  f=owl_malloc(sizeof(owl_filter));
246  owl_filter_init_fromstring(f, "wordwrap", "not ( type ^admin$ or type ^zephyr$ ) ");
247  owl_list_append_element(owl_global_get_filterlist(&g), f);
248
249  f=owl_malloc(sizeof(owl_filter));
250  owl_filter_init_fromstring(f, "trash", "class ^mail$ or opcode ^ping$ or type ^admin$ or ( not login ^none$ )");
251  owl_list_append_element(owl_global_get_filterlist(&g), f);
252
253  f=owl_malloc(sizeof(owl_filter));
254  owl_filter_init_fromstring(f, "ping", "opcode ^ping$");
255  owl_list_append_element(owl_global_get_filterlist(&g), f);
256
257  f=owl_malloc(sizeof(owl_filter));
258  owl_filter_init_fromstring(f, "auto", "opcode ^auto$");
259  owl_list_append_element(owl_global_get_filterlist(&g), f);
260
261  f=owl_malloc(sizeof(owl_filter));
262  owl_filter_init_fromstring(f, "login", "not login ^none$");
263  owl_list_append_element(owl_global_get_filterlist(&g), f);
264
265  f=owl_malloc(sizeof(owl_filter));
266  owl_filter_init_fromstring(f, "reply-lockout", "class ^noc or class ^mail$");
267  owl_list_append_element(owl_global_get_filterlist(&g), f);
268
269  f=owl_malloc(sizeof(owl_filter));
270  owl_filter_init_fromstring(f, "out", "direction ^out$");
271  owl_list_append_element(owl_global_get_filterlist(&g), f);
272
273  f=owl_malloc(sizeof(owl_filter));
274  owl_filter_init_fromstring(f, "aim", "type ^aim$");
275  owl_list_append_element(owl_global_get_filterlist(&g), f);
276
277  f=owl_malloc(sizeof(owl_filter));
278  owl_filter_init_fromstring(f, "zephyr", "type ^zephyr$");
279  owl_list_append_element(owl_global_get_filterlist(&g), f);
280
281  f=owl_malloc(sizeof(owl_filter));
282  owl_filter_init_fromstring(f, "none", "false");
283  owl_list_append_element(owl_global_get_filterlist(&g), f);
284
285  f=owl_malloc(sizeof(owl_filter));
286  owl_filter_init_fromstring(f, "all", "true");
287  owl_list_append_element(owl_global_get_filterlist(&g), f);
288
289  /* set the current view */
290  owl_function_debugmsg("startup: setting the current view");
291  owl_view_create(owl_global_get_current_view(&g), "main", f, owl_global_get_style_by_name(&g, "default"));
292
293  /* AIM init */
294  owl_function_debugmsg("startup: doing AIM initialization");
295  owl_aim_init();
296
297  /* execute the startup function in the configfile */
298  owl_function_debugmsg("startup: executing perl startup, if applicable");
299  perlout = owl_perlconfig_execute("BarnOwl::Hooks::_startup();");
300  if (perlout) owl_free(perlout);
301
302  /* hold on to the window names for convenience */
303  msgwin=owl_global_get_curs_msgwin(&g);
304  recwin=owl_global_get_curs_recwin(&g);
305  sepwin=owl_global_get_curs_sepwin(&g);
306  typwin=owl_global_get_curs_typwin(&g);
307  tw=owl_global_get_typwin(&g);
308
309  /* welcome message */
310  owl_function_debugmsg("startup: creating splash message");
311  owl_function_adminmsg("",
312    "-----------------------------------------------------------------------\n"
313    "Welcome to barnowl version " OWL_VERSION_STRING ".  Press 'h' for on-line help.\n"
314    "To see a quick introduction, type ':show quickstart'.                  \n"
315    "                                                                       \n"
316    "BarnOwl is free software. Type ':show license' for more                \n"
317    "information.                                                     ^ ^   \n"
318    "                                                                 OvO   \n"
319    "Please report any bugs or suggestions to bug-barnowl@mit.edu    (   )  \n"
320    "-----------------------------------------------------------------m-m---\n"
321  );
322  sepbar(NULL);
323
324  /* process the startup file */
325  owl_function_debugmsg("startup: processing startup file");
326  owl_function_source(NULL);
327
328  wrefresh(sepwin);
329
330  /* First buddy check to sync the list without notifications */
331  owl_function_debugmsg("startup: doing initial zephyr buddy check");
332  /* owl_function_zephyr_buddy_check(0); */
333
334  /* set the startup and default style, based on userclue and presence of a
335   * formatting function */
336  owl_function_debugmsg("startup: setting startup and default style");
337  if (0 != strcmp(owl_global_get_default_style(&g), "__unspecified__")) {
338    /* the style was set by the user: leave it alone */
339  } else {
340    owl_global_set_default_style(&g, "default");
341  }
342
343  /* zlog in if we need to */
344  if (owl_global_is_startuplogin(&g)) {
345    owl_function_debugmsg("startup: doing zlog in");
346    owl_zephyr_zlog_in();
347  }
348
349  owl_function_debugmsg("startup: set style for the view: %s", owl_global_get_default_style(&g));
350  s = owl_global_get_style_by_name(&g, owl_global_get_default_style(&g));
351  if(s)
352      owl_view_set_style(owl_global_get_current_view(&g), s);
353  else
354      owl_function_error("No such style: %s", owl_global_get_default_style(&g));
355
356  owl_function_debugmsg("startup: setting context interactive");
357  owl_context_set_interactive(owl_global_get_context(&g));
358
359  nexttimediff=10;
360  nexttime=time(NULL);
361
362
363  owl_select_add_timer(180, 180, owl_zephyr_buddycheck_timer, NULL, NULL);
364
365  /* If we ever deprecate the mainloop hook, remove this. */
366  owl_select_add_timer(0, 1, owl_perlconfig_mainloop, NULL, NULL);
367
368
369  owl_function_debugmsg("startup: entering main loop");
370  /* main loop */
371  while (1) {
372
373    /* if a resize has been scheduled, deal with it */
374    owl_global_resize(&g, 0, 0);
375
376    /* these are here in case a resize changes the windows */
377    msgwin=owl_global_get_curs_msgwin(&g);
378    recwin=owl_global_get_curs_recwin(&g);
379    sepwin=owl_global_get_curs_sepwin(&g);
380    typwin=owl_global_get_curs_typwin(&g);
381
382    followlast=owl_global_should_followlast(&g);
383
384    /* little hack */
385    now=time(NULL);
386    today=localtime(&now);
387    if (today->tm_mon==9 && today->tm_mday==31 && owl_global_get_runtime(&g)<600) {
388      if (time(NULL)>nexttime) {
389        if (nexttimediff==1) {
390          nexttimediff=10;
391        } else {
392          nexttimediff=1;
393        }
394        nexttime+=nexttimediff;
395        owl_hack_animate();
396      }
397    }
398
399    /* Grab incoming messages. */
400    newmsgs=0;
401    while(owl_global_messagequeue_pending(&g)) {
402
403      m = owl_global_messagequeue_popmsg(&g);
404
405      if(owl_process_message(m))
406        newmsgs = 1;
407    }
408
409    /* follow the last message if we're supposed to */
410    if (newmsgs && followlast) {
411      owl_function_lastmsg_noredisplay();
412    }
413
414    /* do the newmsgproc thing */
415    if (newmsgs) {
416      owl_function_do_newmsgproc();
417    }
418   
419    /* redisplay if necessary */
420    /* this should be optimized to not run if the new messages won't be displayed */
421    if (newmsgs) {
422      owl_mainwin_redisplay(owl_global_get_mainwin(&g));
423      sepbar(NULL);
424      if (owl_popwin_is_active(owl_global_get_popwin(&g))) {
425        owl_popwin_refresh(owl_global_get_popwin(&g));
426        /* TODO: this is a broken kludge */
427        if (owl_global_get_viewwin(&g)) {
428          owl_viewwin_redisplay(owl_global_get_viewwin(&g), 0);
429        }
430      }
431      owl_global_set_needrefresh(&g);
432    }
433
434    /* if a popwin just came up, refresh it */
435    pw=owl_global_get_popwin(&g);
436    if (owl_popwin_is_active(pw) && owl_popwin_needs_first_refresh(pw)) {
437      owl_popwin_refresh(pw);
438      owl_popwin_no_needs_first_refresh(pw);
439      owl_global_set_needrefresh(&g);
440      /* TODO: this is a broken kludge */
441      if (owl_global_get_viewwin(&g)) {
442        owl_viewwin_redisplay(owl_global_get_viewwin(&g), 0);
443      }
444    }
445
446    /* update the terminal if we need to */
447    if (owl_global_is_needrefresh(&g)) {
448      /* leave the cursor in the appropriate window */
449      if (owl_global_is_typwin_active(&g)) {
450        owl_function_set_cursor(typwin);
451      } else {
452        owl_function_set_cursor(sepwin);
453      }
454      doupdate();
455      owl_global_set_noneedrefresh(&g);
456    }
457
458    /* select on FDs we know about. */
459    owl_select();
460
461    /* Log any error signals */
462    {
463      siginfo_t si;
464      int signum;
465      if ((signum = owl_global_get_errsignal_and_clear(&g, &si)) > 0) {
466        owl_function_error("Got unexpected signal: %d %s  (code: %d band: %ld  errno: %d)",
467                           signum, signum==SIGPIPE?"SIGPIPE":"SIG????",
468                           si.si_code, si.si_band, si.si_errno);
469      }
470    }
471
472  }
473}
474
475/*
476 * Process a new message passed to us on the message queue from some
477 * protocol. This includes adding it to the message list, updating the
478 * view and scrolling if appropriate, logging it, and so on.
479 *
480 * Either a pointer is kept to the message internally, or it is freed
481 * if unneeded. The caller no longer ``owns'' the message's memory.
482 *
483 * Returns 1 if the message was added to the message list, and 0 if it
484 * was ignored due to user settings or otherwise.
485 */
486int owl_process_message(owl_message *m) {
487  owl_filter *f;
488  /* if this message it on the puntlist, nuke it and continue */
489  if (owl_global_message_is_puntable(&g, m)) {
490    owl_message_free(m);
491    return 0;
492  }
493
494  /*  login or logout that should be ignored? */
495  if (owl_global_is_ignorelogins(&g)
496      && owl_message_is_loginout(m)) {
497    owl_message_free(m);
498    return 0;
499  }
500
501  if (!owl_global_is_displayoutgoing(&g)
502      && owl_message_is_direction_out(m)) {
503    owl_message_free(m);
504    return 0;
505  }
506
507  /* add it to the global list */
508  owl_messagelist_append_element(owl_global_get_msglist(&g), m);
509  /* add it to any necessary views; right now there's only the current view */
510  owl_view_consider_message(owl_global_get_current_view(&g), m);
511
512  if(owl_message_is_direction_in(m)) {
513    /* let perl know about it*/
514    owl_perlconfig_getmsg(m, NULL);
515
516    /* do we need to autoreply? */
517    if (owl_global_is_zaway(&g) && !owl_message_get_attribute_value(m, "isauto")) {
518      if (owl_message_is_type_zephyr(m)) {
519        owl_zephyr_zaway(m);
520      } else if (owl_message_is_type_aim(m)) {
521        if (owl_message_is_private(m)) {
522          owl_function_send_aimawymsg(owl_message_get_sender(m), owl_global_get_zaway_msg(&g));
523        }
524      }
525    }
526
527    /* ring the bell if it's a personal */
528    if (!strcmp(owl_global_get_personalbell(&g), "on")) {
529      if (!owl_message_is_loginout(m) &&
530          !owl_message_is_mail(m) &&
531          owl_message_is_personal(m)) {
532        owl_function_beep();
533      }
534    } else if (!strcmp(owl_global_get_personalbell(&g), "off")) {
535      /* do nothing */
536    } else {
537      f=owl_global_get_filter(&g, owl_global_get_personalbell(&g));
538      if (f && owl_filter_message_match(f, m)) {
539        owl_function_beep();
540      }
541    }
542
543    /* if it matches the alert filter, do the alert action */
544    f=owl_global_get_filter(&g, owl_global_get_alert_filter(&g));
545    if (f && owl_filter_message_match(f, m)) {
546      owl_function_command(owl_global_get_alert_action(&g));
547    }
548
549    /* if it's a zephyr login or logout, update the zbuddylist */
550    if (owl_message_is_type_zephyr(m) && owl_message_is_loginout(m)) {
551      if (owl_message_is_login(m)) {
552        owl_zbuddylist_adduser(owl_global_get_zephyr_buddylist(&g), owl_message_get_sender(m));
553      } else if (owl_message_is_logout(m)) {
554        owl_zbuddylist_deluser(owl_global_get_zephyr_buddylist(&g), owl_message_get_sender(m));
555      } else {
556        owl_function_error("Internal error: received login notice that is neither login nor logout");
557      }
558    }
559  }
560
561  /* let perl know about it */
562  owl_perlconfig_newmsg(m, NULL);
563  /* log the message if we need to */
564  owl_log_message(m);
565
566  return 1;
567}
568
569void owl_process_input(owl_dispatch *d)
570{
571  int ret;
572  owl_input j;
573  owl_popwin *pw;
574  owl_editwin *tw;
575  WINDOW *typwin;
576
577  typwin = owl_global_get_curs_typwin(&g);
578  while (1) {
579    j.ch = wgetch(typwin);
580    if (j.ch == ERR) return;
581   
582    owl_global_set_lastinputtime(&g, time(NULL));
583    pw=owl_global_get_popwin(&g);
584    tw=owl_global_get_typwin(&g);
585
586    j.uch = '\0';
587    if (j.ch >= KEY_MIN && j.ch <= KEY_MAX) {
588      /* This is a curses control character. */
589    }
590    else if (j.ch > 0x7f && j.ch < 0xfe) {
591      /* Pull in a full utf-8 character. */
592      int bytes, i;
593      char utf8buf[7];
594      memset(utf8buf, '\0', 7);
595     
596      utf8buf[0] = j.ch;
597     
598      if ((j.ch & 0xc0) && (~j.ch & 0x20)) bytes = 2;
599      else if ((j.ch & 0xe0) && (~j.ch & 0x10)) bytes = 3;
600      else if ((j.ch & 0xf0) && (~j.ch & 0x08)) bytes = 4;
601      else if ((j.ch & 0xf8) && (~j.ch & 0x04)) bytes = 5;
602      else if ((j.ch & 0xfc) && (~j.ch & 0x02)) bytes = 6;
603      else bytes = 1;
604     
605      for (i = 1; i < bytes; i++) {
606        int tmp =  wgetch(typwin);
607        /* If what we got was not a byte, or not a continuation byte */
608        if (tmp > 0xff || !(tmp & 0x80 && ~tmp & 0x40)) {
609          /* ill-formed UTF-8 code unit subsequence, put back the
610             char we just got. */
611          ungetch(tmp);
612          j.ch = ERR;
613          break;
614        }
615        utf8buf[i] = tmp;
616      }
617     
618      if (j.ch != ERR) {
619        if (g_utf8_validate(utf8buf, -1, NULL)) {
620          j.uch = g_utf8_get_char(utf8buf);
621        }
622        else {
623          j.ch = ERR;
624        }
625      }
626    }
627    else if (j.ch <= 0x7f) {
628      j.uch = j.ch;
629    }
630   
631    owl_global_set_lastinputtime(&g, time(NULL));
632    /* find and activate the current keymap.
633     * TODO: this should really get fixed by activating
634     * keymaps as we switch between windows...
635     */
636    if (pw && owl_popwin_is_active(pw) && owl_global_get_viewwin(&g)) {
637      owl_context_set_popless(owl_global_get_context(&g), 
638                              owl_global_get_viewwin(&g));
639      owl_function_activate_keymap("popless");
640    } else if (owl_global_is_typwin_active(&g) 
641               && owl_editwin_get_style(tw)==OWL_EDITWIN_STYLE_ONELINE) {
642      /*
643        owl_context_set_editline(owl_global_get_context(&g), tw);
644        owl_function_activate_keymap("editline");
645      */
646    } else if (owl_global_is_typwin_active(&g) 
647               && owl_editwin_get_style(tw)==OWL_EDITWIN_STYLE_MULTILINE) {
648      owl_context_set_editmulti(owl_global_get_context(&g), tw);
649      owl_function_activate_keymap("editmulti");
650    } else {
651      owl_context_set_recv(owl_global_get_context(&g));
652      owl_function_activate_keymap("recv");
653    }
654    /* now actually handle the keypress */
655    ret = owl_keyhandler_process(owl_global_get_keyhandler(&g), j);
656    if (ret!=0 && ret!=1) {
657      owl_function_makemsg("Unable to handle keypress");
658    }
659  }
660}
661
662void sig_handler(int sig, siginfo_t *si, void *data)
663{
664  if (sig==SIGWINCH) {
665    /* we can't inturrupt a malloc here, so it just sets a flag
666     * schedulding a resize for later
667     */
668    owl_function_resize();
669  } else if (sig==SIGPIPE || sig==SIGCHLD) {
670    /* Set a flag and some info that we got the sigpipe
671     * so we can record that we got it and why... */
672    owl_global_set_errsignal(&g, sig, si);
673  } else if (sig==SIGTERM || sig==SIGHUP) {
674    owl_function_quit();
675  }
676}
677
678void usage()
679{
680  fprintf(stderr, "Barnowl version %s\n", OWL_VERSION_STRING);
681  fprintf(stderr, "Usage: barnowl [-n] [-d] [-D] [-v] [-h] [-c <configfile>] [-s <confdir>] [-t <ttyname>]\n");
682  fprintf(stderr, "  -n      don't load zephyr subscriptions\n");
683  fprintf(stderr, "  -d      enable debugging\n");
684  fprintf(stderr, "  -D      enable debugging and delete previous debug file\n");
685  fprintf(stderr, "  -v      print the Barnowl version number and exit\n");
686  fprintf(stderr, "  -h      print this help message\n");
687  fprintf(stderr, "  -c      specify an alternate config file\n");
688  fprintf(stderr, "  -s      specify an alternate config dir (default ~/.owl)\n");
689  fprintf(stderr, "  -t      set the tty name\n");
690}
691
692#if OWL_STDERR_REDIR
693
694/* Replaces stderr with a pipe so that we can read from it.
695 * Returns the fd of the pipe from which stderr can be read. */
696int stderr_replace(void)
697{
698  int pipefds[2];
699  if (0 != pipe(pipefds)) {
700    perror("pipe");
701    owl_function_debugmsg("stderr_replace: pipe FAILED\n");
702    return -1;
703  }
704    owl_function_debugmsg("stderr_replace: pipe: %d,%d\n", pipefds[0], pipefds[1]);
705  if (-1 == dup2(pipefds[1], 2 /*stderr*/)) {
706    owl_function_debugmsg("stderr_replace: dup2 FAILED (%s)\n", strerror(errno));
707    perror("dup2");
708    return -1;
709  }
710  return pipefds[0];
711}
712
713/* Sends stderr (read from rfd) messages to the error console */
714void stderr_redirect_handler(owl_dispatch *d)
715{
716  int navail, bread;
717  char buf[4096];
718  int rfd = d->fd;
719  char *err;
720
721  if (rfd<0) return;
722  if (-1 == ioctl(rfd, FIONREAD, (void*)&navail)) {
723    return;
724  }
725  /*owl_function_debugmsg("stderr_redirect: navail = %d\n", navail);*/
726  if (navail <= 0) return;
727  if (navail > sizeof(buf)-1) {
728    navail = sizeof(buf)-1;
729  }
730  bread = read(rfd, buf, navail);
731  if (buf[navail-1] != '\0') {
732    buf[navail] = '\0';
733  }
734
735  err = owl_sprintf("[stderr]\n%s", buf);
736
737  owl_function_log_err(err);
738}
739
740#endif /* OWL_STDERR_REDIR */
741
742void owl_zephyr_buddycheck_timer(owl_timer *t, void *data)
743{
744  if (owl_global_is_pseudologins(&g)) {
745    owl_function_debugmsg("Doing zephyr buddy check");
746    owl_function_zephyr_buddy_check(1);
747  }
748}
Note: See TracBrowser for help on using the repository browser.