Blame src/service.c

Packit 16808d
Packit 16808d
/*
Packit 16808d
  Meanwhile - Unofficial Lotus Sametime Community Client Library
Packit 16808d
  Copyright (C) 2004  Christopher (siege) O'Brien
Packit 16808d
  
Packit 16808d
  This library is free software; you can redistribute it and/or
Packit 16808d
  modify it under the terms of the GNU Library General Public
Packit 16808d
  License as published by the Free Software Foundation; either
Packit 16808d
  version 2 of the License, or (at your option) any later version.
Packit 16808d
  
Packit 16808d
  This library is distributed in the hope that it will be useful,
Packit 16808d
  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 16808d
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 16808d
  Library General Public License for more details.
Packit 16808d
  
Packit 16808d
  You should have received a copy of the GNU Library General Public
Packit 16808d
  License along with this library; if not, write to the Free
Packit 16808d
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Packit 16808d
*/
Packit 16808d
Packit 16808d
#include "mw_channel.h"
Packit 16808d
#include "mw_debug.h"
Packit 16808d
#include "mw_error.h"
Packit 16808d
#include "mw_message.h"
Packit 16808d
#include "mw_service.h"
Packit 16808d
Packit 16808d
Packit 16808d
/* I tried to be explicit with the g_return_* calls, to make the debug
Packit 16808d
   logging a bit more sensible. Hence all the explicit "foo != NULL"
Packit 16808d
   checks. */
Packit 16808d
Packit 16808d
Packit 16808d
void mwService_recvCreate(struct mwService *s, struct mwChannel *chan,
Packit 16808d
			  struct mwMsgChannelCreate *msg) {
Packit 16808d
Packit 16808d
  /* ensure none are null, ensure that the service and channel belong
Packit 16808d
     to the same session, and ensure that the message belongs on the
Packit 16808d
     channel */
Packit 16808d
  g_return_if_fail(s != NULL);
Packit 16808d
  g_return_if_fail(chan != NULL);
Packit 16808d
  g_return_if_fail(msg != NULL);
Packit 16808d
  g_return_if_fail(s->session == mwChannel_getSession(chan));
Packit 16808d
  g_return_if_fail(mwChannel_getId(chan) == msg->channel);
Packit 16808d
Packit 16808d
  if(s->recv_create) {
Packit 16808d
    s->recv_create(s, chan, msg);
Packit 16808d
  } else {
Packit 16808d
    mwChannel_destroy(chan, ERR_FAILURE, NULL);
Packit 16808d
  }
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwService_recvAccept(struct mwService *s, struct mwChannel *chan,
Packit 16808d
			  struct mwMsgChannelAccept *msg) {
Packit 16808d
Packit 16808d
  /* ensure none are null, ensure that the service and channel belong
Packit 16808d
     to the same session, and ensure that the message belongs on the
Packit 16808d
     channel */
Packit 16808d
  g_return_if_fail(s != NULL);
Packit 16808d
  g_return_if_fail(chan != NULL);
Packit 16808d
  g_return_if_fail(msg != NULL);
Packit 16808d
  g_return_if_fail(s->session == mwChannel_getSession(chan));
Packit 16808d
  g_return_if_fail(mwChannel_getId(chan) == msg->head.channel);
Packit 16808d
Packit 16808d
  if(s->recv_accept)
Packit 16808d
    s->recv_accept(s, chan, msg);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwService_recvDestroy(struct mwService *s, struct mwChannel *chan,
Packit 16808d
			   struct mwMsgChannelDestroy *msg) {
Packit 16808d
Packit 16808d
  /* ensure none are null, ensure that the service and channel belong
Packit 16808d
     to the same session, and ensure that the message belongs on the
Packit 16808d
     channel */
Packit 16808d
  g_return_if_fail(s != NULL);
Packit 16808d
  g_return_if_fail(chan != NULL);
Packit 16808d
  g_return_if_fail(msg != NULL);
Packit 16808d
  g_return_if_fail(s->session == mwChannel_getSession(chan));
Packit 16808d
  g_return_if_fail(mwChannel_getId(chan) == msg->head.channel);
Packit 16808d
Packit 16808d
  if(s->recv_destroy)
Packit 16808d
    s->recv_destroy(s, chan, msg);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwService_recv(struct mwService *s, struct mwChannel *chan,
Packit 16808d
		    guint16 msg_type, struct mwOpaque *data) {
Packit 16808d
Packit 16808d
  /* ensure that none are null. zero-length messages are acceptable */
Packit 16808d
  g_return_if_fail(s != NULL);
Packit 16808d
  g_return_if_fail(chan != NULL);
Packit 16808d
  g_return_if_fail(data != NULL);
Packit 16808d
  g_return_if_fail(s->session == mwChannel_getSession(chan));
Packit 16808d
Packit 16808d
  /*
Packit 16808d
  g_message("mwService_recv: session = %p, service = %p, b = %p, n = %u",
Packit 16808d
	    mwService_getSession(s), s, data->data, data->len);
Packit 16808d
  */
Packit 16808d
Packit 16808d
  if(s->recv)
Packit 16808d
    s->recv(s, chan, msg_type, data);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
guint32 mwService_getType(struct mwService *s) {
Packit 16808d
  g_return_val_if_fail(s != NULL, 0x00);
Packit 16808d
  return s->type;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
const char *mwService_getName(struct mwService *s) {
Packit 16808d
  g_return_val_if_fail(s != NULL, NULL);
Packit 16808d
  g_return_val_if_fail(s->get_name != NULL, NULL);
Packit 16808d
Packit 16808d
  return s->get_name(s);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
const char *mwService_getDesc(struct mwService *s) {
Packit 16808d
  g_return_val_if_fail(s != NULL, NULL);
Packit 16808d
  g_return_val_if_fail(s->get_desc != NULL, NULL);
Packit 16808d
Packit 16808d
  return s->get_desc(s);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
struct mwSession *mwService_getSession(struct mwService *s) {
Packit 16808d
  g_return_val_if_fail(s != NULL, NULL);
Packit 16808d
  return s->session;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwService_init(struct mwService *srvc, struct mwSession *sess,
Packit 16808d
		    guint32 type) {
Packit 16808d
Packit 16808d
  /* ensure nothing is null, and there's no such thing as a zero
Packit 16808d
     service type */
Packit 16808d
  g_return_if_fail(srvc != NULL);
Packit 16808d
  g_return_if_fail(sess != NULL);
Packit 16808d
  g_return_if_fail(type != 0x00);
Packit 16808d
Packit 16808d
  srvc->session = sess;
Packit 16808d
  srvc->type = type;
Packit 16808d
  srvc->state = mwServiceState_STOPPED;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
enum mwServiceState mwService_getState(struct mwService *srvc) {
Packit 16808d
  g_return_val_if_fail(srvc != NULL, mwServiceState_STOPPED);
Packit 16808d
  return srvc->state;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwService_start(struct mwService *srvc) {
Packit 16808d
  g_return_if_fail(srvc != NULL);
Packit 16808d
Packit 16808d
  if(! MW_SERVICE_IS_STOPPED(srvc))
Packit 16808d
    return;
Packit 16808d
Packit 16808d
  srvc->state = mwServiceState_STARTING;
Packit 16808d
  g_message("starting service %s", NSTR(mwService_getName(srvc)));
Packit 16808d
Packit 16808d
  if(srvc->start) {
Packit 16808d
    srvc->start(srvc);
Packit 16808d
  } else {
Packit 16808d
    mwService_started(srvc);
Packit 16808d
  }
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwService_started(struct mwService *srvc) {
Packit 16808d
  g_return_if_fail(srvc != NULL);
Packit 16808d
Packit 16808d
  srvc->state = mwServiceState_STARTED;
Packit 16808d
  g_message("started service %s", NSTR(mwService_getName(srvc)));
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwService_error(struct mwService *srvc) {
Packit 16808d
  g_return_if_fail(srvc != NULL);
Packit 16808d
Packit 16808d
  if(MW_SERVICE_IS_DEAD(srvc))
Packit 16808d
    return;
Packit 16808d
Packit 16808d
  srvc->state = mwServiceState_ERROR;
Packit 16808d
  g_message("error in service %s", NSTR(mwService_getName(srvc)));
Packit 16808d
Packit 16808d
  if(srvc->stop) {
Packit 16808d
    srvc->stop(srvc);
Packit 16808d
  } else {
Packit 16808d
    mwService_stopped(srvc);
Packit 16808d
  }
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwService_stop(struct mwService *srvc) {
Packit 16808d
  g_return_if_fail(srvc != NULL);
Packit 16808d
Packit 16808d
  if(MW_SERVICE_IS_DEAD(srvc))
Packit 16808d
    return;
Packit 16808d
Packit 16808d
  srvc->state = mwServiceState_STOPPING;
Packit 16808d
  g_message("stopping service %s", NSTR(mwService_getName(srvc)));
Packit 16808d
Packit 16808d
  if(srvc->stop) {
Packit 16808d
    srvc->stop(srvc);
Packit 16808d
  } else {
Packit 16808d
    mwService_stopped(srvc);
Packit 16808d
  }
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwService_stopped(struct mwService *srvc) {
Packit 16808d
  g_return_if_fail(srvc != NULL);
Packit 16808d
Packit 16808d
  if(srvc->state != mwServiceState_STOPPED) {
Packit 16808d
    srvc->state = mwServiceState_STOPPED;
Packit 16808d
    g_message("stopped service %s", NSTR(mwService_getName(srvc)));
Packit 16808d
  }
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwService_free(struct mwService *srvc) {
Packit 16808d
  g_return_if_fail(srvc != NULL);
Packit 16808d
Packit 16808d
  mwService_stop(srvc);
Packit 16808d
Packit 16808d
  if(srvc->clear)
Packit 16808d
    srvc->clear(srvc);
Packit 16808d
Packit 16808d
  if(srvc->client_cleanup)
Packit 16808d
    srvc->client_cleanup(srvc->client_data);
Packit 16808d
Packit 16808d
  g_free(srvc);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
/** @todo switch the following to using mw_datum */
Packit 16808d
Packit 16808d
void mwService_setClientData(struct mwService *srvc,
Packit 16808d
			     gpointer data, GDestroyNotify cleanup) {
Packit 16808d
Packit 16808d
  g_return_if_fail(srvc != NULL);
Packit 16808d
Packit 16808d
  srvc->client_data = data;
Packit 16808d
  srvc->client_cleanup = cleanup;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
gpointer mwService_getClientData(struct mwService *srvc) {
Packit 16808d
  g_return_val_if_fail(srvc != NULL, NULL);
Packit 16808d
  return srvc->client_data;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwService_removeClientData(struct mwService *srvc) {
Packit 16808d
  g_return_if_fail(srvc != NULL);
Packit 16808d
Packit 16808d
  if(srvc->client_cleanup) {
Packit 16808d
    srvc->client_cleanup(srvc->client_data);
Packit 16808d
    srvc->client_cleanup = NULL;
Packit 16808d
  }
Packit 16808d
Packit 16808d
  srvc->client_data = NULL;
Packit 16808d
}
Packit 16808d