1 #ifndef _COMMON_H_
2 #define _COMMON_H_
3 
4 #include <limits.h>
5 #ifdef HAVE_CONFIG_H
6 	#include "config.h"
7 #endif /* HAVE_CONFIG_H */
8 
9 /* There are many differeces between Linux and Windows.
10  * And we defined things here to unify interfaces,
11  * but it doesn't seem to be very good. */
12 
13 #ifdef WIN32 /* For Windows below. */
14 
15     #ifdef WIN64
16         #ifdef _WIN32_WINNT
17             #undef _WIN32_WINNT
18         #endif
19         #define _WIN32_WINNT 0x0600
20     #endif
21 
22 	#include <stdlib.h>
23 	#include <winsock2.h> /* fd_set, struct sockaddr_in,  */
24 	#include <windows.h> /* For many things */
25 	#include <wininet.h> /* Some internet API, include InternetOpen(), InternetOpenUrl(), etc. */
26 	#include <Shlwapi.h> /* PathMatchSpec() */
27 	#include <ws2tcpip.h> /* struct sockaddr_in6 */
28 
29 	/* In Linux, the last prarmeter of 'send' is mostly MSG_NOSIGNAL(0x4000) (defined in linux headers),
30 	 * but in Windows, no this macro. And this prarmeter is zero, mostly.
31 	 * So we define this macro for Windows.
32 	 */
33 
34 	typedef	int		socklen_t;
35 
36 	/* In Windows, the indetifer of a thread is just a 'HANDLE'. */
37 	typedef	HANDLE	ThreadHandle;
38 	/* And Mutex */
39 	typedef	HANDLE	MutexHandle;
40 
41 	/* Files */
42 	typedef	HANDLE	FileHandle;
43 	#define INVALID_FILE	((FileHandle)NULL)
44 	typedef	HANDLE	MappingHandle;
45 	#define INVALID_MAP		((MappingHandle)NULL)
46 	#define INVALID_MAPPING_FILE	(NULL)
47 
48     /* TCP_TIME_OUT, used as a return value */
49 	#define TCP_TIME_OUT	WSAETIMEDOUT
50 
51 	#define GET_LAST_ERROR()	(WSAGetLastError())
52 	#define SET_LAST_ERROR(i)	(WSASetLastError(i))
53 
54 	/* Close a socket */
55 	#define	CLOSE_SOCKET(s)	(closesocket(s))
56 
57 	/* Threading */
58 	#define CREATE_THREAD(func_ptr, para_ptr, result_holder)	(result_holder) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(func_ptr), (para_ptr), 0, NULL);
59 	#define EXIT_THREAD(r)	return (r)
60 	#define DETACH_THREAD(t)	CloseHandle(t)
61 
62 	/* Mutex */
63 	#define CREATE_MUTEX(m)		((m) = CreateMutex(NULL, FALSE, NULL))
64 	#define GET_MUTEX(m)		(WaitForSingleObject((m), INFINITE))
65 	#define GET_MUTEX_TRY(m)	(WaitForSingleObject((m), 0))
66 	#define RELEASE_MUTEX(m)	(ReleaseMutex(m))
67 	#define DESTROY_MUTEX(m)	(CloseHandle(m))
68 	#define GET_MUTEX_FAILED	WAIT_TIMEOUT /* Used as return value */
69 
70 	/* CRITICAL_SECTION */
71 	#define CRITICAL_SECTION_INIT(c, spin_count)	(InitializeCriticalSectionAndSpinCount(&(c), (spin_count)))
72 	#define ENTER_CRITICAL_SECTION(c)				(EnterCriticalSection(&(c)))
73 	#define ENTER_CRITICAL_SECTION_TRY(c)			(TryEnterCriticalSection(&(c)))
74 	#define CRITICAL_SECTION_TRY_SUCCEED(ret)       ((ret) != 0)
75 	#define LEAVE_CRITICAL_SECTION(c)				(LeaveCriticalSection(&(c)))
76 	#define DELETE_CRITICAL_SECTION(c)				(DeleteCriticalSection(&(c)))
77 
78     /* File and mapping handles*/
79 	#define OPEN_FILE(file)			CreateFile((file), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)
80 	#define CREATE_FILE_MAPPING(handle, size)	CreateFileMapping((handle), NULL, PAGE_READWRITE, 0, size, NULL);
81 	#define MPA_FILE(handle, size)	MapViewOfFile((handle), FILE_MAP_WRITE, 0, 0, 0)
82 
83 	#define UNMAP_FILE(start, size)	UnmapViewOfFile(start)
84 	#define DESTROY_MAPPING(handle)	CloseHandle(handle)
85 	#define CLOSE_FILE(handle)		CloseHandle(handle)
86 
87 	#define PATH_SLASH_CH	'\\'
88 	#define PATH_SLASH_STR	"\\"
89 
90     /* Fill Address  */
91 	#define FILL_ADDR4(addr_struct, family, address_string, port)	(addr_struct).sin_family = (family); \
92 																	(addr_struct).sin_addr.S_un.S_addr = inet_addr(address_string); \
93 																	(addr_struct).sin_port = htons(port);
94 	/* Suspend current thread for some milliseconds */
95 	#define	SLEEP(i)	(Sleep(i))
96 
97 	#define GET_TEMP_DIR()	getenv("TEMP")
98 
99 	#define GET_THREAD_ID()	((int)GetCurrentThreadId())
100 
101 	/* Wildcard match function */
102 	#define WILDCARD_MATCH(p, s)	PathMatchSpec((s), (p))
103 	#define WILDCARD_MATCHED		TRUE	/* Used as return value */
104 
105 	#define	CONNECT_FUNCTION_BLOCKED	WSAEWOULDBLOCK
106 
107 	typedef short	sa_family_t;
108 
109 	#define ExitThisThread()    (ExitThread(0))
110 
111 #else /* For Linux below */
112 
113 	#include <netinet/in.h>	/* For struct 'sockaddr_in' */
114 
115 	/* For function 'socket', 'bind', 'connect', 'send', 'recv',
116 	 * 'sendto', 'recvfrom', 'setsockopt', 'shutdown'. */
117 	#include <sys/socket.h>
118 
119 	#include <unistd.h>		/* For function 'close' , 'sleep' */
120 	#include <errno.h>		/* For extern variable 'errno'. */
121 	#include <arpa/inet.h>	/* For function 'inet_addr'. */
122 	#include <pthread.h>	/* Multithread support. */
123 
124 	#include <sys/types.h>	/* struct stat */
125 	#include <sys/stat.h>	/* stat() */
126 
127 	#include <sys/mman.h>	/* mmap */
128 	#include <fcntl.h>
129 
130 	#ifdef HAVE_SYS_SYSCALL_H
131 		#include <sys/syscall.h> /* syscall */
132 	#endif /* HAVE_SYS_SYSCALL_H */
133 
134 	#include <pwd.h>	/* struct passwd */
135 
136 	#include <fnmatch.h> /* fnmatch() */
137 
138 	/* In Linux, the type of socket is 'int'. */
139 	typedef	int			SOCKET;
140 
141 	/* We use pthread to implement multi threads */
142 	/* The indetifer of pthread is 'pthread_t'. */
143 	typedef	pthread_t			ThreadHandle;
144 	/* And mutex */
145 	typedef	pthread_mutex_t		MutexHandle;
146 	/* spin lock */
147 #ifdef HAVE_PTHREAD_SPIN_INIT
148 	typedef	pthread_spinlock_t	SpinHandle;
149 #else
150 	typedef	pthread_mutex_t		SpinHandle;
151 #endif
152 
153 	/* There are so many HANDLEs are just ints in Linux. */
154 	typedef	int	FileHandle;	/* The type of return value of open() */
155 	#define INVALID_FILE	((FileHandle)(-1))
156 
157 	typedef	int	MappingHandle;
158 	#define INVALID_MAP		((MappingHandle)(-1))
159 	#define INVALID_MAPPING_FILE	((void *)(-1))
160 
161     /* TCP_TIME_OUT, used as a return value */
162 	#define TCP_TIME_OUT	EAGAIN
163 
164 	#define GET_LAST_ERROR()	errno
165 	#define SET_LAST_ERROR(i)	(errno = (i))
166 
167 	/* These are defined in 'windows.h'. */
168 	#define	INVALID_SOCKET	((SOCKET)(~0))
169 	#define	SOCKET_ERROR	(-1)
170 
171 	/* Close a socket */
172 	#define	CLOSE_SOCKET(s)	(close(s))
173 
174 	/* Boolean */
175 	#define	BOOL	int
176 	#define	FALSE	0
177 	#define	TRUE	(!0)
178 
179 
180 #ifndef SO_DONTLINGER
181 	#define SO_DONTLINGER   ((unsigned int) (~SO_LINGER))
182 #endif
183 
184 	/* pthread */
185 	#define CREATE_THREAD(func_ptr, para_ptr, return_value) (pthread_create(&return_value, NULL, (void *(*)())(func_ptr), (para_ptr)))
186 	#define EXIT_THREAD(r)	pthread_exit(r)
187 	#define DETACH_THREAD(t)	pthread_detach(t)
188 
189     /* mutex */
190 	#define CREATE_MUTEX(m)		(pthread_mutex_init(&(m), NULL))
191 	#define GET_MUTEX(m)		(pthread_mutex_lock(&(m)))
192 	#define GET_MUTEX_TRY(m)	(pthread_mutex_trylock(&(m)))
193 	#define RELEASE_MUTEX(m)	(pthread_mutex_unlock(&(m)))
194 	#define DESTROY_MUTEX(m)	(pthread_mutex_destroy(&(m)))
195 	#define GET_MUTEX_FAILED	(!0)
196 
197 	/* spin lock */
198 #ifdef HAVE_PTHREAD_SPIN_INIT
199 	#define CREATE_SPIN(s)		(pthread_spin_init(&(s), PTHREAD_PROCESS_PRIVATE))
200 	#define LOCK_SPIN(s)		(pthread_spin_lock(&(s)))
201 	#define LOCK_SPIN_TRY(s)	(pthread_spin_trylock(&(s)))
202 	#define SPIN_TRY_SUCCEED(ret) ((ret) == 0)
203 	#define UNLOCK_SPIN(s)		(pthread_spin_unlock(&(s)))
204 	#define DESTROY_SPIN(s)		(pthread_spin_destroy(&(s)))
205 #else /*HAVE_PTHREAD_SPIN_INIT  */
206 	#define CREATE_SPIN(s)		(pthread_mutex_init(&(s), NULL))
207 	#define LOCK_SPIN(s)		(pthread_mutex_lock(&(s)))
208 	#define LOCK_SPIN_TRY(s)	(pthread_mutex_trylock(&(s)))
209 	#define SPIN_TRY_SUCCEED(ret) ((ret) == 0)
210 	#define UNLOCK_SPIN(s)		(pthread_mutex_unlock(&(s)))
211 	#define DESTROY_SPIN(s)		(pthread_mutex_destroy(&(s)))
212 #endif /*HAVE_PTHREAD_SPIN_INIT  */
213 
214     /* File and Mapping */
215     /* In Linux, there is no a long process to map a file like Windows. */
216 	#define OPEN_FILE(file)						(open((file), O_RDWR | O_CREAT, S_IRWXU))
217 	#define CREATE_FILE_MAPPING(handle, size)	(lseek((handle), size, SEEK_SET), write((handle), "\0", 1), (handle))
218 	#define MPA_FILE(handle, size)				(mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, (handle), 0))
219 	#define UNMAP_FILE(start, size)				(munmap(start, size))
220 	#define DESTROY_MAPPING(handle)				/* Nothing */
221 	#define CLOSE_FILE(handle)					(close(handle))
222 
223 	#define PATH_SLASH_CH	'/'
224 	#define PATH_SLASH_STR	"/"
225 
226 	#define FILL_ADDR4(addr_struct, family, address_string, port)	(addr_struct).sin_family = (family); \
227 																	(addr_struct).sin_addr.s_addr = inet_addr(address_string); \
228 																	(addr_struct).sin_port = htons(port);
229 
230     /* Suspend current thread for some milliseconds */
231 	#define	SLEEP(i)	do \
232 						{ \
233 							int	Count = 1000; \
234 							do \
235 							{ \
236 								usleep(i); \
237 								--Count; \
238 							} while( Count > 0 ); \
239 						} while( 0 )
240 
241     /* As the name suggests */
242 	#define GET_TEMP_DIR()	"/tmp"
243 
244 #ifdef HAVE_SYS_SYSCALL_H
245 	#define GET_THREAD_ID()	syscall(__NR_gettid)
246 #else /* HAVE_SYS_SYSCALL_H */
247 	#define GET_THREAD_ID()	(-1)
248 #endif /* HAVE_SYS_SYSCALL_H */
249 
250 	#define WILDCARD_MATCH(p, s)	fnmatch((p), (s), FNM_NOESCAPE)
251 	#define WILDCARD_MATCHED	0
252 
253 	#define	CONNECT_FUNCTION_BLOCKED	EINPROGRESS
254 
255 	#define ExitThisThread()    (pthread_exit(NULL))
256 
257 #endif /* WIN32 */
258 
259 #ifdef WIN32
260 	typedef	CRITICAL_SECTION	EFFECTIVE_LOCK;
261 	#define EFFECTIVE_LOCK_INIT(l)		CRITICAL_SECTION_INIT((l), 1024)
262 	#define EFFECTIVE_LOCK_GET(l)		ENTER_CRITICAL_SECTION(l)
263 	#define EFFECTIVE_LOCK_TRY_GET(l)	ENTER_CRITICAL_SECTION_TRY(l)
264 	#define EFFECTIVE_LOCK_TRY_SUCCEED(ret) CRITICAL_SECTION_TRY_SUCCEED(ret)
265 	#define EFFECTIVE_LOCK_RELEASE(l)	LEAVE_CRITICAL_SECTION(l)
266 	#define EFFECTIVE_LOCK_DESTROY(l)	DELETE_CRITICAL_SECTION(l)
267 #else /* WIN32 */
268 	typedef	SpinHandle	EFFECTIVE_LOCK;
269 	#define EFFECTIVE_LOCK_INIT(l)		CREATE_SPIN(l)
270 	#define EFFECTIVE_LOCK_GET(l)		LOCK_SPIN(l)
271 	#define EFFECTIVE_LOCK_TRY_GET(l)	LOCK_SPIN_TRY(l)
272 	#define EFFECTIVE_LOCK_TRY_SUCCEED(ret) SPIN_TRY_SUCCEED(ret)
273 	#define EFFECTIVE_LOCK_RELEASE(l)	UNLOCK_SPIN(l)
274 	#define EFFECTIVE_LOCK_DESTROY(l)	DESTROY_SPIN(l)
275 #endif /* WIN32 */
276 
277 #ifdef WIN32
278 	#define GetFileDirectory(out)	(GetModulePath(out, sizeof(out)))
279 #else /* WIN32 */
280 	#define GetFileDirectory(out)	(GetConfigDirectory(out))
281 #endif /* WIN32 */
282 
283 #define INVALID_THREAD	((ThreadHandle)NULL)
284 
285 #ifndef MSG_NOSIGNAL
286 #define	MSG_NOSIGNAL	0
287 #endif /* MSG_NOSIGNAL */
288 
289 #ifndef MSG_MORE
290 #define	MSG_MORE	0
291 #endif /* MSG_MORE */
292 
293 #ifndef MSG_WAITALL
294 #define	MSG_WAITALL	0
295 #endif /* MSG_WAITALL */
296 
297 /* Unified interfaces end */
298 
299 /* something is STILL on some state */
300 #define __STILL
301 
302 #ifdef HAVE_STDINT_H
303 	#include <stdint.h>
304 #else
305 #ifndef HAVE_CONFIG_H
306 	#ifndef __USE_MISC
307 
308 		#if (INT_MAX == 2147483647)
309 			#define int32_t		int
310 			#define uint32_t		unsigned int
311 			#define UINT32_T_MAX	0xFFFFFFFF
312 		#endif
313 
314 		#if (SHRT_MAX == 32767)
315 			#define int16_t	short
316 			#define uint16_t	unsigned short
317 		#endif
318 
319 	#endif
320 #endif
321 #endif
322 
323 #ifndef HAVE_IN_PORT_T
324 	typedef uint16_t	in_port_t;
325 #endif
326 
327 /* Parameters' tag */
328 #ifndef __in
329 	#define __in
330 #endif /* __in */
331 
332 #ifndef __in_opt
333 	#define __in_opt
334 #endif /* __in_opt */
335 
336 #ifndef __out
337 	#define __out
338 #endif /* __out */
339 
340 #ifndef __out_opt
341 	#define __out_opt
342 #endif /* __out_opt */
343 
344 #ifndef __inout
345 	#define __inout
346 #endif /* __inout */
347 
348 #ifndef __inout_opt
349 	#define __inout_opt
350 #endif /* __inout_opt */
351 
352 #define LENGTH_OF_IPV6_ADDRESS_ASCII	(sizeof("XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:xxx.xxx.xxx.xxx"))
353 #define LENGTH_OF_IPV4_ADDRESS_ASCII	(sizeof("xxx.xxx.xxx.xxx"))
354 
355 typedef struct _Address_Type{
356 
357 	/* Union of address of IPv4 and IPv6 */
358 	union {
359 		struct sockaddr_in	Addr4;
360 		struct sockaddr_in6	Addr6;
361 	}		Addr;
362 
363 	/* Although there is a `family' field in both `struct sockaddr_in' and
364 	 * `struct sockaddr_in6', we also add it out here.
365 	 */
366 	sa_family_t	family;
367 
368 } Address_Type;
369 
370 #endif /* _COMMON_H_ */
371