summaryrefslogtreecommitdiff
path: root/src/lib/evil
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2012-09-11 16:13:11 +0000
committerVincent Torri <vincent.torri@gmail.com>2012-09-11 16:13:11 +0000
commitcd69ef4c8a66e7155967a8b661a014856979cf31 (patch)
tree4a351ae4a4ca91abf29c85254b85ea8da71f74b0 /src/lib/evil
parent59a9dfd11860888a35e96dfe51af63cea5cecfe1 (diff)
merge: add evil files
SVN revision: 76464
Diffstat (limited to 'src/lib/evil')
-rw-r--r--src/lib/evil/Evil.h186
-rw-r--r--src/lib/evil/Makefile.am132
-rw-r--r--src/lib/evil/dirent.h141
-rw-r--r--src/lib/evil/dlfcn.c272
-rw-r--r--src/lib/evil/dlfcn.h258
-rw-r--r--src/lib/evil/evil_dirent.c197
-rw-r--r--src/lib/evil/evil_errno.c9
-rw-r--r--src/lib/evil/evil_fcntl.c124
-rw-r--r--src/lib/evil/evil_fcntl.h110
-rw-r--r--src/lib/evil/evil_fnmatch.c231
-rw-r--r--src/lib/evil/evil_fnmatch_list_of_states.c77
-rw-r--r--src/lib/evil/evil_fnmatch_private.h24
-rw-r--r--src/lib/evil/evil_inet.c648
-rw-r--r--src/lib/evil/evil_inet.h149
-rw-r--r--src/lib/evil/evil_langinfo.c53
-rw-r--r--src/lib/evil/evil_langinfo.h41
-rw-r--r--src/lib/evil/evil_libgen.c103
-rw-r--r--src/lib/evil/evil_libgen.h88
-rw-r--r--src/lib/evil/evil_link_ce.c90
-rw-r--r--src/lib/evil/evil_link_xp.cpp151
-rw-r--r--src/lib/evil/evil_macro.h193
-rw-r--r--src/lib/evil/evil_macro_pop.h93
-rw-r--r--src/lib/evil/evil_main.c74
-rw-r--r--src/lib/evil/evil_main.h52
-rw-r--r--src/lib/evil/evil_mman.c234
-rw-r--r--src/lib/evil/evil_pformat.h61
-rw-r--r--src/lib/evil/evil_pformata.c2493
-rw-r--r--src/lib/evil/evil_pformatw.c9
-rw-r--r--src/lib/evil/evil_print.h37
-rw-r--r--src/lib/evil/evil_printa.c1786
-rw-r--r--src/lib/evil/evil_printw.c4
-rw-r--r--src/lib/evil/evil_private.h20
-rw-r--r--src/lib/evil/evil_pwd.c65
-rw-r--r--src/lib/evil/evil_stdio.c215
-rw-r--r--src/lib/evil/evil_stdio.h196
-rw-r--r--src/lib/evil/evil_stdlib.c453
-rw-r--r--src/lib/evil/evil_stdlib.h199
-rw-r--r--src/lib/evil/evil_string.c128
-rw-r--r--src/lib/evil/evil_string.h152
-rw-r--r--src/lib/evil/evil_time.c45
-rw-r--r--src/lib/evil/evil_time.h61
-rw-r--r--src/lib/evil/evil_unistd.c431
-rw-r--r--src/lib/evil/evil_unistd.h326
-rw-r--r--src/lib/evil/evil_util.c247
-rw-r--r--src/lib/evil/evil_util.h134
-rw-r--r--src/lib/evil/evil_uuid.c12
-rw-r--r--src/lib/evil/fnmatch.h54
-rw-r--r--src/lib/evil/gdtoa/README357
-rw-r--r--src/lib/evil/gdtoa/README.mingw20
-rw-r--r--src/lib/evil/gdtoa/arithchk.c192
-rw-r--r--src/lib/evil/gdtoa/dmisc.c196
-rw-r--r--src/lib/evil/gdtoa/dtoa.c750
-rw-r--r--src/lib/evil/gdtoa/g__fmt.c142
-rw-r--r--src/lib/evil/gdtoa/g_dfmt.c90
-rw-r--r--src/lib/evil/gdtoa/g_ffmt.c88
-rw-r--r--src/lib/evil/gdtoa/g_xfmt.c143
-rw-r--r--src/lib/evil/gdtoa/gd_arith.h6
-rw-r--r--src/lib/evil/gdtoa/gd_qnan.h12
-rw-r--r--src/lib/evil/gdtoa/gdtoa.c733
-rw-r--r--src/lib/evil/gdtoa/gdtoa.h121
-rw-r--r--src/lib/evil/gdtoa/gdtoa_fltrnds.h18
-rw-r--r--src/lib/evil/gdtoa/gdtoaimp.h645
-rw-r--r--src/lib/evil/gdtoa/gethex.c340
-rw-r--r--src/lib/evil/gdtoa/gmisc.c76
-rw-r--r--src/lib/evil/gdtoa/hd_init.c49
-rw-r--r--src/lib/evil/gdtoa/hexnan.c139
-rw-r--r--src/lib/evil/gdtoa/misc.c860
-rw-r--r--src/lib/evil/gdtoa/qnan.c116
-rw-r--r--src/lib/evil/gdtoa/smisc.c149
-rw-r--r--src/lib/evil/gdtoa/strtodg.c979
-rw-r--r--src/lib/evil/gdtoa/strtof.c77
-rw-r--r--src/lib/evil/gdtoa/strtopx.c119
-rw-r--r--src/lib/evil/gdtoa/sum.c91
-rw-r--r--src/lib/evil/gdtoa/ulp.c61
-rw-r--r--src/lib/evil/mingw32ce/errno.h111
-rw-r--r--src/lib/evil/pwd.h71
-rw-r--r--src/lib/evil/sys/mman.h149
77 files changed, 17758 insertions, 0 deletions
diff --git a/src/lib/evil/Evil.h b/src/lib/evil/Evil.h
new file mode 100644
index 0000000..e807dff
--- /dev/null
+++ b/src/lib/evil/Evil.h
@@ -0,0 +1,186 @@
1#ifndef __EVIL_H__
2#define __EVIL_H__
3
4/**
5 * @mainpage Evil
6 * @image html e_big.png
7 * @author Vincent Torri
8 * @version 1.7.0
9 * @date 2008-2012
10 *
11 * @section intro_sec Introduction
12 *
13 * The Evil library is an evil library that ports some evil Unix
14 * functions to the Windows (XP or above, or Mobile) platform. The
15 * evilness is so huge that the most of the functions are not POSIX or
16 * BSD compliant.
17 *
18 * These functions are intended to be used in the Enlightenment
19 * Foundation Libraries only and can be compiled only on Windows,
20 * using MSYS/MinGW on Windows, and cross-compilation on Unix. This
21 * library is minimal in the sense that only the functions needed to
22 * compile the EFL are available. The purpose of this library is NOT
23 * to have a full POSIX emulation et it is NOT a replacement of
24 * cygwin. To compare the size of the DLL themselves, Evil is around
25 * 33 KB and cygwin DLL is around 800 KB.
26 *
27 * @section acknowledgments_sec Acknowledgments
28 *
29 * This library has receive some from people interested in the EFL or
30 * not. Among them, evil thanks to Lars Munch, Raoul Hecky, Nicolas
31 * Aguirre, Tor Lillqvist, Lance Fetters, Vincent Richomme, Paul
32 * Vixie, Daniel Stenberg, who helped the author of the library in
33 * different fields (code and tests).
34 *
35 * @section license_sec license
36 *
37 * The Evil library is distributes under a modified BSD license. See
38 * the files COPYING and COPYING-PLAIN in the top level directory for
39 * the full license text.
40 *
41 * @section reference_sec Reference API
42 *
43 * Use the horizontal menu above to navigate into the reference API
44 */
45
46/**
47 * @file Evil.h
48 * @brief The file that provides miscellaneous functions ported from Unix.
49 * @defgroup Evil Miscellaneous functions ported from Unix.
50 *
51 * This header provides miscellaneous functions that exist on Unix
52 * but not on Windows platform. They try to follow the conformance of
53 * the Unix versions.
54 */
55
56/**
57 * @cond LOCAL
58 */
59
60#ifdef __cplusplus
61extern "C" {
62#endif
63
64
65#ifndef WIN32_LEAN_AND_MEAN
66# define WIN32_LEAN_AND_MEAN
67#endif
68#include <windows.h>
69#undef WIN32_LEAN_AND_MEAN
70
71#include <stdlib.h>
72#include <stdio.h>
73#include <time.h>
74#include <limits.h>
75#include <sys/stat.h>
76#include <fcntl.h>
77#include <math.h>
78#include <direct.h>
79
80
81#ifdef _MSC_VER
82
83# include <io.h>
84
85# define F_OK 0 /* Check for file existence */
86# define X_OK 1 /* MS access() doesn't check for execute permission. */
87# define W_OK 2 /* Check for write permission */
88# define R_OK 4 /* Check for read permission */
89
90typedef DWORD pid_t;
91typedef unsigned short mode_t;
92
93typedef unsigned short uint16_t;
94typedef unsigned int uint32_t;
95typedef signed int int32_t;
96typedef __int64 int64_t;
97typedef unsigned __int64 uint64_t;
98typedef SSIZE_T ssize_t;
99
100# define strdup(s) _strdup(s)
101# define unlink(filename) _unlink(filename)
102# define fileno(f) _fileno(f)
103# define fdopen(fd,m) _fdopen((fd),(m))
104# define access(p,m) _access((p),(m))
105# define hypot(x,y) _hypot((x),(y))
106# define tzset _tzset
107
108#endif /* _MSC_VER */
109
110#ifdef _WIN32_WCE
111# ifndef offsetof
112# define offsetof(type, ident) ((size_t)&(((type*)0)->ident))
113# endif
114#endif
115
116typedef unsigned long uid_t;
117typedef unsigned long gid_t;
118
119
120#include "evil_macro.h"
121#include "evil_fcntl.h"
122#include "evil_inet.h"
123#include "evil_langinfo.h"
124#include "evil_libgen.h"
125#include "evil_main.h"
126#include "evil_print.h"
127#include "evil_stdlib.h"
128#include "evil_stdio.h"
129#include "evil_string.h"
130#include "evil_time.h"
131#include "evil_unistd.h"
132#include "evil_util.h"
133#include "evil_macro_pop.h"
134
135
136#if (defined(_WIN32) && !defined(_UWIN) && !defined(__CYGWIN__))
137# if defined(_MSC_VER) || defined(__MINGW32__)
138
139# ifdef S_ISDIR
140# undef S_ISDIR
141# endif
142# ifdef S_ISREG
143# undef S_ISREG
144# endif
145# define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
146# define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG)
147
148# define S_ISLNK(m) 0
149
150# define S_IRUSR _S_IRUSR
151# define S_IWUSR _S_IWUSR
152# define S_IXUSR _S_IXUSR
153# define S_IRGRP S_IRUSR
154# define S_IROTH S_IRUSR
155# define S_IWGRP S_IWUSR
156# define S_IWOTH S_IWUSR
157# define S_IXGRP S_IXUSR
158# define S_IXOTH S_IXUSR
159
160# define _S_IRWXU (_S_IREAD | _S_IWRITE | _S_IEXEC)
161# define _S_IXUSR _S_IEXEC
162# define _S_IWUSR _S_IWRITE
163# define _S_IRUSR _S_IREAD
164
165# define mkdir(p,m) _mkdir(p)
166 /*
167# define close(fd) _close(fd)
168# define read(fd,buffer,count) _read((fd),(buffer),(count))
169# define write(fd,buffer,count) _write((fd),(buffer),(count))
170# define unlink(filename) _unlink((filename))
171# define lstat(f,s) _stat((f),(s))
172 */
173
174# endif
175#endif
176
177
178#ifdef __cplusplus
179}
180#endif
181
182/**
183 * @endcond
184 */
185
186#endif /* __EVIL_H__ */
diff --git a/src/lib/evil/Makefile.am b/src/lib/evil/Makefile.am
new file mode 100644
index 0000000..62d0d56
--- /dev/null
+++ b/src/lib/evil/Makefile.am
@@ -0,0 +1,132 @@
1
2MAINTAINERCLEANFILES = Makefile.in
3
4lib_LTLIBRARIES = libevil.la libdl.la
5
6install_evilheadersdir = $(includedir)/evil-@VMAJ@
7dist_install_evilheaders_DATA = \
8Evil.h \
9evil_fcntl.h \
10evil_inet.h \
11evil_langinfo.h \
12evil_libgen.h \
13evil_macro.h \
14evil_macro_pop.h \
15evil_main.h \
16evil_print.h \
17evil_stdlib.h \
18evil_stdio.h \
19evil_string.h \
20evil_time.h \
21evil_unistd.h \
22evil_util.h
23
24stdheadersdir = $(includedir)/evil-@VMAJ@
25nobase_dist_stdheaders_DATA = pwd.h sys/mman.h fnmatch.h dirent.h dlfcn.h
26
27if EVIL_HAVE_WINCE
28
29nobase_dist_stdheaders_DATA += mingw32ce/errno.h
30
31endif
32
33# gdtoa
34libevil_la_SOURCES = \
35gdtoa/arithchk.c \
36gdtoa/dmisc.c \
37gdtoa/dtoa.c \
38gdtoa/gd_arith.h \
39gdtoa/g_dfmt.c \
40gdtoa/gd_qnan.h \
41gdtoa/gdtoa.c \
42gdtoa/gdtoa_fltrnds.h \
43gdtoa/gdtoa.h \
44gdtoa/gdtoaimp.h \
45gdtoa/gethex.c \
46gdtoa/g_ffmt.c \
47gdtoa/g__fmt.c \
48gdtoa/gmisc.c \
49gdtoa/g_xfmt.c \
50gdtoa/hd_init.c \
51gdtoa/hexnan.c \
52gdtoa/misc.c \
53gdtoa/qnan.c \
54gdtoa/smisc.c \
55gdtoa/strtodg.c \
56gdtoa/strtof.c \
57gdtoa/strtopx.c \
58gdtoa/sum.c \
59gdtoa/ulp.c
60
61#evil
62libevil_la_SOURCES += \
63evil_dirent.c \
64evil_fcntl.c \
65evil_fnmatch.c \
66evil_fnmatch_list_of_states.c \
67evil_inet.c \
68evil_langinfo.c \
69evil_libgen.c \
70evil_main.c \
71evil_mman.c \
72evil_pformata.c \
73evil_pformatw.c \
74evil_printa.c \
75evil_printw.c \
76evil_pwd.c \
77evil_stdlib.c \
78evil_stdio.c \
79evil_string.c \
80evil_time.c \
81evil_unistd.c \
82evil_util.c \
83evil_uuid.c \
84evil_pformat.h \
85evil_private.h \
86evil_fnmatch_private.h
87
88if EVIL_HAVE_WINCE
89
90libevil_la_SOURCES += evil_errno.c evil_link_ce.c
91
92else
93
94libevil_la_SOURCES += evil_link_xp.cpp
95
96endif
97
98libevil_la_CPPFLAGS = @EVIL_CPPFLAGS@
99libevil_la_CFLAGS = @EVIL_CFLAGS@
100libevil_la_CXXFLAGS = @EVIL_CXXFLAGS@
101libevil_la_LIBADD = @EVIL_LIBS@
102libevil_la_LDFLAGS = -no-undefined -Wl,--enable-auto-import -version-info @version_info@
103
104if EVIL_HAVE_WINCE
105
106libevil_la_LINK = $(LINK) $(libevil_la_LDFLAGS)
107
108else
109
110libevil_la_LINK = $(CXXLINK) $(libevil_la_LDFLAGS)
111
112endif
113
114libdl_la_SOURCES = dlfcn.c
115
116libdl_la_CPPFLAGS = @EVIL_DLFCN_CPPFLAGS@
117libdl_la_CFLAGS = @EVIL_CFLAGS@
118libdl_la_LIBADD = $(top_builddir)/src/lib/libevil.la @EVIL_DLFCN_LIBS@
119libdl_la_LDFLAGS = -no-undefined -Wl,--enable-auto-import -version-info @version_info@
120
121EXTRA_DIST = gdtoa/README gdtoa/README.mingw
122
123install-data-hook:
124 rm -f $(libdir)/libevil.la $(libdir)/libdl.la
125
126uninstall-local:
127 rm -f $(DESTDIR)$(bindir)/libevil-@VMAJ@.dll
128 rm -f $(DESTDIR)$(bindir)/libdl-@VMAJ@.dll
129 rm -f $(DESTDIR)$(libdir)/libevil.dll.a
130 rm -f $(DESTDIR)$(libdir)/libevil.a
131 rm -f $(DESTDIR)$(libdir)/libdl.dll.a
132 rm -f $(DESTDIR)$(libdir)/libdl.a
diff --git a/src/lib/evil/dirent.h b/src/lib/evil/dirent.h
new file mode 100644
index 0000000..3fe9d12
--- /dev/null
+++ b/src/lib/evil/dirent.h
@@ -0,0 +1,141 @@
1#ifndef __EVIL_DIRENT_H__
2#define __EVIL_DIRENT_H__
3
4#ifdef EAPI
5# undef EAPI
6#endif /* EAPI */
7
8#ifdef _WIN32
9# ifdef EFL_EVIL_BUILD
10# ifdef DLL_EXPORT
11# define EAPI __declspec(dllexport)
12# else
13# define EAPI
14# endif /* ! DLL_EXPORT */
15# else
16# define EAPI __declspec(dllimport)
17# endif /* ! EFL_EVIL_BUILD */
18#endif /* _WIN32 */
19
20
21/**
22 * @file dirent.h
23 * @brief The file that provides functions ported from Unix in dirent.h.
24 * @defgroup Evil_Dirent_Group Dirent.h functions
25 *
26 * This header provides functions ported from Unix in dirent.h.
27 *
28 * @{
29 */
30
31
32#ifdef UNICODE
33# include <wchar.h>
34#endif
35
36/**
37 * @def DT_UNKNOWN
38 * Specifies that the file type is unknown.
39 */
40#define DT_UNKNOWN 0
41
42/**
43 * @def DT_DIR
44 * Specifies that the file type is a directory.
45 */
46#define DT_DIR 4
47
48/**
49 * @typedef DIR
50 * @brief A structure that describes a directory stream.
51 */
52typedef struct DIR DIR;
53
54/**
55 * @struct dirent
56 * @brief A structure that describes a directory stream.
57 */
58struct dirent
59{
60 char d_name[260 + 1]; /**< The filename. */
61 int d_mode; /**< The mode */
62 unsigned char d_type; /**< The type */
63};
64
65
66#ifdef __cplusplus
67extern "C" {
68#endif /* __cplusplus */
69
70
71/**
72 * @brief Open the given directory.
73 *
74 * @param name The directory to open.
75 * @return A pointer to the directory stream.
76 *
77 * This function opens the directory @p name and return the directory
78 * stream. On error or if @p dir is NULL, -1 is returned, and errno is
79 * set appropriately (on Windows XP only). On success, 0 is returned.
80 *
81 * @see closedir()
82 * @see readdir()
83 *
84 * Conformity: None.
85 *
86 * Supported OS: Windows XP, CE.
87 */
88EAPI DIR *opendir(char const *name);
89
90/**
91 * @brief Close the given directory.
92 *
93 * @param dir The directory stream to close.
94 * @return A pointer to the directory stream.
95 *
96 * This function closes the stream directory @p dir. On error or is
97 * @p path is NULL or an empty string, NULL is returned, and errno is set
98 * appropriately (on Windows XP only).
99 *
100 * @see opendir()
101 * @see readdir()
102 *
103 * Conformity: None.
104 *
105 * Supported OS: Windows XP, CE.
106 */
107EAPI int closedir(DIR *dir);
108
109/**
110 * @brief Read the given directory.
111 *
112 * @param dir The directory stream to read.
113 * @return A pointer to a dirent structure, @c NULL oterhwise.
114 *
115 * This function returns a pointer to a dirent structure representing
116 * the next directory entry in the directory stream pointed to by
117 * @p dir. It returns NULL on reaching the end of the directory stream
118 * or if an error occurred and errno is set appropriately (on Windows XP only).
119 *
120 * @see opendir()
121 * @see readdir()
122 *
123 * Conformity: None.
124 *
125 * Supported OS: Windows XP, CE.
126 */
127EAPI struct dirent *readdir(DIR *dir);
128
129
130#ifdef __cplusplus
131}
132#endif /* __cplusplus */
133
134
135
136/**
137 * @}
138 */
139
140
141#endif /* __EVIL_DIRENT_H__ */
diff --git a/src/lib/evil/dlfcn.c b/src/lib/evil/dlfcn.c
new file mode 100644
index 0000000..818cabf
--- /dev/null
+++ b/src/lib/evil/dlfcn.c
@@ -0,0 +1,272 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include <stdlib.h>
6
7#if defined(__MINGW32CE__) || defined(_MSC_VER)
8# include <limits.h>
9#endif /* __MINGW32CE__ || _MSC_VER */
10
11#ifndef WIN32_LEAN_AND_MEAN
12# define WIN32_LEAN_AND_MEAN
13#endif
14#include <windows.h>
15#undef WIN32_LEAN_AND_MEAN
16
17#ifdef _WIN32_WCE
18# include <tlhelp32.h> /* CreateToolhelp32Snapshot */
19#else
20# include <psapi.h> /* EnumProcessModules(Ex) */
21#endif
22
23#include "Evil.h"
24
25#include "dlfcn.h"
26
27
28static char *dl_err = NULL;
29static int dl_err_viewed = 0;
30
31static void
32get_last_error(char *desc)
33{
34 char *str;
35 size_t l1;
36 size_t l2;
37
38 str = evil_last_error_get();
39
40 l1 = strlen(desc);
41 l2 = strlen(str);
42
43 if (dl_err)
44 free(dl_err);
45
46 dl_err = (char *)malloc(sizeof(char) * (l1 + l2 + 1));
47 if (!dl_err)
48 dl_err = strdup("not enough resource");
49 else
50 {
51 memcpy(dl_err, desc, l1);
52 memcpy(dl_err + l1, str, l2);
53 dl_err[l1 + l2] = '\0';
54 }
55 free(str);
56 dl_err_viewed = 0;
57}
58
59void *
60dlopen(const char* path, int mode __UNUSED__)
61{
62 HMODULE module = NULL;
63
64 if (!path)
65 {
66 module = GetModuleHandle(NULL);
67 if (!module)
68 get_last_error("GetModuleHandle returned: ");
69 }
70 else
71 {
72 char *new_path;
73 size_t l;
74 unsigned int i;
75
76 /* according to MSDN, we must change the slash to backslash */
77 l = strlen(path);
78 new_path = (char *)malloc(sizeof(char) * (l + 1));
79 if (!new_path)
80 {
81 if (dl_err)
82 free(dl_err);
83 dl_err = strdup("not enough resource");
84 dl_err_viewed = 0;
85 return NULL;
86 }
87 for (i = 0; i <= l; i++)
88 {
89 if (path[i] == '/')
90 new_path[i] = '\\';
91 else
92 new_path[i] = path[i];
93 }
94#ifdef UNICODE
95 {
96 wchar_t *wpath;
97
98 wpath = evil_char_to_wchar(new_path);
99 module = LoadLibrary(wpath);
100 free(wpath);
101 }
102#else
103 module = LoadLibraryEx(new_path, NULL,
104 LOAD_WITH_ALTERED_SEARCH_PATH);
105#endif /* ! UNICODE */
106 if (!module)
107 get_last_error("LoadLibraryEx returned: ");
108
109 free(new_path);
110 }
111
112 return module;
113}
114
115int
116dlclose(void* handle)
117{
118 if (FreeLibrary(handle))
119 return 0;
120 else
121 {
122 get_last_error("FreeLibrary returned: ");
123 return -1;
124 }
125}
126
127void *
128dlsym(void *handle, const char *symbol)
129{
130 FARPROC fp = NULL;
131 LPCTSTR new_symbol;
132
133 if (!symbol || !*symbol) return NULL;
134
135#ifdef UNICODE
136 new_symbol = evil_char_to_wchar(symbol);
137#else
138 new_symbol = symbol;
139#endif /* UNICODE */
140
141 if (handle == RTLD_DEFAULT)
142 {
143#ifdef _WIN32_WCE
144 HANDLE snapshot;
145 MODULEENTRY32 module;
146
147 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS |
148 TH32CS_SNAPMODULE |
149 TH32CS_GETALLMODS,
150 0);
151 if (!snapshot)
152 return NULL;
153
154 module.dwSize = sizeof(module);
155 if (Module32First(snapshot, &module))
156 do {
157 fp = GetProcAddress(module.hModule, new_symbol);
158 if (fp) break;
159 } while (Module32Next(snapshot, &module));
160
161 CloseToolhelp32Snapshot(snapshot);
162#else
163 HMODULE modules[1024];
164 DWORD needed;
165 DWORD i;
166
167 /* TODO: use EnumProcessModulesEx() on Windows >= Vista */
168 if (!EnumProcessModules(GetCurrentProcess(),
169 modules, sizeof(modules), &needed))
170 return NULL;
171
172 for (i = 0; i < (needed / sizeof(HMODULE)); i++)
173 {
174 fp = GetProcAddress(modules[i], new_symbol);
175 if (fp) break;
176 }
177#endif
178 }
179 else
180 fp = GetProcAddress(handle, new_symbol);
181
182#ifdef UNICODE
183 free((void *)new_symbol);
184#endif /* UNICODE */
185
186 if (!fp)
187 get_last_error("GetProcAddress returned: ");
188
189 return fp;
190}
191
192int
193dladdr (const void *addr __UNUSED__, Dl_info *info)
194{
195 TCHAR tpath[PATH_MAX];
196 MEMORY_BASIC_INFORMATION mbi;
197 char *path;
198 char *tmp;
199 size_t length;
200 int ret = 0;
201
202 if (!info)
203 return 0;
204
205#ifdef _WIN32_WINNT
206 length = VirtualQuery(addr, &mbi, sizeof(mbi));
207 if (!length)
208 return 0;
209
210 if (mbi.State != MEM_COMMIT)
211 return 0;
212
213 if (!mbi.AllocationBase)
214 return 0;
215
216 ret = GetModuleFileName((HMODULE)mbi.AllocationBase, (LPTSTR)&tpath, PATH_MAX);
217 if (!ret)
218 return 0;
219#else
220 ret = GetModuleFileName(NULL, (LPTSTR)&tpath, PATH_MAX);
221 if (!ret)
222 return 0;
223#endif
224
225#ifdef UNICODE
226 path = evil_wchar_to_char(tpath);
227#else
228 path = tpath;
229#endif /* ! UNICODE */
230
231 length = strlen (path);
232 if (length >= PATH_MAX)
233 {
234 length = PATH_MAX - 1;
235 path[PATH_MAX - 1] = '\0';
236 }
237
238 /* replace '/' by '\' */
239 tmp = path;
240 while (*tmp)
241 {
242 if (*tmp == '/') *tmp = '\\';
243 tmp++;
244 }
245
246 memcpy (info->dli_fname, path, length + 1);
247 info->dli_fbase = NULL;
248 info->dli_sname = NULL;
249 info->dli_saddr = NULL;
250
251#ifdef UNICODE
252 free (path);
253#endif /* ! UNICODE */
254
255 return 1;
256}
257
258char *
259dlerror (void)
260{
261 if (!dl_err_viewed)
262 {
263 dl_err_viewed = 1;
264 return dl_err;
265 }
266 else
267 {
268 if (dl_err)
269 free(dl_err);
270 return NULL;
271 }
272}
diff --git a/src/lib/evil/dlfcn.h b/src/lib/evil/dlfcn.h
new file mode 100644
index 0000000..610331b
--- /dev/null
+++ b/src/lib/evil/dlfcn.h
@@ -0,0 +1,258 @@
1#ifndef __EVIL_DLFCN_H__
2#define __EVIL_DLFCN_H__
3
4
5#include <limits.h>
6
7
8#ifdef EAPI
9# undef EAPI
10#endif /* EAPI */
11
12#ifdef _WIN32
13# ifdef EFL_EVIL_DLFCN_BUILD
14# ifdef DLL_EXPORT
15# define EAPI __declspec(dllexport)
16# else
17# define EAPI
18# endif /* ! DLL_EXPORT */
19# else
20# define EAPI __declspec(dllimport)
21# endif /* ! EFL_EVIL_DLFCN_BUILD */
22#endif /* _WIN32 */
23
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29#ifdef _WIN32_WCE
30# ifndef PATH_MAX
31# define PATH_MAX 260
32# endif
33#endif
34
35
36/**
37 * @file dlfcn.h
38 * @brief The file that provides functions to manage dynamic-link libraries
39 * @defgroup Dlfcn Functions that manage dynamic-link libraries.
40 *
41 * This header provides functions to load and unload dynamic-link
42 * libaries, to get the address of a symbol, and to get diagnostic
43 * information.
44 */
45
46
47/**
48 * @def RTLD_LAZY
49 * Lazy function call binding.
50 */
51# define RTLD_LAZY 0x00001 /* lazy function call binding */
52
53/**
54 * @def RTLD_NOW
55 * Immediate function call binding.
56 */
57# define RTLD_NOW 0x00002 /* immediate function call binding */
58
59/**
60 * @def RTLD_GLOBAL
61 * Symbols in this dlopen'ed obj are visible to other dlopen'ed objs.
62 */
63# define RTLD_GLOBAL 0x00100 /* symbols in this dlopen'ed obj are visible
64 to other dlopen'ed objs */
65
66/**
67 * @def RTLD_NODELETE
68 * Symbols are not deleted when closed.
69 */
70#define RTLD_NODELETE 0x01000 /* do not delete object when closed. */
71
72/**
73 * @def RTLD_DEFAULT
74 * Symbols are searched in all the DLL opened by the current process.
75 */
76#define RTLD_DEFAULT ((void*)1) /* search the symbol on all the DLL of the current process */
77
78/**
79 * @typedef Dl_info
80 * @brief A structure that stores infomation of a calling process.
81 */
82typedef struct Dl_info Dl_info;
83
84/**
85 * @struct Dl_info
86 * @brief A structure that stores infomation of a calling process.
87 */
88struct Dl_info
89{
90 char dli_fname[PATH_MAX]; /**< Filename of defining object */
91 void *dli_fbase; /**< Load address of that object */
92 const char *dli_sname; /**< Name of nearest lower symbol */
93 void *dli_saddr; /**< Exact value of nearest symbol */
94};
95
96/**
97 * @brief Map a specified executable module (either a .dll or .exe file)
98 * into the address space of the user process.
99 *
100 * @param path Name of the module.
101 * @param mode Unused.
102 * @return A pointer that represent the module, or @c NULL on failure.
103 *
104 * Map a specified executable module (either a .dll or .exe file)
105 * into the address space of the user process. If @p path is @c NULL,
106 * then the module corresponding to the current process is returned.
107 * Otherwise the module specified by @p path is loaded if it exists.
108 * If not, @c NULL is returned. The directory separators can be forward
109 * slash, or backward ones. Mapping a module can map other modules.
110 * @p mode is unused.
111 *
112 * If an error occurred, an error string can be retrived with dlerror().
113 *
114 * According to the OS, the search order of the module can change,
115 * according to the value of SafeDllSearchMode.
116 *
117 * - For Windows Vista, Windows Server 2003, and Windows XP SP2:
118 * SafeDLLSearchMode is enabled by default.
119 * - For Windows XP and Windows 2000 SP4: SafeDLLSearchMode is disabled
120 * by default.
121 *
122 * If SafeDllSearchMode is enabled
123 * - The directory from which the application loaded.
124 * - The system directory. Use the GetSystemDirectory() function
125 * to get the path of this directory.
126 * - The 16-bit system directory. There is no function that obtains
127 * the path of this directory, but it is searched.
128 * - The Windows directory. Use the GetWindowsDirectory() function
129 * to get the path of this directory.
130 * - The current directory.
131 * - The directories that are listed in the PATH environment variable.
132 * Note that this does not include the per-application path specified
133 * by the App Paths registry key.
134 *
135 * If SafeDllSearchMode is disabled
136 * - The directory from which the application loaded.
137 * - The current directory.
138 * - The system directory. Use the GetSystemDirectory() function
139 * to get the path of this directory.
140 * - The 16-bit system directory. There is no function that obtains
141 * the path of this directory, but it is searched.
142 * - The Windows directory. Use the GetWindowsDirectory() function
143 * to get the path of this directory.
144 * - The directories that are listed in the PATH environment variable.
145 * Note that this does not include the per-application path specified
146 * by the App Paths registry key.
147 *
148 * Conformity: None.
149 *
150 * Supported OS: Windows Vista, Windows XP or Windows 2000
151 * Professional.
152 *
153 * @ingroup Dlfcn
154 */
155EAPI void *dlopen(const char* path, int mode);
156
157/**
158 * @brief Close a dynamic-link library.
159 *
160 * @param handle Handle that references a dynamic-link library.
161 * @return O on sucess, -1 otherwise.
162 *
163 * Release a reference to the dynamic-link library referenced
164 * by @p handle. If the reference count drops to 0, the handle is
165 * removed from the address space and is rendered invalid. @p handle
166 * is the value returned by a previous call to dlopen().
167 *
168 * If no error occurred, the returned value is 0, otherwise the
169 * returned value is -1 and an error string can be retrived with
170 * dlerror().
171 *
172 * Conformity: None.
173 *
174 * Supported OS: Windows Vista, Windows XP or Windows 2000
175 * Professional.
176 *
177 * @ingroup Dlfcn
178 */
179EAPI int dlclose(void* handle);
180
181/**
182 * @brief Get the address of a symbol.
183 *
184 * @param handle Handle that references a dynamic-link library.
185 * @param symbol @c NULL-terminated string.
186 * @return O on sucess, NULL otherwise.
187 *
188 * Return the address of the code or data location specified by the
189 * string @p symbol. @p handle references a library that contains
190 * the function or variable @p symbol.
191 *
192 * If no error occurred, the returned value is the code or data
193 * location, otherwise the returned value is NULL and an error
194 * string can be retrived with dlerror().
195 *
196 * Conformity: None.
197 *
198 * Supported OS: Windows Vista, Windows XP or Windows 2000
199 * Professional.
200 *
201 * @ingroup Dlfcn
202 */
203EAPI void *dlsym(void* handle, const char* symbol);
204
205/**
206 * @brief Get the location of the current process (.exe)
207 *
208 * @param addr Unused.
209 * @param info Pointer to the Dl_info to fill.
210 * @return 1 on success, 0 otherwise.
211 *
212 * Fill the dli_fname member of @p info with the absolute name
213 * of the current calling process (.exe file that is executed).
214 * All other members are set to @c NULL.
215 *
216 * Contrary to the unix function, the full name of the shared
217 * library is not returned, but insted the full name of the current
218 * calling process (.exe file).
219 *
220 * Conformity: None.
221 *
222 * Supported OS: Windows Vista, Windows XP or Windows 2000
223 * Professional.
224 *
225 * @ingroup Dlfcn
226 */
227EAPI int dladdr (const void *addr, Dl_info *info);
228
229/**
230 * @brief Get diagnostic information
231 *
232 * @return A @c NULL-terminated string if an error occured, @c NULL
233 * otherwise.
234 *
235 * Return a @c NULL-terminated character string describing the last
236 * error that occurred on this thread during a call to dlopen(),
237 * dlsym(), or dlclose(). If no such error has occurred, dlerror()
238 * returns a null pointer. At each call to dlerror(), the error
239 * indication is reset. Thus in the case of two calls to dlerror(),
240 * where the second call follows the first immediately, the second
241 * call will always return a null pointer.
242 *
243 * Conformity: None.
244 *
245 * Supported OS: Windows Vista, Windows XP or Windows 2000
246 * Professional.
247 *
248 * @ingroup Dlfcn
249 */
250EAPI char *dlerror (void);
251
252
253#ifdef __cplusplus
254}
255#endif
256
257
258#endif /* __EVIL_DLFCN_H__ */
diff --git a/src/lib/evil/evil_dirent.c b/src/lib/evil/evil_dirent.c
new file mode 100644
index 0000000..e02b95f
--- /dev/null
+++ b/src/lib/evil/evil_dirent.c
@@ -0,0 +1,197 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include <dirent.h>
6
7#ifdef HAVE_ERRNO_H
8# include <errno.h>
9#endif
10
11#include "Evil.h"
12
13
14struct DIR
15{
16 struct dirent dirent;
17 WIN32_FIND_DATA data;
18 HANDLE handle;
19};
20
21
22DIR *opendir(char const *name)
23{
24 DIR *dir;
25 char *tmp1;
26 char *tmp2;
27 DWORD attr;
28 size_t l;
29#ifdef UNICODE
30 wchar_t *wname;
31 char *d_name;
32#endif
33
34 /* valid name */
35 if (!name || !*name)
36 {
37#ifdef HAVE_ERRNO_H
38 errno = ENOENT;
39#endif
40 return NULL;
41 }
42
43#ifdef UNICODE
44 wname = evil_char_to_wchar(name);
45 if (!wname)
46 {
47# ifdef HAVE_ERRNO_H
48 errno = ENOMEM;
49# endif
50 return NULL;
51 }
52
53 if((attr = GetFileAttributes(wname)) == 0xFFFFFFFF)
54#else
55 if((attr = GetFileAttributes(name)) == 0xFFFFFFFF)
56#endif
57 {
58#ifdef HAVE_ERRNO_H
59 errno = ENOENT;
60#endif
61 return NULL;
62 }
63
64#ifdef UNICODE
65 free(wname);
66#endif
67
68 /* directory */
69 if (!(attr & FILE_ATTRIBUTE_DIRECTORY))
70 {
71#ifdef HAVE_ERRNO_H
72 errno = ENOTDIR;
73#endif
74 return NULL;
75 }
76
77 dir = (DIR *)malloc(sizeof(DIR));
78 if (!dir)
79 {
80#ifdef HAVE_ERRNO_H
81 errno = ENOMEM;
82#endif
83 return NULL;
84 }
85
86 l = strlen(name);
87 tmp1 = (char *)malloc(sizeof(char) * l + 5);
88 if (!tmp1)
89 {
90#ifdef HAVE_ERRNO_H
91 errno = ENOMEM;
92#endif
93 return NULL;
94 }
95
96 memcpy(tmp1, name, l);
97 memcpy(tmp1 + l, "\\*.*", 5);
98
99 tmp2 = tmp1;
100 while (*tmp2)
101 {
102 if (*tmp2 == '/') *tmp2 = '\\';
103 tmp2++;
104 }
105
106#ifdef UNICODE
107 wname = evil_char_to_wchar(tmp1);
108 if (!wname)
109 {
110#ifdef HAVE_ERRNO_H
111 errno = ENOMEM;
112#endif
113 free(tmp1);
114
115 return NULL;
116 }
117 dir->handle = FindFirstFile(wname, &dir->data);
118 free(wname);
119#else
120 dir->handle = FindFirstFile(tmp1, &dir->data);
121#endif
122
123 free(tmp1);
124
125 if (dir->handle == INVALID_HANDLE_VALUE)
126 {
127 free(dir);
128 return NULL;
129 }
130
131#ifdef UNICODE
132 d_name = evil_wchar_to_char(dir->data.cFileName);
133 strcpy(dir->dirent.d_name, d_name);
134 free(d_name);
135#else
136 strcpy(dir->dirent.d_name, dir->data.cFileName);
137#endif
138 dir->dirent.d_mode = (int)dir->data.dwFileAttributes;
139
140 if (dir->data.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
141 dir->dirent.d_type = DT_DIR;
142 else
143 dir->dirent.d_type = DT_UNKNOWN;
144
145 return dir;
146}
147
148int closedir(DIR *dir)
149{
150 if (!dir)
151 {
152#ifdef HAVE_ERRNO_H
153 errno = EBADF;
154#endif
155 return -1;
156 }
157
158 if (dir->handle != INVALID_HANDLE_VALUE)
159 FindClose(dir->handle);
160 free(dir);
161
162 return 0;
163}
164
165struct dirent *readdir(DIR *dir)
166{
167#ifdef UNICODE
168 char *d_name;
169#endif
170
171 if (!dir)
172 {
173#ifdef HAVE_ERRNO_H
174 errno = EBADF;
175#endif
176 return NULL;
177 }
178
179 if (dir->handle == INVALID_HANDLE_VALUE)
180 return NULL;
181
182#ifdef UNICODE
183 d_name = evil_wchar_to_char(dir->data.cFileName);
184 strcpy(dir->dirent.d_name, d_name);
185 free(d_name);
186#else
187 strcpy(dir->dirent.d_name, dir->data.cFileName);
188#endif
189
190 if (!FindNextFile(dir->handle, &dir->data))
191 {
192 FindClose(dir->handle);
193 dir->handle = INVALID_HANDLE_VALUE;
194 }
195
196 return &dir->dirent;
197}
diff --git a/src/lib/evil/evil_errno.c b/src/lib/evil/evil_errno.c
new file mode 100644
index 0000000..37cac61
--- /dev/null
+++ b/src/lib/evil/evil_errno.c
@@ -0,0 +1,9 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "Evil.h"
6#include "mingw32ce/errno.h"
7
8
9int errno = 0;
diff --git a/src/lib/evil/evil_fcntl.c b/src/lib/evil/evil_fcntl.c
new file mode 100644
index 0000000..7c62c2a
--- /dev/null
+++ b/src/lib/evil/evil_fcntl.c
@@ -0,0 +1,124 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include <stdio.h>
6
7#ifdef _MSC_VER
8# include <io.h> /* for _get_osfhandle _lseek and _locking */
9#endif
10
11#include <sys/locking.h>
12
13#include <winsock2.h> /* for ioctlsocket */
14
15#include "Evil.h"
16
17
18#ifdef __MINGW32CE__
19# define _get_osfhandle(FILEDES) ((HANDLE)FILEDES)
20#endif /* __MINGW32CE__ */
21
22
23/*
24 * port of fcntl function
25 *
26 */
27
28int fcntl(int fd, int cmd, ...)
29{
30 va_list va;
31 HANDLE h;
32 int res = -1;
33
34 va_start (va, cmd);
35
36 h = (HANDLE)_get_osfhandle(fd);
37 if (h == INVALID_HANDLE_VALUE)
38 return -1;
39
40 if (cmd == F_GETFD)
41 {
42#ifndef __MINGW32CE__
43 DWORD flag;
44
45 if (!GetHandleInformation(h, &flag))
46 return -1;
47
48 res = 0;
49#endif /* ! __MINGW32CE__ */
50 }
51
52 if (cmd == F_SETFD)
53 {
54 long flag;
55
56 flag = va_arg(va, long);
57 if (flag == FD_CLOEXEC)
58 {
59#ifndef __MINGW32CE__
60 if (SetHandleInformation(h, HANDLE_FLAG_INHERIT, 0))
61 res = 0;
62#endif /* ! __MINGW32CE__ */
63 }
64 }
65 else if (cmd == F_SETFL)
66 {
67 long flag;
68
69 flag = va_arg(va, long);
70 if (flag == O_NONBLOCK)
71 {
72 u_long arg = 1;
73 int type;
74 int len;
75 int ret;
76
77 len = (int)sizeof(int);
78 ret = getsockopt((SOCKET)fd, SOL_SOCKET, SO_TYPE, (char *)&type, &len);
79 if (!ret && (type == SOCK_STREAM))
80 {
81 if (!ioctlsocket((SOCKET)fd, FIONBIO, &arg) == SOCKET_ERROR)
82 res = 0;
83 }
84 }
85 }
86#ifndef __MINGW32CE__
87 else if ((cmd == F_SETLK) || (cmd == F_SETLKW))
88 {
89 struct flock *fl;
90 off_t length = 0;
91 long pos;
92
93 fl = va_arg(va, struct flock *);
94
95 if (fl->l_len == 0)
96 {
97 length = _lseek(fd, 0L, SEEK_END);
98 if (length != -1L)
99 res = 0;
100 }
101 fl->l_len = length - fl->l_start - 1;
102
103 pos = _lseek(fd, fl->l_start, fl->l_whence);
104 if (pos != -1L)
105 res = 0;
106
107 if ((fl->l_type == F_RDLCK) || (fl->l_type == F_WRLCK))
108 {
109 if (cmd == F_SETLK)
110 res = _locking(fd, _LK_NBLCK, fl->l_len); /* if cannot be locked, we return immediatly */
111 else /* F_SETLKW */
112 res = _locking(fd, _LK_LOCK, fl->l_len); /* otherwise, we try several times */
113 }
114
115 if (fl->l_type == F_UNLCK)
116 res = _locking(fd, _LK_UNLCK, fl->l_len);
117 }
118
119#endif /* ! __MINGW32CE__ */
120
121 va_end(va);
122
123 return res;
124}
diff --git a/src/lib/evil/evil_fcntl.h b/src/lib/evil/evil_fcntl.h
new file mode 100644
index 0000000..194341b
--- /dev/null
+++ b/src/lib/evil/evil_fcntl.h
@@ -0,0 +1,110 @@
1#ifndef __EVIL_FCNTL_H__
2#define __EVIL_FCNTL_H__
3
4
5# include <sys/types.h>
6
7
8/**
9 * @def FD_CLOEXEC
10 * Specifies that the file descriptor should be closed when an exec()
11 * function is invoked.
12 */
13# define FD_CLOEXEC 1
14
15/**
16 * @def O_NONBLOCK
17 * Specifies that the socket is in non-blocking mode.
18 */
19# define O_NONBLOCK 04000
20
21/**
22 * @def F_SETFD
23 * Specifies that fcntl() should set the file descriptor flags
24 * associated with the filedes argument.
25 */
26
27/**
28 * @def F_SETLK
29 * Specifies that fcntl() should set or clear a file segment lock
30 * according to the lock description pointed to by the third argument.
31 */
32
33/**
34 * @def F_SETLKW
35 * Equivalent to F_SETLK except that if a shared or exclusive lock
36 * is blocked by other locks, the thread shall wait until the request
37 * can be satisfied.
38 */
39
40# define F_GETFD 1
41# define F_SETFD 2
42# define F_SETFL 4
43# define F_SETLK 6
44# define F_SETLKW 7
45
46/**
47 * @def F_RDLCK
48 * Read (or shared) lock
49 */
50
51/**
52 * @def F_WRLCK
53 * Write (or exclusive) lock
54 */
55
56/**
57 * @def F_UNLCK
58 * Remove lock
59 */
60
61# ifndef F_RDLCK
62# define F_RDLCK 0
63# define F_WRLCK 1
64# define F_UNLCK 2
65# endif /* ! F_RDLCK */
66
67/**
68 * @struct flock
69 * @brief A structure that controls the lock of a file descriptor.
70 */
71struct flock
72{
73 short int l_type; /**< lock type: read, write, ... */
74 short int l_whence; /**< type of l_start */
75 off_t l_start; /**< starting offset */
76 off_t l_len; /**< 0 means end of the file */
77 pid_t l_pid; /**< lock owner */
78};
79
80
81/**
82 * @brief Provide control over file descriptors.
83 *
84 * @param fd The file descriptor.
85 * @param cmd The type of control.
86 * @return 0 on success, -1 otherwise.
87 *
88 * Performs one of various miscellaneous operations on @p fd.
89 * The operation in question is determined by @p cmd:
90 *
91 * - F_SETFD: Set the close-on-exec flag to the value specified
92 * by the argument after command (only the least significant
93 * bit is used).
94 * - F_SETLK and F_SETLKW: used to manage discretionary file locks.
95 * The third argument must be a pointer to a struct flock (that
96 * may be overwritten by this call).
97 *
98 * This function returns 0 on success, -1 otherwise.
99 *
100 * Conformity: None.
101 *
102 * Supported OS: Windows Vista, Windows XP or Windows 2000
103 * Professional.
104 *
105 * @ingroup Evil
106 */
107EAPI int fcntl(int fd, int cmd, ...);
108
109
110#endif /* __EVIL_FCNTL_H__ */
diff --git a/src/lib/evil/evil_fnmatch.c b/src/lib/evil/evil_fnmatch.c
new file mode 100644
index 0000000..0b4af7b
--- /dev/null
+++ b/src/lib/evil/evil_fnmatch.c
@@ -0,0 +1,231 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include <assert.h>
6#include <string.h>
7
8#include "fnmatch.h"
9#include "evil_fnmatch_private.h"
10
11enum fnmatch_status
12{
13 fnmatch_not_found = 0,
14 fnmatch_found = 1,
15 fnmatch_syntax_error = 2
16};
17
18static
19size_t
20fnmatch_match_class_token(enum fnmatch_status *status,
21 const char *class_token,
22 char c)
23{
24 if (! *class_token)
25 {
26 *status = fnmatch_syntax_error;
27 return 0;
28 }
29 else if (class_token[1] == '-' && class_token[2] != ']')
30 {
31 if (class_token[0] <= c && c <= class_token[2])
32 *status = fnmatch_found;
33 return 3;
34 }
35 else
36 {
37 if (c == *class_token)
38 *status = fnmatch_found;
39 return 1;
40 }
41}
42
43static
44size_t
45fnmatch_complement_class(const char *class_token)
46{
47 switch (*class_token)
48 {
49 case 0:
50 return FNM_SYNTAXERR;
51
52 case '!':
53 return 1;
54
55 default:
56 return 0;
57 }
58}
59
60static
61size_t
62fnmatch_match_class(const char *class,
63 char c)
64{
65 const size_t complement = fnmatch_complement_class(class + 1);
66 enum fnmatch_status status;
67 size_t pos;
68
69 if (complement == FNM_SYNTAXERR)
70 return FNM_SYNTAXERR;
71
72 status = fnmatch_not_found;
73 pos = 1 + complement;
74
75 do
76 pos += fnmatch_match_class_token(&status, class + pos, c);
77 while (class[pos] && class[pos] != ']');
78
79 if (status == fnmatch_syntax_error || ! class[pos])
80 return FNM_SYNTAXERR;
81
82 if (status == fnmatch_found)
83 return complement ? 0 : pos + 1;
84 else
85 return complement ? pos + 1 : 0;
86}
87
88static
89size_t
90fnmatch_chrcasecmp(char a,
91 char b)
92{
93 if ('A' <= a && a <= 'Z')
94 a += 'a' - 'A';
95 if ('A' <= b && b <= 'Z')
96 b += 'a' - 'A';
97 return a == b;
98}
99
100static
101size_t
102fnmatch_match_token(const char *token,
103 char c,
104 e_bool leading,
105 int flags)
106{
107 if (*token == '\\' && !(flags & FNM_NOESCAPE))
108 return token[1] ? (token[1] == c ? 2 : 0) : FNM_SYNTAXERR;
109
110 if (c == '/' && (flags & FNM_PATHNAME))
111 return *token == '/';
112
113 if (c == '.' && leading && (flags & FNM_PERIOD))
114 return *token == '.';
115
116 switch (*token)
117 {
118 case '?':
119 return 1;
120
121 case '[':
122 return fnmatch_match_class(token, c);
123
124 default:
125 if (flags & FNM_CASEFOLD)
126 return fnmatch_chrcasecmp(*token, c);
127 return *token == c ? 1 : 0;
128 }
129}
130
131static
132void
133fnmatch_init_states(struct list_of_states *states)
134{
135 states->size = 1;
136 states->states[0] = 0;
137 memset(states->has, 0, states->reserved * sizeof (*states->has));
138 states->has[0] = 1;
139}
140
141static
142size_t
143fnmatch_check_finals(const char *pattern,
144 const struct list_of_states *states)
145{
146 size_t i, j;
147 for (i = 0; i < states->size; ++i)
148 {
149 e_bool match = 1;
150
151 for (j = states->states[i]; pattern[j]; ++j)
152 if (pattern[j] != '*')
153 {
154 match = 0;
155 break;
156 }
157
158 if (match)
159 return 0;
160 }
161 return FNM_NOMATCH;
162}
163
164int
165fnmatch(const char *pattern,
166 const char *string,
167 int flags)
168{
169 struct list_of_states *states;
170 struct list_of_states *new_states;
171 e_bool leading = 1;
172 char *c;
173 size_t r;
174
175 assert(pattern);
176 assert(string);
177
178 states = fnmatch_list_of_states_alloc(2, strlen(pattern));
179 new_states = states + 1;
180
181 if (! states)
182 return FNM_NOMEM;
183 fnmatch_init_states(states);
184
185
186 for (c = (char *)string; *c && states->size; ++c)
187 {
188 size_t i;
189 fnmatch_list_of_states_clear(new_states);
190
191 for (i = 0; i < states->size; ++i)
192 {
193 const size_t pos = states->states[i];
194
195 if (! pattern[pos])
196 {
197 if (*c == '/' && (flags & FNM_LEADING_DIR))
198 return 0;
199 continue;
200 }
201 else if (pattern[pos] == '*')
202 {
203 fnmatch_list_of_states_insert(states, pos + 1);
204 if ((*c != '/' || !(flags & FNM_PATHNAME)) &&
205 (*c != '.' || !leading || !(flags & FNM_PERIOD)))
206 fnmatch_list_of_states_insert(new_states, pos);
207 }
208 else
209 {
210 const size_t m = fnmatch_match_token(pattern + pos, *c,
211 leading, flags);
212
213 if (m == FNM_SYNTAXERR)
214 return FNM_SYNTAXERR;
215 else if (m)
216 fnmatch_list_of_states_insert(new_states, pos + m);
217 }
218 }
219 {
220 struct list_of_states *tmp = states;
221
222 states = new_states;
223 new_states = tmp;
224 }
225 leading = *c == '/' && (flags & FNM_PATHNAME);
226 }
227
228 r = fnmatch_check_finals(pattern, states);
229 fnmatch_list_of_states_free(states < new_states ? states : new_states, 2);
230 return (int)r;
231}
diff --git a/src/lib/evil/evil_fnmatch_list_of_states.c b/src/lib/evil/evil_fnmatch_list_of_states.c
new file mode 100644
index 0000000..c6cfb7f
--- /dev/null
+++ b/src/lib/evil/evil_fnmatch_list_of_states.c
@@ -0,0 +1,77 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include <assert.h>
6#include <stdlib.h>
7#include <string.h>
8
9#include "evil_fnmatch_private.h"
10
11struct list_of_states*
12fnmatch_list_of_states_alloc(size_t n,
13 size_t pattern_len)
14{
15 struct list_of_states *l;
16
17 const size_t reserved = pattern_len + 1;
18 const size_t states_size = sizeof (*l->states) * reserved;
19 const size_t has_size = sizeof (*l->has) * reserved;
20 const size_t states_has_size = states_size + has_size;
21 const size_t struct_size = sizeof (*l) + states_has_size;
22
23 unsigned char *states;
24 unsigned char *has;
25 size_t i;
26
27 l = malloc(n * struct_size);
28 if (!l)
29 return 0;
30
31 states = (unsigned char *) (l + n);
32 has = states + states_size;
33
34 for (i = 0; i < n; ++i)
35 {
36 l[i].reserved = reserved;
37 l[i].states = (size_t *) states;
38 l[i].has = (e_bool *) has;
39 states += states_has_size;
40 has += states_has_size;
41 }
42
43 return l;
44}
45
46void
47fnmatch_list_of_states_free(struct list_of_states *lists,
48 size_t n)
49{
50 assert(lists);
51
52 (void) n;
53 free(lists);
54}
55
56void
57fnmatch_list_of_states_insert(struct list_of_states *list,
58 size_t state)
59{
60 assert(list);
61 assert(state < list->reserved);
62
63 if (list->has[state])
64 return;
65
66 list->states[list->size++] = state;
67 list->has[state] = 1;
68}
69
70void
71fnmatch_list_of_states_clear(struct list_of_states *list)
72{
73 assert(list);
74
75 list->size = 0;
76 memset(list->has, 0, list->reserved * sizeof (*list->has));
77}
diff --git a/src/lib/evil/evil_fnmatch_private.h b/src/lib/evil/evil_fnmatch_private.h
new file mode 100644
index 0000000..f5ced5d
--- /dev/null
+++ b/src/lib/evil/evil_fnmatch_private.h
@@ -0,0 +1,24 @@
1#ifndef __EVIL_FNMATCH_PRIVATE_H__
2#define __EVIL_FNMATCH_PRIVATE_H__
3
4
5typedef int e_bool;
6
7struct list_of_states
8{
9 size_t reserved;
10 size_t size;
11 size_t *states;
12 e_bool *has;
13};
14
15struct list_of_states *fnmatch_list_of_states_alloc(size_t n, size_t pattern_len);
16
17void fnmatch_list_of_states_free(struct list_of_states *lists, size_t n);
18
19void fnmatch_list_of_states_insert(struct list_of_states *list, size_t state);
20
21void fnmatch_list_of_states_clear(struct list_of_states *list);
22
23
24#endif /* __EVIL_FNMATCH_PRIVATE_H__ */
diff --git a/src/lib/evil/evil_inet.c b/src/lib/evil/evil_inet.c
new file mode 100644
index 0000000..99ce14e
--- /dev/null
+++ b/src/lib/evil/evil_inet.c
@@ -0,0 +1,648 @@
1
2/*
3 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
4 * Copyright (c) 1996,1999 by Internet Software Consortium.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
16 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19/*
20 * Modifications: Vincent Torri, for the integration in Evil
21 * - modification of the name of some functions
22 * * modification of the management of the error
23 */
24
25#ifdef HAVE_CONFIG_H
26# include "config.h"
27#endif /* HAVE_CONFIG_H */
28
29#include <stdio.h>
30#include <ctype.h>
31
32#ifdef HAVE_ERRNO_H
33# include <errno.h>
34#endif /* HAVE_ERRNO_H */
35
36#ifndef WIN32_LEAN_AND_MEAN
37# define WIN32_LEAN_AND_MEAN
38#endif
39#include <winsock2.h>
40#undef WIN32_LEAN_AND_MEAN
41
42#include "evil_macro.h"
43#include "evil_inet.h"
44#include "evil_private.h"
45#define APICHAR char
46#include "evil_print.h"
47
48#ifndef EMSGSIZE
49# define EMSGSIZE WSAEMSGSIZE
50#endif
51
52#ifndef EAFNOSUPPORT
53# define EAFNOSUPPORT WSAEAFNOSUPPORT
54#endif
55
56#define SPRINTF(x) ((size_t)sprintf x)
57
58#define ERRNO ((int)GetLastError())
59#define SET_ERRNO(x) (SetLastError((DWORD)(x)))
60
61#define ISDIGIT(x) (isdigit((int) ((unsigned char)x)))
62#define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x)))
63#define ISUPPER(x) (isupper((int) ((unsigned char)x)))
64
65#define NS_IN6ADDRSZ 16
66#define NS_INT16SZ 2
67#define NS_INADDRSZ sizeof(IN_ADDR)
68
69
70struct ares_in6_addr {
71 union {
72 unsigned char _S6_u8[16];
73 } _S6_un;
74};
75
76const struct ares_in6_addr ares_in6addr_any = { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } };
77
78
79/*
80 * static int
81 * inet_net_pton_ipv4(src, dst, size)
82 * convert IPv4 network number from presentation to network format.
83 * accepts hex octets, hex strings, decimal octets, and /CIDR.
84 * "size" is in bytes and describes "dst".
85 * return:
86 * number of bits, either imputed classfully or specified with /CIDR,
87 * or -1 if some failure occurred (check errno). ENOENT means it was
88 * not an IPv4 network specification.
89 * note:
90 * network byte order assumed. this means 192.5.5.240/28 has
91 * 0b11110000 in its fourth octet.
92 * note:
93 * On Windows we store the error in the thread errno, not
94 * in the winsock error code. This is to avoid loosing the
95 * actual last winsock error. So use macro ERRNO to fetch the
96 * errno this funtion sets when returning (-1), not SOCKERRNO.
97 * author:
98 * Paul Vixie (ISC), June 1996
99 */
100static int
101inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size)
102{
103 static const char xdigits[] = "0123456789abcdef";
104 static const char digits[] = "0123456789";
105 int n, ch, tmp = 0, dirty, bits;
106 const unsigned char *odst = dst;
107
108 ch = *src++;
109 if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
110 && ISXDIGIT(src[1])) {
111 /* Hexadecimal: Eat nybble string. */
112 if (!size)
113 goto emsgsize;
114 dirty = 0;
115 src++; /* skip x or X. */
116 while ((ch = *src++) != '\0' && ISXDIGIT(ch)) {
117 if (ISUPPER(ch))
118 ch = tolower(ch);
119 n = (int)(strchr(xdigits, ch) - xdigits);
120 if (dirty == 0)
121 tmp = n;
122 else
123 tmp = (tmp << 4) | n;
124 if (++dirty == 2) {
125 if (!size--)
126 goto emsgsize;
127 *dst++ = (unsigned char) tmp;
128 dirty = 0;
129 }
130 }
131 if (dirty) { /* Odd trailing nybble? */
132 if (!size--)
133 goto emsgsize;
134 *dst++ = (unsigned char) (tmp << 4);
135 }
136 } else if (ISDIGIT(ch)) {
137 /* Decimal: eat dotted digit string. */
138 for (;;) {
139 tmp = 0;
140 do {
141 n = (int)(strchr(digits, ch) - digits);
142 tmp *= 10;
143 tmp += n;
144 if (tmp > 255)
145 goto enoent;
146 } while ((ch = *src++) != '\0' &&
147 ISDIGIT(ch));
148 if (!size--)
149 goto emsgsize;
150 *dst++ = (unsigned char) tmp;
151 if (ch == '\0' || ch == '/')
152 break;
153 if (ch != '.')
154 goto enoent;
155 ch = *src++;
156 if (!ISDIGIT(ch))
157 goto enoent;
158 }
159 } else
160 goto enoent;
161
162 bits = -1;
163 if (ch == '/' &&
164 ISDIGIT(src[0]) && dst > odst) {
165 /* CIDR width specifier. Nothing can follow it. */
166 ch = *src++; /* Skip over the /. */
167 bits = 0;
168 do {
169 n = (int)(strchr(digits, ch) - digits);
170 bits *= 10;
171 bits += n;
172 } while ((ch = *src++) != '\0' && ISDIGIT(ch));
173 if (ch != '\0')
174 goto enoent;
175 if (bits > 32)
176 goto emsgsize;
177 }
178
179 /* Firey death and destruction unless we prefetched EOS. */
180 if (ch != '\0')
181 goto enoent;
182
183 /* If nothing was written to the destination, we found no address. */
184 if (dst == odst)
185 goto enoent;
186 /* If no CIDR spec was given, infer width from net class. */
187 if (bits == -1) {
188 if (*odst >= 240) /* Class E */
189 bits = 32;
190 else if (*odst >= 224) /* Class D */
191 bits = 8;
192 else if (*odst >= 192) /* Class C */
193 bits = 24;
194 else if (*odst >= 128) /* Class B */
195 bits = 16;
196 else /* Class A */
197 bits = 8;
198 /* If imputed mask is narrower than specified octets, widen. */
199 if (bits < ((dst - odst) * 8))
200 bits = (int)(dst - odst) * 8;
201 /*
202 * If there are no additional bits specified for a class D
203 * address adjust bits to 4.
204 */
205 if (bits == 8 && *odst == 224)
206 bits = 4;
207 }
208 /* Extend network to cover the actual mask. */
209 while (bits > ((dst - odst) * 8)) {
210 if (!size--)
211 goto emsgsize;
212 *dst++ = '\0';
213 }
214 return (bits);
215
216 enoent:
217 SET_ERRNO(ENOENT);
218 return (-1);
219
220 emsgsize:
221 SET_ERRNO(EMSGSIZE);
222 return (-1);
223}
224
225static int
226getbits(const char *src, int *bitsp)
227{
228 static const char digits[] = "0123456789";
229 int n;
230 int val;
231 char ch;
232
233 val = 0;
234 n = 0;
235 while ((ch = *src++) != '\0') {
236 const char *pch;
237
238 pch = strchr(digits, ch);
239 if (pch != NULL) {
240 if (n++ != 0 && val == 0) /* no leading zeros */
241 return (0);
242 val *= 10;
243 val += (pch - digits);
244 if (val > 128) /* range */
245 return (0);
246 continue;
247 }
248 return (0);
249 }
250 if (n == 0)
251 return (0);
252 *bitsp = val;
253 return (1);
254}
255
256static int
257getv4(const char *src, unsigned char *dst, int *bitsp)
258{
259 static const char digits[] = "0123456789";
260 unsigned char *odst = dst;
261 int n;
262 unsigned int val;
263 char ch;
264
265 val = 0;
266 n = 0;
267 while ((ch = *src++) != '\0') {
268 const char *pch;
269
270 pch = strchr(digits, ch);
271 if (pch != NULL) {
272 if (n++ != 0 && val == 0) /* no leading zeros */
273 return (0);
274 val *= 10;
275 val += (pch - digits);
276 if (val > 255) /* range */
277 return (0);
278 continue;
279 }
280 if (ch == '.' || ch == '/') {
281 if (dst - odst > 3) /* too many octets? */
282 return (0);
283 *dst++ = (unsigned char)val;
284 if (ch == '/')
285 return (getbits(src, bitsp));
286 val = 0;
287 n = 0;
288 continue;
289 }
290 return (0);
291 }
292 if (n == 0)
293 return (0);
294 if (dst - odst > 3) /* too many octets? */
295 return (0);
296 *dst++ = (unsigned char)val;
297 return (1);
298}
299
300static int
301inet_net_pton_ipv6(const char *src, unsigned char *dst, size_t size)
302{
303 static const char xdigits_l[] = "0123456789abcdef",
304 xdigits_u[] = "0123456789ABCDEF";
305 unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
306 const char *xdigits, *curtok;
307 int ch, saw_xdigit;
308 unsigned int val;
309 int digits;
310 int bits;
311 size_t bytes;
312 int words;
313 int ipv4;
314
315 memset((tp = tmp), '\0', NS_IN6ADDRSZ);
316 endp = tp + NS_IN6ADDRSZ;
317 colonp = NULL;
318 /* Leading :: requires some special handling. */
319 if (*src == ':')
320 if (*++src != ':')
321 goto enoent;
322 curtok = src;
323 saw_xdigit = 0;
324 val = 0;
325 digits = 0;
326 bits = -1;
327 ipv4 = 0;
328 while ((ch = *src++) != '\0') {
329 const char *pch;
330
331 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
332 pch = strchr((xdigits = xdigits_u), ch);
333 if (pch != NULL) {
334 val <<= 4;
335 val |= (pch - xdigits);
336 if (++digits > 4)
337 goto enoent;
338 saw_xdigit = 1;
339 continue;
340 }
341 if (ch == ':') {
342 curtok = src;
343 if (!saw_xdigit) {
344 if (colonp)
345 goto enoent;
346 colonp = tp;
347 continue;
348 } else if (*src == '\0')
349 goto enoent;
350 if (tp + NS_INT16SZ > endp)
351 return (0);
352 *tp++ = (unsigned char)((val >> 8) & 0xff);
353 *tp++ = (unsigned char)(val & 0xff);
354 saw_xdigit = 0;
355 digits = 0;
356 val = 0;
357 continue;
358 }
359 if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
360 getv4(curtok, tp, &bits) > 0) {
361 tp += NS_INADDRSZ;
362 saw_xdigit = 0;
363 ipv4 = 1;
364 break; /* '\0' was seen by inet_pton4(). */
365 }
366 if (ch == '/' && getbits(src, &bits) > 0)
367 break;
368 goto enoent;
369 }
370 if (saw_xdigit) {
371 if (tp + NS_INT16SZ > endp)
372 goto enoent;
373 *tp++ = (unsigned char)((val >> 8) & 0xff);
374 *tp++ = (unsigned char)(val & 0xff);
375 }
376 if (bits == -1)
377 bits = 128;
378
379 words = (bits + 15) / 16;
380 if (words < 2)
381 words = 2;
382 if (ipv4)
383 words = 8;
384 endp = tmp + 2 * words;
385
386 if (colonp != NULL) {
387 /*
388 * Since some memmove()'s erroneously fail to handle
389 * overlapping regions, we'll do the shift by hand.
390 */
391 const ssize_t n = tp - colonp;
392 ssize_t i;
393
394 if (tp == endp)
395 goto enoent;
396 for (i = 1; i <= n; i++) {
397 *(endp - i) = *(colonp + n - i);
398 *(colonp + n - i) = 0;
399 }
400 tp = endp;
401 }
402 if (tp != endp)
403 goto enoent;
404
405 bytes = (bits + 7) / 8;
406 if (bytes > size)
407 goto emsgsize;
408 memcpy(dst, tmp, bytes);
409 return (bits);
410
411 enoent:
412 SET_ERRNO(ENOENT);
413 return (-1);
414
415 emsgsize:
416 SET_ERRNO(EMSGSIZE);
417 return (-1);
418}
419
420/*
421 * int
422 * inet_net_pton(af, src, dst, size)
423 * convert network number from presentation to network format.
424 * accepts hex octets, hex strings, decimal octets, and /CIDR.
425 * "size" is in bytes and describes "dst".
426 * return:
427 * number of bits, either imputed classfully or specified with /CIDR,
428 * or -1 if some failure occurred (check errno). ENOENT means it was
429 * not a valid network specification.
430 * note:
431 * On Windows we store the error in the thread errno, not
432 * in the winsock error code. This is to avoid loosing the
433 * actual last winsock error. So use macro ERRNO to fetch the
434 * errno this funtion sets when returning (-1), not SOCKERRNO.
435 * author:
436 * Paul Vixie (ISC), June 1996
437 */
438static int
439ares_inet_net_pton(int af, const char *src, void *dst, size_t size)
440{
441 switch (af) {
442 case AF_INET:
443 return (inet_net_pton_ipv4(src, dst, size));
444 case AF_INET6:
445 return (inet_net_pton_ipv6(src, dst, size));
446 default:
447 SET_ERRNO(EAFNOSUPPORT);
448 return (-1);
449 }
450}
451
452int
453evil_inet_pton(int af, const char *src, void *dst)
454{
455 int result;
456 size_t size;
457
458 if (af == AF_INET)
459 size = sizeof(struct in_addr);
460 else if (af == AF_INET6)
461 size = sizeof(struct ares_in6_addr);
462 else
463 {
464 SET_ERRNO(EAFNOSUPPORT);
465 return -1;
466 }
467 result = ares_inet_net_pton(af, src, dst, size);
468 if ((result == -1) && (ERRNO == ENOENT))
469 return 0;
470 return (result > -1 ? 1 : -1);
471}
472
473
474/* const char *
475 * inet_ntop4(src, dst, size)
476 * format an IPv4 address, more or less like inet_ntoa()
477 * return:
478 * `dst' (as a const)
479 * notes:
480 * (1) uses no statics
481 * (2) takes a unsigned char* not an in_addr as input
482 * author:
483 * Paul Vixie, 1996.
484 */
485static const char *
486inet_ntop4(const unsigned char *src, char *dst, size_t size)
487{
488 static const char fmt[] = "%u.%u.%u.%u";
489 char tmp[sizeof "255.255.255.255"];
490
491 if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size)
492 {
493 SET_ERRNO(ENOSPC);
494 return (NULL);
495 }
496 strcpy(dst, tmp);
497 return (dst);
498}
499
500/* const char *
501 * inet_ntop6(src, dst, size)
502 * convert IPv6 binary address into presentation (printable) format
503 * author:
504 * Paul Vixie, 1996.
505 */
506static const char *
507inet_ntop6(const unsigned char *src, char *dst, size_t size)
508{
509 /*
510 * Note that int32_t and int16_t need only be "at least" large enough
511 * to contain a value of the specified size. On some systems, like
512 * Crays, there is no such thing as an integer variable with 16 bits.
513 * Keep this in mind if you think this function should have been coded
514 * to use pointer overlays. All the world's not a VAX.
515 */
516 char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
517 char *tp;
518 struct {
519 long base;
520 long len;
521 } best, cur;
522 unsigned long words[NS_IN6ADDRSZ / NS_INT16SZ];
523 int i;
524
525 /*
526 * Preprocess:
527 * Copy the input (bytewise) array into a wordwise array.
528 * Find the longest run of 0x00's in src[] for :: shorthanding.
529 */
530 memset(words, '\0', sizeof(words));
531 for (i = 0; i < NS_IN6ADDRSZ; i++)
532 words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
533
534 best.base = -1;
535 cur.base = -1;
536 best.len = 0;
537 cur.len = 0;
538
539 for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++)
540 {
541 if (words[i] == 0)
542 {
543 if (cur.base == -1)
544 cur.base = i, cur.len = 1;
545 else
546 cur.len++;
547 }
548 else
549 {
550 if (cur.base != -1)
551 {
552 if (best.base == -1 || cur.len > best.len)
553 best = cur;
554 cur.base = -1;
555 }
556 }
557 }
558 if (cur.base != -1)
559 {
560 if (best.base == -1 || cur.len > best.len)
561 best = cur;
562 }
563 if (best.base != -1 && best.len < 2)
564 best.base = -1;
565
566 /*
567 * Format the result.
568 */
569 tp = tmp;
570 for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++)
571 {
572 /* Are we inside the best run of 0x00's? */
573 if (best.base != -1 && i >= best.base &&
574 i < (best.base + best.len))
575 {
576 if (i == best.base)
577 *tp++ = ':';
578 continue;
579 }
580 /* Are we following an initial run of 0x00s or any real hex? */
581 if (i != 0)
582 *tp++ = ':';
583 /* Is this address an encapsulated IPv4? */
584 if (i == 6 && best.base == 0 &&
585 (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
586 {
587 if (!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp)))
588 return (NULL);
589 tp += strlen(tp);
590 break;
591 }
592 tp += SPRINTF((tp, "%lx", words[i]));
593 }
594
595 /* Was it a trailing run of 0x00's? */
596 if (best.base != -1 && (best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ))
597 *tp++ = ':';
598 *tp++ = '\0';
599
600 /*
601 * Check for overflow, copy, and we're done.
602 */
603 if ((size_t)(tp - tmp) > size)
604 {
605 SET_ERRNO(ENOSPC);
606 return (NULL);
607 }
608 strcpy(dst, tmp);
609 return (dst);
610}
611
612/* char *
613 * inet_ntop(af, src, dst, size)
614 * convert a network format address to presentation format.
615 * return:
616 * pointer to presentation format address (`dst'), or NULL (see errno).
617 * note:
618 * On Windows we store the error in the thread errno, not
619 * in the winsock error code. This is to avoid loosing the
620 * actual last winsock error. So use macro ERRNO to fetch the
621 * errno this funtion sets when returning NULL, not SOCKERRNO.
622 * author:
623 * Paul Vixie, 1996.
624 */
625static const char *
626ares_inet_ntop(int af, const void *src, char *dst, size_t size)
627{
628 switch (af)
629 {
630 case AF_INET:
631 return (inet_ntop4(src, dst, size));
632 case AF_INET6:
633 return (inet_ntop6(src, dst, size));
634 default:
635 SET_ERRNO(EAFNOSUPPORT);
636 return (NULL);
637 }
638 /* NOTREACHED */
639}
640
641const char *evil_inet_ntop(int af, const char *src, void *dst, size_t size)
642{
643 const char *result;
644 result = ares_inet_ntop(af, src, dst, size);
645 if ((result == NULL) && (ERRNO == ENOSPC))
646 return NULL;
647 return result;
648}
diff --git a/src/lib/evil/evil_inet.h b/src/lib/evil/evil_inet.h
new file mode 100644
index 0000000..b81b8ff
--- /dev/null
+++ b/src/lib/evil/evil_inet.h
@@ -0,0 +1,149 @@
1
2/* Copyright (C) 2005 by Daniel Stenberg
3 *
4 * Permission to use, copy, modify, and distribute this
5 * software and its documentation for any purpose and without
6 * fee is hereby granted, provided that the above copyright
7 * notice appear in all copies and that both that copyright
8 * notice and this permission notice appear in supporting
9 * documentation, and that the name of M.I.T. not be used in
10 * advertising or publicity pertaining to distribution of the
11 * software without specific, written prior permission.
12 * M.I.T. makes no representations about the suitability of
13 * this software for any purpose. It is provided "as is"
14 * without express or implied warranty.
15 */
16
17#ifndef __EVIL_INET_H__
18#define __EVIL_INET_H__
19
20
21/**
22 * @file evil_inet.h
23 * @brief The file that provides functions ported from Unix in arpa/inet.h.
24 * @defgroup Evil_Inet_Group Inet.h functions
25 *
26 * This header provides functions ported from Unix in arpa/inet.h.
27 *
28 * @{
29 */
30
31/**
32 * @brief Convert IPv4 and IPv6 addresses from text to binary form.
33 *
34 * @param af The address family.
35 * @param src The address to convert.
36 * @param dst The converted address structure.
37 * @return 1 on success, 0 or -1 otherwise.
38 *
39 * This function converts IPv4 and IPv6 addresses from @p src to the
40 * binary form @p dst. The following address families to pass to @p af
41 * are currently supported:
42 *
43 * <ul>
44 * <li>i AF_INET: @p src points to a character string containing an IPv4
45 * network address in dotted-decimal format, "ddd.ddd.ddd.ddd", where
46 * ddd is a decimal number of up to three digits in the range 0 to
47 * 255. The address is converted to a struct in_addr and copied to
48 * dst, which must be sizeof(struct in_addr) (4) bytes (32 bits) long.
49 * <li> AF_INET6: @p src points to a character string containing an
50 * IPv6 network address. The address is converted to a struct in6_addr
51 * and copied to dst, which must be sizeof(struct in6_addr) (16) bytes
52 * (128 bits) long. The allowed formats for IPv6 addresses follow
53 * these rules:
54 * <ol>
55 * <li>The preferred format is x:x:x:x:x:x:x:x. This form consists of
56 * eight hexadecimal numbers, each of which expresses a 16-bit value
57 * (i.e., each x can be up to 4 hex digits).
58 * <li>A series of contiguous zero values in the preferred format can
59 * be abbreviated to ::. Only one instance of :: can occur in an
60 * address. For example, the loopback address 0:0:0:0:0:0:0:1 can be
61 * abbreviated as ::1. The wildcard address, consisting of all zeros,
62 * can be written as ::.
63 * <li>An alternate format is useful for expressing IPv4-mapped IPv6
64 * addresses. This form is written as x:x:x:x:x:x:d.d.d.d, where the
65 * six leading xs are hexadecimal values that define the six
66 * most-significant 16-bit pieces of the address (i.e., 96 bits), and
67 * the ds express a value in dotted-decimal notation that defines the
68 * least significant 32 bits of the address. An example of such an
69 * address is :: FFFF:204.152.189.116.
70 * </ul>
71 * </ul>
72 * On success this function returns 1 (network address was successfully
73 * converted). 0 is returned if @p src does not contain a character
74 * string representing a valid network address in the specified
75 * address family. If af does not contain a valid address family, -1
76 * is returned and errno is set to EAFNOSUPPORT.
77 *
78 * @see evil_inet_ntop()
79 * @see inet_ntop()
80 *
81 * Conformity: POSIX.1-2001.
82 *
83 * Supported OS: Windows XP, CE.
84 *
85 */
86EAPI int evil_inet_pton(int af, const char *src, void *dst);
87
88/**
89 * @def inet_pton(x,y,z)
90 *
91 * Wrapper around evil_inet_pton().
92 */
93#define inet_pton(x,y,z) evil_inet_pton(x,y,z)
94
95/**
96 * @brief Convert IPv4 and IPv6 addresses from binary to text form.
97 *
98 * @param af The address family.
99 * @param src The address structure to convert.
100 * @param dst A buffer containing the converted string.
101 * @param size The size of the buffer.
102 * @return 1 on success, 0 otherwise.
103 *
104 * This function converts the network address structure @p src in the
105 * @p af address family into a character string. The resulting string
106 * is copied to the buffer pointed to by @p dst, which must be a
107 * non-NULL pointer. The caller specifies the number of bytes
108 * available in this buffer in the argument @p size. The following
109 * address families to pass to @p af are currently supported:
110 *
111 * @li AF_INET: @p src points to a struct in_addr (in network byte
112 * order) which is converted to an IPv4 network address in the
113 * dotted-decimal format, "ddd.ddd.ddd.ddd". The buffer @p dst must be
114 * at least INET_ADDRSTRLEN bytes long.
115 * @li AF_INET6: @p src points to a struct in6_addr (in network byte
116 * order) which is converted to a representation of this address in
117 * the most appropriate IPv6 network address format for this
118 * address. The buffer @p dst must be at least INET6_ADDRSTRLEN bytes
119 * long.
120 *
121 * On success, this function returns a non-NULL pointer to @p dst. NULL is
122 * returned if there was an error, with errno set to indicate the
123 * error.
124 *
125 * @see evil_inet_pton()
126 * @see inet_pton()
127 *
128 * Conformity: POSIX.1-2001.
129 *
130 * Supported OS: Windows XP, CE.
131 *
132 */
133EAPI const char *evil_inet_ntop(int af, const char *src, void *dst, size_t size);
134
135/**
136 * @def inet_ntop(x,y,z,s)
137 *
138 * Wrapper around evil_inet_ntop().
139 */
140#define inet_ntop(x,y,z,s) evil_inet_ntop(x,y,z,s)
141
142
143
144/**
145 * @}
146 */
147
148
149#endif /* __EVIL_INET_H__ */
diff --git a/src/lib/evil/evil_langinfo.c b/src/lib/evil/evil_langinfo.c
new file mode 100644
index 0000000..32b1f41
--- /dev/null
+++ b/src/lib/evil/evil_langinfo.c
@@ -0,0 +1,53 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include "Evil.h"
6
7
8#ifndef __MINGW32CE__
9
10static char *
11replace(char *prev, char *value)
12{
13 if (!value)
14 return prev;
15
16 if (prev)
17 free (prev);
18 return strdup (value);
19}
20
21char *
22nl_langinfo(nl_item index)
23{
24 static char *result = NULL;
25 static char *nothing = "";
26
27 switch (index)
28 {
29 case CODESET:
30 {
31 char *p;
32 result = replace(result, setlocale(LC_CTYPE, NULL));
33 if (!(p = strrchr(result, '.')))
34 return nothing;
35
36 if ((++p - result) > 2)
37 strcpy(result, "cp");
38 else
39 *result = '\0';
40 strcat(result, p);
41
42 return result;
43 }
44 case RADIXCHAR:
45 {
46 return localeconv()->decimal_point;
47 }
48 }
49
50 return nothing;
51}
52
53#endif /* ! __MINGW32CE__ */
diff --git a/src/lib/evil/evil_langinfo.h b/src/lib/evil/evil_langinfo.h
new file mode 100644
index 0000000..0e9485a
--- /dev/null
+++ b/src/lib/evil/evil_langinfo.h
@@ -0,0 +1,41 @@
1#ifndef __EVIL_LANGINFO_H__
2#define __EVIL_LANGINFO_H__
3
4
5#ifndef __MINGW32CE__
6
7#include <locale.h>
8
9
10typedef int nl_item;
11
12#define __NL_ITEM( CATEGORY, INDEX ) ((CATEGORY << 16) | INDEX)
13#define __NL_ITEM_CATEGORY( ITEM ) (ITEM >> 16)
14#define __NL_ITEM_INDEX( ITEM ) (ITEM & 0xffff)
15
16enum {
17 /*
18 * LC_CTYPE category...
19 * Character set classification items.
20 */
21 _NL_CTYPE_CODESET = __NL_ITEM( LC_CTYPE, 0 ),
22 _NL_NUMERIC_RADIXCHAR = __NL_ITEM( LC_NUMERIC, 0 ),
23
24 /*
25 * Dummy entry, to terminate the list.
26 */
27 _NL_ITEM_CLASSIFICATION_END
28};
29
30/*
31 * Define the public aliases for the enumerated classification indices...
32 */
33# define CODESET _NL_CTYPE_CODESET
34# define RADIXCHAR _NL_NUMERIC_RADIXCHAR
35
36EAPI char *nl_langinfo(nl_item index);
37
38#endif /* __MINGW32CE__ */
39
40
41#endif /*__EVIL_LANGINFO_H__ */
diff --git a/src/lib/evil/evil_libgen.c b/src/lib/evil/evil_libgen.c
new file mode 100644
index 0000000..7e98f74
--- /dev/null
+++ b/src/lib/evil/evil_libgen.c
@@ -0,0 +1,103 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include <string.h>
6
7#include "Evil.h"
8
9char _evil_basename_buf[PATH_MAX];
10char _evil_dirname_buf[PATH_MAX];
11
12char *
13evil_basename(char *path)
14{
15 char *p1;
16 char *p2;
17 size_t length;
18
19 /* path must begin by "?:\" or "?:/" */
20 if ((!path) || !evil_path_is_absolute(path))
21 {
22 memcpy(_evil_basename_buf, "C:\\", 4);
23 return _evil_basename_buf;
24 }
25
26 /* '/' --> '\\' */
27 length = strlen(path);
28 p1 = strdup(path);
29 if (!p1)
30 {
31 memcpy(_evil_basename_buf, "C:\\", 4);
32 return _evil_basename_buf;
33 }
34 p2 = p1;
35 while (*p2)
36 {
37 if (*p2 == '/') *p2 = '\\';
38 p2++;
39 }
40
41 /* remove trailing backslashes */
42 p2 = p1 + (length - 1);
43 if (*p2 == '\\')
44 {
45 while (*p2 == '\\')
46 p2--;
47 }
48 *(p2 + 1) = '\0';
49
50 p2 = strrchr(p1, '\\');
51 memcpy(_evil_basename_buf, p2 + 1, (p1 + length + 1) - p2);
52
53 free(p1);
54
55 return _evil_basename_buf;
56}
57
58char *
59evil_dirname(char *path)
60{
61 char *p1;
62 char *p2;
63 size_t length;
64
65 /* path must begin by "?:\" or "?:/" */
66 if ((!path) || !evil_path_is_absolute(path))
67 {
68 memcpy(_evil_dirname_buf, "C:\\", 4);
69 return _evil_dirname_buf;
70 }
71
72 /* '/' --> '\\' */
73 length = strlen(path);
74 p1 = strdup(path);
75 if (!p1)
76 {
77 memcpy(_evil_dirname_buf, "C:\\", 4);
78 return _evil_dirname_buf;
79 }
80 p2 = p1;
81 while (*p2)
82 {
83 if (*p2 == '/') *p2 = '\\';
84 p2++;
85 }
86
87 /* remove trailing backslashes */
88 p2 = p1 + (length - 1);
89 if (*p2 == '\\')
90 {
91 while (*p2 == '\\')
92 p2--;
93 }
94 *(p2 + 1) = '\0';
95
96 p2 = strrchr(p1, '\\');
97 *p2 = '\0';
98 memcpy(_evil_dirname_buf, p1, strlen(p1) + 1);
99
100 free(p1);
101
102 return _evil_dirname_buf;
103}
diff --git a/src/lib/evil/evil_libgen.h b/src/lib/evil/evil_libgen.h
new file mode 100644
index 0000000..4ca977c
--- /dev/null
+++ b/src/lib/evil/evil_libgen.h
@@ -0,0 +1,88 @@
1#ifndef __EVIL_LIBGEN_H__
2#define __EVIL_LIBGEN_H__
3
4
5/**
6 * @file evil_libgen.h
7 * @brief The file that provides functions ported from Unix in libgen.h.
8 * @defgroup Evil_Libgen_Group Libgen.h functions.
9 *
10 * This header provides functions ported from Unix in libgen.h.
11 *
12 * @{
13 */
14
15/**
16 * @brief Parse the base name component of a path.
17 *
18 * @param path The path to parse.
19 * @return The component following the final '/'.
20 *
21 * This function parses @p path and returns its component following
22 * the final '\'. Trailing '\' are not taken into account. On Windows
23 * XP, @p path must beginning by a drive letter followed by ':/' or
24 * ':\', otherwise "C:\" is returned. All characters '/' are replaced by '\'. On
25 * error (memory allocation failure), "C:\" is returned, otherwise the
26 * component following the final '\' is returned as a statically
27 * allocated memory. Hence the returns value must not be freed.
28 *
29 * Concatenating the string returned by dirname(), a "\", and the
30 * string returned by basename() yields a complete pathname.
31 *
32 * @see evil_dirname()
33 * @see dirname()
34 *
35 * Conformity: Non applicable.
36 *
37 * Supported OS: Windows XP.
38 */
39EAPI char *evil_basename(char *path);
40
41/**
42 * @def basename(p)
43 *
44 * Wrapper around evil_basename().
45 */
46#define basename(p) evil_basename(p)
47
48/**
49 * @brief Parse the dir name component of a path.
50 *
51 * @param path The path to parse.
52 * @return The component up to, but not including, the final '/'.
53 *
54 * This function parses @p path and returns its component up to, but
55 * not including, the final '/'. Trailing '\' are not taken into
56 * account. On Windows XP, @p path must beginning by a drive letter
57 * followed by ':/' or ':\', otherwise "C:\" is returned. All
58 * characters '/' are replaced by '\'. On error (memory allocation
59 * failure), "C:\" is returned, otherwise, the component up to, but
60 * not including, the final '/' is returned as a statically allocated
61 * memory. Hence the returns value must not be freed.
62 *
63 * Concatenating the string returned by dirname(), a "\", and the
64 * string returned by basename() yields a complete pathname.
65 *
66 * @see evil_basename()
67 * @see basename()
68 *
69 * Conformity: Non applicable.
70 *
71 * Supported OS: Windows XP.
72 */
73EAPI char *evil_dirname(char *path);
74
75/**
76 * @def dirname(p)
77 *
78 * Wrapper around evil_dirname().
79 */
80#define dirname(p) evil_dirname(p)
81
82
83/**
84 * @}
85 */
86
87
88#endif /* __EVIL_LIBGEN_H__ */
diff --git a/src/lib/evil/evil_link_ce.c b/src/lib/evil/evil_link_ce.c
new file mode 100644
index 0000000..17532cc
--- /dev/null
+++ b/src/lib/evil/evil_link_ce.c
@@ -0,0 +1,90 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#ifndef WIN32_LEAN_AND_MEAN
6# define WIN32_LEAN_AND_MEAN
7#endif
8#include <windows.h>
9#undef WIN32_LEAN_AND_MEAN
10
11#include <shellapi.h>
12
13#include "Evil.h"
14#include "evil_private.h"
15
16
17/*
18 * Symbolic links and directory related functions
19 *
20 */
21
22
23/* REMARK: Windows has no symbolic link. */
24/* Nevertheless, it can create and read .lnk files */
25
26int
27symlink(const char *oldpath, const char *newpath)
28{
29 wchar_t *w_oldpath;
30 wchar_t *w_newpath;
31 BOOL res;
32
33 w_oldpath = evil_char_to_wchar(oldpath);
34 if (!w_oldpath)
35 return -1;
36
37 w_newpath = evil_char_to_wchar(newpath);
38 if (!w_newpath)
39 {
40 free(w_oldpath);
41 return -1;
42 }
43
44 res = SHCreateShortcut(w_newpath, w_oldpath);
45 if (!res)
46 _evil_last_error_display(__FUNCTION__);
47
48 free(w_oldpath);
49 free(w_newpath);
50
51 return res ? 0 : -1;
52}
53
54ssize_t
55readlink(const char *path, char *buf, size_t bufsiz)
56{
57 wchar_t *w_path;
58 wchar_t w_newpath[1024];
59 char *newpath;
60 size_t length;
61 BOOL res;
62
63 w_path = evil_char_to_wchar(path);
64 if (!w_path)
65 return -1;
66
67 res = SHGetShortcutTarget(w_path, w_newpath, 1024);
68 if (!res)
69 _evil_last_error_display(__FUNCTION__);
70
71 free(w_path);
72
73 if (!res)
74 return -1;
75
76 newpath = evil_wchar_to_char(w_newpath);
77 if (!newpath)
78 return -1;
79
80 /* That stupid SHGetShortcutTarget add " around the file name... */
81 length = strlen(newpath) - 2;
82 if (length > bufsiz)
83 length = bufsiz;
84
85 memcpy(buf, newpath + 1, length);
86
87 free(newpath);
88
89 return length;
90}
diff --git a/src/lib/evil/evil_link_xp.cpp b/src/lib/evil/evil_link_xp.cpp
new file mode 100644
index 0000000..675908f
--- /dev/null
+++ b/src/lib/evil/evil_link_xp.cpp
@@ -0,0 +1,151 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#ifdef HAVE_ERRNO_H
6#include <errno.h>
7#endif /* HAVE_ERRNO_H */
8
9#include <shlobj.h>
10#include <objidl.h>
11#include <cstdio>
12
13#include "Evil.h"
14
15
16/*
17 * Symbolic links and directory related functions
18 *
19 */
20
21
22/* REMARK: Windows has no symbolic link. */
23/* Nevertheless, it can create and read .lnk files */
24int
25symlink(const char *oldpath, const char *newpath)
26{
27 char fullname[PATH_MAX];
28 wchar_t *wnewpath;
29 IShellLink *pISL;
30 IPersistFile *pIPF;
31 HRESULT res;
32 size_t size;
33
34 realpath(oldpath, fullname);
35
36 res = CoInitialize(NULL);
37 if (FAILED(res))
38 {
39 if (res == E_OUTOFMEMORY)
40 errno = ENOMEM;
41 return -1;
42 }
43
44 if (FAILED(CoCreateInstance(CLSID_ShellLink,
45 NULL,
46 CLSCTX_INPROC_SERVER,
47 IID_IShellLink,
48 (void **)&pISL)))
49 goto no_instance;
50
51 if (FAILED(pISL->SetPath(fullname)))
52 goto no_setpath;
53
54 if (FAILED(pISL->QueryInterface(IID_IPersistFile, (void **)&pIPF)))
55 goto no_queryinterface;
56
57 size = mbstowcs(NULL, newpath, 0);
58 wnewpath = (wchar_t *)malloc((size + 1) * sizeof(wchar_t));
59 if (!wnewpath)
60 goto malloc_failure;
61 if (mbstowcs(wnewpath, newpath, size + 1) == (size_t)(-1))
62 goto translation_failure;
63 if (FAILED(pIPF->Save(wnewpath, FALSE)))
64 goto no_save;
65
66 free(wnewpath);
67 pIPF->Release();
68 pISL->Release();
69 CoUninitialize();
70
71 return 0;
72
73 no_save:
74 translation_failure:
75 malloc_failure:
76 pIPF->Release();
77 no_queryinterface:
78 no_setpath:
79 pISL->Release();
80 no_instance:
81 CoUninitialize();
82 return -1;
83}
84
85ssize_t
86readlink(const char *path, char *buf, size_t bufsiz)
87{
88 wchar_t *wpath;
89 char new_path[PATH_MAX];
90 IShellLink *pISL;
91 IPersistFile *pIPF;
92 size_t length;
93 HRESULT res;
94 size_t size;
95
96 res = CoInitialize(NULL);
97 if (FAILED(res))
98 {
99 if (res == E_OUTOFMEMORY)
100 errno = ENOMEM;
101 return -1;
102 }
103
104 if (FAILED(CoCreateInstance(CLSID_ShellLink,
105 NULL,
106 CLSCTX_INPROC_SERVER,
107 IID_IShellLink,
108 (void **)&pISL)))
109 goto couninitialize;
110
111 if (FAILED(pISL->QueryInterface(IID_IPersistFile, (void **)&pIPF)))
112 goto release_shell_link;
113
114 size = mbstowcs(NULL, path, 0);
115 wpath = (wchar_t *)malloc((size + 1) * sizeof(wchar_t));
116 if (!wpath)
117 goto release_persist_file;
118
119 mbstowcs(wpath, path, size + 1);
120 if (FAILED(pIPF->Load(wpath, STGM_READ)))
121 goto free_wpath;
122
123 if (FAILED(pISL->Resolve(NULL, SLR_UPDATE | SLR_NO_UI)))
124 goto free_wpath;
125
126 if (FAILED(pISL->GetPath(new_path, PATH_MAX, NULL, 0)))
127 goto free_wpath;
128
129 length = strlen(new_path);
130 if (length > bufsiz)
131 length = bufsiz;
132
133 memcpy(buf, new_path, length);
134
135 free(wpath);
136 pISL->Release();
137 pIPF->Release();
138 CoUninitialize();
139
140 return length;
141
142 free_wpath:
143 free(wpath);
144 release_persist_file:
145 pIPF->Release();
146 release_shell_link:
147 pISL->Release();
148 couninitialize:
149 CoUninitialize();
150 return -1;
151}
diff --git a/src/lib/evil/evil_macro.h b/src/lib/evil/evil_macro.h
new file mode 100644
index 0000000..b2500d3
--- /dev/null
+++ b/src/lib/evil/evil_macro.h
@@ -0,0 +1,193 @@
1#ifndef __EVIL_MACRO_H__
2#define __EVIL_MACRO_H__
3
4
5#ifndef __cdecl
6# define EVIL_CDECL_IS_DEFINED
7# ifdef __GNUC__
8# define __cdecl __attribute__((__cdecl__))
9# else
10# define __cdecl
11# endif
12#endif /* __cdecl */
13
14
15#ifdef EAPI
16# undef EAPI
17#endif /* EAPI */
18
19#ifdef _WIN32
20# ifdef EFL_EVIL_BUILD
21# ifdef DLL_EXPORT
22# define EAPI __declspec(dllexport)
23# else
24# define EAPI
25# endif /* ! DLL_EXPORT */
26# else
27# define EAPI __declspec(dllimport)
28# endif /* ! EFL_EVIL_BUILD */
29#endif /* _WIN32 */
30
31
32#ifndef __EVIL_GNUC_PREREQ
33# if defined __GNUC__ && defined __GNUC_MINOR__
34# define __EVIL_GNUC_PREREQ( major, minor )\
35 (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
36# else
37# define __EVIL_GNUC_PREREQ( major, minor )
38# endif
39#endif /* __EVIL_GNUC_PREREQ */
40
41
42#ifndef __EVIL_NOTHROW
43# if __EVIL_GNUC_PREREQ( 3, 3 )
44# define __EVIL_NOTHROW __attribute__((__nothrow__))
45# else
46# define __EVIL_NOTHROW
47# endif
48#endif /* __EVIL_NOTHROW */
49
50
51#ifndef __EVIL_PRINTF
52# if __EVIL_GNUC_PREREQ( 2, 4 )
53# define __EVIL_PRINTF(fmt, arg) __attribute__((__format__ (__gnu_printf__, fmt, arg)))
54# else
55# define __EVIL_PRINTF(fmt, arg)
56# endif
57#endif /* __EVIL_PRINTF */
58
59
60#ifndef PATH_MAX
61# define PATH_MAX MAX_PATH
62#endif /* PATH_MAX */
63#ifdef fprintf
64# undef fprintf
65#endif
66
67#ifdef printf
68# undef printf
69#endif
70
71#ifdef sprintf
72# undef sprintf
73#endif
74
75#ifdef snprintf
76# undef snprintf
77#endif
78
79#ifdef vfprintf
80# undef vfprintf
81#endif
82
83#ifdef vprintf
84# undef vprintf
85#endif
86
87#ifdef vsprintf
88# undef vsprintf
89#endif
90
91#ifdef vsnprintf
92# undef vsnprintf
93#endif
94
95#ifdef fscanf
96# undef fscanf
97#endif
98
99#ifdef scanf
100# undef scanf
101#endif
102
103#ifdef sscanf
104# undef sscanf
105#endif
106
107#ifdef vfscanf
108# undef vfscanf
109#endif
110
111#ifdef vscanf
112# undef vscanf
113#endif
114
115#ifdef vsscanf
116# undef vsscanf
117#endif
118
119#ifdef asprintf
120# undef asprintf
121#endif
122
123#ifdef vasprintf
124# undef vasprintf
125#endif
126
127
128#if defined(_INTTYPES_H_) && defined(PRId64)
129
130#undef PRId64
131#undef PRIdLEAST64
132#undef PRIdFAST64
133#undef PRIdMAX
134#undef PRIi64
135#undef PRIiLEAST64
136#undef PRIiFAST64
137#undef PRIiMAX
138#undef PRIo64
139#undef PRIoLEAST64
140#undef PRIoFAST64
141#undef PRIoMAX
142#undef PRIu64
143#undef PRIuLEAST64
144#undef PRIuFAST64
145#undef PRIuMAX
146#undef PRIx64
147#undef PRIxLEAST64
148#undef PRIxFAST64
149#undef PRIxMAX
150#undef PRIX64
151#undef PRIXLEAST64
152#undef PRIXFAST64
153#undef PRIXMAX
154
155#undef SCNd64
156#undef SCNdLEAST64
157#undef SCNdFAST64
158#undef SCNdMAX
159#undef SCNi64
160#undef SCNiLEAST64
161#undef SCNiFAST64
162#undef SCNiMAX
163#undef SCNo64
164#undef SCNoLEAST64
165#undef SCNoFAST64
166#undef SCNoMAX
167#undef SCNx64
168#undef SCNxLEAST64
169#undef SCNxFAST64
170#undef SCNxMAX
171#undef SCNu64
172#undef SCNuLEAST64
173#undef SCNuFAST64
174#undef SCNuMAX
175
176#ifdef _WIN64
177#undef PRIdPTR
178#undef PRIiPTR
179#undef PRIoPTR
180#undef PRIuPTR
181#undef PRIxPTR
182#undef PRIXPTR
183
184#undef SCNdPTR
185#undef SCNiPTR
186#undef SCNoPTR
187#undef SCNxPTR
188#undef SCNuPTR
189#endif /* _WIN64 */
190
191#endif /* defined(_INTTYPES_H_) && defined(PRId64) */
192
193#endif /* __EVIL_MACRO_H__ */
diff --git a/src/lib/evil/evil_macro_pop.h b/src/lib/evil/evil_macro_pop.h
new file mode 100644
index 0000000..a82818d
--- /dev/null
+++ b/src/lib/evil/evil_macro_pop.h
@@ -0,0 +1,93 @@
1#ifndef __EVIL_MACRO_POP_H__
2#define __EVIL_MACRO_POP_H__
3
4
5#ifdef EVIL_CDECL_IS_DEFINED
6# undef __cdecl
7# undef EVIL_CDECL_IS_DEFINED
8#endif
9
10#define fprintf _evil_fprintfa
11#define printf _evil_printfa
12#define snprintf _evil_snprintfa
13#define sprintf _evil_sprintfa
14#define vfprintf _evil_vfprintfa
15#define vprintf _evil_vprintfa
16#define vsnprintf _evil_vsnprintfa
17#define vsprintf _evil_vsprintfa
18
19#define fscanf _evil_fscanf
20#define scanf _evil_scanf
21#define sscanf _evil_sscanf
22#define vfscanf _evil_vfscanf
23#define vscanf _evil_vscanf
24#define vsscanf _evil_vsscanf
25
26#define asprintf _evil_asprintf
27#define vasprintf _evil_vasprintf
28
29/* Redefine to GNU specific PRI... and SCN... macros. */
30
31#define PRId64 "lld"
32#define PRIdLEAST64 "lld"
33#define PRIdFAST64 "lld"
34#define PRIdMAX "lld"
35#define PRIi64 "lli"
36#define PRIiLEAST64 "lli"
37#define PRIiFAST64 "lli"
38#define PRIiMAX "lli"
39#define PRIo64 "llo"
40#define PRIoLEAST64 "llo"
41#define PRIoFAST64 "llo"
42#define PRIoMAX "llo"
43#define PRIu64 "llu"
44#define PRIuLEAST64 "llu"
45#define PRIuFAST64 "llu"
46#define PRIuMAX "llu"
47#define PRIx64 "llx"
48#define PRIxLEAST64 "llx"
49#define PRIxFAST64 "llx"
50#define PRIxMAX "llx"
51#define PRIX64 "llX"
52#define PRIXLEAST64 "llX"
53#define PRIXFAST64 "llX"
54#define PRIXMAX "llX"
55
56#define SCNd64 "lld"
57#define SCNdLEAST64 "lld"
58#define SCNdFAST64 "lld"
59#define SCNdMAX "lld"
60#define SCNi64 "lli"
61#define SCNiLEAST64 "lli"
62#define SCNiFAST64 "lli"
63#define SCNiMAX "lli"
64#define SCNo64 "llo"
65#define SCNoLEAST64 "llo"
66#define SCNoFAST64 "llo"
67#define SCNoMAX "llo"
68#define SCNx64 "llx"
69#define SCNxLEAST64 "llx"
70#define SCNxFAST64 "llx"
71#define SCNxMAX "llx"
72#define SCNu64 "llu"
73#define SCNuLEAST64 "llu"
74#define SCNuFAST64 "llu"
75#define SCNuMAX "llu"
76
77#ifdef _WIN64
78#define PRIdPTR "lld"
79#define PRIiPTR "lli"
80#define PRIoPTR "llo"
81#define PRIuPTR "llu"
82#define PRIxPTR "llx"
83#define PRIXPTR "llX"
84
85#define SCNdPTR "lld"
86#define SCNiPTR "lli"
87#define SCNoPTR "llo"
88#define SCNxPTR "llx"
89#define SCNuPTR "llu"
90#endif /* _WIN64 */
91
92
93#endif /* __EVIL_MACRO_POP_H__ */
diff --git a/src/lib/evil/evil_main.c b/src/lib/evil/evil_main.c
new file mode 100644
index 0000000..ee1eb1d
--- /dev/null
+++ b/src/lib/evil/evil_main.c
@@ -0,0 +1,74 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#ifndef WIN32_LEAN_AND_MEAN
6# define WIN32_LEAN_AND_MEAN
7#endif
8#include <winsock2.h>
9#undef WIN32_LEAN_AND_MEAN
10
11#include "Evil.h"
12#include "evil_private.h"
13
14
15static int _evil_init_count = 0;
16
17extern LONGLONG _evil_time_freq;
18extern LONGLONG _evil_time_count;
19extern long _evil_time_second;
20
21int
22evil_init(void)
23{
24 SYSTEMTIME st;
25 LARGE_INTEGER freq;
26 LARGE_INTEGER count;
27 WORD second = 59;
28
29 if (++_evil_init_count != 1)
30 return _evil_init_count;
31
32 if (!QueryPerformanceFrequency(&freq))
33 return 0;
34
35 _evil_time_freq = freq.QuadPart;
36
37 /* be sure that second + 1 != 0 */
38 while (second == 59)
39 {
40 GetSystemTime(&st);
41 second = st.wSecond;
42 }
43
44 /* retrieve the tick corresponding to the time we retrieve above */
45 while (1)
46 {
47 GetSystemTime(&st);
48 QueryPerformanceCounter(&count);
49 if (st.wSecond == second + 1)
50 break;
51 }
52
53 _evil_time_second = _evil_systemtime_to_time(st);
54 if (_evil_time_second < 0)
55 return --_evil_init_count;
56
57 _evil_time_count = count.QuadPart;
58
59 if (!evil_sockets_init())
60 return --_evil_init_count;
61
62 return _evil_init_count;
63}
64
65int
66evil_shutdown(void)
67{
68 if (--_evil_init_count != 0)
69 return _evil_init_count;
70
71 evil_sockets_shutdown();
72
73 return _evil_init_count;
74}
diff --git a/src/lib/evil/evil_main.h b/src/lib/evil/evil_main.h
new file mode 100644
index 0000000..157e602
--- /dev/null
+++ b/src/lib/evil/evil_main.h
@@ -0,0 +1,52 @@
1#ifndef __EVIL_MAIN_H__
2#define __EVIL_MAIN_H__
3
4
5/**
6 * @file evil_main.h
7 * @brief The file that provides functions to initialize and shut down Evil.
8 * @defgroup Evil_Main_Group Main
9 *
10 * This header provides functions to initialize and shut down the Evil
11 * library.
12 *
13 * @{
14 */
15
16
17/**
18 * @brief Initialize the Evil library.
19 *
20 * This function initializes the Evil library. It must be called before
21 * using evil_time_get(), gettimeofday() or pipe(). It returns 0 on
22 * failure, otherwise it returns the number of times it has already been
23 * called.
24 *
25 * When Evil is not used anymore, call evil_shutdown() to shut down
26 * the Evil library.
27 */
28EAPI int evil_init(void);
29
30/**
31 * @brief Shut down the Evil library.
32 *
33 * @return 0 when the Evil library is completely shut down, 1 or
34 * greater otherwise.
35 *
36 * This function shuts down the Evil library. It returns 0 when it has
37 * been called the same number of times than evil_init().
38 *
39 * Once this function succeeds (that is, @c 0 is returned), you must
40 * not call any of the Evil function listed in evil_init()
41 * documentation anymore . You must call evil_init() again to use these
42 * functions again.
43 */
44EAPI int evil_shutdown(void);
45
46
47/**
48 * @}
49 */
50
51
52#endif /* __EVIL_MAIN_H__ */
diff --git a/src/lib/evil/evil_mman.c b/src/lib/evil/evil_mman.c
new file mode 100644
index 0000000..8898357
--- /dev/null
+++ b/src/lib/evil/evil_mman.c
@@ -0,0 +1,234 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include <stdlib.h>
6#include <stdio.h>
7#include <sys/types.h>
8
9#ifndef _MSC_VER
10# include <unistd.h>
11#endif
12
13#ifndef WIN32_LEAN_AND_MEAN
14# define WIN32_LEAN_AND_MEAN
15#endif
16#include <windows.h>
17#undef WIN32_LEAN_AND_MEAN
18
19# include <io.h>
20
21#include "evil_macro.h"
22#include "sys/mman.h"
23#include "evil_util.h"
24#include "evil_private.h"
25#define APICHAR char
26#include "evil_print.h"
27
28#ifdef __MINGW32CE__
29# define _get_osfhandle(FILEDES) ((long)FILEDES)
30#endif /* __MINGW32CE__ */
31
32
33/***** API *****/
34
35
36void *
37mmap(void *addr __UNUSED__,
38 size_t len,
39 int prot,
40 int flags,
41 int fd,
42 off_t offset)
43{
44 OSVERSIONINFO os_version;
45
46 os_version.dwOSVersionInfoSize = sizeof(os_version);
47 if (!GetVersionEx(&os_version))
48 {
49 char *str;
50
51 str = evil_last_error_get();
52 fprintf(stderr, "[Evil] [mmap] GetVersionEx failed: %s\n", str);
53 free(str);
54
55 return MAP_FAILED;
56 }
57
58#ifdef _WIN32_WCE
59 if ((os_version.dwPlatformId == VER_PLATFORM_WIN32_CE) &&
60 (os_version.dwMajorVersion < 5))
61 {
62 void *data;
63 size_t size;
64
65 data = malloc(len);
66 if (!data)
67 {
68 fprintf (stderr, "[Evil] [mmap] malloc failed\n");
69 return MAP_FAILED;
70 }
71
72 size = read(fd, data, len);
73 if (size != len)
74 {
75 fprintf (stderr, "[Evil] [mmap] read failed\n");
76 free(data);
77 return MAP_FAILED;
78 }
79
80 if (lseek(fd, 0, SEEK_SET) == -1)
81 {
82 fprintf (stderr, "[Evil] [mmap] lseek failed\n");
83 free(data);
84 return MAP_FAILED;
85 }
86
87 return data;
88 }
89 else
90#endif /* ! _WIN32_WCE */
91 {
92 HANDLE fm;
93 DWORD protect = PAGE_NOACCESS;
94 DWORD acs = 0;
95 HANDLE handle;
96 void *data;
97
98 /* support only MAP_SHARED */
99 if (!(flags & MAP_SHARED))
100 return MAP_FAILED;
101
102 if (prot & PROT_EXEC)
103 {
104 if (prot & PROT_READ)
105 {
106 if (prot & PROT_WRITE)
107 protect = PAGE_EXECUTE_READWRITE;
108 else
109 protect = PAGE_EXECUTE_READ;
110 }
111 else
112 {
113 if (prot & PROT_WRITE)
114 protect = PAGE_EXECUTE_WRITECOPY;
115 else
116 protect = PAGE_EXECUTE;
117 }
118 }
119 else
120 {
121 if (prot & PROT_READ)
122 {
123 if (prot & PROT_WRITE)
124 protect = PAGE_READWRITE;
125 else
126 protect = PAGE_READONLY;
127 }
128 else if (prot & PROT_WRITE)
129 protect = PAGE_WRITECOPY;
130 }
131
132 handle = (HANDLE)_get_osfhandle(fd);
133 if (handle == INVALID_HANDLE_VALUE)
134 {
135 fprintf(stderr, "[Evil] [mmap] _get_osfhandle failed\n");
136
137 return MAP_FAILED;
138 }
139
140 fm = CreateFileMapping(handle, NULL, protect, 0, 0, NULL);
141 if (!fm)
142 {
143 char *str;
144
145 str = evil_last_error_get();
146 fprintf(stderr, "[Evil] [mmap] CreateFileMapping failed: %s\n", str);
147 free(str);
148
149 return MAP_FAILED;
150 }
151
152 if (protect & PAGE_READWRITE)
153 acs = FILE_MAP_ALL_ACCESS;
154 if (protect & PAGE_WRITECOPY)
155 acs = FILE_MAP_COPY;
156#if 0
157 if (protect & (PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_READ))
158 acs = FILE_MAP_EXECUTE;
159#endif
160 if (protect & (PAGE_READWRITE | PAGE_READONLY))
161 acs = FILE_MAP_READ;
162 else
163 {
164 if (protect & PAGE_READWRITE)
165 acs = FILE_MAP_WRITE;
166 }
167
168 data = MapViewOfFile(fm,
169 acs,
170 offset & 0xffff0000,
171 offset & 0x0000ffff,
172 len);
173 CloseHandle(fm);
174
175 if (!data)
176 {
177 char *str;
178
179 str = evil_last_error_get();
180 fprintf(stderr, "[Evil] [mmap] MapViewOfFile failed: %s\n", str);
181 free(str);
182
183 return MAP_FAILED;
184 }
185
186 return data;
187 }
188}
189
190int
191munmap(void *addr,
192 size_t len __UNUSED__)
193{
194#ifdef _WIN32_WCE
195 OSVERSIONINFO os_version;
196
197 os_version.dwOSVersionInfoSize = sizeof(os_version);
198 if (!GetVersionEx(&os_version))
199 {
200 char *str;
201
202 str = evil_last_error_get();
203 fprintf(stderr, "[Evil] [munmap] GetVersionEx failed: %s\n", str);
204 free(str);
205
206 return -1;
207 }
208
209 if ((os_version.dwPlatformId == VER_PLATFORM_WIN32_CE) &&
210 (os_version.dwMajorVersion < 5))
211 {
212 if (addr && (addr != MAP_FAILED))
213 free(addr);
214
215 return 0;
216 }
217 else
218#endif /* ! _WIN32_WCE */
219 {
220 BOOL res;
221
222 res = UnmapViewOfFile(addr);
223 if (!res)
224 {
225 char *str;
226
227 str = evil_last_error_get();
228 fprintf(stderr, "[Evil] [munmap] UnmapViewOfFile failed: %s\n", str);
229 free(str);
230 }
231
232 return (res == 0) ? -1 : 0;
233 }
234}
diff --git a/src/lib/evil/evil_pformat.h b/src/lib/evil/evil_pformat.h
new file mode 100644
index 0000000..ad9b61e
--- /dev/null
+++ b/src/lib/evil/evil_pformat.h
@@ -0,0 +1,61 @@
1#ifndef __EVIL_PRIVATE_H__
2#define __EVIL_PRIVATE_H__
3
4
5#include "evil_macro.h"
6
7
8#ifdef __BUILD_WIDEAPI
9#define APICHAR wchar_t
10#else
11#define APICHAR char
12#endif
13
14/* The following are the declarations specific to the `pformat' API...
15 */
16#define PFORMAT_TO_FILE 0x1000
17#define PFORMAT_NOLIMIT 0x2000
18
19
20#ifdef __cplusplus
21extern "C" {
22#endif
23
24
25#ifdef __BUILD_WIDEAPI
26# define __fputc(X,STR) fputwc((wchar_t) (X), (STR))
27# define _evil_pformat _evil_pformatw
28
29# define _evil_fprintf _evil_fprintfw
30# define _evil_printf _evil_printfw
31# define _evil_snprintf _evil_snprintfw
32# define _evil_sprintf _evil_sprintfw
33
34# define _evil_vfprintf _evil_vfprintfw
35# define _evil_vprintf _evil_vprintfw
36# define _evil_vsnprintf _evil_vsnprintfw
37# define _evil_vsprintf _evil_vsprintfw
38#else
39# define __fputc(X,STR) fputc((X), (STR))
40# define _evil_pformat _evil_pformata
41
42# define _evil_fprintf _evil_fprintfa
43# define _evil_printf _evil_printfa
44# define _evil_snprintf _evil_snprintfa
45# define _evil_sprintf _evil_sprintfa
46
47# define _evil_vfprintf _evil_vfprintfa
48# define _evil_vprintf _evil_vprintfa
49# define _evil_vsnprintf _evil_vsnprintfa
50# define _evil_vsprintf _evil_vsprintfa
51#endif
52
53int __cdecl _evil_pformat(int, void *, int, const APICHAR *, va_list) __EVIL_NOTHROW;
54
55
56#ifdef __cplusplus
57}
58#endif
59
60
61#endif /* __EVIL_PRIVATE_H__ */
diff --git a/src/lib/evil/evil_pformata.c b/src/lib/evil/evil_pformata.c
new file mode 100644
index 0000000..ee1d68e
--- /dev/null
+++ b/src/lib/evil/evil_pformata.c
@@ -0,0 +1,2493 @@
1/* pformat.c
2 *
3 * $Id: pformat.c,v 1.9 2011/01/07 22:57:00 keithmarshall Exp $
4 *
5 * Provides a core implementation of the formatting capabilities
6 * common to the entire `printf()' family of functions; it conforms
7 * generally to C99 and SUSv3/POSIX specifications, with extensions
8 * to support Microsoft's non-standard format specifications.
9 *
10 * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
11 *
12 * This is free software. You may redistribute and/or modify it as you
13 * see fit, without restriction of copyright.
14 *
15 * This software is provided "as is", in the hope that it may be useful,
16 * but WITHOUT WARRANTY OF ANY KIND, not even any implied warranty of
17 * MERCHANTABILITY, nor of FITNESS FOR ANY PARTICULAR PURPOSE. At no
18 * time will the author accept any form of liability for any damages,
19 * however caused, resulting from the use of this software.
20 *
21 * The elements of this implementation which deal with the formatting
22 * of floating point numbers, (i.e. the `%e', `%E', `%f', `%F', `%g'
23 * and `%G' format specifiers, but excluding the hexadecimal floating
24 * point `%a' and `%A' specifiers), make use of the `__gdtoa' function
25 * written by David M. Gay, and are modelled on his sample code, which
26 * has been deployed under its accompanying terms of use:--
27 *
28 ******************************************************************
29 * Copyright (C) 1997, 1999, 2001 Lucent Technologies
30 * All Rights Reserved
31 *
32 * Permission to use, copy, modify, and distribute this software and
33 * its documentation for any purpose and without fee is hereby
34 * granted, provided that the above copyright notice appear in all
35 * copies and that both that the copyright notice and this
36 * permission notice and warranty disclaimer appear in supporting
37 * documentation, and that the name of Lucent or any of its entities
38 * not be used in advertising or publicity pertaining to
39 * distribution of the software without specific, written prior
40 * permission.
41 *
42 * LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
43 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
44 * IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
45 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
46 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
47 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
48 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
49 * THIS SOFTWARE.
50 ******************************************************************
51 *
52 */
53#include <stdio.h>
54#include <stdarg.h>
55#include <stddef.h>
56#include <stdint.h>
57#include <stdlib.h>
58#include <string.h>
59#include <limits.h>
60#include <locale.h>
61#include <wchar.h>
62#include <math.h>
63
64/* FIXME: The following belongs in values.h, but current MinGW
65 * has nothing useful there! OTOH, values.h is not a standard
66 * header, and it's use may be considered obsolete; perhaps it
67 * is better to just keep these definitions here.
68 */
69#ifndef _VALUES_H
70/*
71 * values.h
72 *
73 */
74#define _VALUES_H
75
76#include <limits.h>
77
78#define _TYPEBITS(type) (sizeof(type) * CHAR_BIT)
79
80#define LLONGBITS _TYPEBITS(long long)
81
82#endif /* !defined _VALUES_H -- end of file */
83
84#include "evil_pformat.h"
85#include "gdtoa/gdtoa.h"
86
87/* Bit-map constants, defining the internal format control
88 * states, which propagate through the flags.
89 */
90#define PFORMAT_GROUPED 0x1000
91#define PFORMAT_HASHED 0x0800
92#define PFORMAT_LJUSTIFY 0x0400
93#define PFORMAT_ZEROFILL 0x0200
94
95#define PFORMAT_JUSTIFY (PFORMAT_LJUSTIFY | PFORMAT_ZEROFILL)
96#define PFORMAT_IGNORE -1
97
98#define PFORMAT_SIGNED 0x01C0
99#define PFORMAT_POSITIVE 0x0100
100#define PFORMAT_NEGATIVE 0x0080
101#define PFORMAT_ADDSPACE 0x0040
102
103#define PFORMAT_XCASE 0x0020
104
105#define PFORMAT_LDOUBLE 0x0004
106
107/* `%o' format digit extraction mask, and shift count...
108 * (These are constant, and do not propagate through the flags).
109 */
110#define PFORMAT_OMASK 0x0007
111#define PFORMAT_OSHIFT 0x0003
112
113/* `%x' and `%X' format digit extraction mask, and shift count...
114 * (These are constant, and do not propagate through the flags).