1
/* vim:ts=8:sts=8:sw=4:noai:noexpandtab
3
* portable security-enhanced CRT functions.
5
* Copyright (c) 2010 Miru Limited.
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
#if !defined (__PGM_IMPL_FRAMEWORK_H_INSIDE__) && !defined (PGM_COMPILATION)
23
# error "Only <framework.h> can be included directly."
26
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
29
#ifndef __PGM_IMPL_SECURITY_H__
30
#define __PGM_IMPL_SECURITY_H__
35
#include <sys/types.h>
36
#include <sys/timeb.h>
37
#include <impl/i18n.h>
38
#include <impl/errno.h>
39
#include <impl/string.h>
43
#ifdef CONFIG_HAVE_FTIME
47
pgm_ftime_s (struct timeb *timeptr)
48
# elif !defined( _MSC_VER )
49
pgm_ftime_s (struct _timeb *timeptr)
51
pgm_ftime_s (struct __timeb64 *timeptr)
55
return ftime (timeptr);
56
# elif !defined( _MSC_VER )
59
# elif defined( CONFIG_HAVE_SECURITY_ENHANCED_CRT )
60
return _ftime64_s (timeptr);
66
#endif /* CONFIG_HAVE_FTIME */
69
# define _TRUNCATE (size_t)-1
74
pgm_strncpy_s (char *dest, size_t size, const char *src, size_t count)
76
#ifndef CONFIG_HAVE_SECURITY_ENHANCED_CRT
77
if (_TRUNCATE == count) {
78
strncpy (dest, src, size);
83
strncpy (dest, src, count + 1);
87
return strncpy_s (dest, size, src, count);
91
static inline int pgm_vsnprintf_s (char*, size_t, size_t, const char*, va_list) PGM_GNUC_PRINTF(4, 0);
95
pgm_vsnprintf_s (char *str, size_t size, size_t count, const char *format, va_list ap)
98
if (_TRUNCATE == count) {
99
const int retval = vsnprintf (str, size, format, ap);
104
const int retval = vsnprintf (str, count + 1, format, ap);
107
#elif !defined( CONFIG_HAVE_SECURITY_ENHANCED_CRT )
108
if (_TRUNCATE == count) {
109
const int retval = _vsnprintf (str, size, format, ap);
114
const int retval = _vsnprintf (str, count + 1, format, ap);
118
return _vsnprintf_s (str, size, count, format, ap);
122
#ifndef CONFIG_HAVE_SECURITY_ENHANCED_CRT
123
static inline int pgm_snprintf_s (char*, size_t, size_t, const char*, ...) PGM_GNUC_PRINTF(4, 5);
124
static inline int pgm_sscanf_s (const char*, const char*, ...) PGM_GNUC_SCANF(2, 3);
128
pgm_snprintf_s (char *str, size_t size, size_t count, const char *format, ...)
133
va_start (ap, format);
134
retval = pgm_vsnprintf_s (str, size, count, format, ap);
141
pgm_sscanf_s (const char *buffer, const char *format, ...)
146
va_start (ap, format);
147
retval = vsscanf (buffer, format, ap);
152
# define pgm_snprintf_s _snprintf_s
153
# define pgm_sscanf_s sscanf_s
154
#endif /* CONFIG_HAVE_SECURITY_ENHANCED_CRT */
158
pgm_strerror_s (char *buffer, size_t size, int errnum)
160
#ifdef CONFIG_HAVE_SECURITY_ENHANCED_CRT
161
if (0 != strerror_s (buffer, size, errnum))
162
pgm_snprintf_s (buffer, size, _TRUNCATE, _("Unknown error %d"), errnum);
164
#elif defined( _WIN32 )
165
pgm_strncpy_s (buffer, size, strerror (errnum), _TRUNCATE);
167
#elif defined( CONFIG_HAVE_GNU_STRERROR_R )
168
/* GNU-specific, failure is noted within buffer contents */
169
return strerror_r (errnum, buffer, size);
172
if (0 != strerror_r (errnum, buffer, size))
173
pgm_snprintf_s (buffer, size, _TRUNCATE, _("Unknown error %d"), errnum);
180
pgm_fopen_s (FILE **pFile, const char *filename, const char *mode)
182
#ifndef CONFIG_HAVE_SECURITY_ENHANCED_CRT
185
if (NULL == (stream = fopen (filename, mode)))
190
return fopen_s (pFile, filename, mode);
194
/* Security-only APIs */
198
pgm_dupenv_s (char **buffer, size_t *count, const char* name)
200
#ifndef CONFIG_HAVE_SECURITY_ENHANCED_CRT
201
const char *val = getenv (name);
208
*buffer = pgm_strdup (val);
210
if (NULL == *buffer) {
213
return errno; /* ENOMEM */
215
*count = strlen (*buffer) + 1;
219
const errno_t err = _dupenv_s (&pValue, count, name);
221
*buffer = pgm_strdup (pValue);
227
/* Win32 specific APIs */
232
pgm_wcstombs_s (size_t *retval, char *dest, size_t size, const wchar_t *src, size_t count)
234
# ifndef CONFIG_HAVE_SECURITY_ENHANCED_CRT
236
if (_TRUNCATE == count) {
237
characters = wcstombs (dest, src, size);
238
/* may invalidate last multi-byte character */
242
characters = wcstombs (dest, src, count + 1);
245
if ((size_t)-1 == characters) {
249
*retval = characters;
252
return wcstombs_s (retval, dest, size, src, count);
260
#endif /* __PGM_IMPL_SECURITY_H__ */