Update networking layer w/ CURL and emscripten impl
This commit is contained in:
+163
@@ -0,0 +1,163 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_COOKIES) || !defined(CURL_DISABLE_ALTSVC) || \
|
||||
!defined(CURL_DISABLE_HSTS)
|
||||
|
||||
#include "urldata.h"
|
||||
#include "rand.h"
|
||||
#include "curl_fopen.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
The dirslash() function breaks a null-terminated pathname string into
|
||||
directory and filename components then returns the directory component up
|
||||
to, *AND INCLUDING*, a final '/'. If there is no directory in the path,
|
||||
this instead returns a "" string.
|
||||
|
||||
This function returns a pointer to malloc'ed memory.
|
||||
|
||||
The input path to this function is expected to have a filename part.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#define PATHSEP "\\"
|
||||
#define IS_SEP(x) (((x) == '/') || ((x) == '\\'))
|
||||
#elif defined(MSDOS) || defined(OS2)
|
||||
#define PATHSEP "\\"
|
||||
#define IS_SEP(x) ((x) == '\\')
|
||||
#else
|
||||
#define PATHSEP "/"
|
||||
#define IS_SEP(x) ((x) == '/')
|
||||
#endif
|
||||
|
||||
static char *dirslash(const char *path)
|
||||
{
|
||||
size_t n;
|
||||
struct dynbuf out;
|
||||
DEBUGASSERT(path);
|
||||
curlx_dyn_init(&out, CURL_MAX_INPUT_LENGTH);
|
||||
n = strlen(path);
|
||||
if(n) {
|
||||
/* find the rightmost path separator, if any */
|
||||
while(n && !IS_SEP(path[n-1]))
|
||||
--n;
|
||||
/* skip over all the path separators, if any */
|
||||
while(n && IS_SEP(path[n-1]))
|
||||
--n;
|
||||
}
|
||||
if(curlx_dyn_addn(&out, path, n))
|
||||
return NULL;
|
||||
/* if there was a directory, append a single trailing slash */
|
||||
if(n && curlx_dyn_addn(&out, PATHSEP, 1))
|
||||
return NULL;
|
||||
return curlx_dyn_ptr(&out);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_fopen() opens a file for writing with a temp name, to be renamed
|
||||
* to the final name when completed. If there is an existing file using this
|
||||
* name at the time of the open, this function will clone the mode from that
|
||||
* file. if 'tempname' is non-NULL, it needs a rename after the file is
|
||||
* written.
|
||||
*/
|
||||
CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
|
||||
FILE **fh, char **tempname)
|
||||
{
|
||||
CURLcode result = CURLE_WRITE_ERROR;
|
||||
unsigned char randbuf[41];
|
||||
char *tempstore = NULL;
|
||||
struct_stat sb;
|
||||
int fd = -1;
|
||||
char *dir = NULL;
|
||||
*tempname = NULL;
|
||||
|
||||
*fh = curlx_fopen(filename, FOPEN_WRITETEXT);
|
||||
if(!*fh)
|
||||
goto fail;
|
||||
if(
|
||||
#ifdef UNDER_CE
|
||||
/* !checksrc! disable BANNEDFUNC 1 */
|
||||
stat(filename, &sb) == -1
|
||||
#else
|
||||
fstat(fileno(*fh), &sb) == -1
|
||||
#endif
|
||||
|| !S_ISREG(sb.st_mode)) {
|
||||
return CURLE_OK;
|
||||
}
|
||||
curlx_fclose(*fh);
|
||||
*fh = NULL;
|
||||
|
||||
result = Curl_rand_alnum(data, randbuf, sizeof(randbuf));
|
||||
if(result)
|
||||
goto fail;
|
||||
|
||||
dir = dirslash(filename);
|
||||
if(dir) {
|
||||
/* The temp filename should not end up too long for the target file
|
||||
system */
|
||||
tempstore = curl_maprintf("%s%s.tmp", dir, randbuf);
|
||||
free(dir);
|
||||
}
|
||||
|
||||
if(!tempstore) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
result = CURLE_WRITE_ERROR;
|
||||
#if (defined(ANDROID) || defined(__ANDROID__)) && \
|
||||
(defined(__i386__) || defined(__arm__))
|
||||
fd = curlx_open(tempstore, O_WRONLY | O_CREAT | O_EXCL,
|
||||
(mode_t)(0600 | sb.st_mode));
|
||||
#else
|
||||
fd = curlx_open(tempstore, O_WRONLY | O_CREAT | O_EXCL,
|
||||
0600 | sb.st_mode);
|
||||
#endif
|
||||
if(fd == -1)
|
||||
goto fail;
|
||||
|
||||
*fh = curlx_fdopen(fd, FOPEN_WRITETEXT);
|
||||
if(!*fh)
|
||||
goto fail;
|
||||
|
||||
*tempname = tempstore;
|
||||
return CURLE_OK;
|
||||
|
||||
fail:
|
||||
if(fd != -1) {
|
||||
close(fd);
|
||||
unlink(tempstore);
|
||||
}
|
||||
|
||||
free(tempstore);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* ! disabled */
|
||||
Reference in New Issue
Block a user