/**
   @file

   Definitions for libcomm.
*/

/*
  Copyright (c) Andreas Hofmeier
  (www.an-h.de, www.an-h.de.vu, www.lgut.uni-bremen.de/an-h/)
  
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program 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
  General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/



//#include "md5.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define true 1
#define false 0

#ifndef nothread
  #include <pthread.h>
#endif

// declaration

// md5auth
// the first authfile, which is fould will be used
// first authfile. 
#define authfile0 "./libcomm_md5auth.pwd"
// second authfile
#define authfile1 "/etc/libcomm_md5auth.pwd"
// one char/byte which seperates the field in the authfile
#define authfilefieldseperator ':'
// maxinam lenght of a line in the authfile
#define authfilemaxlinelenght 4096
// how much random bytes are generated for the authentication
#define authrandomstringsize (int) 16
// Define the message-type for the auth blocks
#define authmessagetype 65535

// structure to stroe the authentication infromationen
struct AUTHINFO {
  // network name
  char *netname;
  // login name
  char *name;
  // login passwd
  char *passwd;
  // Key for encryption (not used yet)
  char *keyencrypt;
  // Key for decryption (not used yet)
  char *keydecrypt;
};

int socket_md5auth(int fd, char *netname, char *name,
		   struct AUTHINFO **locallogin,
		   struct AUTHINFO **remotelogin);
struct AUTHINFO *getauthinfo(char *netname, char *name);



// socket_acceept
#ifndef nothread
struct LIBCOMMPTHREADP {
  void (*socket_accept_do)(int fd, int id, char *pip,
			    struct sockaddr_in their_addr);

  pthread_t        thrd_2;
  pthread_attr_t   thrd_2_attr;
  int              sockport;
  int              id;
};
void socket_accept_thread(struct LIBCOMMPTHREADP *libcommpthreadp);
int socket_accept(int sockport, int id,
	   void (*socket_accept_do)(int fd, int id, char *pip,
			    struct sockaddr_in their_addr));
#endif


// block_receive
#ifndef nothread
struct LIBCOMMPTHREADS {
  void (*block_call_do)(int fd, int id, unsigned int type,
			char *buf, unsigned int size, int term);
  void (*block_call_term)(int fd, int id);

  pthread_t        thrd_1;
  pthread_attr_t   thrd_1_attr;
  int              fd;
  int              id;
  int              term;
};
void thread1(struct LIBCOMMPTHREADS *libcommpthreads);
int block_call(int fd, int id, int term,
	   void (*block_call_do)(int fd, int id, unsigned int type,
				 char *buf, unsigned int size,
				 int term), 
	   void (*block_call_term)(int fd, int id));
#endif
char *block_receive_poll(int fd, unsigned int *type, char *buf,
			 unsigned int *size, unsigned int maxsize,
			 int term);
char *block_receive(int fd, unsigned int *type, char *buf,
		    unsigned int *size, unsigned int maxsize,
		    int term);
int block_receive_integer(int fd, unsigned int *recvi);
int block_receive_nbytes(int fd, char *buf, int n);



// block_send
int block_send(int fd, unsigned int type, char *buf, unsigned int size);



// block_random
char *block_random(char *buf, int size);



// socket_bind
int socket_bind(int port, int cqueue);



// socket_connect
int socket_connect(char *host, int port);



// line monitor
struct LINEMONITOR_THREAD_DATA {
  char *server;
  int port;
  int soft_msec;
  int hard_msec;
  int wait_msec;
  void (*linemonitor_exception)(char *server, int port, int type);
  int sock;
};


void linemonitor_server_thread(struct LINEMONITOR_THREAD_DATA
			  *linemonitor_thread_data);
int linemonitor_server(int port,
		int soft_msec, int hard_msec, int wait_msec,
		void (*linemonitor_exception)(char *server, int port,
					      int type));
void linemonitor_emergencystop(int sock);
int linemonitor_thread(struct LINEMONITOR_THREAD_DATA
		       *linemonitor_thread_data);
int linemonitor(char *server, int port,
		int soft_msec, int hard_msec, int wait_msec,
		void (*linemonitor_exception)(char *server, int port,
					      int type));


