source: message.c @ be0a79f

barnowl_perlaimdebianowlrelease-1.10release-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since be0a79f was be0a79f, checked in by James M. Kretchmar <kretch@mit.edu>, 21 years ago
Started work making owl build without zephyr. Long way left to go though.
  • 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
427#ifdef HAVE_LIBZEPHYR
428ZNotice_t *owl_message_get_notice(owl_message *m)
429{
430  return(&(m->notice));
431}
432#endif
433
434char *owl_message_get_hostname(owl_message *m)
435{
436  return(m->hostname);
437}
438
439
440void owl_message_curs_waddstr(owl_message *m, WINDOW *win, int aline, int bline, int acol, int bcol, int color)
441{
442  owl_fmtext a, b;
443
444  /* this will ensure that our cached copy is up to date */
445  owl_message_format(m);
446
447  owl_fmtext_init_null(&a);
448  owl_fmtext_init_null(&b);
449 
450  owl_fmtext_truncate_lines(&(m->fmtext), aline, bline-aline+1, &a);
451  owl_fmtext_truncate_cols(&a, acol, bcol, &b);
452  if (color!=OWL_COLOR_DEFAULT) {
453    owl_fmtext_colorize(&b, color);
454  }
455
456  if (owl_global_is_search_active(&g)) {
457    owl_fmtext_search_and_highlight(&b, owl_global_get_search_string(&g));
458  }
459     
460  owl_fmtext_curs_waddstr(&b, win);
461
462  owl_fmtext_free(&a);
463  owl_fmtext_free(&b);
464}
465
466int owl_message_is_personal(owl_message *m)
467{
468  if (owl_message_is_type_zephyr(m)) {
469    if (strcasecmp(owl_message_get_class(m), "message")) return(0);
470    if (strcasecmp(owl_message_get_instance(m), "personal")) return(0);
471    if (!strcasecmp(owl_message_get_recipient(m), ZGetSender()) ||
472        !strcasecmp(owl_message_get_sender(m), ZGetSender())) {
473      return(1);
474    }
475  }
476  return(0);
477}
478
479int owl_message_is_from_me(owl_message *m)
480{
481  if (owl_message_is_type_zephyr(m)) {
482    if (!strcasecmp(owl_message_get_sender(m), ZGetSender())) {
483      return(1);
484    } else {
485      return(0);
486    }
487  } else if (owl_message_is_type_aim(m)) {
488    if (!strcasecmp(owl_message_get_sender(m), owl_global_get_aim_screenname(&g))) {
489      return(1);
490    } else {
491      return(0);
492    }
493  } else if (owl_message_is_type_admin(m)) {
494    return(0);
495  }
496  return(0);
497}
498
499int owl_message_is_mail(owl_message *m)
500{
501  if (owl_message_is_type_zephyr(m)) {
502    if (!strcasecmp(owl_message_get_class(m), "mail") && owl_message_is_private(m)) {
503      return(1);
504    } else {
505      return(0);
506    }
507  }
508  return(0);
509}
510
511int owl_message_is_ping(owl_message *m)
512{
513  if (owl_message_is_type_zephyr(m)) {
514    if (!strcasecmp(owl_message_get_opcode(m), "ping")) {
515      return(1);
516    } else {
517      return(0);
518    }
519  }
520  return(0);
521}
522
523int owl_message_is_burningears(owl_message *m)
524{
525  /* we should add a global to cache the short zsender */
526  char sender[LINE], *ptr;
527
528  /* if the message is from us or to us, it doesn't count */
529  if (owl_message_is_from_me(m) || owl_message_is_private(m)) return(0);
530
531  if (owl_message_is_type_zephyr(m)) {
532    strcpy(sender, ZGetSender());
533    ptr=strchr(sender, '@');
534    if (ptr) *ptr='\0';
535  } else if (owl_message_is_type_aim(m)) {
536    strcpy(sender, owl_global_get_aim_screenname(&g));
537  } else {
538    return(0);
539  }
540
541  if (stristr(owl_message_get_body(m), sender)) {
542    return(1);
543  }
544  return(0);
545}
546
547/* caller must free return value. */
548char *owl_message_get_cc(owl_message *m)
549{
550  char *cur, *out, *end;
551
552  cur = owl_message_get_body(m);
553  while (*cur && *cur==' ') cur++;
554  if (strncasecmp(cur, "cc:", 3)) return(NULL);
555  cur+=3;
556  while (*cur && *cur==' ') cur++;
557  out = owl_strdup(cur);
558  end = strchr(out, '\n');
559  if (end) end[0] = '\0';
560  return(out);
561}
562
563int owl_message_get_id(owl_message *m)
564{
565  return(m->id);
566}
567
568/* return 1 if the message contains "string", 0 otherwise.  This is
569 * case insensitive because the functions it uses are
570 */
571int owl_message_search(owl_message *m, char *string)
572{
573
574  owl_message_format(m); /* is this necessary? */
575 
576  return (owl_fmtext_search(&(m->fmtext), string));
577}
578
579
580/* if loginout == -1 it's a logout message
581 *                 0 it's not a login/logout message
582 *                 1 it's a login message
583 */
584void owl_message_create_aim(owl_message *m, char *sender, char *recipient, char *text, int direction, int loginout)
585{
586  owl_message_init(m);
587  owl_message_set_body(m, text);
588  owl_message_set_sender(m, sender);
589  owl_message_set_recipient(m, recipient);
590  owl_message_set_type_aim(m);
591
592  if (direction==OWL_MESSAGE_DIRECTION_IN) {
593    owl_message_set_direction_in(m);
594  } else if (direction==OWL_MESSAGE_DIRECTION_OUT) {
595    owl_message_set_direction_out(m);
596  }
597
598  /* for now all messages that aren't loginout are private */
599  if (!loginout) {
600    owl_message_set_isprivate(m);
601  }
602
603  if (loginout==-1) {
604    owl_message_set_islogout(m);
605  } else if (loginout==1) {
606    owl_message_set_islogin(m);
607  }
608}
609
610void owl_message_create_admin(owl_message *m, char *header, char *text)
611{
612  owl_message_init(m);
613  owl_message_set_type_admin(m);
614  owl_message_set_body(m, text);
615  owl_message_set_attribute(m, "adminheader", header); /* just a hack for now */
616}
617
618void owl_message_create_from_znotice(owl_message *m, ZNotice_t *n)
619{
620  struct hostent *hent;
621  int k;
622  char *ptr, *tmp, *tmp2;
623
624  owl_message_init(m);
625 
626  owl_message_set_type_zephyr(m);
627  owl_message_set_direction_in(m);
628 
629  /* first save the full notice */
630  memcpy(&(m->notice), n, sizeof(ZNotice_t));
631
632  /* a little gross, we'll reaplace \r's with ' ' for now */
633  owl_zephyr_hackaway_cr(&(m->notice));
634 
635  m->delete=0;
636
637  /* set other info */
638  owl_message_set_sender(m, n->z_sender);
639  owl_message_set_class(m, n->z_class);
640  owl_message_set_instance(m, n->z_class_inst);
641  owl_message_set_recipient(m, n->z_recipient);
642  if (n->z_opcode) {
643    owl_message_set_opcode(m, n->z_opcode);
644  } else {
645    owl_message_set_opcode(m, "");
646  }
647  owl_message_set_zsig(m, n->z_message);
648
649  if ((ptr=strchr(n->z_recipient, '@'))!=NULL) {
650    owl_message_set_realm(m, ptr+1);
651  } else {
652    owl_message_set_realm(m, ZGetRealm());
653  }
654
655  /* Set the "isloginout" attribute if it's a login message */
656  if (!strcasecmp(n->z_class, "login")) {
657    if (!strcasecmp(n->z_opcode, "user_login")) {
658      owl_message_set_islogin(m);
659    } else if (!strcasecmp(n->z_opcode, "user_logout")) {
660      owl_message_set_islogout(m);
661    }
662  }
663
664  /* is the "isprivate" attribute if it's a private zephyr */
665  if (!strcasecmp(n->z_recipient, ZGetSender())) {
666    owl_message_set_isprivate(m);
667  }
668
669  m->zwriteline=strdup("");
670
671  /* set the body */
672  ptr=owl_zephyr_get_message(n, &k);
673  tmp=owl_malloc(k+10);
674  memcpy(tmp, ptr, k);
675  tmp[k]='\0';
676  if (owl_global_is_newlinestrip(&g)) {
677    tmp2=owl_util_stripnewlines(tmp);
678    owl_message_set_body(m, tmp2);
679    owl_free(tmp2);
680  } else {
681    owl_message_set_body(m, tmp);
682  }
683  owl_free(tmp);
684
685#ifdef OWL_ENABLE_ZCRYPT
686  /* if zcrypt is enabled try to decrypt the message */
687  if (owl_global_is_zcrypt(&g) && !strcasecmp(n->z_opcode, "crypt")) {
688    char *out;
689    int ret;
690
691    out=owl_malloc(strlen(owl_message_get_body(m))*16+20);
692    ret=zcrypt_decrypt(out, owl_message_get_body(m), owl_message_get_class(m), owl_message_get_instance(m));
693    if (ret==0) {
694      owl_message_set_body(m, out);
695    } else {
696      owl_free(out);
697    }
698  }
699#endif 
700
701  /* save the hostname */
702  owl_function_debugmsg("About to do gethostbyaddr");
703  hent=gethostbyaddr((char *) &(n->z_uid.zuid_addr), sizeof(n->z_uid.zuid_addr), AF_INET);
704  if (hent && hent->h_name) {
705    strcpy(m->hostname, hent->h_name);
706  } else {
707    strcpy(m->hostname, inet_ntoa(n->z_sender_addr));
708  }
709
710  /* save the time */
711  m->time=owl_strdup(ctime((time_t *) &n->z_time.tv_sec));
712  m->time[strlen(m->time)-1]='\0';
713}
714
715void owl_message_create_from_zwriteline(owl_message *m, char *line, char *body, char *zsig)
716{
717  owl_zwrite z;
718  int ret;
719 
720  owl_message_init(m);
721
722  /* create a zwrite for the purpose of filling in other message fields */
723  owl_zwrite_create_from_line(&z, line);
724
725  /* set things */
726  owl_message_set_direction_out(m);
727  owl_message_set_type_zephyr(m);
728  owl_message_set_sender(m, ZGetSender());
729  owl_message_set_class(m, owl_zwrite_get_class(&z));
730  owl_message_set_instance(m, owl_zwrite_get_instance(&z));
731  owl_message_set_recipient(m,
732                            long_zuser(owl_zwrite_get_recip_n(&z, 0))); /* only gets the first user, must fix */
733  owl_message_set_opcode(m, owl_zwrite_get_opcode(&z));
734  owl_message_set_realm(m, owl_zwrite_get_realm(&z)); /* also a hack, but not here */
735  m->zwriteline=owl_strdup(line);
736  owl_message_set_body(m, body);
737  owl_message_set_zsig(m, zsig);
738 
739  /* save the hostname */
740  ret=gethostname(m->hostname, MAXHOSTNAMELEN);
741  if (ret) {
742    strcpy(m->hostname, "localhost");
743  }
744
745  owl_zwrite_free(&z);
746}
747
748
749void owl_message_pretty_zsig(owl_message *m, char *buff)
750{
751  /* stick a one line version of the zsig in buff */
752  char *ptr;
753
754  strcpy(buff, owl_message_get_zsig(m));
755  ptr=strchr(buff, '\n');
756  if (ptr) ptr[0]='\0';
757}
758
759void owl_message_free(owl_message *m)
760{
761  int i, j;
762  owl_pair *p;
763   
764  if (owl_message_is_type_zephyr(m) && owl_message_is_direction_in(m)) {
765    ZFreeNotice(&(m->notice));
766  }
767  if (m->time) owl_free(m->time);
768  if (m->zwriteline) owl_free(m->zwriteline);
769
770  /* free all the attributes */
771  j=owl_list_get_size(&(m->attributes));
772  for (i=0; i<j; i++) {
773    p=owl_list_get_element(&(m->attributes), i);
774    owl_free(owl_pair_get_key(p));
775    owl_free(owl_pair_get_value(p));
776    owl_free(p);
777  }
778
779  owl_list_free_simple(&(m->attributes));
780 
781  owl_fmtext_free(&(m->fmtext));
782}
Note: See TracBrowser for help on using the repository browser.