176 lines
5.1 KiB
C
176 lines
5.1 KiB
C
/* *****************************************************************************
|
|
* core/_init.c -- real libp7 initialization and exit.
|
|
* Copyright (C) 2016-2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
|
*
|
|
* This file is part of libp7.
|
|
* libp7 is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation; either version 3.0 of the License,
|
|
* or (at your option) any later version.
|
|
*
|
|
* libp7 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 Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with libp7; if not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* The `p7_sinit` (former `_p7_init`) is the function that really initializes
|
|
* the communication using the given stream (once the stream is initialized).
|
|
* It went public recently to give the possibility to the user to make a
|
|
* custom stream, probably for its platform.
|
|
* ************************************************************************** */
|
|
#include <libp7/internals.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
/* simple global containing handle size */
|
|
const size_t p7_handle_size = sizeof(p7_handle_t);
|
|
|
|
/* ************************************************************************** */
|
|
/* Get and set handler data */
|
|
/* ************************************************************************** */
|
|
/**
|
|
* p7_get_response:
|
|
* Get response from handle.
|
|
*
|
|
* The handle has an unknown structure for the user.
|
|
*
|
|
* @arg handle the handle.
|
|
* @return the stream.
|
|
*/
|
|
|
|
const p7_packet_t *p7_get_response(p7_handle_t *handle)
|
|
{
|
|
return (&handle->_response);
|
|
}
|
|
|
|
/**
|
|
* p7_get_stream:
|
|
* Get stream from handle.
|
|
*
|
|
* Same reason than above.
|
|
*
|
|
* @arg handle the handle.
|
|
* @return the stream.
|
|
*/
|
|
|
|
const p7_stream_t *p7_get_stream(p7_handle_t *handle)
|
|
{
|
|
return (&handle->_stream);
|
|
}
|
|
|
|
/**
|
|
* p7_get_info:
|
|
* Get server info.
|
|
*
|
|
* @arg handle the handle.
|
|
* @return the server info.
|
|
*/
|
|
|
|
const p7_server_t *p7_get_info(p7_handle_t *handle)
|
|
{
|
|
return (&handle->_server);
|
|
}
|
|
|
|
/* ************************************************************************** */
|
|
/* Initialization */
|
|
/* ************************************************************************** */
|
|
/**
|
|
* p7_sinit:
|
|
* Initialize libp7 with a P7 stream.
|
|
*
|
|
* @arg h the handle to create
|
|
* @arg flags the flags.
|
|
* @arg name the name of the handle.
|
|
* @arg dstream the P7 stream to use.
|
|
* @arg settings the stream settings to use.
|
|
* @return the error (0 if ok)
|
|
*/
|
|
|
|
int p7_sinit(p7_handle_t **h, unsigned int flags,
|
|
const char *name, p7_stream_t dstream, const p7_streamsettings_t *settings)
|
|
{
|
|
int err = 0;
|
|
|
|
/* allocate handle */
|
|
int alloc = !*h;
|
|
if (alloc) {
|
|
logr_info("looks like the handle wasn't allocated! let's make one.");
|
|
*h = NULL;
|
|
if (!(*h = malloc(sizeof(p7_handle_t))))
|
|
return (p7_error_alloc);
|
|
}
|
|
|
|
/* initialize handle */
|
|
p7_handle_t *handle = *h;
|
|
memset(handle, 0, sizeof(p7_handle_t)); /* important! */
|
|
handle->_stream = dstream;
|
|
|
|
/* initialize flags */
|
|
handle->_flags = 0;
|
|
if (alloc) handle->_flags |= p7_intflag_alloc;
|
|
if (flags & P7_ACTIVE) handle->_flags |= p7_intflag_active;
|
|
if (flags & P7_TERM) handle->_flags |= p7_intflag_term;
|
|
|
|
/* prepare the name */
|
|
if (name) {
|
|
handle->_name[0] = ' ';
|
|
strncpy(&handle->_name[1], name, 8);
|
|
handle->_name[9] = 0;
|
|
}
|
|
log_info("handle prepared, masta!");
|
|
|
|
/* set communication thingies */
|
|
log_info("initializing stream settings");
|
|
memcpy(&handle->_settings, settings, sizeof(p7_streamsettings_t));
|
|
p7_setcomm(&handle->_stream, &handle->_settings);
|
|
|
|
/* if active, start */
|
|
if ((handle->_flags & p7_intflag_active)
|
|
&& (err = p7_start(handle, flags & P7_CHECK))) {
|
|
p7_exit(*h); *h = NULL;
|
|
return (err);
|
|
}
|
|
|
|
/* initialization went alright */
|
|
return (0);
|
|
}
|
|
|
|
/* ************************************************************************** */
|
|
/* De-initialization */
|
|
/* ************************************************************************** */
|
|
/**
|
|
* p7_exit:
|
|
* De-initialize libp7.
|
|
*
|
|
* @arg handle the handle to free.
|
|
*/
|
|
|
|
void p7_exit(p7_handle_t *handle)
|
|
{
|
|
/* check if handle is already freed */
|
|
if (!handle) return;
|
|
log_info("let's exit dat thing.");
|
|
|
|
/* terminate communication */
|
|
if (handle->_flags & p7_intflag_active
|
|
&& ~handle->_flags & p7_intflag_terminated
|
|
&& handle->_flags & p7_intflag_term) {
|
|
log_info("we were active, send sending terminate packet");
|
|
if (p7_send_term(handle)) {
|
|
log_warn("couldn't send terminate packet, already disconnected?");
|
|
/* don't bother */
|
|
}
|
|
/* don't bother checking ack */
|
|
}
|
|
|
|
/* close stream */
|
|
(*handle->_stream.close)(handle->_stream.cookie);
|
|
|
|
/* free handle */
|
|
log_info("freeing the handle!");
|
|
if (handle->_flags & p7_intflag_alloc) free(handle);
|
|
}
|