source: owl.c @ 601a9e0

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