Sophie

Sophie

distrib > Mandriva > 2009.1 > x86_64 > media > contrib-release > by-pkgid > 8b14c9edf0f9f9aa126fa64cef89bbeb > files > 4

lib64skyutils2.8-devel-2.8-2mdv2008.1.x86_64.rpm

/******************************************************************************/
/* Skyutils functions - Chained list,socket,string,utils,web,threads, archive */
/* (c) Christophe CALMEJANE (Ze KiLleR) - 1999-05                             */
/******************************************************************************/

/*
    This library 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 2.1 of the License, or (at your option) any later version.

    This library 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 this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/


#ifndef __SKY_UTILS_H__
#define __SKY_UTILS_H__

#define SKYUTILS_VERSION "2.8"
#define SKYUTILS_AUTHOR "Christophe Calmejane"

#if defined(__MACH__) || defined(_AIX)
#define __unix__
#endif /* __MACH__ || _AIX */

#if defined(__cplusplus) && !defined(__BORLANDC__)
extern "C" {
#endif /* __cplusplus */

#ifndef __cplusplus
#ifndef SU_BOOL_TYPE
#undef bool
typedef unsigned int bool;
#define true 1
#define false 0
#define SU_BOOL_TYPE
#endif /* !SU_BOOL_TYPE */
#endif /* !__cplusplus */
#define SU_BOOL unsigned int

#ifndef SU_NO_INCLUDES
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>
#ifndef _WIN32
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
#include <pthread.h>
#include <semaphore.h>
#define SU_SOCKET int
#else /* _WIN32 */
#if defined(_MT) && !defined(_REENTRANT)
#define _REENTRANT
#endif /* _MT */
#ifndef _WINSOCKAPI_
#include <winsock2.h>
#endif /* !_WINSOCKAPI_ */
#include <process.h>
#include <winbase.h>
#include <time.h>
#define SU_SOCKET SOCKET
#endif /* !_WIN32 */
#endif /* !SU_NO_INCLUDES */

#ifdef MSG_NOSIGNAL
#define SU_MSG_NOSIGNAL MSG_NOSIGNAL
#else /* !MSG_NOSIGNAL */
#define SU_MSG_NOSIGNAL 0
#endif /* MSG_NOSIGNAL */

#ifndef INADDR_NONE
#define INADDR_NONE -1
#endif /* !INADDR_NONE */

#ifndef SOCKET_ERROR
#define SOCKET_ERROR -1
#endif /* !SOCKET_ERROR */

#define SU_UDP_MAX_LENGTH 64000

/* Portable types */
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int8 SU_u8;
typedef signed __int8 SU_s8;
typedef unsigned __int16 SU_u16;
typedef signed __int16 SU_s16;
typedef unsigned __int32 SU_u32;
typedef signed __int32 SU_s32;
typedef unsigned __int64 SU_u64;
typedef signed __int64 SU_s64;
#else /* !(_MSC_VER || __BORLANDC__) */
#if defined(__GNUC__) && defined (__linux__) && !defined(_WIN32) && !defined(__MINGW32__)
typedef u_int8_t SU_u8;
typedef int8_t SU_s8;
typedef u_int16_t SU_u16;
typedef int16_t SU_s16;
typedef u_int32_t SU_u32;
typedef int32_t SU_s32;
typedef u_int64_t SU_u64;
typedef int64_t SU_s64;
#else /* Not linux GCC */
typedef unsigned char SU_u8;
typedef signed char SU_s8;
typedef unsigned short SU_u16;
typedef signed short SU_s16;
typedef unsigned int SU_u32;
typedef signed int SU_s32;
typedef unsigned long long SU_u64;
typedef signed long long SU_s64;
#endif /* Linux GCC */
#endif /* _MSC_VER || __BORLANDC__ */


/* **************************************** */
/*            Chained list functions        */
/* **************************************** */
struct SU_SList;

typedef struct SU_SList
{
  struct SU_SList *Next;
  void *Data;
} SU_TList, *SU_PList;

SU_PList SU_AddElementTail(SU_PList,void *);
SU_PList SU_AddElementHead(SU_PList,void *);
SU_PList SU_AddElementPos(SU_PList List,int Pos,void *Elem); /* First element is at pos 0 */
SU_PList SU_DelElementElem(SU_PList,void *); /* This function does NOT free the element */
SU_PList SU_DelElementTail(SU_PList); /* This function does NOT free the element */
SU_PList SU_DelElementHead(SU_PList); /* This function does NOT free the element */
SU_PList SU_DelElementPos(SU_PList,int); /* This function does NOT free the element */ /* First element is at pos 0 */
void *SU_GetElementTail(SU_PList);
void *SU_GetElementHead(SU_PList);
void *SU_GetElementPos(SU_PList,int); /* First element is at pos 0 */
void SU_FreeList(SU_PList); /* This function does NOT free the elements */
void SU_FreeListElem(SU_PList); /* This function DOES free the elements */
unsigned int SU_ListCount(SU_PList);


/* **************************************** */
/*               Socket functions           */
/* **************************************** */
#ifndef SU_INCLUDE_NO_SOCKS
typedef struct
{
  SU_SOCKET sock;
  struct sockaddr_in SAddr;
  void *User;
} SU_TServerInfo, *SU_PServerInfo;

typedef struct
{
  SU_SOCKET sock;
  struct sockaddr_in SAddr;
  void *User;
} SU_TClientSocket, *SU_PClientSocket;

int SU_GetPortByName(char *port,char *proto); /* Returns port number from it's name */
char *SU_GetMachineName(char *RemoteHost);    /* Extracts the machine name from a full host */
char *SU_NameOfPort(char *Host);              /* Returns the host name matching the given ip */
char *SU_AdrsOfPort(char *Host);              /* Returns the ip adrs matching the given host */

SU_PServerInfo SU_CreateServer(int port,int type,bool ReUseAdrs);  /* Returns NULL on error */
int SU_ServerListen(SU_PServerInfo SI);                            /* SOCKET_ERROR on Error */
SU_PClientSocket SU_ServerAcceptConnection(SU_PServerInfo SI);     /* Returns NULL on error */
void SU_ServerDisconnect(SU_PServerInfo SI);
void SU_FreeSI(SU_PServerInfo SI); /* Disconnect and free SI */
SU_PClientSocket SU_ClientConnect(char *adrs,char *port,int type); /* Returns NULL on error */
int SU_ClientSend(SU_PClientSocket CS,char *msg);                  /* SOCKET_ERROR on Error */
int SU_ClientSendBuf(SU_PClientSocket CS,char *buf,int len);       /* SOCKET_ERROR on Error */
void SU_ClientDisconnect(SU_PClientSocket CS);
void SU_FreeCS(SU_PClientSocket CS); /* Disconnect and free CS */
int SU_UDPSendBroadcast(SU_PServerInfo SI,char *Text,int len,char *port);           /* SOCKET_ERROR on Error */
int SU_UDPSendToAddr(SU_PServerInfo SI,char *Text,int len,char *Addr,char *port);   /* SOCKET_ERROR on Error */
int SU_UDPSendToSin(SU_PServerInfo SI,char *Text,int len,struct sockaddr_in);       /* SOCKET_ERROR on Error */
int SU_UDPReceiveFrom(SU_PServerInfo SI,char *Text,int len,char **ip,int Blocking); /* SOCKET_ERROR on Error */
int SU_UDPReceiveFromSin(SU_PServerInfo SI,char *Text,int len,struct sockaddr_in *,int Blocking); /* SOCKET_ERROR on Error */
int SU_SetSocketOpt(SU_SOCKET sock,int Opt,int value); /* SOCKET_ERROR on Error */
#ifdef _WIN32
bool SU_WSInit(int Major,int Minor); /* Inits WinSocks (MUST BE CALL BEFORE ANY OTHER FUNCTION) */
void SU_WSUninit(void); /* Uninits WinSocks (MUST BE CALL BEFORE EXITING) */
#define SU_CLOSE_SOCKET(x) closesocket(x)
#define SU_EAGAIN WSAEWOULDBLOCK
#define SU_errno WSAGetLastError()
#define SU_ioctl ioctlsocket
#else /* !_WIN32 */
#define SU_CLOSE_SOCKET(x) close(x)
#define SU_EAGAIN EAGAIN
#define SU_errno errno
#define SU_ioctl ioctl
#endif /* _WIN32 */
#endif /* !SU_INCLUDE_NO_SOCKS */


/* **************************************** */
/*               String functions           */
/* **************************************** */
char *SU_strcat(char *dest,const char *src,int len); /* like strncat, but always NULL terminate dest */
char *SU_strcpy(char *dest,const char *src,int len); /* like strncpy, but doesn't pad with 0, and always NULL terminate dest */
char *SU_nocasestrstr(char *text, char *tofind);  /* like strstr(), but nocase */
bool SU_strwcmp(const char *s,const char *wild); /* True if wild equals s (wild may use '*') */
bool SU_nocasestrwcmp(const char *s,const char *wild); /* Same as strwcmp but without case */
bool SU_strwparse(const char *s,const char *wild,char buf[],int size,char *buf_ptrs[],int *ptrs_count); /* True if wild equals s (wild may use '*') */
bool SU_nocasestrwparse(const char *s,const char *wild,char buf[],int size,char *buf_ptrs[],int *ptrs_count); /* Same as nocasestrwparse but without case */
unsigned int SU_strnlen(const char *s,unsigned int max); /* Returns MAX(length of a string,max) (not including terminating null char) */
bool SU_ReadLine(FILE *fp,char S[],int len); /* Returns false on EOF */
bool SU_ParseConfig(FILE *fp,char Name[],int nsize,char Value[],int vsize); /* Returns false on EOF */
char *SU_TrimLeft(const char *S);
void SU_TrimRight(char *S);
char *SU_strparse(char *s,char delim); /* Like strtok, but if 2 consecutive delim are found, an empty string is returned (s[0] = 0) */
void SU_ExtractFileName(const char Path[],char FileName[],const int len); /* Extracts file name (with suffix) from path */
char *SU_strchrl(const char *s,const char *l,char *found); /* Searchs the first occurence of one char of l[i] in s, and returns it in found */
char *SU_strrchrl(const char *s,const char *l,char *found); /* Same as SU_strchrl but starting from the end of the string */
unsigned char SU_toupper(unsigned char c);
unsigned char SU_tolower(unsigned char c);
char *SU_strtoupper(char *s); /* s IS modified */
char *SU_strtolower(char *s); /* s IS modified */
bool SU_strcasecmp(const char *s,const char *p);
char *SU_strerror(int ErrorCode); /* Returns a static string which describes the error code (errno on linux, GetLastError on windows) */

#define SU_strdup(x) ((x)==NULL)?NULL:strdup(x)
#ifdef _WIN32
#define strcasecmp stricmp
#define strncasecmp strnicmp
#define snprintf _snprintf
#endif /* _WIN32 */


/* **************************************** */
/*               Utils functions            */
/* **************************************** */
#ifndef FlagOn
#define FlagOn(x,f) ((x) & (f))
#endif /* !FlagOn */
#ifndef SetFlag
#define SetFlag(x,f) ((x) |= (f))
#endif /* !SetFlag */
#ifndef ClearFlag
#define ClearFlag(x,f) ((x) &= ~(f))
#endif /* !ClearFlag */

FILE *SU_OpenLogFile(const char LogName[]);
void SU_CloseLogFile(FILE *fp);
void SU_WriteToLogFile(FILE *fp,const char Text[]);
/* Checks the http_proxy env var */
void SU_CheckProxyEnv(void);
/* Remove arguments for skyutils, and returns number of remaining arguments for main */
/* This function automatically calls SU_CheckProxyEnv if no proxy found in params */
int SU_GetSkyutilsParams(int argc,char *argv[]);
char *SU_LoadUserHeaderFile(const char FName[]);
char *SU_GetOptionsString(void);
#ifdef __unix__
bool SU_Daemonize(void);
bool SU_SetUserGroup(const char User[],const char Group[]); /* If User and/or Group is != NULL, setuid and setgid are used */
#endif /* __unix__ */
void SU_SetDebugLevel(const char AppName[],const int Level);
int SU_GetDebugLevel(void);
void SU_PrintSyslog(int Level,char *Txt, ...);
void SU_PrintDebug(int Level,char *Txt, ...);
#ifndef DEBUG
#ifdef __unix__
#define SU_PrintDebug(x,...) /* If you have an error here, remove 'x,...' from the () */
#include <syslog.h>
#define SU_SYSLOG_FN(x,y) syslog(x,y)
#else /* !__unix__ */
#define SU_PrintDebug() /* Avoid compilation warnings */
extern FILE *SU_LogFile;
#define SU_SYSLOG_FN(x,y) SU_WriteToLogFile(SU_LogFile,y)
#endif /* __unix__ */
#else /* DEBUG */
#define SU_SYSLOG_FN(x,y) printf(y)
#endif /* !DEBUG */
#ifdef _WIN32
#define SU_SLEEP(x) Sleep(x*1000)
#define SU_USLEEP(x) Sleep(x)
#else /* !_WIN32 */
#define SU_SLEEP(x) sleep(x)
#define SU_USLEEP(x) usleep(x*1000)
#endif /* _WIN32 */
#define SU_ANSI_BLACK  "0"
#define SU_ANSI_RED    "1"
#define SU_ANSI_GREEN  "2"
#define SU_ANSI_YELLOW "3"
#define SU_ANSI_BLUE   "4"
#define SU_ANSI_PINK   "5"
#define SU_ANSI_CYAN   "6"
#define SU_ANSI_WHITE  "7"
#if SU_ENABLE_ANSI_CODE
#define SU_ANSI_COLOR(f,b) "\033[3" f ";4" b "m"
#define SU_ANSI_BLINK      "\033[5m"
#define SU_ANSI_HIGHLIGHT  "\033[1m"
#define SU_ANSI_RESET      "\033[0m"
#else /* !SU_ENABLE_ANSI_CODE */
#define SU_ANSI_COLOR(f,b) ""
#define SU_ANSI_BLINK      ""
#define SU_ANSI_HIGHLIGHT  ""
#define SU_ANSI_RESET      ""
#endif /* SU_ENABLE_ANSI_CODE */
#ifdef _WIN32
typedef unsigned __int64 SU_TICKS;
#else /* !WIN32 */
typedef unsigned long long SU_TICKS;
#endif /* _WIN32 */
typedef unsigned long SU_CPUSPEED;
SU_CPUSPEED SU_GetCPUSpeed(void);
void SU_GetTicks(SU_TICKS *tick); /* Returned value in processor ticks (Use SU_ElapsedTime to compute time in msec) */
unsigned long int SU_ElapsedTime(SU_TICKS t1,SU_TICKS t2,SU_CPUSPEED speed); /* Returned value in msec */
FILE *SU_fmemopen(void *buf,size_t size,const char *opentype);


/* **************************************** */
/*              Memory functions            */
/* **************************************** */
#ifndef SU_MALLOC_ALIGN_SIZE
#define SU_MALLOC_ALIGN_SIZE 16
#else /* SU_MALLOC_ALIGN_SIZE */
#if SU_MALLOC_ALIGN_SIZE < 8
#error "SU_MALLOC_ALIGN_SIZE must be strictly greater than 8"
#endif /* SU_MALLOC_ALIGN_SIZE < 8 */
#endif /* !SU_MALLOC_ALIGN_SIZE */
typedef void (SU_PRINT_FUNC)(bool Fatal,char *Txt, ...);
void SU_SetPrintFunc(SU_PRINT_FUNC *Func);
typedef void (SU_MEM_STATS_FUNC)(void *ptr,long int size,long int time,const char *file,int line);

void *SU_malloc(long int size); /* Allocates a bloc of memory aligned on SU_MALLOC_ALIGN_SIZE */
void *SU_calloc(long int nbelem,long int size); /* Allocates a bloc of memory aligned on SU_MALLOC_ALIGN_SIZE, and zeros it */
void *SU_realloc(void *memblock,long int size); /* Reallocates a bloc of memory aligned on SU_MALLOC_ALIGN_SIZE */
char *SU_strdup_memory(const char *in); /* Dups a string using a bloc of memory aligned on SU_MALLOC_ALIGN_SIZE */
void SU_free(void *memblock);   /* Frees a bloc previously allocated using SU_malloc */
#ifdef SU_MALLOC_TRACE
#undef calloc
#undef strdup
#define malloc(x) SU_malloc_trace(x,__FILE__,__LINE__)
#define calloc(x,y) SU_calloc_trace(x,y,__FILE__,__LINE__)
#define realloc(x,y) SU_realloc_trace(x,y,__FILE__,__LINE__)
#define strdup(x) SU_strdup_trace(x,__FILE__,__LINE__)
#define free(x) SU_free_trace(x,__FILE__,__LINE__)
#define trace_print SU_alloc_trace_print(true)
#define trace_print_count SU_alloc_trace_print(false)
#endif /* SU_MALLOC_TRACE */
void *SU_malloc_trace(long int size,char *file,int line);
void *SU_calloc_trace(long int nbelem,long int size,char *file,int line);
void *SU_realloc_trace(void *memblock,long int size,char *file,int line);
char *SU_strdup_trace(const char *in,char *file,int line);
void SU_free_trace(void *memblock,char *file,int line);
void SU_alloc_trace_print(bool detail); /* Print all allocated blocks (if detail is true), and total number of chunks */
void SU_check_memory(void); /* Check memory heap */
void SU_alloc_stats(SU_MEM_STATS_FUNC *Func); /* Call Func for each chunk of memory */
unsigned long int SU_alloc_total_size(void); /* Returns the total size allocated */ /* Only available with SU_xx_trace functions */
/* MALLOC_CHECK_ environment variable :
 *   0 : If a memory error occurs, execution silently goes on
 *   1 : If a memory error occurs, a debug message is printed in stdout, and execution goes on
 *   2 or not defined : If a memory error occurs, a debug message is printed in stdout, and abort is called
*/
/* SU_MALLOC_TRACE environment variable :
 *   0 or not defined : SU_free_trace does free trace of associated malloc
 *   1 : SU_free_trace keep trace of associated malloc, and display more debug information if block already freed
*/
/* SU_MALLOC_PRINT environment variable :
 *   0 or not defined : Nothing happens
 *   1 : SU_malloc_trace/SU_free_trace functions print memory bloc and file/line from where the function is called
*/


/* **************************************** */
/*                 web functions            */
/* **************************************** */
#define ACT_GET    1
#define ACT_POST   2
#define ACT_PUT    3
#define ACT_DELETE 4

#define URL_BUF_SIZE 2048

typedef struct
{
  int Code;
  char *Location;

  char *Data;      /* NULL if no data */
  int Data_Length; /* -1 if no data */
  int Data_ToReceive;
} SU_TAnswer, *SU_PAnswer;

struct SU_SHTTPActions;

typedef struct
{
  void (*OnSendingCommand)(struct SU_SHTTPActions *); /* User's CallBack just before sending request */
  void (*OnAnswer)(SU_PAnswer,void *); /* User's CallBack just after answer received */
  void (*OnOk)(SU_PAnswer,void *); /* User's CallBack for a 200 reply */
  void (*OnCreated)(SU_PAnswer,void *); /* User's CallBack for a 201 reply */
  void (*OnModified)(SU_PAnswer,void *); /* User's CallBack for a 202 reply */
  void (*OnMoved)(SU_PAnswer,void *); /* User's CallBack for a 302 reply */
  void (*OnForbidden)(SU_PAnswer,void *); /* User's CallBack for a 403 reply */
  void (*OnNotFound)(SU_PAnswer,void *); /* User's CallBack for a 404 reply */
  void (*OnTooBig)(SU_PAnswer,void *); /* User's CallBack for a 413 reply */
  void (*OnUnknownHost)(SU_PAnswer,void *); /* User's CallBack for a 503 reply */
  void (*OnOtherReply)(SU_PAnswer,int,void *); /* User's CallBack for all other replies */
  void (*OnErrorSendingFile)(int,void *); /* User's CallBack for an error sending file (errno code passed) */
} SU_THTTP_CB, *SU_PHTTP_CB;

typedef struct
{
  char *Header; /* Header to send */
  char *FileName; /* File to send (exclude Data) */
  char *Data; /* Data to send (exclude FileName) */
  int Length; /* Length of data */
} SU_THTTPPart, *SU_PHTTPPart;

typedef struct SU_SHTTPActions
{ /* Info to set BEFORE any call to ExecuteActions */
  int  Command; /* ACT_xxx */
  char URL[URL_BUF_SIZE];
  char *URL_Params; /* ACT_GET & ACT_POST */
  char *Post_Data;  /* ACT_POST */
  int  Post_Length; /* ACT_POST */
  char *ContentType; /* Content-type or use default */ /* ACT_GET & ACT_POST */
  char *FileName;   /* ACT_PUT */ /* URL must contain the URL+New file name */ /* If defined for GET or POST, dump result to this file */
  char *Referer;
  SU_PList MultiParts; /* SU_PHTTPPart */ /* MultiParts, exclude Post_Data */ /* ACT_POST */
  void *User;       /* User's info Passed to Callbacks */
  int  Sleep;       /* Time to wait before sending command (sec) */
  SU_THTTP_CB CB;   /* Callbacks structure */

  /* Info used internally */
  char Host[100];
  bool SSL;
} SU_THTTPActions, *SU_PHTTPActions;

typedef struct
{
  char *Name;
  char *Value;
  char *Domain;
  char *Path;
  char *Expire;
  bool Secured;
} SU_TCookie, *SU_PCookie;

typedef struct
{
  char *Type;
  char *Name;
  char *Value;
} SU_TInput, *SU_PInput;

typedef struct
{
  char *Src;
  char *Name;
} SU_TImage, *SU_PImage;

typedef struct
{
  char *Method;
  char *Name;
  char *Action;
  SU_PList Inputs;
} SU_TForm, *SU_PForm;

/* Sets the UserAgent string to send in every web request. Will not be used if SU_LoadUserHeaderFile() is used */
void SU_SetUserAgent(const char UA[]);
/* Sets proxy server,port, user and password values to be used by ExecuteActions (use NULL for proxy to remove use of the proxy) */
void SU_SetProxy(const char Proxy[],const int Port,const char User[], const char Password[]);
/* Sets the socket connection timeout (use 0 to reset default value) */
void SU_SetSocketTimeout(const int Timeout);
/* Returns 0 if ok, -1 if cannot connect to the host, -2 if a timeout occured */
int SU_ExecuteActions(SU_PList Actions);
void SU_FreeAction(SU_PHTTPActions Act);

SU_PInput SU_GetInput(char *html);
SU_PInput SU_GetNextInput(void);
void SU_FreeInput(SU_PInput In);

SU_PImage SU_GetImage(char *html);
SU_PImage SU_GetNextImage(void);
void SU_FreeImage(SU_PImage Im);

void SU_FreeForm(SU_PForm Form);

/* Retrieves the url (into a SU_PHTTPActions struct) of the 'link' from the 'Ans' page associated with the 'URL' request */
SU_PHTTPActions SU_RetrieveLink(const char URL[],const char Ans[],const char link[]);
/* Retrieve link from a frameset */
SU_PHTTPActions SU_RetrieveFrame(const char URL[],const char Ans[],const char framename[]);
/* Retrieve document.forms[num] */
SU_PForm SU_RetrieveForm(const char Ans[],const int num);

char *SU_AddLocationToUrl(const char *URL,const char *Host,const char *Location,bool ssl_mode);

/* Encodes an URL */
char *SU_EncodeURL(const char URL_in[],char URL_out[],int URL_out_len);

/* Skips white spaces before the string, then extracts it */
char *SU_GetStringFromHtml(const char Ans[],const char TextBefore[]);

void SU_FreeCookie(SU_PCookie Cok);
extern SU_PList SW_Cookies; /* SU_PCookie */


/* **************************************** */
/*               Threads functions          */
/* **************************************** */
#ifndef SU_INCLUDE_NO_THREAD
#ifdef __unix__
#define SU_THREAD_HANDLE pthread_t
#define SU_THREAD_ROUTINE_TYPE(x) void *(*x)(void *)
#define SU_THREAD_ROUTINE(x,y) void * x(void *y)
#define SU_END_THREAD(x) pthread_exit(x)
#define SU_PROCESS_SELF getpid()
#define SU_THREAD_SELF pthread_self()
#define SU_THREAD_KEY_HANDLE pthread_key_t
#define SU_THREAD_ONCE_HANDLE pthread_once_t
#define SU_THREAD_ONCE_INIT PTHREAD_ONCE_INIT
#define SU_THREAD_ONCE(x,y) pthread_once(&x,y)
#define SU_THREAD_GET_SPECIFIC(x) pthread_getspecific(x)
#define SU_THREAD_SET_SPECIFIC(x,y) pthread_setspecific(x,y)
#define SU_THREAD_DESTROY_SPECIFIC(x,y)
#define SU_SEM_HANDLE sem_t
#define SU_SEM_WAIT(x) sem_wait(&(x))
#define SU_SEM_POST(x) sem_post(&(x))
#define SU_MUTEX_HANDLE pthread_mutex_t
#define SU_MUTEX_WAIT(x) pthread_mutex_lock(&(x))
#define SU_MUTEX_POST(x) pthread_mutex_unlock(&(x))
#define SU_CRITICAL pthread_mutex_t
#define SU_CRITICAL_ENTER(x) pthread_mutex_lock(&(x))
#define SU_CRITICAL_LEAVE(x) pthread_mutex_unlock(&(x))
#define SU_CRITICAL_TRY_AND_ENTER(x) (pthread_mutex_trylock(&(x)) == 0)
#else /* !__unix__ */
#define SU_THREAD_HANDLE unsigned long
#define SU_THREAD_ROUTINE_TYPE(x) void (__cdecl *x)(void *)
#define SU_THREAD_ROUTINE(x,y) void __cdecl x(void *y)
#define SU_END_THREAD(x) _endthread()
#define SU_PROCESS_SELF GetCurrentProcessId()
#define SU_THREAD_SELF GetCurrentThreadId()
#define SU_THREAD_KEY_HANDLE DWORD
#define SU_THREAD_ONCE_HANDLE DWORD
#define SU_THREAD_ONCE_INIT 0
#define SU_THREAD_ONCE(x,y) y()
#define SU_THREAD_GET_SPECIFIC(x) TlsGetValue(x)
#define SU_THREAD_SET_SPECIFIC(x,y) TlsSetValue(x,(LPVOID)y)
#define SU_THREAD_DESTROY_SPECIFIC(x,y) x(y)
#define SU_SEM_HANDLE HANDLE
#define SU_SEM_WAIT(x) WaitForSingleObject(x,INFINITE)
#define SU_SEM_POST(x) ReleaseSemaphore(x,1,NULL)
#define SU_MUTEX_HANDLE HANDLE
#define SU_MUTEX_WAIT(x) WaitForSingleObject(x,INFINITE)
#define SU_MUTEX_POST(x) ReleaseMutex(x)
#define SU_CRITICAL CRITICAL_SECTION
#define SU_CRITICAL_ENTER(x) EnterCriticalSection(&(x))
#define SU_CRITICAL_LEAVE(x) LeaveCriticalSection(&(x))
#define SU_CRITICAL_TRY_AND_ENTER(x) TryEnterCriticalSection(&(x))
#endif /* __unix__ */
/* Create a new thread */
bool SU_CreateThread(SU_THREAD_HANDLE *Handle,SU_THREAD_ROUTINE_TYPE(Entry),void *User,bool Detached); /* True on success */
/* Kill the specified thread */
void SU_KillThread(SU_THREAD_HANDLE Handle);
/* Terminate the specified thread */
void SU_TermThread(SU_THREAD_HANDLE Handle);
/* Suspend a thread */
void SU_SuspendThread(SU_THREAD_HANDLE Handle);
/* Resume a suspended thread */
void SU_ResumeThread(SU_THREAD_HANDLE Handle);
/* Create a new semaphore */
bool SU_CreateSem(SU_SEM_HANDLE *Handle,int InitialCount,int MaximumCount,const char SemName[]); /* True on success */
/* Free a semaphore */
bool SU_FreeSem(SU_SEM_HANDLE *Handle);
/* Create a new thread key */
bool SU_CreateThreadKey(SU_THREAD_KEY_HANDLE *Handle,SU_THREAD_ONCE_HANDLE *Once,void (*destroyts)(void *)); /* True on success */
/* Block all signals for the calling thread */
void SU_ThreadBlockSigs(void);
/* Create a new mutex */
bool SU_CreateMutex(SU_MUTEX_HANDLE *Handle,const char MutexName[]); /* True on success */
/* Free a mutex */
bool SU_FreeMutex(SU_MUTEX_HANDLE *Handle);
/* Create a critical section */
#define SU_CRITICAL_TYPE_ANY           1
#define SU_CRITICAL_TYPE_RECURSIVE     2
#define SU_CRITICAL_TYPE_NON_RECURSIVE 3
bool SU_CriticalInit(SU_CRITICAL *Crit,int Type); /* True on success */
/* Free a critical section */
bool SU_CriticalDelete(SU_CRITICAL *Crit);
#endif /* !SU_INCLUDE_NO_THREAD */


/* **************************************** */
/*           dynamic load functions         */
/* **************************************** */
#ifdef SU_USE_DL
#ifdef __unix__
#include <dlfcn.h>
#include <signal.h>
#define SU_DL_HANDLE void *
#define SU_DL_OPEN(x) dlopen(x,RTLD_LAZY)
#define SU_DL_CLOSE(x) dlclose(x)
#define SU_DL_SYM(x,y) dlsym(x,y)
#else /* !__unix__ */
#define SU_DL_HANDLE HINSTANCE
#define SU_DL_OPEN(x) LoadLibrary(x)
#define SU_DL_CLOSE(x) FreeLibrary(x)
#define SU_DL_SYM(x,y) GetProcAddress(x,y)
#endif /* __unix__ */
/* Loads the symbol "Name" from handle, but if not found, try with "_Name" */
void *SU_DL_GetSym(SU_DL_HANDLE handle, const char Name[]);
#endif /* SU_USE_DL */


/* **************************************** */
/*             Archive  functions           */
/* **************************************** */
#ifdef SU_USE_ARCH

#define SU_ARCH_COMP_NONE 1
#define SU_ARCH_COMP_Z    2
#define SU_ARCH_COMP_BZ   4

typedef struct
{
  void *Data;             /* Resource data ('Size' bytes of data in this buffer) */
  unsigned long int Size; /* Size of the data pointer                            */
  time_t Stamp;           /* Time stamp of the original resource                 */
} SU_TRes, *SU_PRes;

typedef struct
{
  unsigned long int Offset;   /* Offset of data                   */
  unsigned long int CompSize; /* Compressed size                  */
  unsigned long int CompType; /* Compression type                 */
  unsigned long int Reserved; /* Reserved for future use          */
  unsigned long int OrigSize; /* Original size                    */
  time_t            OrigTime; /* Original time stamp              */

  void              *Data;    /* Data pointer used when creating  */
  bool              IsFile;   /* If Data represents a filename    */
} SU_TResHdr, *SU_PResHdr;

typedef struct
{
  FILE *fp;                /* Resource file              */
  SU_TResHdr *Resources;   /* Table of resources header  */
  unsigned long int NbRes; /* Number of resources        */
  bool Flush;              /* Archive need to be flushed */
} SU_TArch, *SU_PArch;

typedef unsigned int SU_AR_COMP_TYPE;

/* *** Reading functions *** */
/* Opens a skyutils archive file (or a binary file [exe/dll] if the archive is selfcontained) */
SU_PArch SU_AR_OpenArchive(const char FileName[]);
/* Reads resource ResNum (0 is the first one) (NULL if failed) */
SU_PRes SU_AR_ReadRes(SU_PArch Arch,const unsigned int ResNum,bool GetData);
/* Save resource ResNum to FileName (0 is the first one) (true on success) */
bool SU_AR_ReadResFile(SU_PArch Arch,const unsigned int ResNum,const char FileName[]);


/* *** Writing functions *** */
/* Creates a new archive file. FileName can't be NULL */
SU_PArch SU_AR_CreateArchive(const char FileName[]);
/* Adds a resource to the archive (Data can be freed upon return) (true on success) */
bool SU_AR_AddRes(SU_PArch Arch,void *Data,unsigned long int Size,time_t Time,SU_AR_COMP_TYPE Type);
/* Adds a file resource to the archive (true on success) */
bool SU_AR_AddResFile(SU_PArch Arch,const char FileName[],SU_AR_COMP_TYPE Type);


/* *** Other functions *** */
/* Closes a previous opened/created archive (true on success) */
bool SU_AR_CloseArchive(SU_PArch Arch);
/* Frees a previous returned resource */
void SU_AR_FreeRes(SU_PRes Res);
/* Returns supported compression types (as a bit field) */
SU_AR_COMP_TYPE SU_AR_SupportedComps(void);

#endif /* SU_USE_ARCH */


/* **************************************** */
/*             Registry functions           */
/* **************************************** */
#ifndef SU_INCLUDE_NO_REG
#ifdef _WIN32
#include <winreg.h>
#else /* !_WIN32 */
#define HKEY void *
#endif /* _WIN32 */

#define SU_RB_ERR_SUCCESS       0
#define SU_RB_ERR_ACCESS_DENIED 1
#define SU_RB_ERR_WRONG_TYPE    2
#define SU_RB_ERR_INVALID_KEY   3
#define SU_RB_ERR_INVALID_PATH  4
#define SU_RB_ERR_LOCK_FAILED   5
#define SU_RB_ERR_PREMATURE_EOF 6
#define SU_RB_ERR_WRITE_ERROR   7
#define SU_RB_ERR_INVALID_TYPE  8
#define SU_RB_ERR_CORRUPTED     9
#define SU_RB_ERR_MORE_DATA    10
#define SU_RB_ERR_NO_SUCH_KEY  11

int SU_RB_GetLastError();

/* 'Key' parameter must be a succession of subkeys separated by '\', and finished by a keyname. To set/get the default value of a subkey, put a trailing '\' on 'Key' */
bool SU_RB_GetStrValue(const char Key[],char *buf,int buf_len,const char Default[]); /* True on success. Call SU_RB_GetLastError() for error */
bool SU_RB_GetStrLength(const char Key[],int *length); /* True on success. Call SU_RB_GetLastError() for error */
bool SU_RB_GetIntValue(const char Key[],int *Value,int Default); /* True on success. Call SU_RB_GetLastError() for error */
bool SU_RB_GetBinValue(const char Key[],char *buf,int buf_len,char *Default,int def_len); /* True on success. Call SU_RB_GetLastError() for error */
bool SU_RB_GetBinLength(const char Key[],int *length); /* True on success. Call SU_RB_GetLastError() for error */
bool SU_RB_SetStrValue(const char Key[],const char Value[]); /* True on success. Call SU_RB_GetLastError() for error */
bool SU_RB_SetIntValue(const char Key[],int Value); /* True on success. Call SU_RB_GetLastError() for error */
bool SU_RB_SetBinValue(const char Key[],const char *Value,int val_len); /* True on success. Call SU_RB_GetLastError() for error */
bool SU_RB_DelKey(const char Key[]); /* Recursively deletes All sub-keys and values of Key (and Key itself) */ /* True on success. Call SU_RB_GetLastError() for error */
bool SU_RB_DelValue(const char Key[]); /* True on success. Call SU_RB_GetLastError() for error */

bool SU_RB_OpenRegistry(const char RegistryPath[]); /* Opens registry for reading/writing. True on success - Only one registry opened at one time, close previous one if opened */
bool SU_RB_CloseRegistry(void); /* Flush all writings since registry was opened and close it. True on success. If failed, nothing was flushed */

HKEY SU_RB_OpenKeys(const char Key[],int Access); /* Opened HKEY or 0 on error */
HKEY SU_RB_CreateKeys(const char Key[]); /* Created HKEY or 0 on error */
bool SU_RB_EnumKey(HKEY Key,int Idx,char *Name,int name_len); /* True on Success. False when no more values available */
bool SU_RB_EnumStrValue(HKEY Key,int Idx,char *Name,int name_len,char *Value,int value_len); /* True on Success. False when no more values available */ /* All values must be of same type in the HKEY (int or string) */
bool SU_RB_EnumIntValue(HKEY Key,int Idx,char *Name,int name_len,int *Value); /* True on Success. False when no more values available */ /* All values must be of same type in the HKEY (int or string) */
void SU_RB_CloseKey(HKEY Key);
#endif /* !SU_INCLUDE_NO_REG */


/* **************************************** */
/*              Debug  functions            */
/* **************************************** */
#define SU_DBG_OUTPUT_NONE    0
#define SU_DBG_OUTPUT_PRINTF  1
#define SU_DBG_OUTPUT_CONSOLE 2
#define SU_DBG_OUTPUT_FILE    4
#define SU_DBG_OUTPUT_SOCKET  8
#define SU_DBG_OUTPUT_POPUP   16

#define SU_DBG_CONSOLE_DEFAULT_WINDOW_NAME "SkyUtils_Debug_Window"

/* ** Global options */
void SU_DBG_SetFlags(const SU_u64 Flags); /* Effective immediatly */
void SU_DBG_SetOutput(const SU_u16 Output); /* Effective immediatly */
/* If PrintTime is set to true, date/time is also printed. CurrentProcessId/CurrentThreadId is printed if PrintProcessId/PrintThreadId is set to true */
void SU_DBG_SetOptions(const bool PrintTime,const bool PrintProcessId,const bool PrintThreadId); /* Effective immediatly */

/* ** Printf Output Options ** */
/* Ansi color is used if AnsiColor is set to true */
void SU_DBG_OUT_PRINTF_SetOptions(const bool AnsiColor); /* Effective immediatly */
/* ** Console Output Options ** */
/* WindowName is the name of the debug console window. Set it to NULL to stop sending messages to it */
void SU_DBG_OUT_CONSOLE_SetOptions(const char WindowName[]); /* Effective immediatly (changes the Console immediatly) */
/* ** File Output Options ** */
/* FileName is the name of the log file. Set it to NULL to close log file. File is deleted if DeletePreviousLog is set to true */
void SU_DBG_OUT_FILE_SetOptions(const char FileName[],bool DeletePreviousLog); /* Effective immediatly (closes old file if any, opens the new one) */
/* ** Socket Output Options ** */
/* HostName:Port is the Host and port to connect to. Set Port to 0, to remove this host from list of socket */
void SU_DBG_OUT_SOCKET_SetOptions(const char HostName[],const int Port); /* Effective immediatly (adds a new socket) */

/* PrintDebug fonction. \n is added a the end of the string */
void SU_DBG_PrintDebug(const SU_u64 Type,char *Txt, ...);

/* **** Debug Env vars **** */
#define SU_DBG_HELP_MESSAGE "SkyUtils Debug : Environment variables HELP (overrides application init on the first 'SU_DBG_PrintDebug' call) :\n\n" \
"   Global env var : SU_DBG_HELP = Print this help\n" \
"                    SU_DBG_OUTPUT = {printf,console,file,socket,popup} (space separated)\n" \
"                    SU_DBG_FLAGS = <Flags> (Flags is a 64bits bitfield defining which flags to output)\n" \
"                    SU_DBG_OPTIONS = {time,process,thread} (space separated)\n" \
"    printf env var : SU_DBG_OUT_PRINTF = {0|1} (AnsiColor boolean)\n" \
"    console env var : SU_DBG_OUT_CONSOLE = <WindowName>\n" \
"    file env var : SU_DBG_OUT_FILE = {0|1} <FileName> (0|1 is DeletePreviousLog boolean)\n" \
"    socket env var : SU_DBG_OUT_SOCKET = <HostName:Port>[ <HostName:Port>] ...\n" \
"    popup env var : N/A\n" \
"\n"

#ifdef _WIN32
/* Special Windows Config Function (pops up a GUI to choose debug options, overriding application init, and env vars) - Returns true if debug options were changed */
/* hInstance must be the Instance of the module who is linked with the skyutils library (use GetModuleHandle(NULL) to retrieve calling process' HINSTANCE) */
bool SU_DBG_ChooseDebugOptions_Windows(HINSTANCE hInstance,HWND Parent);
#endif /* _WIN32 */



/* **************************************** */
/*              MISC   functions            */
/* **************************************** */

/* Dummy functions used by configure, to check correct version of skyutils */
/* Remove old ones if compatibility has been broken */
void SU_Dummy208(void);


#if defined(__cplusplus) && !defined(__BORLANDC__)
}
#endif /* __cplusplus */

#endif /* !__SKY_UTILS_H__ */