source: owl.c @ c01e477

barnowl_perlaimdebianowlrelease-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since c01e477 was 4b464a4, checked in by James M. Kretchmar <kretch@mit.edu>, 19 years ago
Messages now have a direciton (in, out or none). Filters can this direction Outbound messages are no longer type 'admin' but are of the appropriate message type (i.e. 'zephyr') and are direction 'out'. Smartnarrow now works on outgoing messages 'info' updated to show more information for admin and outgoing messages Renamed pretty_sender to short_zuser and renamed long_sender to long_zuser
  • Property mode set to 100644
File size: 11.8 KB
Line 
1/* Written by James Kretchmar, MIT
2 *
3 * Copyright 2001 Massachusetts Institute of Technology
4 *
5 * Permission to use, copy, modify, and distribute this software and
6 * its documentation for any purpose and without fee is hereby
7 * granted, provided that the above copyright notice and this
8 * permission notice appear in all copies and in supporting
9 * documentation.  No representation is made about the suitability of
10 * this software for any purpose.  It is provided "as is" without
11 * express or implied warranty.
12 */
13
14#include <stdio.h>
15#include <unistd.h>
16#include <stdlib.h>
17#include <string.h>
18#include <zephyr/zephyr.h>
19#include <com_err.h>
20#include <signal.h>
21#include <sys/param.h>
22#include "owl.h"
23
24static const char fileIdent[] = "$Id$";
25
26int main(int argc, char **argv, char **env) {
27  WINDOW *recwin, *sepwin, *typwin, *msgwin;
28  owl_editwin *tw;
29  owl_popwin *pw;
30  int j, ret, initialsubs, debug, newzephyrs, argcsave, followlast;
31  struct sigaction sigact;
32  char *configfile, *tty, *perlout;
33  char buff[LINE], startupmsg[LINE];
34  char **argvsave;
35  owl_filter *f;
36  time_t nexttime;
37  int nexttimediff;
38
39  argcsave=argc;
40  argvsave=argv;
41  configfile=NULL;
42  tty=NULL;
43  debug=0;
44  if (argc>0) {
45    argv++;
46    argc--;
47  }
48  while (argc>0) {
49    if (!strcmp(argv[0], "-n")) {
50      initialsubs=0;
51      argv++;
52      argc--;
53    } else if (!strcmp(argv[0], "-c")) {
54      if (argc<2) {
55        fprintf(stderr, "Too few arguments to -c\n");
56        usage();
57        exit(1);
58      }
59      configfile=argv[1];
60      argv+=2;
61      argc-=2;
62    } else if (!strcmp(argv[0], "-t")) {
63      if (argc<2) {
64        fprintf(stderr, "Too few arguments to -t\n");
65        usage();
66        exit(1);
67      }
68      tty=argv[1];
69      argv+=2;
70      argc-=2;
71    } else if (!strcmp(argv[0], "-d")) {
72      debug=1;
73      argv++;
74      argc--;
75    } else if (!strcmp(argv[0], "-v")) {
76      printf("This is owl version %s\n", OWL_VERSION_STRING);
77      exit(0);
78    } else {
79      fprintf(stderr, "Uknown argument\n");
80      usage();       
81      exit(1);
82    }
83  }
84
85  /* zephyr init */
86  if ((ret = ZInitialize()) != ZERR_NONE) {
87    com_err("owl",ret,"while initializing");
88    exit(1);
89  }
90  if ((ret = ZOpenPort(NULL)) != ZERR_NONE) {
91    com_err("owl",ret,"while opening port");
92    exit(1);
93  }
94
95  /* signal handler */
96  sigact.sa_handler=sig_handler;
97  sigemptyset(&sigact.sa_mask);
98  sigact.sa_flags=0;
99  sigaction(SIGWINCH, &sigact, NULL);
100  sigaction(SIGALRM, &sigact, NULL);
101
102  /* screen init */
103  sprintf(buff, "TERMINFO=%s", TERMINFO);
104  putenv(buff);
105  initscr();
106  start_color();
107  use_default_colors();
108  raw();
109  noecho();
110
111#if 0 /* Removed to prevent flashing of popwin */
112  intrflush(stdscr,FALSE);
113  keypad(stdscr,TRUE);
114  nodelay(stdscr,1);
115  meta(stdscr,TRUE);
116#endif /*0*/
117
118  /* define simple color pairs */
119  if (has_colors() && COLOR_PAIRS>=8) {
120    init_pair(OWL_COLOR_BLACK,   COLOR_BLACK,   -1);
121    init_pair(OWL_COLOR_RED,     COLOR_RED,     -1);
122    init_pair(OWL_COLOR_GREEN,   COLOR_GREEN,   -1);
123    init_pair(OWL_COLOR_YELLOW,  COLOR_YELLOW,  -1);
124    init_pair(OWL_COLOR_BLUE,    COLOR_BLUE,    -1);
125    init_pair(OWL_COLOR_MAGENTA, COLOR_MAGENTA, -1);
126    init_pair(OWL_COLOR_CYAN,    COLOR_CYAN,    -1);
127    init_pair(OWL_COLOR_WHITE,   COLOR_WHITE,   -1);
128  }
129   
130  /* owl init */
131  owl_global_init(&g);
132  if (debug) owl_global_set_debug_on(&g);
133  owl_global_set_startupargs(&g, argcsave, argvsave);
134  owl_global_set_tty(&g, tty);
135  owl_context_set_readconfig(owl_global_get_context(&g));
136
137  /* setup the default filters */
138  f=malloc(sizeof(owl_filter));
139  owl_filter_init_fromstring(f, "personal", "( class ^message$ and instance ^personal$ ) or ( type ^admin$ and recipient .+ )"); /* fix to use admintype */
140  owl_list_append_element(owl_global_get_filterlist(&g), f);
141
142  f=malloc(sizeof(owl_filter));
143  owl_filter_init_fromstring(f, "trash", "class ^mail$ or opcode ^ping$ or type ^admin$ or class ^login$");
144  owl_list_append_element(owl_global_get_filterlist(&g), f);
145
146  f=malloc(sizeof(owl_filter));
147  owl_filter_init_fromstring(f, "ping", "opcode ^ping$");
148  owl_list_append_element(owl_global_get_filterlist(&g), f);
149
150  f=malloc(sizeof(owl_filter));
151  owl_filter_init_fromstring(f, "auto", "opcode ^auto$");
152  owl_list_append_element(owl_global_get_filterlist(&g), f);
153
154  f=malloc(sizeof(owl_filter));
155  owl_filter_init_fromstring(f, "login", "class ^login$");
156  owl_list_append_element(owl_global_get_filterlist(&g), f);
157
158  f=malloc(sizeof(owl_filter));
159  owl_filter_init_fromstring(f, "reply-lockout", "class ^noc or class ^mail$");
160  owl_list_append_element(owl_global_get_filterlist(&g), f);
161
162  f=malloc(sizeof(owl_filter));
163  owl_filter_init_fromstring(f, "all", "class .*");
164  owl_list_append_element(owl_global_get_filterlist(&g), f);
165
166  /* set the current view */
167  owl_view_create(owl_global_get_current_view(&g), f);
168
169  /* read the config file */
170  ret=owl_readconfig(configfile);
171  if (ret) {
172    endwin();
173    printf("\nError parsing configfile\n");
174    exit(1);
175  }
176  perlout = owl_config_execute("owl::startup();");
177  if (perlout) owl_free(perlout);
178  owl_function_debugmsg("-- Owl Startup --");
179 
180  /* hold on to the window names for convenience */
181  msgwin=owl_global_get_curs_msgwin(&g);
182  recwin=owl_global_get_curs_recwin(&g);
183  sepwin=owl_global_get_curs_sepwin(&g);
184  typwin=owl_global_get_curs_typwin(&g);
185
186  tw=owl_global_get_typwin(&g);
187
188  wrefresh(sepwin);
189
190  /* load zephyr subs */
191  ret=owl_zephyr_loadsubs(NULL);
192  if (ret!=-1) {
193    owl_global_add_userclue(&g, OWL_USERCLUE_CLASSES);
194  }
195
196  /* load login subs */
197  if (owl_global_is_loginsubs(&g)) {
198    loadloginsubs(NULL);
199  }
200
201  /* zlog in if we need to */
202  if (owl_global_is_startuplogin(&g)) {
203    owl_function_zlog_in();
204  }
205
206  /* welcome message */
207  sprintf(buff, "Welcome to owl version %s.\n", OWL_VERSION_STRING);
208  strcpy(startupmsg, "-------------------------------------------------------------------------\n");
209  strcat(startupmsg, buff);
210  strcat(startupmsg, "Press 'h' for on line help.                                   ^ ^        \n");
211  strcat(startupmsg, "                                                              OvO        \n");
212  strcat(startupmsg, "Please report any bugs or suggestions to bug-owl@mit.edu     (   )       \n");
213  strcat(startupmsg, "--------------------------------------------------------------m-m--------\n");
214 
215  owl_function_adminmsg("", startupmsg);
216  /* owl_function_makemsg(buff); */
217  sepbar(NULL);
218 
219  owl_context_set_interactive(owl_global_get_context(&g));
220
221  nexttimediff=20;
222  nexttime=time(NULL);
223
224  /* main loop */
225  while (1) {
226
227    /* if a resize has been scheduled, deal with it */
228    owl_global_resize(&g, 0, 0);
229
230    /* these are here in case a resize changes the windows */
231    msgwin=owl_global_get_curs_msgwin(&g);
232    recwin=owl_global_get_curs_recwin(&g);
233    sepwin=owl_global_get_curs_sepwin(&g);
234    typwin=owl_global_get_curs_typwin(&g);
235
236    followlast=owl_global_should_followlast(&g);
237
238    /* little hack */
239    if (0 && owl_global_get_runtime(&g)<300) {
240      if (time(NULL)>nexttime) {
241        if (nexttimediff==1) {
242          nexttimediff=20;
243        } else {
244          nexttimediff=1;
245        }
246        nexttime+=nexttimediff;
247        owl_hack_animate();
248      }
249    }
250
251    /* grab incoming zephyrs */
252    newzephyrs=0;
253    while(ZPending()) {
254      ZNotice_t notice;
255      struct sockaddr_in from;
256      owl_message *m;
257
258      ZReceiveNotice(&notice, &from);
259
260      /* is this an ack from a zephyr we sent? */
261      if (owl_zephyr_notice_is_ack(&notice)) {
262        owl_zephyr_handle_ack(&notice);
263        continue;
264      }
265     
266      /* if it's a ping and we're not viewing pings then skip it */
267      if (!owl_global_is_rxping(&g) && !strcasecmp(notice.z_opcode, "ping")) {
268        continue;
269      }
270
271      /* create the new message */
272      m=owl_malloc(sizeof(owl_message));
273      owl_message_create_from_zephyr(m, &notice);
274     
275      /* if it's on the puntlist then, nuke it and continue */
276      if (owl_global_message_is_puntable(&g, m)) {
277        owl_message_free(m);
278        continue;
279      }
280
281      /* otherwise add it to the global list */
282      owl_messagelist_append_element(owl_global_get_msglist(&g), m);
283      newzephyrs=1;
284
285      /* let the config know the new message has been received */
286      owl_config_getmsg(m, 0);
287
288      /* add it to any necessary views; right now there's only the current view */
289      owl_view_consider_message(owl_global_get_current_view(&g), m);
290
291      /* do we need to autoreply? */
292      if (owl_global_is_zaway(&g)) {
293        owl_zephyr_zaway(m);
294      }
295
296      /* ring the bell if it's a personal */
297      if (owl_global_is_personalbell(&g) && owl_message_is_personal(m)) {
298        owl_function_beep();
299        owl_global_set_needrefresh(&g);
300      }
301
302      /* check for burning ears message */
303      /* this is an unsupported feature */
304      if (owl_global_is_burningears(&g) && owl_message_is_burningears(m)) {
305        char *buff;
306        buff = owl_sprintf("@i(Burning ears message on class %s)", owl_message_get_class(m));
307        /* owl_function_makemsg(buff); */
308        owl_function_adminmsg(buff, "");
309        owl_free(buff);
310        owl_function_beep();
311      }
312
313      /* log the zephyr if we need to */
314      if (owl_global_is_logging(&g) || owl_global_is_classlogging(&g)) {
315        owl_log_incoming(m);
316      }
317    }
318
319    /* follow the last message if we're supposed to */
320    if (newzephyrs && followlast) {
321      owl_function_lastmsg_noredisplay();
322    }
323   
324    /* redisplay if necessary */
325    if (newzephyrs) {
326      owl_mainwin_redisplay(owl_global_get_mainwin(&g));
327      sepbar(NULL);
328      if (owl_popwin_is_active(owl_global_get_popwin(&g))) {
329        owl_popwin_refresh(owl_global_get_popwin(&g));
330        /* TODO: this is a broken kludge */
331        if (owl_global_get_viewwin(&g)) {
332          owl_viewwin_redisplay(owl_global_get_viewwin(&g), 0);
333        }
334      }
335      owl_global_set_needrefresh(&g);
336    }
337
338    /* if a popwin just came up, refresh it */
339    pw=owl_global_get_popwin(&g);
340    if (owl_popwin_is_active(pw) && owl_popwin_needs_first_refresh(pw)) {
341      owl_popwin_refresh(pw);
342      owl_popwin_no_needs_first_refresh(pw);
343      owl_global_set_needrefresh(&g);
344      /* TODO: this is a broken kludge */
345      if (owl_global_get_viewwin(&g)) {
346        owl_viewwin_redisplay(owl_global_get_viewwin(&g), 0);
347      }
348    }
349
350    /* update the terminal if we need to */
351    if (owl_global_is_needrefresh(&g)) {
352      /* leave the cursor in the appropriate window */
353      if (owl_global_is_typwin_active(&g)) {
354        owl_function_set_cursor(typwin);
355      } else {
356        owl_function_set_cursor(sepwin);
357      }
358      doupdate();
359      owl_global_set_noneedrefresh(&g);
360    }
361
362    /* handle all keypresses */
363    j=wgetch(typwin);
364    if (j==ERR) {
365      usleep(10);
366      continue;
367    }
368    /* find and activate the current keymap.
369     * TODO: this should really get fixed by activating
370     * keymaps as we switch between windows...
371     */
372    if (pw && owl_popwin_is_active(pw) && owl_global_get_viewwin(&g)) {
373      owl_context_set_popless(owl_global_get_context(&g), 
374                              owl_global_get_viewwin(&g));
375      owl_function_activate_keymap("popless");
376    } else if (owl_global_is_typwin_active(&g) 
377               && owl_editwin_get_style(tw)==OWL_EDITWIN_STYLE_ONELINE) {
378      owl_context_set_editline(owl_global_get_context(&g), tw);
379      owl_function_activate_keymap("editline");
380    } else if (owl_global_is_typwin_active(&g) 
381               && owl_editwin_get_style(tw)==OWL_EDITWIN_STYLE_MULTILINE) {
382      owl_context_set_editmulti(owl_global_get_context(&g), tw);
383      owl_function_activate_keymap("editmulti");
384    } else {
385      owl_context_set_recv(owl_global_get_context(&g));
386      owl_function_activate_keymap("recv");
387    }
388    /* now actually handle the keypress */
389    ret = owl_keyhandler_process(owl_global_get_keyhandler(&g), j);
390    if (ret!=0 && ret!=1) {
391      owl_function_makemsg("Unable to handle keypress");
392    }
393  }
394
395}
396
397void sig_handler(int sig) {
398  if (sig==SIGWINCH) {
399    /* we can't inturrupt a malloc here, so it just sets a flag */
400    owl_function_resize();
401  }
402}
403
404void usage() {
405  fprintf(stderr, "Usage: owl [-n] [-d] [-v] [-c <configfile>] [-t <ttyname>]\n");
406}
Note: See TracBrowser for help on using the repository browser.