source: message.c @ 6500907

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