1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-12-04 14:46:47 -05:00

join temp file name creation and file creation

This commit is contained in:
sgerwk 2021-03-31 19:24:26 +02:00
parent ab758c79b5
commit 1e842bc445
4 changed files with 102 additions and 26 deletions

View File

@ -1018,3 +1018,84 @@ get_system_str(int xwin)
{ {
return xwin ? SYSTEM_STR "-xwin" : SYSTEM_STR; return xwin ? SYSTEM_STR "-xwin" : SYSTEM_STR;
} }
#if _DEFAULT_SOURCE || _SVID_SOURCE || _BSD_SOURCE
/* tempnam() replacement without races */
int isdirectory(char *path) {
struct stat ss;
if (path == NULL)
return 0;
if (-1 == stat(path, &ss))
return 0;
return S_ISDIR(ss.st_mode);
}
char *tempname(char *dir, char *pfx, char *suff) {
struct string path;
char *ret;
int fd;
if (isdirectory(getenv("TMPDIR")))
dir = getenv("TMPDIR");
else if (dir != NULL)
dir = dir;
else if (isdirectory(P_tmpdir))
dir = P_tmpdir;
else if (isdirectory("/tmp"))
dir = "/tmp";
else {
errno = ENOTDIR;
return NULL;
}
if (!init_string(&path)) {
errno = ENOMEM;
return NULL;
}
add_to_string(&path, dir);
add_to_string(&path, "/");
add_to_string(&path, pfx);
add_to_string(&path, "XXXXXX");
if (suff)
add_shell_safe_to_string(&path, suff, strlen(suff));
fd = mkstemps(path.source, suff ? strlen(suff) : 0);
if (fd == -1) {
done_string(&path);
errno = ENOENT;
return NULL;
}
close(fd);
ret = strdup(path.source);
done_string(&path);
return ret;
}
#else
#warning mkstemps does not exist, using tempnam
char *tempname(char *dir, char *pfx, char *suff) {
char *temp, *ret;
struct string name;
temp = tempnam(dir, pfx);
if (temp == NULL)
return NULL;
if (!init_string(&name)) {
free(temp);
return NULL;
}
add_to_string(&name, temp);
free(temp);
add_shell_safe_to_string(&name, suff, strlen(suff));
ret = strdup(name.source);
done_string(&name);
return ret;
}
#endif

View File

@ -52,6 +52,7 @@ int resize_window(int, int, int, int);
int can_resize_window(int); int can_resize_window(int);
int can_open_os_shell(int); int can_open_os_shell(int);
void set_highpri(void); void set_highpri(void);
char *tempname(char *dir, char *pfx, char *suff);
#ifdef USE_OPEN_PREALLOC #ifdef USE_OPEN_PREALLOC
int open_prealloc(char *, int, int, off_t); int open_prealloc(char *, int, int, off_t);

View File

@ -800,7 +800,7 @@ lookup_unique_name(struct terminal *term, char *ofile,
} }
/* Check if the file already exists (file != ofile). */ /* Check if the file already exists (file != ofile). */
file = get_unique_name(ofile); file = (flags & DOWNLOAD_OVERWRITE) ? ofile : get_unique_name(ofile);
if (!file || overwrite == 1 || file == ofile) { if (!file || overwrite == 1 || file == ofile) {
/* Still nothing special to do... */ /* Still nothing special to do... */
@ -885,7 +885,9 @@ create_download_file_do(struct terminal *term, char *file,
* --pasky */ * --pasky */
h = open(file, O_CREAT | O_WRONLY h = open(file, O_CREAT | O_WRONLY
| (flags & DOWNLOAD_RESUME_SELECTED ? 0 : O_TRUNC) | (flags & DOWNLOAD_RESUME_SELECTED ? 0 : O_TRUNC)
| (sf && !(flags & DOWNLOAD_RESUME_SELECTED) ? O_EXCL : 0), | (sf &&
!(flags & DOWNLOAD_RESUME_SELECTED) &&
!(flags & DOWNLOAD_OVERWRITE) ? O_EXCL : 0),
sf ? 0600 : 0666); sf ? 0600 : 0666);
saved_errno = errno; /* Saved in case of ... --Zas */ saved_errno = errno; /* Saved in case of ... --Zas */
@ -999,31 +1001,17 @@ create_download_file(struct terminal *term, char *fi,
static char * static char *
get_temp_name(struct uri *uri) get_temp_name(struct uri *uri)
{ {
struct string name;
char *extension; char *extension;
/* FIXME char *nm;
* We use tempnam() here, which is unsafe (race condition), for now.
* This should be changed at some time, but it needs an in-depth work
* of whole download code. --Zas */
char *nm = tempnam(NULL, ELINKS_TEMPNAME_PREFIX);
if (!nm) return NULL;
if (!init_string(&name)) {
free(nm);
return NULL;
}
add_to_string(&name, nm);
free(nm);
extension = get_extension_from_uri(uri); extension = get_extension_from_uri(uri);
if (extension) { if (!extension)
add_shell_safe_to_string(&name, extension, strlen(extension)); extension = stracpy("");
mem_free(extension);
}
return name.source; nm = tempname(NULL, ELINKS_TEMPNAME_PREFIX, extension);
mem_free(extension);
return nm;
} }
@ -1321,7 +1309,6 @@ continue_download(void *data, char *file)
} }
if (type_query->external_handler) { if (type_query->external_handler) {
/* FIXME: get_temp_name() calls tempnam(). --Zas */
file = get_temp_name(type_query->uri); file = get_temp_name(type_query->uri);
if (!file) { if (!file) {
mem_free(codw_hop); mem_free(codw_hop);
@ -1338,7 +1325,9 @@ continue_download(void *data, char *file)
create_download_file(type_query->ses->tab->term, file, create_download_file(type_query->ses->tab->term, file,
&codw_hop->real_file, &codw_hop->real_file,
type_query->external_handler type_query->external_handler
? DOWNLOAD_RESUME_ALLOWED | DOWNLOAD_EXTERNAL ? DOWNLOAD_RESUME_ALLOWED |
DOWNLOAD_EXTERNAL |
DOWNLOAD_OVERWRITE
: DOWNLOAD_RESUME_ALLOWED, : DOWNLOAD_RESUME_ALLOWED,
continue_download_do, codw_hop); continue_download_do, codw_hop);
} }

View File

@ -39,7 +39,12 @@ enum download_flags {
DOWNLOAD_RESUME_SELECTED = 2, DOWNLOAD_RESUME_SELECTED = 2,
/** The file will be opened in an external handler. */ /** The file will be opened in an external handler. */
DOWNLOAD_EXTERNAL = 4 DOWNLOAD_EXTERNAL = 4,
/** File overwriting is allowed. This is for temp names, since
* the file is created by the same function that chooses its
* name. */
DOWNLOAD_OVERWRITE = 8
}; };
struct download { struct download {