source: message.c @ bd3f232

barnowl_perlaimdebianowlrelease-1.10release-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since bd3f232 was bd3f232, checked in by James M. Kretchmar <kretch@mit.edu>, 21 years ago
Styles implemented It's still a little buggy ... if a format_msg(); is used in perl admin messages (or maybe just the first admin message) are not formatted.
  • Property mode set to 100644
File size: 17.7 KB
Line 
1#include <zephyr/zephyr.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <string.h>
5#include <sys/socket.h>
6#include <netdb.h>
7#include <sys/types.h>
8#include <sys/socket.h>
9#include <netinet/in.h>
10#include <arpa/inet.h>
11#include <time.h>
12#include "owl.h"
13
14static const char fileIdent[] = "$Id$";
15
16void owl_message_init(owl_message *m)
17{
18  time_t t;
19
20  m->id=owl_global_get_nextmsgid(&g);
21  m->type=OWL_MESSAGE_TYPE_GENERIC;
22  owl_message_set_direction_none(m);
23  m->delete=0;
24  strcpy(m->hostname, "");
25  m->zwriteline=strdup("");
26  m->invalid_format=1;
27
28  owl_list_create(&(m->attributes));
29 
30  /* save the time */
31  t=time(NULL);
32  m->time=owl_strdup(ctime(&t));
33  m->time[strlen(m->time)-1]='\0';
34  owl_fmtext_init_null(&(m->fmtext));
35}
36
37void owl_message_set_attribute(owl_message *m, char *attrname, char *attrvalue)
38{
39  /* add the named attribute to the message.  If an attribute with the
40     name already exists, replace the old value with the new value */
41
42  int i, j;
43  owl_pair *p;
44
45  /* look for an existing pair with this key, and nuke the entry if
46     found */
47  j=owl_list_get_size(&(m->attributes));
48  for (i=0; i<j; i++) {
49    p=owl_list_get_element(&(m->attributes), i);
50    if (!strcmp(owl_pair_get_key(p), attrname)) {
51      owl_free(owl_pair_get_key(p));
52      owl_free(owl_pair_get_value(p));
53      owl_free(p);
54      owl_list_remove_element(&(m->attributes), i);
55      break;
56    }
57  }
58
59  p=owl_malloc(sizeof(owl_pair));
60  owl_pair_create(p, owl_strdup(attrname), owl_strdup(attrvalue));
61  owl_list_append_element(&(m->attributes), p);
62}
63
64char *owl_message_get_attribute_value(owl_message *m, char *attrname)
65{
66  /* return the value associated with the named attribute, or NULL if
67     the attribute does not exist */
68  int i, j;
69  owl_pair *p;
70
71  j=owl_list_get_size(&(m->attributes));
72  for (i=0; i<j; i++) {
73    p=owl_list_get_element(&(m->attributes), i);
74    if (!strcmp(owl_pair_get_key(p), attrname)) {
75      return(owl_pair_get_value(p));
76    }
77  }
78  owl_function_debugmsg("No attribute %s found", attrname);
79  return(NULL);
80}
81
82/* We cheat and indent it for now, since we really want this for
83 * the 'info' function.  Later there should just be a generic
84 * function to indent fmtext.
85 */
86void owl_message_attributes_tofmtext(owl_message *m, owl_fmtext *fm) {
87  int i, j;
88  owl_pair *p;
89  char *buff;
90
91  owl_fmtext_init_null(fm);
92
93  j=owl_list_get_size(&(m->attributes));
94  for (i=0; i<j; i++) {
95    p=owl_list_get_element(&(m->attributes), i);
96    buff=owl_sprintf("  %-15.15s: %-35.35s\n", owl_pair_get_key(p), owl_pair_get_value(p));
97    owl_fmtext_append_normal(fm, buff);
98    owl_free(buff);
99  }
100}
101
102void owl_message_invalidate_format(owl_message *m)
103{
104  m->invalid_format=1;
105}
106
107owl_fmtext *owl_message_get_fmtext(owl_message *m)
108{
109  owl_style *s;
110
111  /* if the format is invalid, regenerate the text based on the
112   * current style
113   */
114  if (m->invalid_format) {
115    owl_fmtext_free(&(m->fmtext));
116    owl_fmtext_init_null(&(m->fmtext));
117    s=owl_global_get_current_style(&g);
118    owl_style_get_formattext(s, &(m->fmtext), m);
119    m->invalid_format=0;
120  }
121  return(&(m->fmtext));
122}
123
124void owl_message_set_class(owl_message *m, char *class)
125{
126  owl_message_set_attribute(m, "class", class);
127}
128
129char *owl_message_get_class(owl_message *m)
130{
131  char *class;
132
133  class=owl_message_get_attribute_value(m, "class");
134  if (!class) return("");
135  return(class);
136}
137
138void owl_message_set_instance(owl_message *m, char *inst)
139{
140  owl_message_set_attribute(m, "instance", inst);
141}
142
143char *owl_message_get_instance(owl_message *m)
144{
145  char *instance;
146
147  instance=owl_message_get_attribute_value(m, "instance");
148  if (!instance) return("");
149  return(instance);
150}
151
152void owl_message_set_sender(owl_message *m, char *sender)
153{
154  owl_message_set_attribute(m, "sender", sender);
155}
156
157char *owl_message_get_sender(owl_message *m)
158{
159  char *sender;
160
161  sender=owl_message_get_attribute_value(m, "sender");
162  if (!sender) return("");
163  return(sender);
164}
165
166void owl_message_set_zsig(owl_message *m, char *zsig)
167{
168  owl_message_set_attribute(m, "zsig", zsig);
169}
170
171char *owl_message_get_zsig(owl_message *m)
172{
173  char *zsig;
174
175  zsig=owl_message_get_attribute_value(m, "zsig");
176  if (!zsig) return("");
177  return(zsig);
178}
179
180void owl_message_set_recipient(owl_message *m, char *recip)
181{
182  owl_message_set_attribute(m, "recipient", recip);
183}
184
185char *owl_message_get_recipient(owl_message *m)
186{
187  /* this is stupid for outgoing messages, we need to fix it. */
188
189  char *recip;
190
191  recip=owl_message_get_attribute_value(m, "recipient");
192  if (!recip) return("");
193  return(recip);
194}
195
196void owl_message_set_realm(owl_message *m, char *realm)
197{
198  owl_message_set_attribute(m, "realm", realm);
199}
200
201char *owl_message_get_realm(owl_message *m)
202{
203  char *realm;
204 
205  realm=owl_message_get_attribute_value(m, "realm");
206  if (!realm) return("");
207  return(realm);
208}
209
210void owl_message_set_body(owl_message *m, char *body)
211{
212  owl_message_set_attribute(m, "body", body);
213}
214
215char *owl_message_get_body(owl_message *m)
216{
217  char *body;
218
219  body=owl_message_get_attribute_value(m, "body");
220  if (!body) return("");
221  return(body);
222}
223
224
225void owl_message_set_opcode(owl_message *m, char *opcode)
226{
227  owl_message_set_attribute(m, "opcode", opcode);
228}
229
230char *owl_message_get_opcode(owl_message *m)
231{
232  char *opcode;
233
234  opcode=owl_message_get_attribute_value(m, "opcode");
235  if (!opcode) return("");
236  return(opcode);
237}
238
239
240void owl_message_set_islogin(owl_message *m)
241{
242  owl_message_set_attribute(m, "loginout", "login");
243}
244
245
246void owl_message_set_islogout(owl_message *m)
247{
248  owl_message_set_attribute(m, "loginout", "logout");
249}
250
251int owl_message_is_loginout(owl_message *m)
252{
253  char *res;
254
255  res=owl_message_get_attribute_value(m, "loginout");
256  if (!res) return(0);
257  return(1);
258}
259
260int owl_message_is_login(owl_message *m)
261{
262  char *res;
263
264  res=owl_message_get_attribute_value(m, "loginout");
265  if (!res) return(0);
266  if (!strcmp(res, "login")) return(1);
267  return(0);
268}
269
270
271int owl_message_is_logout(owl_message *m)
272{
273  char *res;
274
275  res=owl_message_get_attribute_value(m, "loginout");
276  if (!res) return(0);
277  if (!strcmp(res, "logout")) return(1);
278  return(0);
279}
280
281void owl_message_set_isprivate(owl_message *m)
282{
283  owl_message_set_attribute(m, "isprivate", "");
284}
285
286int owl_message_is_private(owl_message *m)
287{
288  char *res;
289
290  res=owl_message_get_attribute_value(m, "isprivate");
291  if (!res) return(0);
292  return(1);
293}
294
295char *owl_message_get_timestr(owl_message *m)
296{
297  return(m->time);
298}
299
300void owl_message_set_type_admin(owl_message *m)
301{
302  m->type=OWL_MESSAGE_TYPE_ADMIN;
303}
304
305void owl_message_set_type_zephyr(owl_message *m)
306{
307  m->type=OWL_MESSAGE_TYPE_ZEPHYR;
308}
309
310void owl_message_set_type_aim(owl_message *m)
311{
312  m->type=OWL_MESSAGE_TYPE_AIM;
313}
314                                               
315int owl_message_is_type_admin(owl_message *m)
316{
317  if (m->type==OWL_MESSAGE_TYPE_ADMIN) return(1);
318  return(0);
319}
320
321int owl_message_is_type_zephyr(owl_message *m)
322{
323  if (m->type==OWL_MESSAGE_TYPE_ZEPHYR) return(1);
324  return(0);
325}
326
327int owl_message_is_type_aim(owl_message *m)
328{
329  if (m->type==OWL_MESSAGE_TYPE_AIM) return(1);
330  return(0);
331}
332
333int owl_message_is_type_generic(owl_message *m)
334{
335  if (m->type==OWL_MESSAGE_TYPE_GENERIC) return(1);
336  return(0);
337}
338
339char *owl_message_type_to_string(owl_message *m)
340{
341  if (m->type==OWL_MESSAGE_TYPE_ADMIN) return("admin");
342  if (m->type==OWL_MESSAGE_TYPE_GENERIC) return("generic");
343  if (m->type==OWL_MESSAGE_TYPE_ZEPHYR) return("zephyr");
344  if (m->type==OWL_MESSAGE_TYPE_AIM) return("aim");
345  if (m->type==OWL_MESSAGE_TYPE_JABBER) return("jabber");
346  if (m->type==OWL_MESSAGE_TYPE_ICQ) return("icq");
347  if (m->type==OWL_MESSAGE_TYPE_MSN) return("msn");
348  return("unknown");
349}
350
351char *owl_message_get_text(owl_message *m)
352{
353  return(owl_fmtext_get_text(&(m->fmtext)));
354}
355
356void owl_message_set_direction_in(owl_message *m)
357{
358  m->direction=OWL_MESSAGE_DIRECTION_IN;
359}
360
361void owl_message_set_direction_out(owl_message *m)
362{
363  m->direction=OWL_MESSAGE_DIRECTION_OUT;
364}
365
366void owl_message_set_direction_none(owl_message *m)
367{
368  m->direction=OWL_MESSAGE_DIRECTION_NONE;
369}
370
371int owl_message_is_direction_in(owl_message *m)
372{
373  if (m->direction==OWL_MESSAGE_DIRECTION_IN) return(1);
374  return(0);
375}
376
377int owl_message_is_direction_out(owl_message *m)
378{
379  if (m->direction==OWL_MESSAGE_DIRECTION_OUT) return(1);
380  return(0);
381}
382
383int owl_message_is_direction_none(owl_message *m)
384{
385  if (m->direction==OWL_MESSAGE_DIRECTION_NONE) return(1);
386  return(0);
387}
388
389int owl_message_get_numlines(owl_message *m)
390{
391  if (m == NULL) return(0);
392  (void) owl_message_get_fmtext(m);
393  return(owl_fmtext_num_lines(&(m->fmtext)));
394}
395
396void owl_message_mark_delete(owl_message *m)
397{
398  if (m == NULL) return;
399  m->delete=1;
400}
401
402void owl_message_unmark_delete(owl_message *m)
403{
404  if (m == NULL) return;
405  m->delete=0;
406}
407
408char *owl_message_get_zwriteline(owl_message *m)
409{
410  return(m->zwriteline);
411}
412
413void owl_message_set_zwriteline(owl_message *m, char *line)
414{
415  m->zwriteline=strdup(line);
416}
417
418int owl_message_is_delete(owl_message *m)
419{
420  if (m == NULL) return(0);
421  if (m->delete==1) return(1);
422  return(0);
423}
424
425ZNotice_t *owl_message_get_notice(owl_message *m)
426{
427  return(&(m->notice));
428}
429
430char *owl_message_get_hostname(owl_message *m)
431{
432  return(m->hostname);
433}
434
435
436void owl_message_curs_waddstr(owl_message *m, WINDOW *win, int aline, int bline, int acol, int bcol, int color)
437{
438  owl_fmtext a, b;
439
440  /* this will ensure that our cached copy is up to date */
441  (void) owl_message_get_fmtext(m);
442
443  owl_fmtext_init_null(&a);
444  owl_fmtext_init_null(&b);
445 
446  owl_fmtext_truncate_lines(&(m->fmtext), aline, bline-aline+1, &a);
447  owl_fmtext_truncate_cols(&a, acol, bcol, &b);
448  if (color!=OWL_COLOR_DEFAULT) {
449    owl_fmtext_colorize(&b, color);
450  }
451
452  if (owl_global_is_search_active(&g)) {
453    owl_fmtext_search_and_highlight(&b, owl_global_get_search_string(&g));
454  }
455     
456  owl_fmtext_curs_waddstr(&b, win);
457
458  owl_fmtext_free(&a);
459  owl_fmtext_free(&b);
460}
461
462int owl_message_is_personal(owl_message *m)
463{
464  if (owl_message_is_type_zephyr(m)) {
465    if (strcasecmp(owl_message_get_class(m), "message")) return(0);
466    if (strcasecmp(owl_message_get_instance(m), "personal")) return(0);
467    if (!strcasecmp(owl_message_get_recipient(m), ZGetSender()) ||
468        !strcasecmp(owl_message_get_sender(m), ZGetSender())) {
469      return(1);
470    }
471  }
472  return(0);
473}
474
475int owl_message_is_from_me(owl_message *m)
476{
477  if (owl_message_is_type_zephyr(m)) {
478    if (!strcasecmp(owl_message_get_sender(m), ZGetSender())) {
479      return(1);
480    } else {
481      return(0);
482    }
483  } else if (owl_message_is_type_aim(m)) {
484    if (!strcasecmp(owl_message_get_sender(m), owl_global_get_aim_screenname(&g))) {
485      return(1);
486    } else {
487      return(0);
488    }
489  } else if (owl_message_is_type_admin(m)) {
490    return(0);
491  }
492  return(0);
493}
494
495int owl_message_is_mail(owl_message *m)
496{
497  if (owl_message_is_type_zephyr(m)) {
498    if (!strcasecmp(owl_message_get_class(m), "mail") && owl_message_is_private(m)) {
499      return(1);
500    } else {
501      return(0);
502    }
503  }
504  return(0);
505}
506
507int owl_message_is_ping(owl_message *m)
508{
509  if (owl_message_is_type_zephyr(m)) {
510    if (!strcasecmp(owl_message_get_opcode(m), "ping")) {
511      return(1);
512    } else {
513      return(0);
514    }
515  }
516  return(0);
517}
518
519int owl_message_is_burningears(owl_message *m)
520{
521  /* we should add a global to cache the short zsender */
522  char sender[LINE], *ptr;
523
524  /* if the message is from us or to us, it doesn't count */
525  if (owl_message_is_from_me(m) || owl_message_is_private(m)) return(0);
526
527  if (owl_message_is_type_zephyr(m)) {
528    strcpy(sender, ZGetSender());
529    ptr=strchr(sender, '@');
530    if (ptr) *ptr='\0';
531  } else if (owl_message_is_type_aim(m)) {
532    strcpy(sender, owl_global_get_aim_screenname(&g));
533  } else {
534    return(0);
535  }
536
537  if (stristr(owl_message_get_body(m), sender)) {
538    return(1);
539  }
540  return(0);
541}
542
543/* caller must free return value. */
544char *owl_message_get_cc(owl_message *m)
545{
546  char *cur, *out, *end;
547
548  cur = owl_message_get_body(m);
549  while (*cur && *cur==' ') cur++;
550  if (strncasecmp(cur, "cc:", 3)) return(NULL);
551  cur+=3;
552  while (*cur && *cur==' ') cur++;
553  out = owl_strdup(cur);
554  end = strchr(out, '\n');
555  if (end) end[0] = '\0';
556  return(out);
557}
558
559int owl_message_get_id(owl_message *m)
560{
561  return(m->id);
562}
563
564/* return 1 if the message contains "string", 0 otherwise.  This is
565 * case insensitive because the functions it uses are
566 */
567int owl_message_search(owl_message *m, char *string)
568{
569
570  (void) owl_message_get_fmtext(m); /* is this necessary? */
571 
572  return (owl_fmtext_search(&(m->fmtext), string));
573}
574
575
576/* if loginout == -1 it's a logout message
577 *                 0 it's not a login/logout message
578 *                 1 it's a login message
579 */
580void owl_message_create_aim(owl_message *m, char *sender, char *recipient, char *text, int direction, int loginout)
581{
582  owl_message_init(m);
583  owl_message_set_body(m, text);
584  owl_message_set_sender(m, sender);
585  owl_message_set_recipient(m, recipient);
586  owl_message_set_type_aim(m);
587
588  if (direction==OWL_MESSAGE_DIRECTION_IN) {
589    owl_message_set_direction_in(m);
590  } else if (direction==OWL_MESSAGE_DIRECTION_OUT) {
591    owl_message_set_direction_out(m);
592  }
593
594  /* for now all messages that aren't loginout are private */
595  if (!loginout) {
596    owl_message_set_isprivate(m);
597  }
598
599  if (loginout==-1) {
600    owl_message_set_islogout(m);
601  } else if (loginout==1) {
602    owl_message_set_islogin(m);
603  }
604}
605
606void owl_message_create_admin(owl_message *m, char *header, char *text)
607{
608  owl_message_init(m);
609  owl_message_set_type_admin(m);
610  owl_message_set_body(m, text);
611  owl_message_set_attribute(m, "adminheader", header); /* just a hack for now */
612}
613
614void owl_message_create_from_znotice(owl_message *m, ZNotice_t *n)
615{
616  struct hostent *hent;
617  int k;
618  char *ptr, *tmp, *tmp2;
619
620  owl_message_init(m);
621 
622  owl_message_set_type_zephyr(m);
623  owl_message_set_direction_in(m);
624 
625  /* first save the full notice */
626  memcpy(&(m->notice), n, sizeof(ZNotice_t));
627
628  /* a little gross, we'll reaplace \r's with ' ' for now */
629  owl_zephyr_hackaway_cr(&(m->notice));
630 
631  m->delete=0;
632
633  /* set other info */
634  owl_message_set_sender(m, n->z_sender);
635  owl_message_set_class(m, n->z_class);
636  owl_message_set_instance(m, n->z_class_inst);
637  owl_message_set_recipient(m, n->z_recipient);
638  if (n->z_opcode) {
639    owl_message_set_opcode(m, n->z_opcode);
640  } else {
641    owl_message_set_opcode(m, "");
642  }
643  owl_message_set_zsig(m, n->z_message);
644
645  if ((ptr=strchr(n->z_recipient, '@'))!=NULL) {
646    owl_message_set_realm(m, ptr+1);
647  } else {
648    owl_message_set_realm(m, ZGetRealm());
649  }
650
651  /* Set the "isloginout" attribute if it's a login message */
652  if (!strcasecmp(n->z_class, "login")) {
653    if (!strcasecmp(n->z_opcode, "user_login")) {
654      owl_message_set_islogin(m);
655    } else if (!strcasecmp(n->z_opcode, "user_logout")) {
656      owl_message_set_islogout(m);
657    }
658  }
659
660  /* is the "isprivate" attribute if it's a private zephyr */
661  if (!strcasecmp(n->z_recipient, ZGetSender())) {
662    owl_message_set_isprivate(m);
663  }
664
665  m->zwriteline=strdup("");
666
667  /* set the body */
668  ptr=owl_zephyr_get_message(n, &k);
669  tmp=owl_malloc(k+10);
670  memcpy(tmp, ptr, k);
671  tmp[k]='\0';
672  if (owl_global_is_newlinestrip(&g)) {
673    tmp2=owl_util_stripnewlines(tmp);
674    owl_message_set_body(m, tmp2);
675    owl_free(tmp2);
676  } else {
677    owl_message_set_body(m, tmp);
678  }
679  owl_free(tmp);
680
681#ifdef OWL_ENABLE_ZCRYPT
682  /* if zcrypt is enabled try to decrypt the message */
683  if (owl_global_is_zcrypt(&g) && !strcasecmp(n->z_opcode, "crypt")) {
684    char *out;
685    int ret;
686
687    out=owl_malloc(strlen(owl_message_get_body(m))*16+20);
688    ret=zcrypt_decrypt(out, owl_message_get_body(m), owl_message_get_class(m), owl_message_get_instance(m));
689    if (ret==0) {
690      owl_message_set_body(m, out);
691    } else {
692      owl_free(out);
693    }
694  }
695#endif 
696
697  /* save the hostname */
698  owl_function_debugmsg("About to do gethostbyaddr");
699  hent=gethostbyaddr((char *) &(n->z_uid.zuid_addr), sizeof(n->z_uid.zuid_addr), AF_INET);
700  if (hent && hent->h_name) {
701    strcpy(m->hostname, hent->h_name);
702  } else {
703    strcpy(m->hostname, inet_ntoa(n->z_sender_addr));
704  }
705
706  /* save the time */
707  m->time=owl_strdup(ctime((time_t *) &n->z_time.tv_sec));
708  m->time[strlen(m->time)-1]='\0';
709}
710
711void owl_message_create_from_zwriteline(owl_message *m, char *line, char *body, char *zsig)
712{
713  owl_zwrite z;
714  int ret;
715 
716  owl_message_init(m);
717
718  /* create a zwrite for the purpose of filling in other message fields */
719  owl_zwrite_create_from_line(&z, line);
720
721  /* set things */
722  owl_message_set_direction_out(m);
723  owl_message_set_type_zephyr(m);
724  owl_message_set_sender(m, ZGetSender());
725  owl_message_set_class(m, owl_zwrite_get_class(&z));
726  owl_message_set_instance(m, owl_zwrite_get_instance(&z));
727  owl_message_set_recipient(m,
728                            long_zuser(owl_zwrite_get_recip_n(&z, 0))); /* only gets the first user, must fix */
729  owl_message_set_opcode(m, owl_zwrite_get_opcode(&z));
730  owl_message_set_realm(m, owl_zwrite_get_realm(&z)); /* also a hack, but not here */
731  m->zwriteline=owl_strdup(line);
732  owl_message_set_body(m, body);
733  owl_message_set_zsig(m, zsig);
734 
735  /* save the hostname */
736  ret=gethostname(m->hostname, MAXHOSTNAMELEN);
737  if (ret) {
738    strcpy(m->hostname, "localhost");
739  }
740
741  owl_zwrite_free(&z);
742}
743
744
745void owl_message_pretty_zsig(owl_message *m, char *buff)
746{
747  /* stick a one line version of the zsig in buff */
748  char *ptr;
749
750  strcpy(buff, owl_message_get_zsig(m));
751  ptr=strchr(buff, '\n');
752  if (ptr) ptr[0]='\0';
753}
754
755void owl_message_free(owl_message *m)
756{
757  int i, j;
758  owl_pair *p;
759   
760  if (owl_message_is_type_zephyr(m) && owl_message_is_direction_in(m)) {
761    ZFreeNotice(&(m->notice));
762  }
763  if (m->time) owl_free(m->time);
764  if (m->zwriteline) owl_free(m->zwriteline);
765
766  /* free all the attributes */
767  j=owl_list_get_size(&(m->attributes));
768  for (i=0; i<j; i++) {
769    p=owl_list_get_element(&(m->attributes), i);
770    owl_free(owl_pair_get_key(p));
771    owl_free(owl_pair_get_value(p));
772    owl_free(p);
773  }
774
775  owl_list_free_simple(&(m->attributes));
776 
777  owl_fmtext_free(&(m->fmtext));
778}
Note: See TracBrowser for help on using the repository browser.