source: zephyr.c @ db654df

owl
Last change on this file since db654df was db654df, checked in by James M. Kretchmar <kretch@mit.edu>, 16 years ago
remove the excessive process_events (it oddly made the situation worse) and instead call it just on sending login and logout notificatinos. new debug message in loadsubs new handle_ack
  • Property mode set to 100644
File size: 24.9 KB
Line 
1#include <stdlib.h>
2#include <unistd.h>
3#include <sys/types.h>
4#include <sys/wait.h>
5#include <sys/stat.h>
6#include <string.h>
7#include "owl.h"
8
9static const char fileIdent[] = "$Id$";
10
11#ifdef HAVE_LIBZEPHYR
12Code_t ZResetAuthentication();
13#endif
14
15int owl_zephyr_initialize()
16{
17#ifdef HAVE_LIBZEPHYR
18  int ret;
19 
20  if ((ret = ZInitialize()) != ZERR_NONE) {
21    com_err("owl",ret,"while initializing");
22    return(1);
23  }
24  if ((ret = ZOpenPort(NULL)) != ZERR_NONE) {
25    com_err("owl",ret,"while opening port");
26    return(1);
27  }
28#endif
29  return(0);
30}
31
32
33int owl_zephyr_shutdown()
34{
35#ifdef HAVE_LIBZEPHYR
36  unsuball();
37  ZClosePort();
38#endif
39  return(0);
40}
41
42int owl_zephyr_zpending()
43{
44#ifdef HAVE_LIBZEPHYR
45  return(ZPending());
46#else
47  return(0);
48#endif
49}
50
51char *owl_zephyr_get_realm()
52{
53#ifdef HAVE_LIBZEPHYR
54  return(ZGetRealm());
55#else
56  return("");
57#endif
58}
59
60char *owl_zephyr_get_sender()
61{
62#ifdef HAVE_LIBZEPHYR
63  return(ZGetSender());
64#else
65  return("");
66#endif
67}
68
69#ifdef HAVE_LIBZEPHYR
70int owl_zephyr_loadsubs_helper(ZSubscription_t subs[], int count)
71{
72  int i, ret = 0;
73  /* sub without defaults */
74  if (ZSubscribeToSansDefaults(subs,count,0) != ZERR_NONE) {
75    owl_function_error("Error subscribing to zephyr notifications.");
76    ret=-2;
77  }
78
79  /* free stuff */
80  for (i=0; i<count; i++) {
81    owl_free(subs[i].zsub_class);
82    owl_free(subs[i].zsub_classinst);
83    owl_free(subs[i].zsub_recipient);
84  }
85  return ret;
86}
87#endif
88
89/* Load zephyr subscriptions form 'filename'.  If 'filename' is NULL,
90 * the default file $HOME/.zephyr.subs will be used.
91 *
92 * Returns 0 on success.  If the file does not exist, return -1 if
93 * 'error_on_nofile' is 1, otherwise return 0.  Return -1 if the file
94 * exists but can not be read.  Return -2 if there is a failure from
95 * zephyr to load the subscriptions.
96 */
97int owl_zephyr_loadsubs(char *filename, int error_on_nofile)
98{
99#ifdef HAVE_LIBZEPHYR
100  FILE *file;
101  char *tmp, *start;
102  char buffer[1024], subsfile[1024];
103  ZSubscription_t subs[3001];
104  int count, ret;
105  struct stat statbuff;
106
107  if (filename==NULL) {
108    sprintf(subsfile, "%s/%s", owl_global_get_homedir(&g), ".zephyr.subs");
109  } else {
110    strcpy(subsfile, filename);
111  }
112
113  ret=stat(subsfile, &statbuff);
114  if (ret) {
115    owl_function_debugmsg("loadsubs: could not stat file %s", subsfile)
116    if (error_on_nofile==1) return(-1);
117    return(0);
118  }
119
120  ZResetAuthentication();
121  count=0;
122  file=fopen(subsfile, "r");
123  if (!file) {
124    owl_function_debugmsg("loadsubs: could not open file %s", subsfile)
125    return(-1);
126  }
127  while ( fgets(buffer, 1024, file)!=NULL ) {
128    if (buffer[0]=='#' || buffer[0]=='\n' || buffer[0]=='\n') continue;
129   
130    if (buffer[0]=='-') {
131      start=buffer+1;
132    } else {
133      start=buffer;
134    }
135   
136    if (count >= 3000) {
137      ret = owl_zephyr_loadsubs_helper(subs, count);
138      if (ret != 0) {
139        fclose(file);
140        return(ret);
141      }
142      count=0;
143    }
144   
145    /* add it to the list of subs */
146    if ((tmp=(char *) strtok(start, ",\n\r"))==NULL) continue;
147    subs[count].zsub_class=owl_strdup(tmp);
148    if ((tmp=(char *) strtok(NULL, ",\n\r"))==NULL) continue;
149    subs[count].zsub_classinst=owl_strdup(tmp);
150    if ((tmp=(char *) strtok(NULL, " \t\n\r"))==NULL) continue;
151    subs[count].zsub_recipient=owl_strdup(tmp);
152   
153    /* if it started with '-' then add it to the global punt list */
154    if (buffer[0]=='-') {
155      owl_function_zpunt(subs[count].zsub_class, subs[count].zsub_classinst, subs[count].zsub_recipient, 0);
156    }
157   
158    count++;
159  }
160  fclose(file);
161
162  ret=owl_zephyr_loadsubs_helper(subs, count);
163
164  return(ret);
165#else
166  return(0);
167#endif
168}
169
170int owl_zephyr_loaddefaultsubs()
171{
172#ifdef HAVE_LIBZEPHYR
173  ZSubscription_t subs[10];
174   
175  if (ZSubscribeTo(subs,0,0) != ZERR_NONE) {
176    owl_function_error("Error subscribing to default zephyr notifications.");
177    return(-1);
178  }
179  return(0);
180#else
181  return(0);
182#endif
183}
184
185int owl_zephyr_loadloginsubs(char *filename)
186{
187#ifdef HAVE_LIBZEPHYR
188  FILE *file;
189  ZSubscription_t subs[3001];
190  char subsfile[1024], buffer[1024];
191  int count, ret, i;
192  struct stat statbuff;
193
194  if (filename==NULL) {
195    sprintf(subsfile, "%s/%s", owl_global_get_homedir(&g), ".anyone");
196  } else {
197    strcpy(subsfile, filename);
198  }
199 
200  ret=stat(subsfile, &statbuff);
201  if (ret) return(0);
202
203  ret=0;
204
205  ZResetAuthentication();
206  /* need to redo this to do chunks, not just bag out after 3000 */
207  count=0;
208  file=fopen(subsfile, "r");
209  if (file) {
210    while ( fgets(buffer, 1024, file)!=NULL ) {
211      if (buffer[0]=='#' || buffer[0]=='\n' || buffer[0]=='\n') continue;
212     
213      if (count >= 3000) break; /* also tell the user */
214
215      buffer[strlen(buffer)-1]='\0';
216      subs[count].zsub_class="login";
217      subs[count].zsub_recipient="*";
218      if (strchr(buffer, '@')) {
219        subs[count].zsub_classinst=owl_strdup(buffer);
220      } else {
221        subs[count].zsub_classinst=owl_sprintf("%s@%s", buffer, ZGetRealm());
222      }
223
224      count++;
225    }
226    fclose(file);
227  } else {
228    count=0;
229    ret=-1;
230  }
231
232  /* sub with defaults */
233  if (ZSubscribeToSansDefaults(subs,count,0) != ZERR_NONE) {
234    owl_function_error("Error subscribing to zephyr notifications.");
235    ret=-2;
236  }
237
238  /* free stuff */
239  for (i=0; i<count; i++) {
240    owl_free(subs[i].zsub_classinst);
241  }
242
243  return(ret);
244#else
245  return(0);
246#endif
247}
248
249void unsuball()
250{
251#if HAVE_LIBZEPHYR
252  int ret;
253
254  ZResetAuthentication();
255  ret=ZCancelSubscriptions(0);
256  if (ret != ZERR_NONE) {
257    com_err("owl",ret,"while unsubscribing");
258  }
259#endif
260}
261
262int owl_zephyr_sub(char *class, char *inst, char *recip)
263{
264#ifdef HAVE_LIBZEPHYR
265  ZSubscription_t subs[5];
266
267  subs[0].zsub_class=class;
268  subs[0].zsub_classinst=inst;
269  subs[0].zsub_recipient=recip;
270
271  ZResetAuthentication();
272  if (ZSubscribeTo(subs,1,0) != ZERR_NONE) {
273    owl_function_error("Error subbing to <%s,%s,%s>", class, inst, recip);
274    return(-2);
275  }
276  return(0);
277#else
278  return(0);
279#endif
280}
281
282
283int owl_zephyr_unsub(char *class, char *inst, char *recip)
284{
285#ifdef HAVE_LIBZEPHYR
286  ZSubscription_t subs[5];
287
288  subs[0].zsub_class=class;
289  subs[0].zsub_classinst=inst;
290  subs[0].zsub_recipient=recip;
291
292  ZResetAuthentication();
293  if (ZUnsubscribeTo(subs,1,0) != ZERR_NONE) {
294    owl_function_error("Error unsubbing from <%s,%s,%s>", class, inst, recip);
295    return(-2);
296  }
297  return(0);
298#else
299  return(0);
300#endif
301}
302
303/* return a pointer to the data in the Jth field, (NULL terminated by
304 * definition).  Caller must free the return.
305 */
306#ifdef HAVE_LIBZEPHYR
307char *owl_zephyr_get_field(ZNotice_t *n, int j)
308{
309  int i, count, save;
310  char *out;
311
312  /* If there's no message here, just run along now */
313  if (n->z_message_len == 0)
314    return(owl_strdup(""));
315
316  count=save=0;
317  for (i=0; i<n->z_message_len; i++) {
318    if (n->z_message[i]=='\0') {
319      count++;
320      if (count==j) {
321        /* just found the end of the field we're looking for */
322        return(owl_strdup(n->z_message+save));
323      } else {
324        save=i+1;
325      }
326    }
327  }
328  /* catch the last field, which might not be null terminated */
329  if (count==j-1) {
330    out=owl_malloc(n->z_message_len-save+5);
331    memcpy(out, n->z_message+save, n->z_message_len-save);
332    out[n->z_message_len-save]='\0';
333    return(out);
334  }
335
336  return(owl_strdup(""));
337}
338#else
339char *owl_zephyr_get_field(void *n, int j)
340{
341  return(owl_strdup(""));
342}
343#endif
344
345
346#ifdef HAVE_LIBZEPHYR
347int owl_zephyr_get_num_fields(ZNotice_t *n)
348{
349  int i, fields;
350
351  if(n->z_message_len == 0)
352    return 0;
353
354  fields=1;
355  for (i=0; i<n->z_message_len; i++) {
356    if (n->z_message[i]=='\0') fields++;
357  }
358 
359  return(fields);
360}
361#else
362int owl_zephyr_get_num_fields(void *n)
363{
364  return(0);
365}
366#endif
367
368#ifdef HAVE_LIBZEPHYR
369/* return a pointer to the message, place the message length in k
370 * caller must free the return
371 */
372char *owl_zephyr_get_message(ZNotice_t *n)
373{
374  /* don't let ping messages have a body */
375  if (!strcasecmp(n->z_opcode, "ping")) {
376    return(owl_strdup(""));
377  }
378
379  /* deal with MIT Athena OLC messages */
380  if (!strcasecmp(n->z_sender, "olc.matisse@ATHENA.MIT.EDU")) {
381    return(owl_zephyr_get_field(n, 1));
382  }
383  /* deal with MIT NOC messages */
384  else if (!strcasecmp(n->z_sender, "rcmd.achilles@ATHENA.MIT.EDU")) {
385    /* $opcode service on $instance $3.\n$4 */
386    char *msg, *opcode, *instance, *field3, *field4;
387
388    opcode = n->z_opcode;
389    instance = n->z_class_inst;
390    field3 = owl_zephyr_get_field(n, 3);
391    field4 = owl_zephyr_get_field(n, 4);
392
393    msg = owl_sprintf("%s service on %s %s\n%s", opcode, instance, field3, field4);
394    if (msg) {
395      return msg;
396    }
397  }
398
399  return(owl_zephyr_get_field(n, 2));
400}
401#endif
402
403#ifdef HAVE_LIBZEPHYR
404char *owl_zephyr_get_zsig(ZNotice_t *n, int *k)
405{
406  /* return a pointer to the zsig if there is one */
407
408  /* message length 0? No zsig */
409  if (n->z_message_len==0) {
410    *k=0;
411    return("");
412  }
413
414  /* No zsig for OLC messages */
415  if (!strcasecmp(n->z_sender, "olc.matisse@ATHENA.MIT.EDU")) {
416    return("");
417  }
418
419  /* Everything else is field 1 */
420  *k=strlen(n->z_message);
421  return(n->z_message);
422}
423#else
424char *owl_zephyr_get_zsig(void *n, int *k)
425{
426  return("");
427}
428#endif
429
430int send_zephyr(char *opcode, char *zsig, char *class, char *instance, char *recipient, char *message)
431{
432#ifdef HAVE_LIBZEPHYR
433  int ret;
434  ZNotice_t notice;
435   
436  memset(&notice, 0, sizeof(notice));
437
438  ZResetAuthentication();
439
440  if (!zsig) zsig="";
441 
442  notice.z_kind=ACKED;
443  notice.z_port=0;
444  notice.z_class=class;
445  notice.z_class_inst=instance;
446  if (!strcmp(recipient, "*") || !strcmp(recipient, "@")) {
447    notice.z_recipient="";
448  } else {
449    notice.z_recipient=recipient;
450  }
451  notice.z_default_format="Class $class, Instance $instance:\nTo: @bold($recipient) at $time $date\nFrom: @bold{$1 <$sender>}\n\n$2";
452  notice.z_sender=NULL;
453  if (opcode) notice.z_opcode=opcode;
454
455  notice.z_message_len=strlen(zsig)+1+strlen(message);
456  notice.z_message=owl_malloc(notice.z_message_len+10);
457  strcpy(notice.z_message, zsig);
458  memcpy(notice.z_message+strlen(zsig)+1, message, strlen(message));
459
460  /* ret=ZSendNotice(&notice, ZAUTH); */
461  ret=ZSrvSendNotice(&notice, ZAUTH, send_zephyr_helper);
462 
463  /* free then check the return */
464  owl_free(notice.z_message);
465  ZFreeNotice(&notice);
466  if (ret!=ZERR_NONE) {
467    owl_function_error("Error sending zephyr");
468    return(ret);
469  }
470  return(0);
471#else
472  return(0);
473#endif
474}
475
476#ifdef HAVE_LIBZEPHYR
477Code_t send_zephyr_helper(ZNotice_t *notice, char *buf, int len, int wait)
478{
479  int ret;
480  ret=ZSendPacket(buf, len, 0);
481  return(ret);
482}
483#endif
484
485void send_ping(char *to)
486{
487#ifdef HAVE_LIBZEPHYR
488  send_zephyr("PING", "", "MESSAGE", "PERSONAL", to, "");
489#endif
490}
491
492#ifdef HAVE_LIBZEPHYR
493void owl_zephyr_handle_ack(ZNotice_t *retnotice)
494{
495  char *tmp;
496 
497  /* if it's an HMACK ignore it */
498  if (retnotice->z_kind == HMACK) return;
499
500  if (retnotice->z_kind == SERVNAK) {
501    owl_function_error("Authorization failure sending zephyr");
502  } else if ((retnotice->z_kind != SERVACK) || !retnotice->z_message_len) {
503    owl_function_error("Detected server failure while receiving acknowledgement");
504  } else if (!strcmp(retnotice->z_message, ZSRVACK_SENT)) {
505    if (!strcasecmp(retnotice->z_opcode, "ping")) {
506      return;
507    } else if (!strcasecmp(retnotice->z_class, "message") &&
508               !strcasecmp(retnotice->z_class_inst, "personal")) {
509      tmp=short_zuser(retnotice->z_recipient);
510      owl_function_makemsg("Message sent to %s.", tmp);
511      free(tmp);
512    } else {
513      owl_function_makemsg("Message sent to -c %s -i %s\n", retnotice->z_class, retnotice->z_class_inst);
514    }
515  } else if (!strcmp(retnotice->z_message, ZSRVACK_NOTSENT)) {
516    #define BUFFLEN 1024
517    if (retnotice->z_recipient == NULL
518        || *retnotice->z_recipient == 0
519        || *retnotice->z_recipient == '@') {
520      char buff[BUFFLEN];
521      owl_function_error("No one subscribed to class %s", retnotice->z_class);
522      snprintf(buff, BUFFLEN, "Could not send message to class %s: no one subscribed.\n", retnotice->z_class);
523      owl_function_adminmsg("", buff);
524    } else {
525      char buff[BUFFLEN];
526      tmp = short_zuser(retnotice->z_recipient);
527      owl_function_error("%s: Not logged in or subscribing.", tmp);
528      if(strcmp(retnotice->z_class, "message")) {
529        snprintf(buff, BUFFLEN,
530                 "Could not send message to %s: "
531                 "not logged in or subscribing to class %s, instance %s.\n", 
532                 tmp,
533                 retnotice->z_class,
534                 retnotice->z_class_inst);
535      } else {
536        snprintf(buff, BUFFLEN,
537                 "Could not send message to %s: "
538                 "not logged in or subscribing to messages.\n",
539                 tmp);
540      }
541      owl_function_adminmsg("", buff);
542      owl_log_outgoing_zephyr_error(tmp, buff);
543      owl_free(tmp);
544    }
545  } else {
546    owl_function_error("Internal error on ack (%s)", retnotice->z_message);
547  }
548}
549#else
550void owl_zephyr_handle_ack(void *retnotice)
551{
552}
553#endif
554
555#ifdef HAVE_LIBZEPHYR
556int owl_zephyr_notice_is_ack(ZNotice_t *n)
557{
558  if (n->z_kind == SERVNAK || n->z_kind == SERVACK || n->z_kind == HMACK) {
559    if (!strcasecmp(n->z_class, LOGIN_CLASS)) return(0);
560    return(1);
561  }
562  return(0);
563}
564#else
565int owl_zephyr_notice_is_ack(void *n)
566{
567  return(0);
568}
569#endif
570 
571void owl_zephyr_zaway(owl_message *m)
572{
573#ifdef HAVE_LIBZEPHYR
574  char *tmpbuff, *myuser, *to;
575  owl_message *mout;
576 
577  /* bail if it doesn't look like a message we should reply to.  Some
578   * of this defined by the way zaway(1) works
579   */
580  if (strcasecmp(owl_message_get_class(m), "message")) return;
581  if (strcasecmp(owl_message_get_recipient(m), ZGetSender())) return;
582  if (!strcasecmp(owl_message_get_sender(m), "")) return;
583  if (!strcasecmp(owl_message_get_opcode(m), "ping")) return;
584  if (!strcasecmp(owl_message_get_opcode(m), "auto")) return;
585  if (!strcasecmp(owl_message_get_zsig(m), "Automated reply:")) return;
586  if (!strcasecmp(owl_message_get_sender(m), ZGetSender())) return;
587  if (owl_message_get_attribute_value(m, "isauto")) return;
588
589  if (owl_global_is_smartstrip(&g)) {
590    to=owl_zephyr_smartstripped_user(owl_message_get_sender(m));
591  } else {
592    to=owl_strdup(owl_message_get_sender(m));
593  }
594
595  send_zephyr("",
596              "Automated reply:",
597              owl_message_get_class(m),
598              owl_message_get_instance(m),
599              to,
600              owl_global_get_zaway_msg(&g));
601
602  myuser=short_zuser(to);
603  if (!strcasecmp(owl_message_get_instance(m), "personal")) {
604    tmpbuff = owl_sprintf("zwrite %s", myuser);
605  } else {
606    tmpbuff = owl_sprintf("zwrite -i %s %s", owl_message_get_instance(m), myuser);
607  }
608  owl_free(myuser);
609  owl_free(to);
610
611  /* display the message as an admin message in the receive window */
612  mout=owl_function_make_outgoing_zephyr(owl_global_get_zaway_msg(&g), tmpbuff, "Automated reply:");
613  owl_function_add_message(mout);
614  owl_free(tmpbuff);
615#endif
616}
617
618#ifdef HAVE_LIBZEPHYR
619void owl_zephyr_hackaway_cr(ZNotice_t *n)
620{
621  /* replace \r's with ' '.  Gross-ish */
622  int i;
623
624  for (i=0; i<n->z_message_len; i++) {
625    if (n->z_message[i]=='\r') {
626      n->z_message[i]=' ';
627    }
628  }
629}
630#endif
631
632char *owl_zephyr_zlocate(char *user, int auth)
633{
634#ifdef HAVE_LIBZEPHYR
635  int ret, numlocs;
636  int one = 1;
637  ZLocations_t locations;
638  char *myuser, *out, *tmp;
639 
640  ZResetAuthentication();
641  ret=ZLocateUser(user,&numlocs,auth?ZAUTH:ZNOAUTH);
642  if (ret != ZERR_NONE) {
643    return(owl_sprintf("Error locating user %s\n", user));
644  }
645
646  if (numlocs==0) {
647    myuser=short_zuser(user);
648    out=owl_sprintf("%s: Hidden or not logged in\n", myuser);
649    owl_free(myuser);
650    return(out);
651  }
652
653  out=strdup("");
654  for (;numlocs;numlocs--) {
655    ZGetLocations(&locations,&one);
656    myuser=short_zuser(user);
657    tmp=owl_sprintf("%s%s: %s\t%s\t%s\n",
658                    out,
659                    myuser,
660                    locations.host ? locations.host : "?",
661                    locations.tty ? locations.tty : "?",
662                    locations.time ? locations.time : "?");
663    owl_free(out);
664    out=tmp;
665    owl_free(myuser);
666  }
667  return(out);
668#else
669  return(owl_strdup("Zephyr not available"));
670#endif
671}
672
673void owl_zephyr_addsub(char *filename, char *class, char *inst, char *recip)
674{
675#ifdef HAVE_LIBZEPHYR
676  char *line, subsfile[LINE], buff[LINE];
677  FILE *file;
678
679  line=owl_zephyr_makesubline(class, inst, recip);
680
681  if (filename==NULL) {
682    sprintf(subsfile, "%s/%s", owl_global_get_homedir(&g), ".zephyr.subs");
683  } else {
684    strcpy(subsfile, filename);
685  }
686
687  /* if the file already exists, check to see if the sub is already there */
688  file=fopen(subsfile, "r");
689  if (file) {
690    while (fgets(buff, LINE, file)!=NULL) {
691      if (!strcasecmp(buff, line)) {
692        owl_function_error("Subscription already present in %s", subsfile);
693        owl_free(line);
694        fclose(file);
695        return;
696      }
697    }
698    fclose(file);
699  }
700
701  /* if we get here then we didn't find it */
702  file=fopen(subsfile, "a");
703  if (!file) {
704    owl_function_error("Error opening file %s for writing", subsfile);
705    owl_free(line);
706    return;
707  }
708  fputs(line, file);
709  fclose(file);
710  owl_function_makemsg("Subscription added");
711 
712  owl_free(line);
713#endif
714}
715
716void owl_zephyr_delsub(char *filename, char *class, char *inst, char *recip)
717{
718#ifdef HAVE_LIBZEPHYR
719  char *line, *subsfile;
720 
721  line=owl_zephyr_makesubline(class, inst, recip);
722  line[strlen(line)-1]='\0';
723
724  if (!filename) {
725    subsfile=owl_sprintf("%s/.zephyr.subs", owl_global_get_homedir(&g));
726  } else {
727    subsfile=owl_strdup(filename);
728  }
729 
730  owl_util_file_deleteline(subsfile, line, 1);
731  owl_free(subsfile);
732  owl_free(line);
733  owl_function_makemsg("Subscription removed");
734#endif
735}
736
737/* caller must free the return */
738char *owl_zephyr_makesubline(char *class, char *inst, char *recip)
739{
740  return(owl_sprintf("%s,%s,%s\n", class, inst, !strcmp(recip, "") ? "*" : recip));
741}
742
743void owl_zephyr_zlog_in(void)
744{
745#ifdef HAVE_LIBZEPHYR
746  char *exposure, *eset;
747  int ret;
748
749  ZResetAuthentication();
750   
751  eset=EXPOSE_REALMVIS;
752  exposure=ZGetVariable("exposure");
753  if (exposure==NULL) {
754    eset=EXPOSE_REALMVIS;
755  } else if (!strcasecmp(exposure,EXPOSE_NONE)) {
756    eset = EXPOSE_NONE;
757  } else if (!strcasecmp(exposure,EXPOSE_OPSTAFF)) {
758    eset = EXPOSE_OPSTAFF;
759  } else if (!strcasecmp(exposure,EXPOSE_REALMVIS)) {
760    eset = EXPOSE_REALMVIS;
761  } else if (!strcasecmp(exposure,EXPOSE_REALMANN)) {
762    eset = EXPOSE_REALMANN;
763  } else if (!strcasecmp(exposure,EXPOSE_NETVIS)) {
764    eset = EXPOSE_NETVIS;
765  } else if (!strcasecmp(exposure,EXPOSE_NETANN)) {
766    eset = EXPOSE_NETANN;
767  }
768   
769  ret=ZSetLocation(eset);
770  owl_zephyr_process_events(NULL);
771  if (ret != ZERR_NONE) {
772    /* owl_function_makemsg("Error setting location: %s", error_message(ret)); */
773  }
774#endif
775}
776
777void owl_zephyr_zlog_out(void)
778{
779#ifdef HAVE_LIBZEPHYR
780  int ret;
781
782  ZResetAuthentication();
783  ret=ZUnsetLocation();
784  owl_zephyr_process_events(NULL);
785  if (ret != ZERR_NONE) {
786    /* owl_function_makemsg("Error unsetting location: %s", error_message(ret)); */
787  }
788#endif
789}
790
791void owl_zephyr_addbuddy(char *name)
792{
793  char *filename;
794  FILE *file;
795 
796  filename=owl_sprintf("%s/.anyone", owl_global_get_homedir(&g));
797  file=fopen(filename, "a");
798  owl_free(filename);
799  if (!file) {
800    owl_function_error("Error opening zephyr buddy file for append");
801    return;
802  }
803  fprintf(file, "%s\n", name);
804  fclose(file);
805}
806
807void owl_zephyr_delbuddy(char *name)
808{
809  char *filename;
810
811  filename=owl_sprintf("%s/.anyone", owl_global_get_homedir(&g));
812  owl_util_file_deleteline(filename, name, 0);
813  owl_free(filename);
814}
815
816/* return auth string */
817#ifdef HAVE_LIBZEPHYR
818char *owl_zephyr_get_authstr(ZNotice_t *n)
819{
820
821  if (!n) return("UNKNOWN");
822
823  if (n->z_auth == ZAUTH_FAILED) {
824    return ("FAILED");
825  } else if (n->z_auth == ZAUTH_NO) {
826    return ("NO");
827  } else if (n->z_auth == ZAUTH_YES) {
828    return ("YES");
829  } else {
830    return ("UNKNOWN");
831  }           
832}
833#else
834char *owl_zephyr_get_authstr(void *n)
835{
836  return("");
837}
838#endif
839
840/* Returns a buffer of subscriptions or an error message.  Caller must
841 * free the return.
842 */
843char *owl_zephyr_getsubs()
844{
845#ifdef HAVE_LIBZEPHYR
846  int ret, num, i, one;
847  int buffsize;
848  ZSubscription_t sub;
849  char *out;
850  one=1;
851
852  ret=ZRetrieveSubscriptions(0, &num);
853  if (ret==ZERR_TOOMANYSUBS) {
854    return(owl_strdup("Zephyr: too many subscriptions\n"));
855  } else if (ret || (num <= 0)) {
856    return(owl_strdup("Zephyr: error retriving subscriptions\n"));
857  }
858
859  buffsize = (num + 1) * 50;
860  out=owl_malloc(buffsize);
861  strcpy(out, "");
862  for (i=0; i<num; i++) {
863    if ((ret = ZGetSubscriptions(&sub, &one)) != ZERR_NONE) {
864      owl_free(out);
865      ZFlushSubscriptions();
866      out=owl_strdup("Error while getting subscriptions\n");
867      return(out);
868    } else {
869      int tmpbufflen;
870      char *tmpbuff;
871      tmpbuff = owl_sprintf("<%s,%s,%s>\n%s", sub.zsub_class, sub.zsub_classinst, sub.zsub_recipient, out);
872      tmpbufflen = strlen(tmpbuff) + 1;
873      if (tmpbufflen > buffsize) {
874        char *out2;
875        buffsize = tmpbufflen * 2;
876        out2 = owl_realloc(out, buffsize);
877        if (out2 == NULL) {
878          owl_free(out);
879          owl_free(tmpbuff);
880          ZFlushSubscriptions();
881          out=owl_strdup("Realloc error while getting subscriptions\n");
882          return(out);   
883        }
884        out = out2;
885      }
886      strcpy(out, tmpbuff);
887      owl_free(tmpbuff);
888    }
889  }
890
891  ZFlushSubscriptions();
892  return(out);
893#else
894  return(owl_strdup("Zephyr not available"));
895#endif
896}
897
898char *owl_zephyr_get_variable(char *var)
899{
900#ifdef HAVE_LIBZEPHYR
901  return(ZGetVariable(var));
902#else
903  return("");
904#endif
905}
906
907void owl_zephyr_set_locationinfo(char *host, char *val)
908{
909#ifdef HAVE_LIBZEPHYR
910  ZInitLocationInfo(host, val);
911#endif
912}
913 
914/* Strip a local realm fron the zephyr user name.
915 * The caller must free the return
916 */
917char *short_zuser(char *in)
918{
919  char *out, *ptr;
920
921  out=owl_strdup(in);
922  ptr=strchr(out, '@');
923  if (ptr) {
924    if (!strcasecmp(ptr+1, owl_zephyr_get_realm())) {
925      *ptr='\0';
926    }
927  }
928  return(out);
929}
930
931/* Append a local realm to the zephyr user name if necessary.
932 * The caller must free the return.
933 */
934char *long_zuser(char *in)
935{
936  if (strchr(in, '@')) {
937    return(owl_strdup(in));
938  }
939  return(owl_sprintf("%s@%s", in, owl_zephyr_get_realm()));
940}
941
942/* strip out the instance from a zsender's principal.  Preserves the
943 * realm if present.  daemon.webzephyr is a special case.  The
944 * caller must free the return
945 */
946char *owl_zephyr_smartstripped_user(char *in)
947{
948  char *ptr, *realm, *out;
949
950  out=owl_strdup(in);
951
952  /* bail immeaditly if we don't have to do any work */
953  ptr=strchr(in, '.');
954  if (!strchr(in, '/') && !ptr) {
955    /* no '/' and no '.' */
956    return(out);
957  }
958  if (ptr && strchr(in, '@') && (ptr > strchr(in, '@'))) {
959    /* There's a '.' but it's in the realm */
960    return(out);
961  }
962  if (!strncasecmp(in, OWL_WEBZEPHYR_PRINCIPAL, strlen(OWL_WEBZEPHYR_PRINCIPAL))) {
963    return(out);
964  }
965
966  /* remove the realm from ptr, but hold on to it */
967  realm=strchr(out, '@');
968  if (realm) realm[0]='\0';
969
970  /* strip */
971  ptr=strchr(out, '.');
972  if (!ptr) ptr=strchr(out, '/');
973  ptr[0]='\0';
974
975  /* reattach the realm if we had one */
976  if (realm) {
977    strcat(out, "@");
978    strcat(out, realm+1);
979  }
980
981  return(out);
982}
983
984/* read the list of users in 'filename' as a .anyone file, and put the
985 * names of the zephyr users in the list 'in'.  If 'filename' is NULL,
986 * use the default .anyone file in the users home directory.  Returns
987 * -1 on failure, 0 on success.
988 */
989int owl_zephyr_get_anyone_list(owl_list *in, char *filename)
990{
991#ifdef HAVE_LIBZEPHYR
992  char *ourfile, *tmp, buff[LINE];
993  FILE *f;
994
995  if (filename==NULL) {
996    tmp=owl_global_get_homedir(&g);
997    ourfile=owl_sprintf("%s/.anyone", owl_global_get_homedir(&g));
998  } else {
999    ourfile=owl_strdup(filename);
1000  }
1001 
1002  f=fopen(ourfile, "r");
1003  if (!f) {
1004    owl_function_error("Error opening file %s: %s", ourfile, strerror(errno) ? strerror(errno) : "");
1005    owl_free(ourfile);
1006    return(-1);
1007  }
1008
1009  while (fgets(buff, LINE, f)!=NULL) {
1010    /* ignore comments, blank lines etc. */
1011    if (buff[0]=='#') continue;
1012    if (buff[0]=='\n') continue;
1013    if (buff[0]=='\0') continue;
1014   
1015    /* strip the \n */
1016    buff[strlen(buff)-1]='\0';
1017   
1018    /* ingore from # on */
1019    tmp=strchr(buff, '#');
1020    if (tmp) tmp[0]='\0';
1021   
1022    /* ingore from SPC */
1023    tmp=strchr(buff, ' ');
1024    if (tmp) tmp[0]='\0';
1025   
1026    /* stick on the local realm. */
1027    if (!strchr(buff, '@')) {
1028      strcat(buff, "@");
1029      strcat(buff, ZGetRealm());
1030    }
1031    owl_list_append_element(in, owl_strdup(buff));
1032  }
1033  fclose(f);
1034  owl_free(ourfile);
1035  return(0);
1036#else
1037  return(-1);
1038#endif
1039}
1040
1041
1042#ifdef HAVE_LIBZEPHYR
1043void owl_zephyr_process_events(owl_dispatch *d) {
1044  int zpendcount=0;
1045  ZNotice_t notice;
1046  struct sockaddr_in from;
1047  owl_message *m=NULL;
1048
1049  while(owl_zephyr_zpending() && zpendcount < 20) {
1050    if (owl_zephyr_zpending()) {
1051      ZReceiveNotice(&notice, &from);
1052      zpendcount++;
1053
1054      /* is this an ack from a zephyr we sent? */
1055      if (owl_zephyr_notice_is_ack(&notice)) {
1056        owl_zephyr_handle_ack(&notice);
1057        continue;
1058      }
1059
1060      /* if it's a ping and we're not viewing pings then skip it */
1061      if (!owl_global_is_rxping(&g) && !strcasecmp(notice.z_opcode, "ping")) {
1062        continue;
1063      }
1064
1065      /* create the new message */
1066      m=owl_malloc(sizeof(owl_message));
1067      owl_message_create_from_znotice(m, &notice);
1068
1069      owl_global_messagequeue_addmsg(&g, m);
1070    }
1071  }
1072}
1073
1074#else
1075void owl_zephyr_process_events(owl_dispatch *d) {
1076 
1077}
1078#endif
Note: See TracBrowser for help on using the repository browser.