source: message.c @ 1d3e925

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