source: message.c @ 8f95fc4

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