source: message.c @ f271129

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