source: message.c @ 0ee43c8

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