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

network.c

/**
 * Network functions.  Co-ordinates server and client connections.
 */

#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <netdb.h>
#include <unistd.h>

#include <stdio.h>

#include "zchat.h"

#define PORT 4000

typedef enum {
  ModeClientOnly,
  ModeClientServer
} Mode;
   
static Mode mode = ModeClientServer;

int network_callback();
int session_id = 0;

int network_init() {
  int res;

  res = server_init(PORT);
  if (!res) {
    printf("Failed to initialise server.  Running as in CLIENT-ONLY mode.\n");
    mode = ModeClientOnly;
  }

  gtk_timeout_add(200, network_callback, NULL);

  /* Generate a random 32 bit integer. */
  session_id = rand();

  return 1;
}


/**
 * Callback to handle new data on any of the connections.
 */

int network_callback() {
  if (mode == ModeClientServer)
    server_accept();
  check_connection_data();
  check_newly_connected();
  return 1;
}

/**
 * Attempts to create a new client connection to a given host and port.
 */

int connect_to_client(char * host, int port) {

  struct in_addr inet_address;
  struct hostent * hp;
  struct sockaddr_in * sock = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
  struct connection * tmp;
  int fd, res;
  char buf[16384];

  if (port < 0 || port > 65535) {
    printf("connect_to_client: silly port %d\n", port);
    free(sock);
    return 0;
  }

  /* Nameserver lookup stuff. */

  if (isalpha(*host)) {
    hp = gethostbyname(host);
    if (!hp) {
      printf("Unknown host.");
      free(sock);
      return 0;
    }
    
    memcpy ((char *)&inet_address, hp->h_addr, sizeof(struct in_addr));
  }
  else
    inet_address.s_addr = inet_addr(host);
  
  fd = socket(AF_INET, SOCK_STREAM, 0);
  if (fd == -1) {
    perror("Cache::retrieve()");
    free(sock);
    return 0;
  }
  
  sock->sin_family=AF_INET;
  sock->sin_port = htons(port);
  sock->sin_addr = inet_address;

  /* This is a non-blocking connect.  Should be interesting to handle. */
  if (connect(fd, (struct sockaddr *)sock, sizeof(struct sockaddr_in)) == -1) {
    perror("connect_to_client: connect");
    close(fd);
    free(sock);
    return 0;
  }

  /* Non-blocking socket. */

#ifdef WIN32
  unsigned long enable = 1;
  res = ioctlsocket(fd, FIONBIO, &enable);
#else
  res = fcntl(fd, F_SETFL, O_NONBLOCK);
#endif
  if (res == -1) {
    perror("connect_to_client: non-blocking");
    free(sock);
    exit(1);
  }

  /* Successful client, so create a new connection to store this. */

  tmp = new_connection(fd);
  tmp->status = ConnConnecting;
  tmp->client = sock;

  {
    char buf[1024];
    uint8_t * ptr = (uint8_t *)&sock->sin_addr.s_addr;
    sprintf(buf, "%d.%d.%d.%d", *ptr, *(ptr+1), *(ptr+2), *(ptr+3));
    tmp->hostname = strdup(buf);
  }

  sprintf(buf, "Created connection to %s:%d on fd %d.\n", host, port, fd);
  output_append(buf);

  return fd;
}

uint16_t zchat_to_host(uint16_t num) {

  uint16_t new_num;
  uint8_t * ptr = (uint8_t *)&new_num;

  printf("Input: %d\n", num);

#ifndef __BIG_ENDIAN__
  ptr[0] = num % 256;
  ptr[1] = num / 256;
#else
  ptr[0] = num / 256;
  ptr[1] = num % 256;
#endif

  printf("Returning %d in host byte order.\n", new_num);

  return new_num;
}

uint16_t host_to_zchat(uint16_t num) {

  uint16_t new_num;
  uint8_t * ptr = (uint8_t *)&new_num;

  printf("Input: %d\n", num);

#ifndef __BIG_ENDIAN__
  ptr[0] = num % 256;
  ptr[1] = num / 256;
#else
  ptr[0] = num / 256;
  ptr[1] = num % 256;
#endif

  printf("Returning %d in host byte order.\n", new_num);

  return new_num;
}

Generated by  Doxygen 1.6.0   Back to index