src/network.c

Wed, 16 Apr 2014 20:32:25 +0200

author
Mike Becker <universe@uap-core.de>
date
Wed, 16 Apr 2014 20:32:25 +0200
changeset 39
4d3d398ba689
parent 34
c4d4b8a8f902
child 45
e14a1d9aa91d
permissions
-rw-r--r--

mvwasyncgetnstr now echos EOL

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2014 Mike Becker. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include "network.h"

#define new_socket() socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

int net_create(Server *server, char* port) {
    server->info = NULL;
    
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(atoi(port));
    
    server->fd = new_socket();
    if (server->fd > -1) {
        int true = 1;
        setsockopt(server->fd, SOL_SOCKET, SO_REUSEADDR, &true, sizeof(int));
        if (bind(server->fd, (struct sockaddr*)&addr, sizeof(addr))) {
            server->fd = -1;
            return 1;
        } else {
            return 0;
        }
    } else {
        return 1;
    }
}

int getaddrinfo_intrnl(char *host, char *port, struct addrinfo **info) {
    struct addrinfo hints;
    memset(&hints, 0, sizeof(hints));
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    
    return getaddrinfo(host, port, &hints, info);
}

int net_find(Server *server, char *host, char* port) {
    memset(server, 0, sizeof(Server));
    server->fd = -1;
    
    return getaddrinfo_intrnl(host, port, &(server->info));
}

int net_listen(Server *server) {
    listen(server->fd, 1);
    Client* client = calloc(1, sizeof(Client));
    client->fd = -1;
    server->client = client;
    
    client->fd = accept(server->fd,
        &(client->address), &(client->address_len));
    
    return client->fd == -1;
}

int net_connect(Server *server) {
    
    Client* client = calloc(1, sizeof(Client));
    client->fd = -1;
    server->fd = new_socket();
    server->client = client;
    
    if (server->fd == -1) {
        return 1;
    }
    
    return connect(server->fd, server->info->ai_addr, server->info->ai_addrlen);
}

int net_destroy(Server *server) {
    if (server->info) {
        freeaddrinfo(server->info);
    }
    if (server->client) {
        shutdown(server->client->fd, SHUT_RDWR);
        free(server->client);
    }
    if (server->fd > -1) {
        return shutdown(server->fd, SHUT_RDWR);
    }
    
    return EXIT_SUCCESS;
}

void net_send_code(int socket, uint8_t code) {
    send(socket, &code, sizeof(uint8_t), 0);
}

void net_send_data(int socket, uint8_t code, void *data, size_t len) {
    uint8_t pkg[len+1];
    pkg[0] = code;
    memcpy(pkg+1, data, len);
    send(socket, pkg, len+1, 0);
}

uint8_t net_recieve_code(int socket) {
    uint8_t code;
    recv(socket, &code, sizeof(uint8_t), 0);
    return code;
}

void net_recieve_data(int socket, void *data, size_t len) {
    recv(socket, data, len, 0);
}

int net_setnonblocking(int socket, _Bool nonblocking) {
    int opts = fcntl(socket, F_GETFL);
	if (opts < 0) {
		return 1;
	}
    
    if (nonblocking) {
        opts |= O_NONBLOCK;
    } else {
        opts &= ~O_NONBLOCK;
    }
	if (fcntl(socket, F_SETFL, opts) < 0) {
		return 1;
	}
    
    return 0;
}

mercurial