source: message.c @ a882637

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