Commit c39ca55a authored by David Woodhouse's avatar David Woodhouse

Add open_utf8() and fopen_utf8() functions for opening files

These will convert to legacy charset as required (or UTF-16 for Windows).
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent c0712176
......@@ -236,17 +236,12 @@ static int check_certificate_expiry(struct openconnect_info *vpninfo, gnutls_x50
return 0;
}
/* For systems that don't support O_CLOEXEC, just don't bother.
It's not open for long anyway. */
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif
static int load_datum(struct openconnect_info *vpninfo,
gnutls_datum_t *datum, const char *fname)
{
struct stat st;
int fd, err;
#ifdef ANDROID_KEYSTORE
if (!strncmp(fname, "keystore:", 9)) {
int len;
......
......@@ -520,6 +520,12 @@ int dumb_socketpair(int socks[2], int make_overlapped);
#endif
#endif
/* For systems that don't support O_CLOEXEC, just don't bother.
We don't keep files open for long anyway. */
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif
/* I always coded as if it worked like this. Now it does. */
#define realloc_inplace(p, size) do { \
void *__realloc_old = p; \
......@@ -584,6 +590,8 @@ void cmd_fd_set(struct openconnect_info *vpninfo, fd_set *fds, int *maxfd);
void check_cmd_fd(struct openconnect_info *vpninfo, fd_set *fds);
int is_cancel_pending(struct openconnect_info *vpninfo, fd_set *fds);
void poll_cmd_fd(struct openconnect_info *vpninfo, int timeout);
int open_utf8(struct openconnect_info *vpninfo, const char *fname, int mode);
FILE *fopen_utf8(struct openconnect_info *vpninfo, const char *fname, const char *mode);
/* {gnutls,openssl}.c */
int openconnect_open_https(struct openconnect_info *vpninfo);
......
......@@ -656,3 +656,61 @@ void poll_cmd_fd(struct openconnect_info *vpninfo, int timeout)
check_cmd_fd(vpninfo, &rd_set);
}
}
#ifdef _WIN32
int open_utf8(struct openconnect_info *vpninfo, const char *fname, int mode)
{
wchar_t *fname_w;
int nr_chars = MultiByteToWideChar(CP_UTF8, 0, fname, -1, NULL, 0);
int fd;
if (!nr_chars) {
errno = EINVAL;
return -1;
}
fname_w = malloc(nr_chars * sizeof(wchar_t));
if (!fname_w) {
errno = ENOMEM;
return -1;
}
MultiByteToWideChar(CP_UTF8, 0, fname, -1, fname_w, nr_chars);
fd = _wopen(fname_w, mode);
free(fname_w);
return fd;
}
#else
int open_utf8(struct openconnect_info *vpninfo, const char *fname, int mode)
{
char *legacy_fname = openconnect_utf8_to_legacy(vpninfo, fname);
int fd;
fd = open(legacy_fname, mode);
if (legacy_fname != fname)
free(legacy_fname);
return fd;
}
#endif
FILE *fopen_utf8(struct openconnect_info *vpninfo, const char *fname,
const char *mode)
{
int fd;
/* This should never happen, but if we forget and start using other
modes without implementing proper mode->flags conversion, complain! */
if (strcmp(mode, "rb")) {
vpn_progress(vpninfo, PRG_ERR,
_("fopen_utf8() used with unsupported mode '%s'\n"),
mode);
return NULL;
}
fd = open_utf8(vpninfo, fname, O_RDONLY|O_CLOEXEC|O_BINARY);
if (fd == -1)
return NULL;
return fdopen(fd, mode);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment