source: message.c @ ecaec21

release-1.10release-1.7release-1.8release-1.9
Last change on this file since ecaec21 was 4727d31, checked in by Nelson Elhage <nelhage@mit.edu>, 14 years ago
Cache Zephyr CCs into an attribute on the message object.
  • Property mode set to 100644
File size: 24.4 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));
76    owl_pair_create(pair, owl_global_intern(&g, attrname), NULL);
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{
[e849734]498  m->hostname=owl_global_intern(&g, 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 */
[839697d]586GList *owl_message_get_cc_without_recipient(const owl_message *m)
[48609ce]587{
[839697d]588  char *cc, *shortuser, *recip;
[e19eb97]589  const char *user;
[839697d]590  GList *out = NULL;
[48609ce]591
592  cc = owl_message_get_cc(m);
[9c590d4]593  if (cc == NULL)
594    return NULL;
595
596  recip = short_zuser(owl_message_get_recipient(m));
[48609ce]597
598  user = strtok(cc, " ");
599  while (user != NULL) {
[18108b1e]600    shortuser = short_zuser(user);
601    if (strcasecmp(shortuser, recip) != 0) {
[839697d]602      out = g_list_prepend(out, owl_strdup(user));
[48609ce]603    }
[27f6487]604    owl_free(shortuser);
[48609ce]605    user = strtok(NULL, " ");
606  }
607
[9c590d4]608  owl_free(recip);
[48609ce]609  owl_free(cc);
[9c590d4]610
[48609ce]611  return(out);
612}
613
[c08c70a]614int owl_message_get_id(const owl_message *m)
[0ff8fb57]615{
[4b464a4]616  return(m->id);
617}
[bd3f232]618
[c08c70a]619const char *owl_message_get_type(const owl_message *m) {
[e19eb97]620  const char * type = owl_message_get_attribute_value(m, "type");
[30678ae]621  if(!type) {
622    return "generic";
[dd16bdd]623  }
[30678ae]624  return type;
[dd16bdd]625}
626
[c08c70a]627const char *owl_message_get_direction(const owl_message *m) {
[f1e629d]628  switch (m->direction) {
629  case OWL_MESSAGE_DIRECTION_IN:
630    return("in");
631  case OWL_MESSAGE_DIRECTION_OUT:
632    return("out");
633  case OWL_MESSAGE_DIRECTION_NONE:
634    return("none");
635  default:
636    return("unknown");
637  }
638}
639
[e19eb97]640int owl_message_parse_direction(const char *d) {
[dd16bdd]641  if(!strcmp(d, "in")) {
642    return OWL_MESSAGE_DIRECTION_IN;
643  } else if(!strcmp(d, "out")) {
644    return OWL_MESSAGE_DIRECTION_OUT;
645  } else {
646    return OWL_MESSAGE_DIRECTION_NONE;
647  }
648}
649
650
[c08c70a]651const char *owl_message_get_login(const owl_message *m) {
[f1e629d]652  if (owl_message_is_login(m)) {
653    return "login";
654  } else if (owl_message_is_logout(m)) {
655    return "logout";
656  } else {
657    return "none";
658  }
659}
660
[dd16bdd]661
[c08c70a]662const char *owl_message_get_header(const owl_message *m) {
[f1e629d]663  return owl_message_get_attribute_value(m, "adminheader");
664}
665
[bd3f232]666/* return 1 if the message contains "string", 0 otherwise.  This is
667 * case insensitive because the functions it uses are
668 */
[89b2daf]669int owl_message_search(owl_message *m, const owl_regex *re)
[0ff8fb57]670{
[4b464a4]671
[f14a7ee]672  owl_message_format(m); /* is this necessary? */
[bd3f232]673 
[41c9a96]674  return (owl_fmtext_search(&(m->fmtext->fmtext), re));
[4b464a4]675}
676
677
[d559df9]678/* if loginout == -1 it's a logout message
679 *                 0 it's not a login/logout message
680 *                 1 it's a login message
681 */
[e19eb97]682void owl_message_create_aim(owl_message *m, const char *sender, const char *recipient, const char *text, int direction, int loginout)
[0ff8fb57]683{
[d09e5a1]684  owl_message_init(m);
685  owl_message_set_body(m, text);
686  owl_message_set_sender(m, sender);
[440ce01]687  owl_message_set_recipient(m, recipient);
[d09e5a1]688  owl_message_set_type_aim(m);
[3abf28b]689
[d559df9]690  if (direction==OWL_MESSAGE_DIRECTION_IN) {
691    owl_message_set_direction_in(m);
692  } else if (direction==OWL_MESSAGE_DIRECTION_OUT) {
693    owl_message_set_direction_out(m);
[3abf28b]694  }
695
[d559df9]696  /* for now all messages that aren't loginout are private */
697  if (!loginout) {
698    owl_message_set_isprivate(m);
699  }
[3abf28b]700
[d559df9]701  if (loginout==-1) {
702    owl_message_set_islogout(m);
703  } else if (loginout==1) {
704    owl_message_set_islogin(m);
705  }
[aa5f725]706}
707
[e19eb97]708void owl_message_create_admin(owl_message *m, const char *header, const char *text)
[0ff8fb57]709{
[d0d65df]710  owl_message_init(m);
[4b464a4]711  owl_message_set_type_admin(m);
[d0d65df]712  owl_message_set_body(m, text);
[bd3f232]713  owl_message_set_attribute(m, "adminheader", header); /* just a hack for now */
[7d4fbcd]714}
715
[37eab7f]716/* caller should set the direction */
[e19eb97]717void owl_message_create_loopback(owl_message *m, const char *text)
[37eab7f]718{
719  owl_message_init(m);
720  owl_message_set_type_loopback(m);
721  owl_message_set_body(m, text);
[eec69e1]722  owl_message_set_sender(m, "loopsender");
723  owl_message_set_recipient(m, "looprecip");
[37eab7f]724  owl_message_set_isprivate(m);
725}
726
[4727d31]727void owl_message_save_ccs(owl_message *m) {
728  GList *cc;
729  char *tmp;
730
731  cc = owl_message_get_cc_without_recipient(m);
732
733  if (cc != NULL) {
734    GString *recips = g_string_new("");
735    cc = g_list_prepend(cc, short_zuser(owl_message_get_sender(m)));
736    cc = g_list_prepend(cc, short_zuser(owl_message_get_recipient(m)));
737    cc = g_list_sort(cc, (GCompareFunc)strcasecmp);
738
739    while(cc != NULL) {
740      /* Collapse any identical entries */
741      while (cc->next && strcasecmp(cc->data, cc->next->data) == 0) {
742        owl_free(cc->data);
743        cc = g_list_delete_link(cc, cc);
744      }
745
746      tmp = short_zuser(cc->data);
747      g_string_append(recips, tmp);
748
749      owl_free(tmp);
750      owl_free(cc->data);
751      cc = g_list_delete_link(cc, cc);
752
753      if (cc)
754        g_string_append_c(recips, ' ');
755    }
756
757    owl_message_set_attribute(m, "zephyr_ccs", recips->str);
758    g_string_free(recips, true);
759  }
760}
761
[09489b89]762#ifdef HAVE_LIBZEPHYR
[1077891a]763void owl_message_create_from_znotice(owl_message *m, const ZNotice_t *n)
[0ff8fb57]764{
[ba88ae7]765#ifdef ZNOTICE_SOCKADDR
766  char hbuf[NI_MAXHOST];
767#else /* !ZNOTICE_SOCKADDR */
[7d4fbcd]768  struct hostent *hent;
[ba88ae7]769#endif /* ZNOTICE_SOCKADDR */
[e19eb97]770  const char *ptr;
[65b2173]771  char *tmp, *tmp2;
[804ab8a]772  int len;
[7d4fbcd]773
[d0d65df]774  owl_message_init(m);
775 
[4b464a4]776  owl_message_set_type_zephyr(m);
777  owl_message_set_direction_in(m);
[7d4fbcd]778 
779  /* first save the full notice */
[66a8cd6]780  m->notice = *n;
[7d4fbcd]781
[25dd31a]782  /* a little gross, we'll replace \r's with ' ' for now */
[7d4fbcd]783  owl_zephyr_hackaway_cr(&(m->notice));
784 
[25dd31a]785  /* save the time, we need to nuke the string saved by message_init */
[5a95b69]786  if (m->timestr) owl_free(m->timestr);
[25dd31a]787  m->time=n->z_time.tv_sec;
788  m->timestr=owl_strdup(ctime(&(m->time)));
789  m->timestr[strlen(m->timestr)-1]='\0';
790
[7d4fbcd]791  /* set other info */
[d0d65df]792  owl_message_set_sender(m, n->z_sender);
793  owl_message_set_class(m, n->z_class);
794  owl_message_set_instance(m, n->z_class_inst);
795  owl_message_set_recipient(m, n->z_recipient);
[7d4fbcd]796  if (n->z_opcode) {
[d0d65df]797    owl_message_set_opcode(m, n->z_opcode);
[7d4fbcd]798  } else {
[d0d65df]799    owl_message_set_opcode(m, "");
[7d4fbcd]800  }
[804ab8a]801  owl_message_set_zsig(m, owl_zephyr_get_zsig(n, &len));
[7d4fbcd]802
803  if ((ptr=strchr(n->z_recipient, '@'))!=NULL) {
[d0d65df]804    owl_message_set_realm(m, ptr+1);
[7d4fbcd]805  } else {
[09489b89]806    owl_message_set_realm(m, owl_zephyr_get_realm());
[7d4fbcd]807  }
808
[5789230]809  /* Set the "isloginout" attribute if it's a login message */
[1d3e925]810  if (!strcasecmp(n->z_class, "login") || !strcasecmp(n->z_class, OWL_WEBZEPHYR_CLASS)) {
[5a95b69]811    if (!strcasecmp(n->z_opcode, "user_login") || !strcasecmp(n->z_opcode, "user_logout")) {
[b0430a6]812      tmp=owl_zephyr_get_field(n, 1);
[5a95b69]813      owl_message_set_attribute(m, "loginhost", tmp);
814      owl_free(tmp);
815
[b0430a6]816      tmp=owl_zephyr_get_field(n, 3);
[5a95b69]817      owl_message_set_attribute(m, "logintty", tmp);
818      owl_free(tmp);
819    }
820
[d559df9]821    if (!strcasecmp(n->z_opcode, "user_login")) {
822      owl_message_set_islogin(m);
823    } else if (!strcasecmp(n->z_opcode, "user_logout")) {
824      owl_message_set_islogout(m);
825    }
[5789230]826  }
827
[5a95b69]828 
[963542b]829  /* set the "isprivate" attribute if it's a private zephyr.
[ce74deb]830   ``private'' means recipient is non-empty and doesn't start wit
831   `@' */
[963542b]832  if (*n->z_recipient && *n->z_recipient != '@') {
[5789230]833    owl_message_set_isprivate(m);
834  }
835
[9854278]836  /* set the "isauto" attribute if it's an autoreply */
837  if (!strcasecmp(n->z_message, "Automated reply:") ||
838      !strcasecmp(n->z_opcode, "auto")) {
839    owl_message_set_attribute(m, "isauto", "");
840  }
841
[85d1795]842  /* save the hostname */
[ba88ae7]843#ifdef ZNOTICE_SOCKADDR
844  owl_function_debugmsg("About to do getnameinfo");
845  if (getnameinfo(&n->z_sender_sockaddr.sa, sizeof(n->z_sender_sockaddr), hbuf, sizeof(hbuf), NULL, 0, 0) == 0)
846    owl_message_set_hostname(m, hbuf);
847#else /* !ZNOTICE_SOCKADDR */
[85d1795]848  owl_function_debugmsg("About to do gethostbyaddr");
[ba88ae7]849  hent = gethostbyaddr(&n->z_uid.zuid_addr, sizeof(n->z_uid.zuid_addr), AF_INET);
850  if (hent && hent->h_name)
[85d1795]851    owl_message_set_hostname(m, hent->h_name);
[ba88ae7]852  else
[85d1795]853    owl_message_set_hostname(m, inet_ntoa(n->z_sender_addr));
[ba88ae7]854#endif /* ZNOTICE_SOCKADDR */
[85d1795]855
[b45293f]856  /* set the body */
[85d1795]857  tmp=owl_zephyr_get_message(n, m);
[7e3e00a]858  if (owl_global_is_newlinestrip(&g)) {
[d0d65df]859    tmp2=owl_util_stripnewlines(tmp);
860    owl_message_set_body(m, tmp2);
861    owl_free(tmp2);
[7e3e00a]862  } else {
[d0d65df]863    owl_message_set_body(m, tmp);
[7e3e00a]864  }
[ecd5dc5]865  owl_free(tmp);
[7d4fbcd]866
[d309eb3]867  /* if zcrypt is enabled try to decrypt the message */
868  if (owl_global_is_zcrypt(&g) && !strcasecmp(n->z_opcode, "crypt")) {
[d564c3d]869    const char *argv[] = {
870      "zcrypt",
871      "-D",
872      "-c", owl_message_get_class(m),
873      "-i", owl_message_get_instance(m),
874      NULL
875    };
876    char *out;
877    int rv;
878    int status;
[9a7b4f2]879    char *zcrypt;
[d564c3d]880
[9a7b4f2]881    zcrypt = owl_sprintf("%s/zcrypt", owl_get_bindir());
882
883    rv = call_filter(zcrypt, argv, owl_message_get_body(m), &out, &status);
884    owl_free(zcrypt);
[d564c3d]885
886    if(!rv && !status) {
887      int len = strlen(out);
888      if(len >= 8 && !strcmp(out + len - 8, "**END**\n")) {
889        out[len - 8] = 0;
890      }
[d0d65df]891      owl_message_set_body(m, out);
[dacb555]892      owl_free(out);
[d564c3d]893    } else if(out) {
894      owl_free(out);
[dacb555]895    }
[d309eb3]896  }
[4727d31]897
898  owl_message_save_ccs(m);
[7d4fbcd]899}
[09489b89]900#else
[1077891a]901void owl_message_create_from_znotice(owl_message *m, const void *n)
[09489b89]902{
903}
904#endif
[7d4fbcd]905
[5a95b69]906/* If 'direction' is '0' it is a login message, '1' is a logout message. */
[e19eb97]907void owl_message_create_pseudo_zlogin(owl_message *m, int direction, const char *user, const char *host, const char *time, const char *tty)
[5a95b69]908{
[65b2173]909  char *longuser;
[e19eb97]910  const char *ptr;
[5a95b69]911
[ba9f236]912#ifdef HAVE_LIBZEPHYR
[5a95b69]913  memset(&(m->notice), 0, sizeof(ZNotice_t));
[ba9f236]914#endif
915 
[5a95b69]916  longuser=long_zuser(user);
917 
918  owl_message_init(m);
919 
920  owl_message_set_type_zephyr(m);
921  owl_message_set_direction_in(m);
922
923  owl_message_set_attribute(m, "pseudo", "");
924  owl_message_set_attribute(m, "loginhost", host ? host : "");
925  owl_message_set_attribute(m, "logintty", tty ? tty : "");
926
927  owl_message_set_sender(m, longuser);
928  owl_message_set_class(m, "LOGIN");
929  owl_message_set_instance(m, longuser);
930  owl_message_set_recipient(m, "");
931  if (direction==0) {
932    owl_message_set_opcode(m, "USER_LOGIN");
933    owl_message_set_islogin(m);
934  } else if (direction==1) {
935    owl_message_set_opcode(m, "USER_LOGOUT");
936    owl_message_set_islogout(m);
937  }
938
939  if ((ptr=strchr(longuser, '@'))!=NULL) {
940    owl_message_set_realm(m, ptr+1);
941  } else {
942    owl_message_set_realm(m, owl_zephyr_get_realm());
943  }
944
945  owl_message_set_body(m, "<uninitialized>");
946
947  /* save the hostname */
[2de4f20]948  owl_function_debugmsg("create_pseudo_login: host is %s", host ? host : "");
[8298425]949  owl_message_set_hostname(m, host ? host : "");
[5a95b69]950  owl_free(longuser);
951}
952
[24ccc01]953void owl_message_create_from_zwrite(owl_message *m, const owl_zwrite *z, const char *body)
[0ff8fb57]954{
[b45293f]955  int ret;
[8298425]956  char hostbuff[5000];
[b45293f]957 
[d0d65df]958  owl_message_init(m);
[b45293f]959
960  /* set things */
961  owl_message_set_direction_out(m);
962  owl_message_set_type_zephyr(m);
[09489b89]963  owl_message_set_sender(m, owl_zephyr_get_sender());
[24ccc01]964  owl_message_set_class(m, owl_zwrite_get_class(z));
965  owl_message_set_instance(m, owl_zwrite_get_instance(z));
966  if (owl_zwrite_get_numrecips(z)>0) {
967    char *longzuser = long_zuser(owl_zwrite_get_recip_n(z, 0));
[9ceee9d]968    owl_message_set_recipient(m,
[7d471c3]969                              longzuser); /* only gets the first user, must fix */
970    owl_free(longzuser);
[9ceee9d]971  }
[24ccc01]972  owl_message_set_opcode(m, owl_zwrite_get_opcode(z));
973  owl_message_set_realm(m, owl_zwrite_get_realm(z)); /* also a hack, but not here */
974  if(z->zwriteline) {
975    owl_message_set_zwriteline(m, z->zwriteline);
976  }
[d0d65df]977  owl_message_set_body(m, body);
[24ccc01]978  owl_message_set_zsig(m, owl_zwrite_get_zsig(z));
[b45293f]979 
980  /* save the hostname */
[8298425]981  ret=gethostname(hostbuff, MAXHOSTNAMELEN);
982  hostbuff[MAXHOSTNAMELEN]='\0';
[b45293f]983  if (ret) {
[8298425]984    owl_message_set_hostname(m, "localhost");
985  } else {
986    owl_message_set_hostname(m, hostbuff);
[b45293f]987  }
[312675c]988
[ce74deb]989  /* set the "isprivate" attribute if it's a private zephyr. */
[24ccc01]990  if (owl_zwrite_is_personal(z)) {
[312675c]991    owl_message_set_isprivate(m);
[ce74deb]992  }
[4727d31]993
994  owl_message_save_ccs(m);
[b45293f]995}
[7d4fbcd]996
[a44cd91]997void owl_message_cleanup(owl_message *m)
[0ff8fb57]998{
[d0d65df]999  int i, j;
1000  owl_pair *p;
[09489b89]1001#ifdef HAVE_LIBZEPHYR   
[4b464a4]1002  if (owl_message_is_type_zephyr(m) && owl_message_is_direction_in(m)) {
[7d4fbcd]1003    ZFreeNotice(&(m->notice));
1004  }
[09489b89]1005#endif
[25dd31a]1006  if (m->timestr) owl_free(m->timestr);
[d0d65df]1007
1008  /* free all the attributes */
1009  j=owl_list_get_size(&(m->attributes));
1010  for (i=0; i<j; i++) {
1011    p=owl_list_get_element(&(m->attributes), i);
1012    owl_free(owl_pair_get_value(p));
1013    owl_free(p);
1014  }
1015
[5e5f08f]1016  owl_list_cleanup(&(m->attributes), NULL);
[7d4fbcd]1017 
[a387d12e]1018  owl_message_invalidate_format(m);
[7d4fbcd]1019}
[91634ec]1020
1021void owl_message_delete(owl_message *m)
1022{
[a44cd91]1023  owl_message_cleanup(m);
[91634ec]1024  owl_free(m);
1025}
Note: See TracBrowser for help on using the repository browser.