Logo Search packages:      
Sourcecode: zephyr version File versions  Download package

zephyr.c

#include "xzwrite.h"
#include <string.h>
#include <dyn.h>
#include <com_err.h>

#include <zephyr/zephyr.h>

static int zeph_send_notice();
extern Defaults defs;
extern DynObject zsigs;

/* ARGSUSED */
void zeph_dispatch(client_data, source, input_id)
   XtPointer client_data;
   int *source;
   XtInputId *input_id;
{
     ZNotice_t notice;
     struct sockaddr_in from;
     int ret;

     while (ZPending() > 0) {
        ret = ZReceiveNotice(&notice, &from);
        if (ret != ZERR_NONE) {
             Warning(error_message(ret), " while receiving Zephyr notice.",
                   NULL);
             continue;
        }

        if (defs.track_logins &&
            (! strcmp(notice.z_opcode, "USER_LOGIN") ||
             ! strcmp(notice.z_opcode, "USER_LOGOUT")))
             logins_deal(&notice);

        else if (defs.auto_reply &&
               ! strcasecmp(notice.z_class, DEFAULT_CLASS) &&
               ! strcasecmp(notice.z_recipient, ZGetSender()))
             dest_add_reply(&notice);
        
        /* Handle the zlocating bug the Zephyr library explicitly. */
        /* Only display bogon zlocate packets in debug mode */
        else if (strcmp(notice.z_class, LOCATE_CLASS) || defs.debug) {
             Warning("XZwrite: Unexpected notice received.  ",
                   "You can probably ignore this.\n",
                   "To: <", notice.z_class, ", ",
                   notice.z_class_inst, ", ", (*notice.z_recipient) ?
                   notice.z_recipient : "*", ">\n",
                   "From: ", notice.z_sender, "\nOpcode: ",
                   notice.z_opcode, "\nMessage: ", notice.z_message,
                   "\n", NULL);
        }
        
        ZFreeNotice(&notice);
     }
}

void zeph_init()
{
     int    retval;
     
     retval = ZInitialize();
     if (retval != ZERR_NONE)
        Error("Cannot initialize the Zephyr library.", NULL);

     retval = ZOpenPort(NULL);
     if (retval != ZERR_NONE)
        Error("Cannot open Zephyr port.", NULL);
}

int zeph_locateable(user)
   char *user;
{
     char   buf[BUFSIZ];
     int   n;

     if (strchr(user, '@') == NULL)
        sprintf(buf, "%s@%s", user, ZGetRealm());
     ZLocateUser(buf, &n, ZAUTH);
     return (!! n);
}

/* XXX This will break on interrealm zephyr */
void zeph_subto_logins(users, num)
   char **users;
   int num;
{
     ZSubscription_t    *sublist;
     char         *name, *realm;
     int          rlen, c = 0;

     realm = ZGetRealm();
     rlen = strlen(realm);
     sublist = (ZSubscription_t *) Malloc(num*sizeof(ZSubscription_t),
                                "while subscribing to logins", NULL);

     while (c < num) {
        sublist[c].zsub_class = "login";
        sublist[c].zsub_recipient = "";
        name = (char *) Malloc(strlen(users[c])+rlen+2,
                         "while subscribing to login, ", users[c],
                         NULL);
        if (strchr(users[c], '@'))
             sprintf(name, "%s", users[c]);
        else
             sprintf(name, "%s@%s", users[c], realm);
        sublist[c].zsub_classinst = name;
        c += 1;
     }

     ZSubscribeToSansDefaults(sublist, c, (unsigned short) 0);
     for(; c; --c)
        free(sublist[c-1].zsub_classinst);
     free(sublist);
}

void zeph_subto_replies()
{
     ZSubscription_t sub;

     sub.zsub_class = "message";
     sub.zsub_classinst = "*";
     sub.zsub_recipient = ZGetSender();

     ZSubscribeToSansDefaults(&sub, 1, (unsigned short) 0);
}

int zeph_send_message(dest, msg)
   Dest     dest;
   char     *msg;
{
     ZNotice_t    notice;
     int    msglen, siglen, ret;
     char   *sig_msg, *sig;

     if (!zsigs) sig = defs.signature;
     else {
       char **tmp;
       tmp = (char **) DynGet (zsigs, rand() % DynSize(zsigs));
       sig = *tmp; }

     msglen = strlen(msg);
     siglen = strlen(sig);
     sig_msg = (char *) Malloc(msglen + siglen + 2, "while sending message",
                         NULL);
     sprintf(sig_msg, "%s%c%s", sig, '\0', msg);
          
     memset((char *) &notice, 0, sizeof(ZNotice_t));
     notice.z_kind = ACKED;
     notice.z_class = dest->zclass;
     notice.z_class_inst = dest->zinst;
     notice.z_recipient = dest->zrecip;
     notice.z_sender = 0;
     notice.z_opcode = defs.opcode;
     notice.z_port = 0;
     notice.z_message = sig_msg;
     notice.z_message_len = msglen + siglen + 1;

     /* This really gross looking mess is brought to you by zwrite.c */
     if (defs.auth) {
        if (*sig)
             notice.z_default_format = "Class $class, Instance $instance:\nTo: @bold($recipient)\n@bold($1) <$sender>\n\n$2";
        else
             notice.z_default_format = "Class $class, Instance $instance:\nTo: @bold($recipient)\n$message";
     }
     else {
        if (*sig)
             notice.z_default_format = "@bold(UNAUTHENTIC) Class $class, Instance $instance:\n@bold($1) <$sender>\n\n$2";
        else
             notice.z_default_format = "@bold(UNAUTHENTIC) Class $class, Instance $instance:\n$message";
     }
     
     ret = zeph_send_notice(&notice, (defs.auth) ? ZAUTH : ZNOAUTH);
     free(sig_msg);

     /* log to file */
     if (defs.logfile)
       if (strcmp(defs.logfile, "*"))
       log_message (dest, msg);

     return ret;
}

int zeph_ping(dest)
   Dest     dest;
{
     ZNotice_t          notice;

     (void) memset((char *) &notice, 0, sizeof(ZNotice_t));
     notice.z_kind = ACKED;
     notice.z_class = dest->zclass;
     notice.z_class_inst = dest->zinst;
     notice.z_recipient = dest->zrecip;
     notice.z_opcode = "PING";

     /* Should a PING ever be authenticated? */
     return (zeph_send_notice(&notice, ZNOAUTH));
}

int zeph_pong(dest)
   Dest dest;
{
     ZNotice_t          notice;

     (void) memset((char *) &notice, 0, sizeof(ZNotice_t));
     notice.z_kind = ACKED;
     notice.z_class = dest->zclass;
     notice.z_class_inst = dest->zinst;
     notice.z_recipient = dest->zrecip;
     notice.z_opcode = "PING";
     notice.z_message = "PONG";
     notice.z_message_len = 4;

     /* Should a PING ever be authenticated? */
     return (zeph_send_notice(&notice, ZNOAUTH));
}

char *zeph_get_signature()
{
     char *sig;
        
     sig = ZGetVariable("xzwrite-signature");
     if (! sig) sig = ZGetVariable("zwrite-signature");
     return sig;
}

static int zeph_send_notice(notice, auth)
   ZNotice_t      *notice;
   int            (*auth)();
{
     int    retval;
     ZNotice_t    retnotice;

     /* Send message with appropriate authentication */
     retval = ZSendNotice(notice, auth);
     if (retval != ZERR_NONE) {
        if (defs.debug)
             Warning(error_message(retval), " while sending message.", NULL);
        return SENDFAIL_SEND;
     }

     /* Wait for server acknowledgement */
     retval = ZIfNotice(&retnotice, (struct sockaddr_in *) 0,
                  ZCompareUIDPred, (char *) &notice->z_uid);

     if (retval != ZERR_NONE) {
        if (defs.debug)
             Warning(error_message(retval),
                   " while waiting for acknowledgement.", NULL);
        return SENDFAIL_ACK;
     }

     /* Make sure someone receives it */
     if (strcmp(retnotice.z_message, ZSRVACK_NOTSENT)==0)
        return SENDFAIL_RECV;

     return SEND_OK;
}

void log_message(dest, msg)
   Dest     dest;
   char     *msg;
{
  FILE *fp;
  int i;
  time_t now;

  fp = fopen(defs.logfile, "a");
  if (!fp) {
    fp = fopen(defs.logfile, "w");
    if (!fp) {
      fprintf(stderr, "xzwrite: could not open log file \"%s\".\n",
            defs.logfile);
      return; }
  }

  now = time (NULL);
  fprintf(fp, "To: %s, %s, %s\n", dest->zclass, dest->zinst, dest->zrecip);
  fprintf(fp, "Date: %s\n", ctime (&now));

  i = strlen(msg)-1;
  while (msg[i] == '\n' && i > 0) i--;
  if (msg[i] != '\n') i++; msg[i] = 0;
  fputs(msg, fp); fprintf(fp, "\n\n");
  fclose(fp);
}

Generated by  Doxygen 1.6.0   Back to index