/******************************************************************************/ /* 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__ */