Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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: David Woodhouse <David.Woodhouse@intel.com>
  • Loading branch information
David Woodhouse authored and David Woodhouse committed Jul 31, 2014
1 parent c071217 commit c39ca55
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 6 deletions.
7 changes: 1 addition & 6 deletions gnutls.c
Expand Up @@ -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;
Expand Down
8 changes: 8 additions & 0 deletions openconnect-internal.h
Expand Up @@ -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; \
Expand Down Expand Up @@ -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);
Expand Down
58 changes: 58 additions & 0 deletions ssl.c
Expand Up @@ -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);
}

0 comments on commit c39ca55

Please sign in to comment.