source: message.c @ f14a7ee

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