source: zephyr.c @ 9948234

owl
Last change on this file since 9948234 was f19fef4, checked in by James M. Kretchmar <kretch@mit.edu>, 15 years ago
missed semicolons
  • Property mode set to 100644
File size: 24.9 KB
RevLine 
[7d4fbcd]1#include <stdlib.h>
2#include <unistd.h>
3#include <sys/types.h>
4#include <sys/wait.h>
[4357be8]5#include <sys/stat.h>
[7d4fbcd]6#include <string.h>
7#include "owl.h"
8
[1aee7d9]9static const char fileIdent[] = "$Id$";
10
[09489b89]11#ifdef HAVE_LIBZEPHYR
[8262340]12Code_t ZResetAuthentication();
[09489b89]13#endif
[8262340]14
[be0a79f]15int owl_zephyr_initialize()
16{
[09489b89]17#ifdef HAVE_LIBZEPHYR
[be0a79f]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  }
[09489b89]28#endif
29  return(0);
30}
31
32
33int owl_zephyr_shutdown()
34{
35#ifdef HAVE_LIBZEPHYR
36  unsuball();
37  ZClosePort();
38#endif
[be0a79f]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
[09489b89]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
[dab82f29]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
[95474d7]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.
[2de4f20]96 */
[95474d7]97int owl_zephyr_loadsubs(char *filename, int error_on_nofile)
[31e48a3]98{
[be0a79f]99#ifdef HAVE_LIBZEPHYR
[7d4fbcd]100  FILE *file;
101  char *tmp, *start;
102  char buffer[1024], subsfile[1024];
103  ZSubscription_t subs[3001];
[dab82f29]104  int count, ret;
[4357be8]105  struct stat statbuff;
[7d4fbcd]106
107  if (filename==NULL) {
108    sprintf(subsfile, "%s/%s", owl_global_get_homedir(&g), ".zephyr.subs");
109  } else {
110    strcpy(subsfile, filename);
111  }
[8262340]112
[4357be8]113  ret=stat(subsfile, &statbuff);
[95474d7]114  if (ret) {
[f19fef4]115    owl_function_debugmsg("loadsubs: could not stat file %s", subsfile);
[95474d7]116    if (error_on_nofile==1) return(-1);
117    return(0);
118  }
[4357be8]119
[8262340]120  ZResetAuthentication();
[7d4fbcd]121  count=0;
122  file=fopen(subsfile, "r");
[db654df]123  if (!file) {
[f19fef4]124    owl_function_debugmsg("loadsubs: could not open file %s", subsfile);
[db654df]125    return(-1);
126  }
[95474d7]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;
[7d4fbcd]134    }
[95474d7]135   
[dab82f29]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    }
[95474d7]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++;
[7d4fbcd]159  }
[95474d7]160  fclose(file);
[7d4fbcd]161
[dab82f29]162  ret=owl_zephyr_loadsubs_helper(subs, count);
[7d4fbcd]163
164  return(ret);
[be0a79f]165#else
166  return(0);
167#endif
[7d4fbcd]168}
169
[4357be8]170int owl_zephyr_loaddefaultsubs()
171{
[40d834a]172#ifdef HAVE_LIBZEPHYR
[4357be8]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);
[40d834a]180#else
181  return(0);
182#endif
[4357be8]183}
184
[31e48a3]185int owl_zephyr_loadloginsubs(char *filename)
186{
[be0a79f]187#ifdef HAVE_LIBZEPHYR
[7d4fbcd]188  FILE *file;
189  ZSubscription_t subs[3001];
190  char subsfile[1024], buffer[1024];
191  int count, ret, i;
[4357be8]192  struct stat statbuff;
[7d4fbcd]193
194  if (filename==NULL) {
195    sprintf(subsfile, "%s/%s", owl_global_get_homedir(&g), ".anyone");
196  } else {
197    strcpy(subsfile, filename);
198  }
[4357be8]199 
200  ret=stat(subsfile, &statbuff);
201  if (ret) return(0);
202
203  ret=0;
[7d4fbcd]204
[8262340]205  ZResetAuthentication();
[7d4fbcd]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 {
[1c6c4d3]221        subs[count].zsub_classinst=owl_sprintf("%s@%s", buffer, ZGetRealm());
[7d4fbcd]222      }
223
224      count++;
225    }
226    fclose(file);
227  } else {
228    count=0;
229    ret=-1;
230  }
231
232  /* sub with defaults */
[7933748]233  if (ZSubscribeToSansDefaults(subs,count,0) != ZERR_NONE) {
[252a5c2]234    owl_function_error("Error subscribing to zephyr notifications.");
[7d4fbcd]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);
[be0a79f]244#else
245  return(0);
246#endif
[7d4fbcd]247}
248
[31e48a3]249void unsuball()
250{
[be0a79f]251#if HAVE_LIBZEPHYR
[7d4fbcd]252  int ret;
[8262340]253
254  ZResetAuthentication();
[7d4fbcd]255  ret=ZCancelSubscriptions(0);
256  if (ret != ZERR_NONE) {
257    com_err("owl",ret,"while unsubscribing");
258  }
[be0a79f]259#endif
[7d4fbcd]260}
261
[31e48a3]262int owl_zephyr_sub(char *class, char *inst, char *recip)
263{
[be0a79f]264#ifdef HAVE_LIBZEPHYR
[7d4fbcd]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
[8262340]271  ZResetAuthentication();
[7d4fbcd]272  if (ZSubscribeTo(subs,1,0) != ZERR_NONE) {
[97cd00be]273    owl_function_error("Error subbing to <%s,%s,%s>", class, inst, recip);
274    return(-2);
[7d4fbcd]275  }
276  return(0);
[be0a79f]277#else
278  return(0);
279#endif
[7d4fbcd]280}
281
282
[31e48a3]283int owl_zephyr_unsub(char *class, char *inst, char *recip)
284{
[be0a79f]285#ifdef HAVE_LIBZEPHYR
[7d4fbcd]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
[8262340]292  ZResetAuthentication();
[7d4fbcd]293  if (ZUnsubscribeTo(subs,1,0) != ZERR_NONE) {
[97cd00be]294    owl_function_error("Error unsubbing from <%s,%s,%s>", class, inst, recip);
295    return(-2);
[7d4fbcd]296  }
297  return(0);
[be0a79f]298#else
299  return(0);
300#endif
[7d4fbcd]301}
302
[b0430a6]303/* return a pointer to the data in the Jth field, (NULL terminated by
304 * definition).  Caller must free the return.
305 */
[be0a79f]306#ifdef HAVE_LIBZEPHYR
[b0430a6]307char *owl_zephyr_get_field(ZNotice_t *n, int j)
[31e48a3]308{
[7d4fbcd]309  int i, count, save;
[b0430a6]310  char *out;
[7d4fbcd]311
[dab82f29]312  /* If there's no message here, just run along now */
313  if (n->z_message_len == 0)
314    return(owl_strdup(""));
315
[7d4fbcd]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 */
[b0430a6]322        return(owl_strdup(n->z_message+save));
[7d4fbcd]323      } else {
324        save=i+1;
325      }
326    }
327  }
[b0430a6]328  /* catch the last field, which might not be null terminated */
[7d4fbcd]329  if (count==j-1) {
[b0430a6]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);
[7d4fbcd]334  }
[b0430a6]335
336  return(owl_strdup(""));
[7d4fbcd]337}
[09489b89]338#else
[701a184]339char *owl_zephyr_get_field(void *n, int j)
[09489b89]340{
[b0430a6]341  return(owl_strdup(""));
[09489b89]342}
[be0a79f]343#endif
[7d4fbcd]344
[b0430a6]345
[be0a79f]346#ifdef HAVE_LIBZEPHYR
[31e48a3]347int owl_zephyr_get_num_fields(ZNotice_t *n)
348{
[7d4fbcd]349  int i, fields;
350
[dab82f29]351  if(n->z_message_len == 0)
352    return 0;
353
[7d4fbcd]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}
[09489b89]361#else
362int owl_zephyr_get_num_fields(void *n)
363{
364  return(0);
365}
[be0a79f]366#endif
[7d4fbcd]367
[be0a79f]368#ifdef HAVE_LIBZEPHYR
[bf73bdd]369/* return a pointer to the message, place the message length in k
370 * caller must free the return
371 */
[b0430a6]372char *owl_zephyr_get_message(ZNotice_t *n)
[31e48a3]373{
[405d5e6]374  /* don't let ping messages have a body */
[7d4fbcd]375  if (!strcasecmp(n->z_opcode, "ping")) {
[bf73bdd]376    return(owl_strdup(""));
[7d4fbcd]377  }
378
[405d5e6]379  /* deal with MIT Athena OLC messages */
[fe67f1f]380  if (!strcasecmp(n->z_sender, "olc.matisse@ATHENA.MIT.EDU")) {
[405d5e6]381    return(owl_zephyr_get_field(n, 1));
382  }
[dab82f29]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  }
[405d5e6]398
[b0430a6]399  return(owl_zephyr_get_field(n, 2));
[7d4fbcd]400}
[be0a79f]401#endif
[7d4fbcd]402
[be0a79f]403#ifdef HAVE_LIBZEPHYR
[31e48a3]404char *owl_zephyr_get_zsig(ZNotice_t *n, int *k)
405{
[7d4fbcd]406  /* return a pointer to the zsig if there is one */
407
[405d5e6]408  /* message length 0? No zsig */
[7d4fbcd]409  if (n->z_message_len==0) {
410    *k=0;
411    return("");
412  }
[405d5e6]413
414  /* No zsig for OLC messages */
[fe67f1f]415  if (!strcasecmp(n->z_sender, "olc.matisse@ATHENA.MIT.EDU")) {
[405d5e6]416    return("");
417  }
418
419  /* Everything else is field 1 */
[7d4fbcd]420  *k=strlen(n->z_message);
421  return(n->z_message);
422}
[09489b89]423#else
424char *owl_zephyr_get_zsig(void *n, int *k)
425{
426  return("");
427}
[be0a79f]428#endif
[7d4fbcd]429
[31e48a3]430int send_zephyr(char *opcode, char *zsig, char *class, char *instance, char *recipient, char *message)
431{
[be0a79f]432#ifdef HAVE_LIBZEPHYR
[7d4fbcd]433  int ret;
434  ZNotice_t notice;
435   
436  memset(&notice, 0, sizeof(notice));
437
[8262340]438  ZResetAuthentication();
[8ba37ec]439
440  if (!zsig) zsig="";
[8262340]441 
[7d4fbcd]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
[56330ff]455  notice.z_message_len=strlen(zsig)+1+strlen(message);
[7d4fbcd]456  notice.z_message=owl_malloc(notice.z_message_len+10);
[56330ff]457  strcpy(notice.z_message, zsig);
458  memcpy(notice.z_message+strlen(zsig)+1, message, strlen(message));
[7d4fbcd]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) {
[ec6ff52]467    owl_function_error("Error sending zephyr");
[7d4fbcd]468    return(ret);
469  }
470  return(0);
[be0a79f]471#else
472  return(0);
473#endif
[7d4fbcd]474}
475
[be0a79f]476#ifdef HAVE_LIBZEPHYR
[31e48a3]477Code_t send_zephyr_helper(ZNotice_t *notice, char *buf, int len, int wait)
478{
[6d7e6c6]479  int ret;
480  ret=ZSendPacket(buf, len, 0);
481  return(ret);
[7d4fbcd]482}
[be0a79f]483#endif
[7d4fbcd]484
[31e48a3]485void send_ping(char *to)
486{
[be0a79f]487#ifdef HAVE_LIBZEPHYR
[7d4fbcd]488  send_zephyr("PING", "", "MESSAGE", "PERSONAL", to, "");
[be0a79f]489#endif
[7d4fbcd]490}
491
[be0a79f]492#ifdef HAVE_LIBZEPHYR
[31e48a3]493void owl_zephyr_handle_ack(ZNotice_t *retnotice)
494{
[db654df]495  char *tmp;
[7d4fbcd]496 
497  /* if it's an HMACK ignore it */
498  if (retnotice->z_kind == HMACK) return;
[aecf3e6]499
[7d4fbcd]500  if (retnotice->z_kind == SERVNAK) {
[ec6ff52]501    owl_function_error("Authorization failure sending zephyr");
[7d4fbcd]502  } else if ((retnotice->z_kind != SERVACK) || !retnotice->z_message_len) {
[ec6ff52]503    owl_function_error("Detected server failure while receiving acknowledgement");
[7d4fbcd]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")) {
[4b464a4]509      tmp=short_zuser(retnotice->z_recipient);
[b4db911]510      owl_function_makemsg("Message sent to %s.", tmp);
[7d4fbcd]511      free(tmp);
512    } else {
[b4db911]513      owl_function_makemsg("Message sent to -c %s -i %s\n", retnotice->z_class, retnotice->z_class_inst);
[7d4fbcd]514    }
515  } else if (!strcmp(retnotice->z_message, ZSRVACK_NOTSENT)) {
[db654df]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);
[9119a47]523      owl_function_adminmsg("", buff);
[7d4fbcd]524    } else {
[db654df]525      char buff[BUFFLEN];
[4b464a4]526      tmp = short_zuser(retnotice->z_recipient);
[db654df]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      }
[9119a47]541      owl_function_adminmsg("", buff);
[180cd15]542      owl_log_outgoing_zephyr_error(tmp, buff);
[1c6c4d3]543      owl_free(tmp);
[7d4fbcd]544    }
545  } else {
[ec6ff52]546    owl_function_error("Internal error on ack (%s)", retnotice->z_message);
[7d4fbcd]547  }
548}
[09489b89]549#else
550void owl_zephyr_handle_ack(void *retnotice)
551{
552}
[be0a79f]553#endif
[7d4fbcd]554
[be0a79f]555#ifdef HAVE_LIBZEPHYR
[31e48a3]556int owl_zephyr_notice_is_ack(ZNotice_t *n)
557{
[7d4fbcd]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}
[09489b89]564#else
565int owl_zephyr_notice_is_ack(void *n)
566{
567  return(0);
568}
[be0a79f]569#endif
[7d4fbcd]570 
[31e48a3]571void owl_zephyr_zaway(owl_message *m)
572{
[be0a79f]573#ifdef HAVE_LIBZEPHYR
[7c8060d0]574  char *tmpbuff, *myuser, *to;
[15b34fd]575  owl_message *mout;
[7d4fbcd]576 
[aa2f6364]577  /* bail if it doesn't look like a message we should reply to.  Some
[2de4f20]578   * of this defined by the way zaway(1) works
579   */
[7d4fbcd]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;
[d023c25]585  if (!strcasecmp(owl_message_get_zsig(m), "Automated reply:")) return;
[7d4fbcd]586  if (!strcasecmp(owl_message_get_sender(m), ZGetSender())) return;
[9854278]587  if (owl_message_get_attribute_value(m, "isauto")) return;
[7d4fbcd]588
[7c8060d0]589  if (owl_global_is_smartstrip(&g)) {
[e3d9c77]590    to=owl_zephyr_smartstripped_user(owl_message_get_sender(m));
[7c8060d0]591  } else {
592    to=owl_strdup(owl_message_get_sender(m));
593  }
594
[7d4fbcd]595  send_zephyr("",
596              "Automated reply:",
597              owl_message_get_class(m),
598              owl_message_get_instance(m),
[7c8060d0]599              to,
[7d4fbcd]600              owl_global_get_zaway_msg(&g));
601
[7c8060d0]602  myuser=short_zuser(to);
[aa2f6364]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);
[7c8060d0]609  owl_free(to);
[aa2f6364]610
[7d4fbcd]611  /* display the message as an admin message in the receive window */
[15b34fd]612  mout=owl_function_make_outgoing_zephyr(owl_global_get_zaway_msg(&g), tmpbuff, "Automated reply:");
613  owl_function_add_message(mout);
[7d4fbcd]614  owl_free(tmpbuff);
[be0a79f]615#endif
[7d4fbcd]616}
617
[be0a79f]618#ifdef HAVE_LIBZEPHYR
[31e48a3]619void owl_zephyr_hackaway_cr(ZNotice_t *n)
620{
[7d4fbcd]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}
[be0a79f]630#endif
[7d4fbcd]631
[e01449c]632char *owl_zephyr_zlocate(char *user, int auth)
[31e48a3]633{
[be0a79f]634#ifdef HAVE_LIBZEPHYR
[7d4fbcd]635  int ret, numlocs;
636  int one = 1;
637  ZLocations_t locations;
[e01449c]638  char *myuser, *out, *tmp;
[7d4fbcd]639 
[8262340]640  ZResetAuthentication();
[7d4fbcd]641  ret=ZLocateUser(user,&numlocs,auth?ZAUTH:ZNOAUTH);
642  if (ret != ZERR_NONE) {
[e01449c]643    return(owl_sprintf("Error locating user %s\n", user));
[7d4fbcd]644  }
645
646  if (numlocs==0) {
[2527615]647    myuser=short_zuser(user);
[e01449c]648    out=owl_sprintf("%s: Hidden or not logged in\n", myuser);
[2527615]649    owl_free(myuser);
[e01449c]650    return(out);
[7d4fbcd]651  }
[e01449c]652
653  out=strdup("");
[7d4fbcd]654  for (;numlocs;numlocs--) {
655    ZGetLocations(&locations,&one);
[4b464a4]656    myuser=short_zuser(user);
[e01449c]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;
[7d4fbcd]665    owl_free(myuser);
666  }
[e01449c]667  return(out);
[9b9e2d9c]668#else
669  return(owl_strdup("Zephyr not available"));
[be0a79f]670#endif
[7d4fbcd]671}
[bde7714]672
[31e48a3]673void owl_zephyr_addsub(char *filename, char *class, char *inst, char *recip)
674{
[be0a79f]675#ifdef HAVE_LIBZEPHYR
[bde7714]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
[74037d9]687  /* if the file already exists, check to see if the sub is already there */
[bde7714]688  file=fopen(subsfile, "r");
[74037d9]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);
[dab82f29]694        fclose(file);
[74037d9]695        return;
696      }
[bde7714]697    }
[dab82f29]698    fclose(file);
[bde7714]699  }
700
701  /* if we get here then we didn't find it */
702  file=fopen(subsfile, "a");
703  if (!file) {
[ec6ff52]704    owl_function_error("Error opening file %s for writing", subsfile);
[bde7714]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);
[be0a79f]713#endif
[bde7714]714}
715
[31e48a3]716void owl_zephyr_delsub(char *filename, char *class, char *inst, char *recip)
717{
[be0a79f]718#ifdef HAVE_LIBZEPHYR
[b2a91b6]719  char *line, *subsfile;
[bde7714]720 
721  line=owl_zephyr_makesubline(class, inst, recip);
[b2a91b6]722  line[strlen(line)-1]='\0';
[bde7714]723
[b2a91b6]724  if (!filename) {
725    subsfile=owl_sprintf("%s/.zephyr.subs", owl_global_get_homedir(&g));
[bde7714]726  } else {
[b2a91b6]727    subsfile=owl_strdup(filename);
[bde7714]728  }
[b2a91b6]729 
730  owl_util_file_deleteline(subsfile, line, 1);
731  owl_free(subsfile);
[bde7714]732  owl_free(line);
733  owl_function_makemsg("Subscription removed");
[be0a79f]734#endif
[bde7714]735}
736
[b2a91b6]737/* caller must free the return */
[31e48a3]738char *owl_zephyr_makesubline(char *class, char *inst, char *recip)
739{
[765fa34]740  return(owl_sprintf("%s,%s,%s\n", class, inst, !strcmp(recip, "") ? "*" : recip));
[bde7714]741}
[31e48a3]742
743void owl_zephyr_zlog_in(void)
744{
[be0a79f]745#ifdef HAVE_LIBZEPHYR
[31e48a3]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);
[6d7e6c6]770  owl_zephyr_process_events(NULL);
[31e48a3]771  if (ret != ZERR_NONE) {
[765fa34]772    /* owl_function_makemsg("Error setting location: %s", error_message(ret)); */
[31e48a3]773  }
[be0a79f]774#endif
[31e48a3]775}
776
777void owl_zephyr_zlog_out(void)
778{
[be0a79f]779#ifdef HAVE_LIBZEPHYR
[31e48a3]780  int ret;
781
782  ZResetAuthentication();
783  ret=ZUnsetLocation();
[6d7e6c6]784  owl_zephyr_process_events(NULL);
[31e48a3]785  if (ret != ZERR_NONE) {
[765fa34]786    /* owl_function_makemsg("Error unsetting location: %s", error_message(ret)); */
[31e48a3]787  }
[be0a79f]788#endif
[31e48a3]789}
790
[65ad073]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) {
[ec6ff52]800    owl_function_error("Error opening zephyr buddy file for append");
[65ad073]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}
[9381782]815
816/* return auth string */
[09489b89]817#ifdef HAVE_LIBZEPHYR
[9381782]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}
[09489b89]833#else
834char *owl_zephyr_get_authstr(void *n)
835{
836  return("");
837}
838#endif
[9381782]839
[2de4f20]840/* Returns a buffer of subscriptions or an error message.  Caller must
841 * free the return.
[09489b89]842 */
843char *owl_zephyr_getsubs()
844{
845#ifdef HAVE_LIBZEPHYR
846  int ret, num, i, one;
[765fa34]847  int buffsize;
[09489b89]848  ZSubscription_t sub;
[765fa34]849  char *out;
[09489b89]850  one=1;
851
852  ret=ZRetrieveSubscriptions(0, &num);
853  if (ret==ZERR_TOOMANYSUBS) {
[c8735aa]854    return(owl_strdup("Zephyr: too many subscriptions\n"));
[765fa34]855  } else if (ret || (num <= 0)) {
[c8735aa]856    return(owl_strdup("Zephyr: error retriving subscriptions\n"));
[09489b89]857  }
858
[765fa34]859  buffsize = (num + 1) * 50;
860  out=owl_malloc(buffsize);
[09489b89]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 {
[765fa34]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      }
[09489b89]886      strcpy(out, tmpbuff);
[765fa34]887      owl_free(tmpbuff);
[09489b89]888    }
889  }
890
891  ZFlushSubscriptions();
892  return(out);
893#else
[12c35df]894  return(owl_strdup("Zephyr not available"));
[09489b89]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 
[e3d9c77]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{
[1971b59]936  if (strchr(in, '@')) {
937    return(owl_strdup(in));
[e3d9c77]938  }
[1971b59]939  return(owl_sprintf("%s@%s", in, owl_zephyr_get_realm()));
[e3d9c77]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}
[5a95b69]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}
[dab82f29]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.