source: message.c @ 3f6555d

release-1.7release-1.8release-1.9
Last change on this file since 3f6555d was 3f6555d, checked in by David Benjamin <davidben@mit.edu>, 11 years ago
Punt obarray and friends in favor of g_intern_string It's somewhat faster (about 1.5x by completely unrigorous tests), and it's less code for us to maintain. Signed-off-by: David Benjamin <davidben@mit.edu>
  • Property mode set to 100644
File size: 23.6 KB
RevLine 
[7d4fbcd]1#include <stdlib.h>
[b45293f]2#include <unistd.h>
[7d4fbcd]3#include <string.h>
4#include <sys/socket.h>
5#include <netdb.h>
6#include <sys/types.h>
7#include <sys/socket.h>
8#include <netinet/in.h>
9#include <arpa/inet.h>
10#include <time.h>
11#include "owl.h"
[d564c3d]12#include "filterproc.h"
[7d4fbcd]13
[a387d12e]14static owl_fmtext_cache fmtext_cache[OWL_FMTEXT_CACHE_SIZE];
15static owl_fmtext_cache * fmtext_cache_next = fmtext_cache;
16
[c79a047]17void owl_message_init_fmtext_cache(void)
[a387d12e]18{
19    int i;
20    for(i = 0; i < OWL_FMTEXT_CACHE_SIZE; i++) {
21        owl_fmtext_init_null(&(fmtext_cache[i].fmtext));
22        fmtext_cache[i].message = NULL;
23    }
24}
25
[e9c6fc8]26static owl_fmtext_cache *owl_message_next_fmtext(void)
[a387d12e]27{
[ad15610]28    owl_fmtext_cache * f = fmtext_cache_next;
[a387d12e]29    if(fmtext_cache_next->message != NULL) {
30        owl_message_invalidate_format(fmtext_cache_next->message);
31    }
32    fmtext_cache_next++;
33    if(fmtext_cache_next - fmtext_cache == OWL_FMTEXT_CACHE_SIZE)
34        fmtext_cache_next = fmtext_cache;
35    return f;
36}
37
[0ff8fb57]38void owl_message_init(owl_message *m)
39{
[7d4fbcd]40  m->id=owl_global_get_nextmsgid(&g);
[4b464a4]41  owl_message_set_direction_none(m);
[7d4fbcd]42  m->delete=0;
43
[2d1feac]44  owl_message_set_hostname(m, "");
[d0d65df]45  owl_list_create(&(m->attributes));
46 
[7d4fbcd]47  /* save the time */
[25dd31a]48  m->time=time(NULL);
49  m->timestr=owl_strdup(ctime(&(m->time)));
50  m->timestr[strlen(m->timestr)-1]='\0';
51
[a387d12e]52  m->fmtext = NULL;
[4b464a4]53}
54
[5a95b69]55/* add the named attribute to the message.  If an attribute with the
56 * name already exists, replace the old value with the new value
57 */
[e19eb97]58void owl_message_set_attribute(owl_message *m, const char *attrname, const char *attrvalue)
[0ff8fb57]59{
[d0d65df]60  int i, j;
[e849734]61  owl_pair *p = NULL, *pair = NULL;
[d0d65df]62
[e849734]63  /* look for an existing pair with this key, */
[d0d65df]64  j=owl_list_get_size(&(m->attributes));
65  for (i=0; i<j; i++) {
66    p=owl_list_get_element(&(m->attributes), i);
67    if (!strcmp(owl_pair_get_key(p), attrname)) {
68      owl_free(owl_pair_get_value(p));
[e849734]69      pair = p;
[d0d65df]70      break;
71    }
72  }
73
[e849734]74  if(pair ==  NULL) {
75    pair = owl_malloc(sizeof(owl_pair));
[3f6555d]76    owl_pair_create(pair, g_intern_string(attrname), NULL);
[e849734]77    owl_list_append_element(&(m->attributes), pair);
78  }
[6201646]79  owl_pair_set_value(pair, owl_validate_or_convert(attrvalue));
[d0d65df]80}
81
[5a95b69]82/* return the value associated with the named attribute, or NULL if
83 * the attribute does not exist
84 */
[c08c70a]85const char *owl_message_get_attribute_value(const owl_message *m, const char *attrname)
[0ff8fb57]86{
[d0d65df]87  int i, j;
88  owl_pair *p;
89
90  j=owl_list_get_size(&(m->attributes));
91  for (i=0; i<j; i++) {
92    p=owl_list_get_element(&(m->attributes), i);
93    if (!strcmp(owl_pair_get_key(p), attrname)) {
94      return(owl_pair_get_value(p));
95    }
96  }
[f4d0975]97
98  /*
99  owl_function_debugmsg("No attribute %s found for message %i",
100                        attrname,
101                        owl_message_get_id(m));
102  */
[d0d65df]103  return(NULL);
104}
105
[5789230]106/* We cheat and indent it for now, since we really want this for
107 * the 'info' function.  Later there should just be a generic
108 * function to indent fmtext.
109 */
[c08c70a]110void owl_message_attributes_tofmtext(const owl_message *m, owl_fmtext *fm) {
[5789230]111  int i, j;
112  owl_pair *p;
113  char *buff;
114
115  owl_fmtext_init_null(fm);
116
117  j=owl_list_get_size(&(m->attributes));
118  for (i=0; i<j; i++) {
119    p=owl_list_get_element(&(m->attributes), i);
120    buff=owl_sprintf("  %-15.15s: %-35.35s\n", owl_pair_get_key(p), owl_pair_get_value(p));
[6711361]121    if(buff == NULL) {
122      buff=owl_sprintf("  %-15.15s: %-35.35s\n", owl_pair_get_key(p), "<error>");
123      if(buff == NULL)
124        buff=owl_strdup("   <error>\n");
125    }
[5789230]126    owl_fmtext_append_normal(fm, buff);
127    owl_free(buff);
128  }
129}
[4b464a4]130
[bd3f232]131void owl_message_invalidate_format(owl_message *m)
132{
[a387d12e]133  if(m->fmtext) {
134    m->fmtext->message = NULL;
135    owl_fmtext_clear(&(m->fmtext->fmtext));
136    m->fmtext=NULL;
137  }
[bd3f232]138}
139
[0ff8fb57]140owl_fmtext *owl_message_get_fmtext(owl_message *m)
141{
[f14a7ee]142  owl_message_format(m);
[a387d12e]143  return(&(m->fmtext->fmtext));
[f14a7ee]144}
145
146void owl_message_format(owl_message *m)
147{
[1fdab04]148  const owl_style *s;
[9e5c9f3]149  const owl_view *v;
[bd3f232]150
[a387d12e]151  if (!m->fmtext) {
152    m->fmtext = owl_message_next_fmtext();
153    m->fmtext->message = m;
[421c8ef7]154    /* for now we assume there's just the one view and use that style */
[ef56a67]155    v=owl_global_get_current_view(&g);
156    s=owl_view_get_style(v);
157
[a387d12e]158    owl_style_get_formattext(s, &(m->fmtext->fmtext), m);
[bd3f232]159  }
[4b464a4]160}
161
[e19eb97]162void owl_message_set_class(owl_message *m, const char *class)
[0ff8fb57]163{
[d0d65df]164  owl_message_set_attribute(m, "class", class);
[4b464a4]165}
166
[c08c70a]167const char *owl_message_get_class(const owl_message *m)
[0ff8fb57]168{
[e19eb97]169  const char *class;
[d0d65df]170
171  class=owl_message_get_attribute_value(m, "class");
172  if (!class) return("");
173  return(class);
[4b464a4]174}
175
[e19eb97]176void owl_message_set_instance(owl_message *m, const char *inst)
[0ff8fb57]177{
[d0d65df]178  owl_message_set_attribute(m, "instance", inst);
[4b464a4]179}
180
[c08c70a]181const char *owl_message_get_instance(const owl_message *m)
[0ff8fb57]182{
[e19eb97]183  const char *instance;
[d0d65df]184
185  instance=owl_message_get_attribute_value(m, "instance");
186  if (!instance) return("");
187  return(instance);
[4b464a4]188}
189
[e19eb97]190void owl_message_set_sender(owl_message *m, const char *sender)
[0ff8fb57]191{
[d0d65df]192  owl_message_set_attribute(m, "sender", sender);
[4b464a4]193}
194
[c08c70a]195const char *owl_message_get_sender(const owl_message *m)
[0ff8fb57]196{
[e19eb97]197  const char *sender;
[d0d65df]198
199  sender=owl_message_get_attribute_value(m, "sender");
200  if (!sender) return("");
201  return(sender);
[4b464a4]202}
203
[e19eb97]204void owl_message_set_zsig(owl_message *m, const char *zsig)
[0ff8fb57]205{
[d0d65df]206  owl_message_set_attribute(m, "zsig", zsig);
[b45293f]207}
208
[c08c70a]209const char *owl_message_get_zsig(const owl_message *m)
[0ff8fb57]210{
[e19eb97]211  const char *zsig;
[d0d65df]212
213  zsig=owl_message_get_attribute_value(m, "zsig");
214  if (!zsig) return("");
215  return(zsig);
[b45293f]216}
217
[e19eb97]218void owl_message_set_recipient(owl_message *m, const char *recip)
[0ff8fb57]219{
[d0d65df]220  owl_message_set_attribute(m, "recipient", recip);
[4b464a4]221}
222
[c08c70a]223const char *owl_message_get_recipient(const owl_message *m)
[0ff8fb57]224{
[4b464a4]225  /* this is stupid for outgoing messages, we need to fix it. */
[d0d65df]226
[e19eb97]227  const char *recip;
[0ff8fb57]228
229  recip=owl_message_get_attribute_value(m, "recipient");
[d0d65df]230  if (!recip) return("");
231  return(recip);
[4b464a4]232}
233
[7f6a8a2]234void owl_message_set_realm(owl_message *m, const char *realm)
[0ff8fb57]235{
[d0d65df]236  owl_message_set_attribute(m, "realm", realm);
[4b464a4]237}
238
[c08c70a]239const char *owl_message_get_realm(const owl_message *m)
[0ff8fb57]240{
[e19eb97]241  const char *realm;
[d0d65df]242 
243  realm=owl_message_get_attribute_value(m, "realm");
244  if (!realm) return("");
245  return(realm);
246}
247
[e19eb97]248void owl_message_set_body(owl_message *m, const char *body)
[0ff8fb57]249{
[d0d65df]250  owl_message_set_attribute(m, "body", body);
251}
252
[c08c70a]253const char *owl_message_get_body(const owl_message *m)
[0ff8fb57]254{
[e19eb97]255  const char *body;
[d0d65df]256
257  body=owl_message_get_attribute_value(m, "body");
258  if (!body) return("");
259  return(body);
[4b464a4]260}
261
[d0d65df]262
[e19eb97]263void owl_message_set_opcode(owl_message *m, const char *opcode)
[0ff8fb57]264{
[d0d65df]265  owl_message_set_attribute(m, "opcode", opcode);
[4b464a4]266}
267
[c08c70a]268const char *owl_message_get_opcode(const owl_message *m)
[0ff8fb57]269{
[e19eb97]270  const char *opcode;
[d0d65df]271
272  opcode=owl_message_get_attribute_value(m, "opcode");
273  if (!opcode) return("");
274  return(opcode);
[4b464a4]275}
276
[5789230]277
[d559df9]278void owl_message_set_islogin(owl_message *m)
[5789230]279{
[d559df9]280  owl_message_set_attribute(m, "loginout", "login");
281}
282
283
284void owl_message_set_islogout(owl_message *m)
285{
286  owl_message_set_attribute(m, "loginout", "logout");
[5789230]287}
288
[c08c70a]289int owl_message_is_loginout(const owl_message *m)
[5789230]290{
[e19eb97]291  const char *res;
[5789230]292
[d559df9]293  res=owl_message_get_attribute_value(m, "loginout");
[5789230]294  if (!res) return(0);
295  return(1);
296}
297
[c08c70a]298int owl_message_is_login(const owl_message *m)
[d559df9]299{
[e19eb97]300  const char *res;
[d559df9]301
302  res=owl_message_get_attribute_value(m, "loginout");
303  if (!res) return(0);
304  if (!strcmp(res, "login")) return(1);
305  return(0);
306}
307
308
[c08c70a]309int owl_message_is_logout(const owl_message *m)
[d559df9]310{
[e19eb97]311  const char *res;
[d559df9]312
313  res=owl_message_get_attribute_value(m, "loginout");
314  if (!res) return(0);
315  if (!strcmp(res, "logout")) return(1);
316  return(0);
317}
318
[5789230]319void owl_message_set_isprivate(owl_message *m)
320{
[312675c]321  owl_message_set_attribute(m, "isprivate", "true");
[5789230]322}
323
[c08c70a]324int owl_message_is_private(const owl_message *m)
[5789230]325{
[e19eb97]326  const char *res;
[5789230]327
328  res=owl_message_get_attribute_value(m, "isprivate");
329  if (!res) return(0);
[635881c]330  return !strcmp(res, "true");
[5789230]331}
332
[c08c70a]333const char *owl_message_get_timestr(const owl_message *m)
[0ff8fb57]334{
[25dd31a]335  if (m->timestr) return(m->timestr);
336  return("");
337}
338
[0ff8fb57]339void owl_message_set_type_admin(owl_message *m)
340{
[30678ae]341  owl_message_set_attribute(m, "type", "admin");
[4b464a4]342}
343
[37eab7f]344void owl_message_set_type_loopback(owl_message *m)
345{
[30678ae]346  owl_message_set_attribute(m, "type", "loopback");
[37eab7f]347}
348
[0ff8fb57]349void owl_message_set_type_zephyr(owl_message *m)
350{
[30678ae]351  owl_message_set_attribute(m, "type", "zephyr");
[4b464a4]352}
[d09e5a1]353
[0ff8fb57]354void owl_message_set_type_aim(owl_message *m)
355{
[e363375]356  owl_message_set_attribute(m, "type", "AIM");
[d09e5a1]357}
[dd16bdd]358
[e19eb97]359void owl_message_set_type(owl_message *m, const char* type)
[dd16bdd]360{
[30678ae]361  owl_message_set_attribute(m, "type", type);
362}
363
[c08c70a]364int owl_message_is_type(const owl_message *m, const char *type) {
[e19eb97]365  const char * t = owl_message_get_attribute_value(m, "type");
[30678ae]366  if(!t) return 0;
[e363375]367  return !strcasecmp(t, type);
[dd16bdd]368}
[4b464a4]369                                               
[c08c70a]370int owl_message_is_type_admin(const owl_message *m)
[0ff8fb57]371{
[30678ae]372  return owl_message_is_type(m, "admin");
[4b464a4]373}
374
[c08c70a]375int owl_message_is_type_zephyr(const owl_message *m)
[0ff8fb57]376{
[30678ae]377  return owl_message_is_type(m, "zephyr");
[4b464a4]378}
379
[c08c70a]380int owl_message_is_type_aim(const owl_message *m)
[0ff8fb57]381{
[30678ae]382  return owl_message_is_type(m, "aim");
[d09e5a1]383}
384
[30678ae]385/* XXX TODO: deprecate this */
[c08c70a]386int owl_message_is_type_jabber(const owl_message *m)
[5a95b69]387{
[30678ae]388  return owl_message_is_type(m, "jabber");
[421c8ef7]389}
390
[c08c70a]391int owl_message_is_type_loopback(const owl_message *m)
[421c8ef7]392{
[30678ae]393  return owl_message_is_type(m, "loopback");
[421c8ef7]394}
395
[c08c70a]396int owl_message_is_pseudo(const owl_message *m)
[421c8ef7]397{
398  if (owl_message_get_attribute_value(m, "pseudo")) return(1);
[4b464a4]399  return(0);
400}
401
[e19eb97]402const char *owl_message_get_text(owl_message *m)
[0ff8fb57]403{
[21f0a9d]404  owl_message_format(m);
[a387d12e]405  return(owl_fmtext_get_text(&(m->fmtext->fmtext)));
[4b464a4]406}
407
[0ff8fb57]408void owl_message_set_direction_in(owl_message *m)
409{
[4b464a4]410  m->direction=OWL_MESSAGE_DIRECTION_IN;
411}
412
[0ff8fb57]413void owl_message_set_direction_out(owl_message *m)
414{
[4b464a4]415  m->direction=OWL_MESSAGE_DIRECTION_OUT;
416}
417
[0ff8fb57]418void owl_message_set_direction_none(owl_message *m)
419{
[4b464a4]420  m->direction=OWL_MESSAGE_DIRECTION_NONE;
421}
422
[dd16bdd]423void owl_message_set_direction(owl_message *m, int direction)
424{
425  m->direction=direction;
426}
427
[c08c70a]428int owl_message_is_direction_in(const owl_message *m)
[0ff8fb57]429{
[4b464a4]430  if (m->direction==OWL_MESSAGE_DIRECTION_IN) return(1);
431  return(0);
432}
433
[c08c70a]434int owl_message_is_direction_out(const owl_message *m)
[0ff8fb57]435{
[4b464a4]436  if (m->direction==OWL_MESSAGE_DIRECTION_OUT) return(1);
437  return(0);
438}
439
[c08c70a]440int owl_message_is_direction_none(const owl_message *m)
[0ff8fb57]441{
[4b464a4]442  if (m->direction==OWL_MESSAGE_DIRECTION_NONE) return(1);
443  return(0);
444}
445
[0ff8fb57]446int owl_message_get_numlines(owl_message *m)
447{
[4b464a4]448  if (m == NULL) return(0);
[f14a7ee]449  owl_message_format(m);
[a387d12e]450  return(owl_fmtext_num_lines(&(m->fmtext->fmtext)));
[4b464a4]451}
452
[0ff8fb57]453void owl_message_mark_delete(owl_message *m)
454{
[4b464a4]455  if (m == NULL) return;
456  m->delete=1;
457}
458
[0ff8fb57]459void owl_message_unmark_delete(owl_message *m)
460{
[4b464a4]461  if (m == NULL) return;
462  m->delete=0;
463}
464
[c08c70a]465const char *owl_message_get_zwriteline(const owl_message *m)
[0ff8fb57]466{
[e19eb97]467  const char *z = owl_message_get_attribute_value(m, "zwriteline");
[147d880]468  if (!z) return "";
469  return z;
[4b464a4]470}
471
[e19eb97]472void owl_message_set_zwriteline(owl_message *m, const char *line)
[0ff8fb57]473{
[147d880]474  owl_message_set_attribute(m, "zwriteline", line);
[4b464a4]475}
476
[c08c70a]477int owl_message_is_delete(const owl_message *m)
[0ff8fb57]478{
[4b464a4]479  if (m == NULL) return(0);
480  if (m->delete==1) return(1);
481  return(0);
482}
483
[be0a79f]484#ifdef HAVE_LIBZEPHYR
[c08c70a]485const ZNotice_t *owl_message_get_notice(const owl_message *m)
[0ff8fb57]486{
[4b464a4]487  return(&(m->notice));
488}
[09489b89]489#else
[c08c70a]490void *owl_message_get_notice(const owl_message *m)
[09489b89]491{
492  return(NULL);
493}
[be0a79f]494#endif
[4b464a4]495
[e19eb97]496void owl_message_set_hostname(owl_message *m, const char *hostname)
[8298425]497{
[3f6555d]498  m->hostname = g_intern_string(hostname);
[8298425]499}
500
[c08c70a]501const char *owl_message_get_hostname(const owl_message *m)
[0ff8fb57]502{
[4b464a4]503  return(m->hostname);
504}
505
[8fa9562]506void owl_message_curs_waddstr(owl_message *m, WINDOW *win, int aline, int bline, int acol, int bcol, int fgcolor, int bgcolor)
[0ff8fb57]507{
[4b464a4]508  owl_fmtext a, b;
509
[bd3f232]510  /* this will ensure that our cached copy is up to date */
[f14a7ee]511  owl_message_format(m);
[bd3f232]512
[af2ca19]513  owl_fmtext_init_null(&a);
514  owl_fmtext_init_null(&b);
515 
[3a7cf49]516  owl_fmtext_truncate_lines(&(m->fmtext->fmtext), aline, bline-aline, &a);
[4b464a4]517  owl_fmtext_truncate_cols(&a, acol, bcol, &b);
[9866c3a]518  owl_fmtext_colorize(&b, fgcolor);
519  owl_fmtext_colorizebg(&b, bgcolor);
[4b464a4]520
[47519e1b]521  owl_fmtext_curs_waddstr(&b, win);
[4b464a4]522
[7ab0020]523  owl_fmtext_cleanup(&a);
524  owl_fmtext_cleanup(&b);
[4b464a4]525}
526
[c08c70a]527int owl_message_is_personal(const owl_message *m)
[0ff8fb57]528{
[4542047]529  const owl_filter * f = owl_global_get_filter(&g, "personal");
[ce74deb]530  if(!f) {
531      owl_function_error("personal filter is not defined");
532      return (0);
[0ff8fb57]533  }
[ce74deb]534  return owl_filter_message_match(f, m);
[0ff8fb57]535}
536
[c08c70a]537int owl_message_is_question(const owl_message *m)
[f4d32cd]538{
539  if(!owl_message_is_type_admin(m)) return 0;
540  if(owl_message_get_attribute_value(m, "question") != NULL) return 1;
541  return 0;
542}
543
[c08c70a]544int owl_message_is_answered(const owl_message *m) {
[e19eb97]545  const char *q;
[f4d32cd]546  if(!owl_message_is_question(m)) return 0;
[ad15610]547  q = owl_message_get_attribute_value(m, "question");
[f4d32cd]548  if(!q) return 0;
549  return !strcmp(q, "answered");
550}
551
552void owl_message_set_isanswered(owl_message *m) {
553  owl_message_set_attribute(m, "question", "answered");
554}
555
[c08c70a]556int owl_message_is_mail(const owl_message *m)
[0ff8fb57]557{
558  if (owl_message_is_type_zephyr(m)) {
[5789230]559    if (!strcasecmp(owl_message_get_class(m), "mail") && owl_message_is_private(m)) {
[0ff8fb57]560      return(1);
561    } else {
562      return(0);
563    }
[4b464a4]564  }
565  return(0);
566}
567
568/* caller must free return value. */
[c08c70a]569char *owl_message_get_cc(const owl_message *m)
[0ff8fb57]570{
[e19eb97]571  const char *cur;
[65b2173]572  char *out, *end;
[4b464a4]573
574  cur = owl_message_get_body(m);
575  while (*cur && *cur==' ') cur++;
[985f85b]576  if (strncasecmp(cur, "cc:", 3)) return(NULL);
[4b464a4]577  cur+=3;
578  while (*cur && *cur==' ') cur++;
579  out = owl_strdup(cur);
580  end = strchr(out, '\n');
581  if (end) end[0] = '\0';
582  return(out);
583}
584
[48609ce]585/* caller must free return value */
[c08c70a]586char *owl_message_get_cc_without_recipient(const owl_message *m)
[48609ce]587{
[65b2173]588  char *cc, *out, *end, *shortuser, *recip;
[e19eb97]589  const char *user;
[48609ce]590
591  cc = owl_message_get_cc(m);
[9c590d4]592  if (cc == NULL)
593    return NULL;
594
595  recip = short_zuser(owl_message_get_recipient(m));
[ce5d181]596  out = owl_malloc(strlen(cc) + 2);
[48609ce]597  end = out;
598
599  user = strtok(cc, " ");
600  while (user != NULL) {
[18108b1e]601    shortuser = short_zuser(user);
602    if (strcasecmp(shortuser, recip) != 0) {
[48609ce]603      strcpy(end, user);
604      end[strlen(user)] = ' ';
605      end += strlen(user) + 1;
606    }
[27f6487]607    owl_free(shortuser);
[48609ce]608    user = strtok(NULL, " ");
609  }
610  end[0] = '\0';
611
[9c590d4]612  owl_free(recip);
[48609ce]613  owl_free(cc);
[9c590d4]614
615  if (strlen(out) == 0) {
616    owl_free(out);
617    out = NULL;
618  }
619
[48609ce]620  return(out);
621}
622
[c08c70a]623int owl_message_get_id(const owl_message *m)
[0ff8fb57]624{
[4b464a4]625  return(m->id);
626}
[bd3f232]627
[c08c70a]628const char *owl_message_get_type(const owl_message *m) {
[e19eb97]629  const char * type = owl_message_get_attribute_value(m, "type");
[30678ae]630  if(!type) {
631    return "generic";
[dd16bdd]632  }
[30678ae]633  return type;
[dd16bdd]634}
635
[c08c70a]636const char *owl_message_get_direction(const owl_message *m) {
[f1e629d]637  switch (m->direction) {
638  case OWL_MESSAGE_DIRECTION_IN:
639    return("in");
640  case OWL_MESSAGE_DIRECTION_OUT:
641    return("out");
642  case OWL_MESSAGE_DIRECTION_NONE:
643    return("none");
644  default:
645    return("unknown");
646  }
647}
648
[e19eb97]649int owl_message_parse_direction(const char *d) {
[dd16bdd]650  if(!strcmp(d, "in")) {
651    return OWL_MESSAGE_DIRECTION_IN;
652  } else if(!strcmp(d, "out")) {
653    return OWL_MESSAGE_DIRECTION_OUT;
654  } else {
655    return OWL_MESSAGE_DIRECTION_NONE;
656  }
657}
658
659
[c08c70a]660const char *owl_message_get_login(const owl_message *m) {
[f1e629d]661  if (owl_message_is_login(m)) {
662    return "login";
663  } else if (owl_message_is_logout(m)) {
664    return "logout";
665  } else {
666    return "none";
667  }
668}
669
[dd16bdd]670
[c08c70a]671const char *owl_message_get_header(const owl_message *m) {
[f1e629d]672  return owl_message_get_attribute_value(m, "adminheader");
673}
674
[bd3f232]675/* return 1 if the message contains "string", 0 otherwise.  This is
676 * case insensitive because the functions it uses are
677 */
[89b2daf]678int owl_message_search(owl_message *m, const owl_regex *re)
[0ff8fb57]679{
[4b464a4]680
[f14a7ee]681  owl_message_format(m); /* is this necessary? */
[bd3f232]682 
[41c9a96]683  return (owl_fmtext_search(&(m->fmtext->fmtext), re));
[4b464a4]684}
685
686
[d559df9]687/* if loginout == -1 it's a logout message
688 *                 0 it's not a login/logout message
689 *                 1 it's a login message
690 */
[e19eb97]691void owl_message_create_aim(owl_message *m, const char *sender, const char *recipient, const char *text, int direction, int loginout)
[0ff8fb57]692{
[d09e5a1]693  owl_message_init(m);
694  owl_message_set_body(m, text);
695  owl_message_set_sender(m, sender);
[440ce01]696  owl_message_set_recipient(m, recipient);
[d09e5a1]697  owl_message_set_type_aim(m);
[3abf28b]698
[d559df9]699  if (direction==OWL_MESSAGE_DIRECTION_IN) {
700    owl_message_set_direction_in(m);
701  } else if (direction==OWL_MESSAGE_DIRECTION_OUT) {
702    owl_message_set_direction_out(m);
[3abf28b]703  }
704
[d559df9]705  /* for now all messages that aren't loginout are private */
706  if (!loginout) {
707    owl_message_set_isprivate(m);
708  }
[3abf28b]709
[d559df9]710  if (loginout==-1) {
711    owl_message_set_islogout(m);
712  } else if (loginout==1) {
713    owl_message_set_islogin(m);
714  }
[aa5f725]715}
716
[e19eb97]717void owl_message_create_admin(owl_message *m, const char *header, const char *text)
[0ff8fb57]718{
[d0d65df]719  owl_message_init(m);
[4b464a4]720  owl_message_set_type_admin(m);
[d0d65df]721  owl_message_set_body(m, text);
[bd3f232]722  owl_message_set_attribute(m, "adminheader", header); /* just a hack for now */
[7d4fbcd]723}
724
[37eab7f]725/* caller should set the direction */
[e19eb97]726void owl_message_create_loopback(owl_message *m, const char *text)
[37eab7f]727{
728  owl_message_init(m);
729  owl_message_set_type_loopback(m);
730  owl_message_set_body(m, text);
[eec69e1]731  owl_message_set_sender(m, "loopsender");
732  owl_message_set_recipient(m, "looprecip");
[37eab7f]733  owl_message_set_isprivate(m);
734}
735
[09489b89]736#ifdef HAVE_LIBZEPHYR
[1077891a]737void owl_message_create_from_znotice(owl_message *m, const ZNotice_t *n)
[0ff8fb57]738{
[ba88ae7]739#ifdef ZNOTICE_SOCKADDR
740  char hbuf[NI_MAXHOST];
741#else /* !ZNOTICE_SOCKADDR */
[7d4fbcd]742  struct hostent *hent;
[ba88ae7]743#endif /* ZNOTICE_SOCKADDR */
[e19eb97]744  const char *ptr;
[65b2173]745  char *tmp, *tmp2;
[804ab8a]746  int len;
[7d4fbcd]747
[d0d65df]748  owl_message_init(m);
749 
[4b464a4]750  owl_message_set_type_zephyr(m);
751  owl_message_set_direction_in(m);
[7d4fbcd]752 
753  /* first save the full notice */
[66a8cd6]754  m->notice = *n;
[7d4fbcd]755
[25dd31a]756  /* a little gross, we'll replace \r's with ' ' for now */
[7d4fbcd]757  owl_zephyr_hackaway_cr(&(m->notice));
758 
[25dd31a]759  /* save the time, we need to nuke the string saved by message_init */
[5a95b69]760  if (m->timestr) owl_free(m->timestr);
[25dd31a]761  m->time=n->z_time.tv_sec;
762  m->timestr=owl_strdup(ctime(&(m->time)));
763  m->timestr[strlen(m->timestr)-1]='\0';
764
[7d4fbcd]765  /* set other info */
[d0d65df]766  owl_message_set_sender(m, n->z_sender);
767  owl_message_set_class(m, n->z_class);
768  owl_message_set_instance(m, n->z_class_inst);
769  owl_message_set_recipient(m, n->z_recipient);
[7d4fbcd]770  if (n->z_opcode) {
[d0d65df]771    owl_message_set_opcode(m, n->z_opcode);
[7d4fbcd]772  } else {
[d0d65df]773    owl_message_set_opcode(m, "");
[7d4fbcd]774  }
[804ab8a]775  owl_message_set_zsig(m, owl_zephyr_get_zsig(n, &len));
[7d4fbcd]776
777  if ((ptr=strchr(n->z_recipient, '@'))!=NULL) {
[d0d65df]778    owl_message_set_realm(m, ptr+1);
[7d4fbcd]779  } else {
[09489b89]780    owl_message_set_realm(m, owl_zephyr_get_realm());
[7d4fbcd]781  }
782
[5789230]783  /* Set the "isloginout" attribute if it's a login message */
[1d3e925]784  if (!strcasecmp(n->z_class, "login") || !strcasecmp(n->z_class, OWL_WEBZEPHYR_CLASS)) {
[5a95b69]785    if (!strcasecmp(n->z_opcode, "user_login") || !strcasecmp(n->z_opcode, "user_logout")) {
[b0430a6]786      tmp=owl_zephyr_get_field(n, 1);
[5a95b69]787      owl_message_set_attribute(m, "loginhost", tmp);
788      owl_free(tmp);
789
[b0430a6]790      tmp=owl_zephyr_get_field(n, 3);
[5a95b69]791      owl_message_set_attribute(m, "logintty", tmp);
792      owl_free(tmp);
793    }
794
[d559df9]795    if (!strcasecmp(n->z_opcode, "user_login")) {
796      owl_message_set_islogin(m);
797    } else if (!strcasecmp(n->z_opcode, "user_logout")) {
798      owl_message_set_islogout(m);
799    }
[5789230]800  }
801
[5a95b69]802 
[963542b]803  /* set the "isprivate" attribute if it's a private zephyr.
[ce74deb]804   ``private'' means recipient is non-empty and doesn't start wit
805   `@' */
[963542b]806  if (*n->z_recipient && *n->z_recipient != '@') {
[5789230]807    owl_message_set_isprivate(m);
808  }
809
[9854278]810  /* set the "isauto" attribute if it's an autoreply */
811  if (!strcasecmp(n->z_message, "Automated reply:") ||
812      !strcasecmp(n->z_opcode, "auto")) {
813    owl_message_set_attribute(m, "isauto", "");
814  }
815
[85d1795]816  /* save the hostname */
[ba88ae7]817#ifdef ZNOTICE_SOCKADDR
818  owl_function_debugmsg("About to do getnameinfo");
819  if (getnameinfo(&n->z_sender_sockaddr.sa, sizeof(n->z_sender_sockaddr), hbuf, sizeof(hbuf), NULL, 0, 0) == 0)
820    owl_message_set_hostname(m, hbuf);
821#else /* !ZNOTICE_SOCKADDR */
[85d1795]822  owl_function_debugmsg("About to do gethostbyaddr");
[ba88ae7]823  hent = gethostbyaddr(&n->z_uid.zuid_addr, sizeof(n->z_uid.zuid_addr), AF_INET);
824  if (hent && hent->h_name)
[85d1795]825    owl_message_set_hostname(m, hent->h_name);
[ba88ae7]826  else
[85d1795]827    owl_message_set_hostname(m, inet_ntoa(n->z_sender_addr));
[ba88ae7]828#endif /* ZNOTICE_SOCKADDR */
[85d1795]829
[b45293f]830  /* set the body */
[85d1795]831  tmp=owl_zephyr_get_message(n, m);
[7e3e00a]832  if (owl_global_is_newlinestrip(&g)) {
[d0d65df]833    tmp2=owl_util_stripnewlines(tmp);
834    owl_message_set_body(m, tmp2);
835    owl_free(tmp2);
[7e3e00a]836  } else {
[d0d65df]837    owl_message_set_body(m, tmp);
[7e3e00a]838  }
[ecd5dc5]839  owl_free(tmp);
[7d4fbcd]840
[d309eb3]841  /* if zcrypt is enabled try to decrypt the message */
842  if (owl_global_is_zcrypt(&g) && !strcasecmp(n->z_opcode, "crypt")) {
[d564c3d]843    const char *argv[] = {
844      "zcrypt",
845      "-D",
846      "-c", owl_message_get_class(m),
847      "-i", owl_message_get_instance(m),
848      NULL
849    };
850    char *out;
851    int rv;
852    int status;
[9a7b4f2]853    char *zcrypt;
[d564c3d]854
[9a7b4f2]855    zcrypt = owl_sprintf("%s/zcrypt", owl_get_bindir());
856
857    rv = call_filter(zcrypt, argv, owl_message_get_body(m), &out, &status);
858    owl_free(zcrypt);
[d564c3d]859
860    if(!rv && !status) {
861      int len = strlen(out);
862      if(len >= 8 && !strcmp(out + len - 8, "**END**\n")) {
863        out[len - 8] = 0;
864      }
[d0d65df]865      owl_message_set_body(m, out);
[dacb555]866      owl_free(out);
[d564c3d]867    } else if(out) {
868      owl_free(out);
[dacb555]869    }
[d309eb3]870  }
[7d4fbcd]871}
[09489b89]872#else
[1077891a]873void owl_message_create_from_znotice(owl_message *m, const void *n)
[09489b89]874{
875}
876#endif
[7d4fbcd]877
[5a95b69]878/* If 'direction' is '0' it is a login message, '1' is a logout message. */
[e19eb97]879void owl_message_create_pseudo_zlogin(owl_message *m, int direction, const char *user, const char *host, const char *time, const char *tty)
[5a95b69]880{
[65b2173]881  char *longuser;
[e19eb97]882  const char *ptr;
[5a95b69]883
[ba9f236]884#ifdef HAVE_LIBZEPHYR
[5a95b69]885  memset(&(m->notice), 0, sizeof(ZNotice_t));
[ba9f236]886#endif
887 
[5a95b69]888  longuser=long_zuser(user);
889 
890  owl_message_init(m);
891 
892  owl_message_set_type_zephyr(m);
893  owl_message_set_direction_in(m);
894
895  owl_message_set_attribute(m, "pseudo", "");
896  owl_message_set_attribute(m, "loginhost", host ? host : "");
897  owl_message_set_attribute(m, "logintty", tty ? tty : "");
898
899  owl_message_set_sender(m, longuser);
900  owl_message_set_class(m, "LOGIN");
901  owl_message_set_instance(m, longuser);
902  owl_message_set_recipient(m, "");
903  if (direction==0) {
904    owl_message_set_opcode(m, "USER_LOGIN");
905    owl_message_set_islogin(m);
906  } else if (direction==1) {
907    owl_message_set_opcode(m, "USER_LOGOUT");
908    owl_message_set_islogout(m);
909  }
910
911  if ((ptr=strchr(longuser, '@'))!=NULL) {
912    owl_message_set_realm(m, ptr+1);
913  } else {
914    owl_message_set_realm(m, owl_zephyr_get_realm());
915  }
916
917  owl_message_set_body(m, "<uninitialized>");
918
919  /* save the hostname */
[2de4f20]920  owl_function_debugmsg("create_pseudo_login: host is %s", host ? host : "");
[8298425]921  owl_message_set_hostname(m, host ? host : "");
[5a95b69]922  owl_free(longuser);
923}
924
[24ccc01]925void owl_message_create_from_zwrite(owl_message *m, const owl_zwrite *z, const char *body)
[0ff8fb57]926{
[b45293f]927  int ret;
[8298425]928  char hostbuff[5000];
[b45293f]929 
[d0d65df]930  owl_message_init(m);
[b45293f]931
932  /* set things */
933  owl_message_set_direction_out(m);
934  owl_message_set_type_zephyr(m);
[09489b89]935  owl_message_set_sender(m, owl_zephyr_get_sender());
[24ccc01]936  owl_message_set_class(m, owl_zwrite_get_class(z));
937  owl_message_set_instance(m, owl_zwrite_get_instance(z));
938  if (owl_zwrite_get_numrecips(z)>0) {
939    char *longzuser = long_zuser(owl_zwrite_get_recip_n(z, 0));
[9ceee9d]940    owl_message_set_recipient(m,
[7d471c3]941                              longzuser); /* only gets the first user, must fix */
942    owl_free(longzuser);
[9ceee9d]943  }
[24ccc01]944  owl_message_set_opcode(m, owl_zwrite_get_opcode(z));
945  owl_message_set_realm(m, owl_zwrite_get_realm(z)); /* also a hack, but not here */
946  if(z->zwriteline) {
947    owl_message_set_zwriteline(m, z->zwriteline);
948  }
[d0d65df]949  owl_message_set_body(m, body);
[24ccc01]950  owl_message_set_zsig(m, owl_zwrite_get_zsig(z));
[b45293f]951 
952  /* save the hostname */
[8298425]953  ret=gethostname(hostbuff, MAXHOSTNAMELEN);
954  hostbuff[MAXHOSTNAMELEN]='\0';
[b45293f]955  if (ret) {
[8298425]956    owl_message_set_hostname(m, "localhost");
957  } else {
958    owl_message_set_hostname(m, hostbuff);
[b45293f]959  }
[312675c]960
[ce74deb]961  /* set the "isprivate" attribute if it's a private zephyr. */
[24ccc01]962  if (owl_zwrite_is_personal(z)) {
[312675c]963    owl_message_set_isprivate(m);
[ce74deb]964  }
[b45293f]965}
[7d4fbcd]966
[a44cd91]967void owl_message_cleanup(owl_message *m)
[0ff8fb57]968{
[d0d65df]969  int i, j;
970  owl_pair *p;
[09489b89]971#ifdef HAVE_LIBZEPHYR   
[4b464a4]972  if (owl_message_is_type_zephyr(m) && owl_message_is_direction_in(m)) {
[7d4fbcd]973    ZFreeNotice(&(m->notice));
974  }
[09489b89]975#endif
[25dd31a]976  if (m->timestr) owl_free(m->timestr);
[d0d65df]977
978  /* free all the attributes */
979  j=owl_list_get_size(&(m->attributes));
980  for (i=0; i<j; i++) {
981    p=owl_list_get_element(&(m->attributes), i);
982    owl_free(owl_pair_get_value(p));
983    owl_free(p);
984  }
985
[5e5f08f]986  owl_list_cleanup(&(m->attributes), NULL);
[7d4fbcd]987 
[a387d12e]988  owl_message_invalidate_format(m);
[7d4fbcd]989}
[91634ec]990
991void owl_message_delete(owl_message *m)
992{
[a44cd91]993  owl_message_cleanup(m);
[91634ec]994  owl_free(m);
995}
Note: See TracBrowser for help on using the repository browser.