source: zephyr.c @ 15b34fd

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