Files @ da79b5082151
Branch filter:

Location: DistRen/src/client/libdistren_request.c

binki
Extend the distren CLI a little bit more and specify some more of the protocol so that the client can be further worked on while cleaning up nonfunctional distrend.
/*
 * Copyright 2010 Nathan Phillip Brink
 *
 * This file is a part of DistRen.
 *
 * DistRen is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * DistRen is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with DistRen.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "common/config.h"

#include "libdistren.h"

#include "common/protocol.h"
#include "common/remoteio.h"
#include "common/request.h"

static void handle_ping(struct remoteio *rem, struct distren_request *req, void *req_data);
static void handle_version(struct remoteio *rem, struct distren_request *req, void *req_data);
static void handle_disconnect(distren_t distren, struct remoteio *rem, struct distren_request *req, void *req_data);

size_t libdistren_remoteio_read_handle(struct remoteio *rem, void *garbage, void *buf, size_t len, distren_t distren)
{
  size_t to_return;
  size_t last_len;
  short err;

  struct distren_request *req;
  void *req_data;

  to_return = 0;
  while(!distren->done_ad)
    {
      if(!len)
	return to_return;

      putchar(*(char *)buf);
      if(*(char *)buf == '\n')
	distren->done_ad = 1;

      len --;
      to_return ++;
      buf ++;
    }

  /* hack to get into the loop at all ;-) */
  last_len = 1; 
  while(last_len)
    {
      last_len = distren_request_handle(NULL, buf, len, &req, &req_data, &err);
      if(err)
	{
	  remoteio_close(rem);
	  return to_return;
	}
      if(!last_len)
	return to_return;

      switch((enum distren_request_type)req->type)
	{
	case DISTREN_REQUEST_PING:
	  handle_ping(rem, req, req_data);
	  break;

	case DISTREN_REQUEST_VERSION:
	  handle_version(rem, req, req_data);
	  break;

	case DISTREN_REQUEST_DISCONNECT:
	  handle_disconnect(distren, rem, req, req_data);
	  break;

	default:
	  /*
	   * we don't implement everything because we don't need to do
	   * so. But, we should complain when we get something we
	   * don't recognize because... server protocols change
	   * ;-). Oh, and when I'm first writing this, this
	   * block will be hit a lot ;-).
	   */
	  fprintf(stderr, "Unrecognized request type: %lu\n", (unsigned long)req->type);
	  break;
	}

      distren_request_free(req);
      buf += last_len;
      len -= last_len;
    }

  return to_return;
}

void libdistren_remoteio_close_handle(void *garbage, distren_t distren)
{
  distren->rem = NULL;
}


/* handlers */

static void handle_ping(struct remoteio *rem, struct distren_request *req, void *req_data)
{
  struct distren_request *pong_req;
  void *pong_req_data;

  distren_request_poing(&pong_req, &pong_req_data, 0, req_data, req->len);
  distren_request_send(rem, pong_req, pong_req_data);
  distren_request_free_with_data(pong_req, pong_req_data);
}

static void handle_version(struct remoteio *rem, struct distren_request *req, void *req_data)
{
  static const char *package_string = PACKAGE_STRING;

  size_t counter;

  fprintf(stderr, "info: connected to a server running ");
  for(counter = 0; counter < req->len; counter ++)
    putc(((char *)req_data)[counter], stderr);
  putc('\n', stderr);

  /* am I supposed to respond here? ;-) */
}

static void handle_disconnect(distren_t distren, struct remoteio *rem, struct distren_request *req, void *req_data)
{
  size_t tmp;

  fputs("warning: The server has disconnected us because ``", stderr);
  tmp = fwrite(req_data, 1, req->len, stderr);
  fputs("''\n", stderr);

  remoteio_close(distren->rem);
}