Files @ a47f25c479d3
Branch filter:

Location: DistRen/src/server/listen.c

binki
fix warnings, fix initializations
/*
  Copyright 2009 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 "listen.h"

#include <list.h>
#include <malloc.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/select.h>
#include <sys/socket.h>

/* local */

struct distrend_clientset
{
  LIST *clients;

  /*
    for select()
   */
  fd_set readfds;
  fd_set writefds;
  int nfds;
};

int distrend_client_new(struct distrend_client **client, int sock, enum distrend_client_state state);
int distrend_client_free(struct distrend_client *client);

int distrend_listen(struct distrend_config *config, struct distrend_clientset **clients)
{
  int tmp;

  struct sockaddr_in6 sockaddr =
    {
      .sin6_family = AF_INET6,
      .sin6_port = 0,
      .sin6_flowinfo = 0,
      .sin6_addr = IN6ADDR_ANY_INIT,
      .sin6_scope_id = 0
    };

  *clients = malloc(sizeof(struct distrend_clientset));

  (*clients)->clients = list_init();

  sockaddr.sin6_port = htonl(4050);

  config->listens->sock = socket(AF_INET6, SOCK_STREAM, 0);
  tmp = bind(config->listens->sock, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
  if(tmp == -1)
    {
      perror("bind");
      free(*clients);

      return 1;
    }

  tmp = listen(config->listens->sock, 1);

  FD_ZERO(&(*clients)->readfds);
  FD_ZERO(&(*clients)->writefds);

  /** accept()able sockets are considered ``readable'' */
  FD_SET(config->listens->sock, &(*clients)->readfds);

  return 0;
}

int distrend_handleread(struct distrend_config *config,
		    struct distrend_client *client)
{
  fprintf(stderr, "%s:%d: STUB: I'm supposed to read data from the client\n",
	  __FILE__, __LINE__);

  return 0;
}

struct distrend_accept_client_proc_data
{
  fd_set *fdset;
  struct distrend_config *config;
};
int distrend_accept_client_proc(struct distrend_accept_client_proc_data *data,
				struct distrend_client *client)
{
  if(!FD_ISSET(client->sock, data->fdset))
    /** continue iteration through the list */
    return TRUE;

  fprintf(stderr, "%s:%d: My traversal says that sock %d has data waiting\n",
	  __FILE__, __LINE__, client->sock);
  distrend_handleread(data->config, client);

  /** continue iteration through the list */
  return TRUE;
}

int distrend_accept(struct distrend_config *config, struct distrend_clientset *clients)
{
  int tmp;
  fd_set readfds;
  fd_set writefds;

  memcpy(&readfds, &clients->readfds, sizeof(fd_set));
  memcpy(&writefds, &clients->writefds, sizeof(fd_set));

  tmp = select(clients->nfds, &readfds, &writefds, NULL, (struct timeval *)NULL);
  if(tmp == -1)
    {
      perror("select");

      return 1;
    }

  /**
     deal with all sockets that have data waiting
   */
  list_traverse(clients->clients, &readfds, (list_traverse_func_t)&distrend_accept_client_proc, LIST_FRNT | LIST_ALTR);


  return 0;
}

int distrend_unlisten(struct distrend_listen *listens, struct distrend_clientset *clients)
{
  fprintf(stderr, "%s:%d: I am a stub that needn't be implemented 'til later\n", __FILE__, __LINE__);

  return 1;
}
/**
   This is probably just NOT a placeholder for remotio
*/
void remotio_send_to_client(struct distrend_client *client, const char *msg, size_t len)
{
    fprintf(stderr, "%s:%d: STUB I should queue data for writing to a client\n", __FILE__, __LINE__);
}

int distrend_client_new(struct distrend_client **client, int sock, enum distrend_client_state state)
{
  *client = malloc(sizeof(struct distrend_client));
  if(!*client)
    {
      fprintf(stderr, "OOM\n");
      return 1;
    }
  (*client)->sock = sock;
  (*client)->state = state;
  (*client)->inmsgs = list_init();
  (*client)->outmsgs = list_init();

  return 0;
}

int distrend_client_free(struct distrend_client *client)
{
  list_free(client->inmsgs, (void *)LIST_DEALLOC);
  list_free(client->outmsgs, (void *)LIST_DEALLOC);

  fprintf(stderr, "%s:%d: stub!", __FILE__, __LINE__);
  return 1;
}