1 /*
2  * prog_util.h - utility functions for programs
3  *
4  * Copyright 2016 Eric Biggers
5  *
6  * Permission is hereby granted, free of charge, to any person
7  * obtaining a copy of this software and associated documentation
8  * files (the "Software"), to deal in the Software without
9  * restriction, including without limitation the rights to use,
10  * copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following
13  * conditions:
14  *
15  * The above copyright notice and this permission notice shall be
16  * included in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25  * OTHER DEALINGS IN THE SOFTWARE.
26  */
27 
28 #ifndef PROGRAMS_PROG_UTIL_H
29 #define PROGRAMS_PROG_UTIL_H
30 
31 #ifdef HAVE_CONFIG_H
32 #  include "config.h"
33 #endif
34 
35 #include "libdeflate.h"
36 
37 #include <limits.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #ifndef _WIN32
42 #  include <sys/types.h>
43 #endif
44 
45 #include "../common/common_defs.h"
46 
47 #ifdef __GNUC__
48 # define _printf(str_idx, args_idx)	\
49 		__attribute__((format(printf, str_idx, args_idx)))
50 #else
51 # define _printf(str_idx, args_idx)
52 #endif
53 
54 #ifdef _MSC_VER
55 /*
56  * Old versions (e.g. VS2010) of MSC have stdint.h but not the C99 header
57  * inttypes.h.  Work around this by defining the PRI* macros ourselves.
58  */
59 # define PRIu8  "hhu"
60 # define PRIu16 "hu"
61 # define PRIu32 "u"
62 # define PRIu64 "llu"
63 # define PRIi8  "hhi"
64 # define PRIi16 "hi"
65 # define PRIi32 "i"
66 # define PRIi64 "lli"
67 # define PRIx8  "hhx"
68 # define PRIx16 "hx"
69 # define PRIx32 "x"
70 # define PRIx64 "llx"
71 #else
72 # include <inttypes.h>
73 #endif
74 
75 #ifdef _WIN32
76 
77 /*
78  * Definitions for Windows builds.  Mainly, 'tchar' is defined to be the 2-byte
79  * 'wchar_t' type instead of 'char'.  This is the only "easy" way I know of to
80  * get full Unicode support on Windows...
81  */
82 
83 #include <wchar.h>
84 int wmain(int argc, wchar_t **argv);
85 #  define	tmain		wmain
86 #  define	tchar		wchar_t
87 #  define	_T(text)	L##text
88 #  define	T(text)		_T(text)
89 #  define	TS		"ls"
90 #  define	TC		"lc"
91 #  define	tmemcpy		wmemcpy
92 #  define	topen		_wopen
93 #  define	tstrchr		wcschr
94 #  define	tstrcmp		wcscmp
95 #  define	tstrlen		wcslen
96 #  define	tstrrchr	wcsrchr
97 #  define	tstrtoul	wcstoul
98 #  define	tstrxcmp	wcsicmp
99 #  define	tunlink		_wunlink
100 #  define	tutimbuf	__utimbuf64
101 #  define	tutime		_wutime64
102 #  define	tstat		_wstat64
103 #  define	tfstat		_fstat64
104 #  define	stat_t		struct _stat64
105 #  ifdef _MSC_VER
106 #    define	STDIN_FILENO	0
107 #    define	STDOUT_FILENO	1
108 #    define	STDERR_FILENO	2
109 #    define	S_ISREG(m)      (((m) & S_IFMT) == S_IFREG)
110 #    define	S_ISDIR(m)      (((m) & S_IFMT) == S_IFDIR)
111 #  endif
112 
113 #else /* _WIN32 */
114 
115 /* Standard definitions for everyone else */
116 
117 #  define	tmain		main
118 #  define	tchar		char
119 #  define	T(text)		text
120 #  define	TS		"s"
121 #  define	TC		"c"
122 #  define	tmemcpy		memcpy
123 #  define	topen		open
124 #  define	tstrchr		strchr
125 #  define	tstrcmp		strcmp
126 #  define	tstrlen		strlen
127 #  define	tstrrchr	strrchr
128 #  define	tstrtoul	strtoul
129 #  define	tstrxcmp	strcmp
130 #  define	tunlink		unlink
131 #  define	tutimbuf	utimbuf
132 #  define	tutime		utime
133 #  define	tstat		stat
134 #  define	tfstat		fstat
135 #  define	stat_t		struct stat
136 
137 #endif /* !_WIN32 */
138 
139 extern const tchar *prog_invocation_name;
140 
141 void _printf(1, 2) msg(const char *fmt, ...);
142 void _printf(1, 2) msg_errno(const char *fmt, ...);
143 
144 void *xmalloc(size_t size);
145 
146 void begin_program(tchar *argv[]);
147 
148 struct file_stream {
149 	int fd;
150 	tchar *name;
151 	bool is_standard_stream;
152 	void *mmap_token;
153 	void *mmap_mem;
154 	size_t mmap_size;
155 };
156 
157 int xopen_for_read(const tchar *path, bool symlink_ok,
158 		   struct file_stream *strm);
159 int xopen_for_write(const tchar *path, bool force, struct file_stream *strm);
160 int map_file_contents(struct file_stream *strm, u64 size);
161 
162 ssize_t xread(struct file_stream *strm, void *buf, size_t count);
163 int full_write(struct file_stream *strm, const void *buf, size_t count);
164 
165 int xclose(struct file_stream *strm);
166 
167 int parse_compression_level(tchar opt_char, const tchar *arg);
168 
169 struct libdeflate_compressor *alloc_compressor(int level);
170 struct libdeflate_decompressor *alloc_decompressor(void);
171 
172 /* tgetopt.c */
173 
174 extern tchar *toptarg;
175 extern int toptind, topterr, toptopt;
176 
177 int tgetopt(int argc, tchar *argv[], const tchar *optstring);
178 
179 #endif /* PROGRAMS_PROG_UTIL_H */
180