source: message.c @ 80b5c42

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