source: message.c @ d9fbfd8

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