2016-06-14 00:22:14 +00:00
|
|
|
/* radare - LGPL - Copyright 2007-2016 - pancake */
|
2009-02-05 21:08:46 +00:00
|
|
|
|
|
|
|
#include "r_types.h"
|
|
|
|
#include "r_util.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <unistd.h>
|
2011-03-13 20:00:46 +00:00
|
|
|
#include <fcntl.h>
|
2011-03-18 08:24:16 +00:00
|
|
|
#if __UNIX__
|
2010-11-17 20:15:34 +00:00
|
|
|
#include <sys/mman.h>
|
|
|
|
#endif
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2016-01-03 00:28:02 +00:00
|
|
|
R_API bool r_file_truncate (const char *filename, ut64 newsize) {
|
2014-04-29 16:10:35 +00:00
|
|
|
int fd;
|
2016-06-29 09:35:16 +00:00
|
|
|
if (r_file_is_directory (filename)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (!r_file_exists (filename) || !r_file_is_regular (filename)) {
|
|
|
|
return false;
|
|
|
|
}
|
2014-05-19 08:54:29 +00:00
|
|
|
#if __WINDOWS__
|
|
|
|
fd = r_sandbox_open (filename, O_RDWR, 0644);
|
|
|
|
#else
|
2014-04-29 16:10:35 +00:00
|
|
|
fd = r_sandbox_open (filename, O_RDWR|O_SYNC, 0644);
|
2014-05-19 08:54:29 +00:00
|
|
|
#endif
|
2016-06-29 09:35:16 +00:00
|
|
|
if (fd == -1) {
|
|
|
|
return false;
|
|
|
|
}
|
2014-04-29 16:10:35 +00:00
|
|
|
ftruncate (fd, newsize);
|
|
|
|
close (fd);
|
2016-06-29 09:35:16 +00:00
|
|
|
return true;
|
2014-04-29 16:10:35 +00:00
|
|
|
}
|
|
|
|
|
2014-12-12 12:59:39 +00:00
|
|
|
/*
|
|
|
|
Example:
|
|
|
|
str = r_file_basename ("home/inisider/Downloads/user32.dll");
|
2015-04-10 22:42:30 +00:00
|
|
|
// str == user32.dll
|
2014-12-12 12:59:39 +00:00
|
|
|
*/
|
2010-03-03 10:35:03 +00:00
|
|
|
R_API const char *r_file_basename (const char *path) {
|
2014-12-12 12:59:39 +00:00
|
|
|
const char *ptr = r_str_rchr (path, NULL, '/');
|
|
|
|
if (ptr) {
|
|
|
|
path = ptr + 1;
|
|
|
|
} else {
|
|
|
|
ptr = r_str_rchr (path, NULL, '\\');
|
|
|
|
if (ptr) path = ptr + 1;
|
|
|
|
}
|
2010-03-03 10:35:03 +00:00
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
2014-12-12 12:59:39 +00:00
|
|
|
/*
|
|
|
|
Example:
|
|
|
|
str = r_file_basename ("home/inisider/Downloads");
|
|
|
|
// str == "home/inisider/Downloads"
|
|
|
|
free (str);
|
|
|
|
*/
|
|
|
|
R_API char *r_file_dirname (const char *path) {
|
|
|
|
char *newpath = strdup (path);
|
|
|
|
char *ptr = (char*)r_str_rchr (newpath, NULL, '/');
|
|
|
|
if (ptr) {
|
|
|
|
*ptr = 0;
|
|
|
|
} else {
|
|
|
|
ptr = (char*)r_str_rchr (newpath, NULL, '\\');
|
|
|
|
if (ptr) *ptr = 0;
|
|
|
|
}
|
|
|
|
return newpath;
|
|
|
|
}
|
|
|
|
|
2016-01-03 00:28:02 +00:00
|
|
|
R_API bool r_file_is_regular(const char *str) {
|
2013-12-28 01:34:15 +00:00
|
|
|
struct stat buf = {0};
|
2016-06-29 09:35:16 +00:00
|
|
|
if (!str || !*str || stat (str, &buf) == -1) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return ((S_IFREG & buf.st_mode)==S_IFREG)? true: false;
|
2013-12-28 01:34:15 +00:00
|
|
|
}
|
|
|
|
|
2016-01-03 00:28:02 +00:00
|
|
|
R_API bool r_file_is_directory(const char *str) {
|
2013-02-08 10:42:46 +00:00
|
|
|
struct stat buf = {0};
|
2013-12-28 01:34:15 +00:00
|
|
|
if (!str||!*str)
|
2016-06-29 09:35:16 +00:00
|
|
|
return false;
|
2012-02-01 02:32:14 +00:00
|
|
|
if (stat (str, &buf)==-1)
|
2016-06-29 09:35:16 +00:00
|
|
|
return false;
|
2014-01-21 01:08:51 +00:00
|
|
|
if ((S_IFBLK & buf.st_mode) == S_IFBLK)
|
2016-06-29 09:35:16 +00:00
|
|
|
return false;
|
|
|
|
return (S_IFDIR==(S_IFDIR & buf.st_mode))? true: false;
|
2012-02-01 02:32:14 +00:00
|
|
|
}
|
|
|
|
|
2016-01-03 00:28:02 +00:00
|
|
|
R_API bool r_file_fexists(const char *fmt, ...) {
|
2013-06-08 23:09:47 +00:00
|
|
|
int ret;
|
|
|
|
char string[1024];
|
|
|
|
va_list ap;
|
|
|
|
va_start (ap, fmt);
|
|
|
|
vsnprintf (string, sizeof (string), fmt, ap);
|
|
|
|
ret = r_file_exists (string);
|
|
|
|
va_end (ap);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-01-03 00:28:02 +00:00
|
|
|
R_API bool r_file_exists(const char *str) {
|
2013-02-08 10:42:46 +00:00
|
|
|
struct stat buf = {0};
|
2013-01-02 23:47:58 +00:00
|
|
|
if (str && *str && stat (str, &buf)==-1)
|
2016-06-29 09:35:16 +00:00
|
|
|
return false;
|
|
|
|
return (S_ISREG (buf.st_mode))? true: false;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2016-06-09 20:23:39 +00:00
|
|
|
R_API long r_file_proc_size(FILE *fd) {
|
|
|
|
long size = 0;
|
|
|
|
while (fgetc (fd) != EOF) {
|
|
|
|
size++;
|
|
|
|
}
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
2014-09-20 13:53:29 +00:00
|
|
|
R_API ut64 r_file_size(const char *str) {
|
2013-02-08 10:42:46 +00:00
|
|
|
struct stat buf = {0};
|
2011-12-01 09:53:02 +00:00
|
|
|
if (stat (str, &buf)==-1)
|
|
|
|
return 0;
|
2014-09-20 13:53:29 +00:00
|
|
|
return (ut64)buf.st_size;
|
2011-12-01 09:53:02 +00:00
|
|
|
}
|
|
|
|
|
2015-06-12 09:49:58 +00:00
|
|
|
R_API int r_file_is_abspath(const char *file) {
|
|
|
|
return ((*file && file[1]==':') || *file == '/');
|
|
|
|
}
|
|
|
|
|
2010-11-17 20:15:34 +00:00
|
|
|
R_API char *r_file_abspath(const char *file) {
|
2015-11-18 12:03:35 +00:00
|
|
|
char *cwd, *ret = NULL;
|
|
|
|
if (!file || !strcmp (file, ".") || !strcmp (file, "./")) {
|
|
|
|
return r_sys_getdir ();
|
|
|
|
}
|
|
|
|
if (strstr (file, "://")) {
|
2015-08-28 02:19:57 +00:00
|
|
|
return strdup (file);
|
|
|
|
}
|
2015-11-18 12:03:35 +00:00
|
|
|
cwd = r_sys_getdir ();
|
2015-06-11 10:12:22 +00:00
|
|
|
if (!strncmp (file, "~/", 2) || !strncmp (file, "~\\", 2)) {
|
2016-05-15 22:59:29 +00:00
|
|
|
ret = r_str_home (file + 2);
|
2015-05-19 13:35:08 +00:00
|
|
|
} else {
|
2015-04-10 22:42:30 +00:00
|
|
|
#if __UNIX__ || __CYGWIN__
|
2015-05-19 13:35:08 +00:00
|
|
|
if (cwd && *file != '/')
|
2015-06-09 11:47:45 +00:00
|
|
|
ret = r_str_newf ("%s"R_SYS_DIR"%s", cwd, file);
|
2015-04-10 22:42:30 +00:00
|
|
|
#elif __WINDOWS__ && !__CYGWIN__
|
2015-06-12 09:49:58 +00:00
|
|
|
if (cwd && !strchr (file, ':')) {
|
2015-05-19 13:35:08 +00:00
|
|
|
ret = r_str_newf ("%s\\%s", cwd, file);
|
2015-06-12 09:49:58 +00:00
|
|
|
}
|
2010-02-20 05:40:02 +00:00
|
|
|
#endif
|
2015-05-19 13:35:08 +00:00
|
|
|
}
|
2011-09-04 00:34:54 +00:00
|
|
|
free (cwd);
|
2015-05-19 13:35:08 +00:00
|
|
|
if (!ret) ret = strdup (file);
|
|
|
|
#if __UNIX__
|
|
|
|
{
|
2016-06-06 15:30:07 +00:00
|
|
|
char *resolved_path = calloc(4096, 1); // TODO: use MAXPATH
|
|
|
|
char *abspath = realpath (ret, resolved_path);
|
2015-05-19 13:35:08 +00:00
|
|
|
if (abspath) {
|
|
|
|
free (ret);
|
|
|
|
ret = abspath;
|
Fix a handful of boring leaks (#5518)
Valgrinding to get exp. Testing with "r2 -Aqcq /bin/ls"
Before:
definitely lost: 22,735 bytes in 250 blocks
indirectly lost: 23,542 bytes in 605 blocks
possibly lost: 2,464 bytes in 7 blocks
still reachable: 3,876,216 bytes in 80,761 blocks
After:
definitely lost: 25,216 bytes in 58 blocks
indirectly lost: 24,830 bytes in 739 blocks
possibly lost: 0 bytes in 0 blocks
still reachable: 20,105 bytes in 34 blocks
The "goto beach" (named like that for consistency) change resulted in
freeing most of the "still reachable" stuff on quit, which also moved
stuff out of "possibly lost", so.. it looks like it's leaking more now.
Yay.
2016-08-15 22:45:33 +00:00
|
|
|
} else {
|
|
|
|
free (resolved_path);
|
2015-05-19 13:35:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return ret;
|
2010-02-20 05:40:02 +00:00
|
|
|
}
|
|
|
|
|
2010-03-03 10:35:03 +00:00
|
|
|
R_API char *r_file_path(const char *bin) {
|
2009-02-09 00:54:09 +00:00
|
|
|
char file[1024];
|
2015-03-22 21:41:46 +00:00
|
|
|
char *path_env;
|
2009-02-09 00:54:09 +00:00
|
|
|
char *path = NULL;
|
|
|
|
char *str, *ptr;
|
2015-03-22 21:41:46 +00:00
|
|
|
if (!bin) return NULL;
|
|
|
|
path_env = (char *)r_sys_getenv ("PATH");
|
2009-02-09 00:54:09 +00:00
|
|
|
if (path_env) {
|
2010-03-03 10:35:03 +00:00
|
|
|
str = path = strdup (path_env);
|
2009-02-09 00:54:09 +00:00
|
|
|
do {
|
2010-03-03 10:35:03 +00:00
|
|
|
ptr = strchr (str, ':');
|
2009-02-09 00:54:09 +00:00
|
|
|
if (ptr) {
|
2011-09-23 10:25:06 +00:00
|
|
|
*ptr = '\0';
|
2015-06-09 11:47:45 +00:00
|
|
|
snprintf (file, sizeof (file), "%s"R_SYS_DIR"%s", str, bin);
|
2012-09-06 06:59:13 +00:00
|
|
|
if (r_file_exists (file)) {
|
2010-03-03 10:35:03 +00:00
|
|
|
free (path);
|
2011-08-27 22:01:03 +00:00
|
|
|
free (path_env);
|
2010-03-03 10:35:03 +00:00
|
|
|
return strdup (file);
|
2009-02-09 00:54:09 +00:00
|
|
|
}
|
2011-09-23 10:25:06 +00:00
|
|
|
str = ptr + 1;
|
2009-02-09 00:54:09 +00:00
|
|
|
}
|
2010-03-03 10:35:03 +00:00
|
|
|
} while (ptr);
|
2011-08-27 22:01:03 +00:00
|
|
|
}
|
|
|
|
free (path_env);
|
2010-03-03 10:35:03 +00:00
|
|
|
free (path);
|
|
|
|
return strdup (bin);
|
2009-02-09 00:54:09 +00:00
|
|
|
}
|
|
|
|
|
2014-10-19 22:42:45 +00:00
|
|
|
R_API char *r_stdin_slurp (int *sz) {
|
|
|
|
#define BS 1024
|
|
|
|
#if __UNIX__
|
2015-01-14 01:53:34 +00:00
|
|
|
int i, ret, newfd;
|
|
|
|
char *buf;
|
2015-01-25 11:10:08 +00:00
|
|
|
if ((newfd = dup(0)) < 0)
|
2015-01-14 01:53:34 +00:00
|
|
|
return NULL;
|
|
|
|
buf = malloc (BS);
|
2014-10-19 22:42:45 +00:00
|
|
|
for (i=ret=0;;i+=ret) {
|
2015-02-19 23:58:12 +00:00
|
|
|
char *new = realloc (buf, i+BS);
|
|
|
|
if (!new) {
|
|
|
|
eprintf ("Cannot realloc to %d\n", i+BS);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
buf = new;
|
2014-10-19 22:42:45 +00:00
|
|
|
ret = read (0, buf+i, BS);
|
|
|
|
if (ret<1)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
buf[i] = 0;
|
|
|
|
dup2 (newfd, 0);
|
|
|
|
close (newfd);
|
|
|
|
if (sz)
|
|
|
|
*sz = i;
|
|
|
|
if (i==0) {
|
|
|
|
R_FREE (buf);
|
|
|
|
}
|
|
|
|
return buf;
|
|
|
|
#else
|
|
|
|
#warning TODO r_stdin_slurp
|
|
|
|
return NULL;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2014-09-20 12:43:18 +00:00
|
|
|
R_API char *r_file_slurp(const char *str, int *usz) {
|
2010-10-27 14:53:06 +00:00
|
|
|
size_t rsz;
|
|
|
|
char *ret;
|
|
|
|
FILE *fd;
|
2014-09-20 12:43:18 +00:00
|
|
|
long sz;
|
2012-09-06 06:59:13 +00:00
|
|
|
if (!r_file_exists (str))
|
2010-06-24 21:14:12 +00:00
|
|
|
return NULL;
|
2012-10-19 22:31:18 +00:00
|
|
|
fd = r_sandbox_fopen (str, "rb");
|
2016-06-14 00:22:14 +00:00
|
|
|
if (!fd) {
|
2010-10-27 14:53:06 +00:00
|
|
|
return NULL;
|
2016-06-14 00:22:14 +00:00
|
|
|
}
|
|
|
|
(void)fseek (fd, 0, SEEK_END);
|
2010-10-27 14:53:06 +00:00
|
|
|
sz = ftell (fd);
|
2016-06-14 00:22:14 +00:00
|
|
|
if (sz == 0) {
|
2016-06-09 20:23:39 +00:00
|
|
|
if (r_file_is_regular (str)) {
|
|
|
|
/* proc file */
|
|
|
|
fseek (fd, 0, SEEK_SET);
|
|
|
|
sz = r_file_proc_size (fd);
|
|
|
|
if (!sz) sz = -1;
|
|
|
|
} else {
|
|
|
|
sz = 65536;
|
|
|
|
}
|
|
|
|
}
|
2016-06-14 00:22:14 +00:00
|
|
|
if (sz < 0) {
|
2012-09-06 01:12:54 +00:00
|
|
|
fclose (fd);
|
|
|
|
return NULL;
|
|
|
|
}
|
2010-10-27 14:53:06 +00:00
|
|
|
fseek (fd, 0, SEEK_SET);
|
2016-06-14 00:22:14 +00:00
|
|
|
ret = (char *)calloc (sz + 1, 1);
|
2015-04-10 22:42:30 +00:00
|
|
|
if (!ret) {
|
|
|
|
fclose (fd);
|
|
|
|
return NULL;
|
|
|
|
}
|
2010-10-27 14:53:06 +00:00
|
|
|
rsz = fread (ret, 1, sz, fd);
|
2014-06-04 01:51:18 +00:00
|
|
|
if (rsz != sz) {
|
|
|
|
// eprintf ("r_file_slurp: fread: error\n");
|
|
|
|
sz = rsz;
|
|
|
|
}
|
2010-10-27 14:31:51 +00:00
|
|
|
fclose (fd);
|
2016-08-05 11:25:20 +00:00
|
|
|
ret[sz] = '\0';
|
|
|
|
if (usz) {
|
2016-08-16 12:22:26 +00:00
|
|
|
*usz = (int)sz;
|
2016-08-05 11:25:20 +00:00
|
|
|
}
|
2010-10-27 14:53:06 +00:00
|
|
|
return ret;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2014-08-10 16:24:00 +00:00
|
|
|
R_API ut8 *r_file_gzslurp(const char *str, int *outlen, int origonfail) {
|
2014-09-20 12:43:18 +00:00
|
|
|
int sz;
|
2014-08-10 16:24:00 +00:00
|
|
|
ut8 *in, *out;
|
2014-08-10 16:13:12 +00:00
|
|
|
if (outlen) *outlen = 0;
|
2014-08-10 16:24:00 +00:00
|
|
|
in = (ut8*)r_file_slurp (str, &sz);
|
2014-08-10 16:13:12 +00:00
|
|
|
if (!in) return NULL;
|
2015-04-03 01:20:04 +00:00
|
|
|
out = r_inflate (in, sz, NULL, outlen);
|
2014-08-10 16:24:00 +00:00
|
|
|
if (!out && origonfail) {
|
|
|
|
// if uncompression fails, return orig buffer ?
|
2016-06-14 00:22:14 +00:00
|
|
|
if (outlen) {
|
2014-08-10 16:24:00 +00:00
|
|
|
*outlen = sz;
|
2016-06-14 00:22:14 +00:00
|
|
|
}
|
2014-08-10 16:24:00 +00:00
|
|
|
in[sz] = 0;
|
|
|
|
return in;
|
|
|
|
}
|
2014-08-10 16:13:12 +00:00
|
|
|
free (in);
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
2010-03-03 10:35:03 +00:00
|
|
|
R_API ut8 *r_file_slurp_hexpairs(const char *str, int *usz) {
|
2009-09-17 12:02:44 +00:00
|
|
|
ut8 *ret;
|
|
|
|
long sz;
|
|
|
|
int c, bytes = 0;
|
2012-10-19 22:31:18 +00:00
|
|
|
FILE *fd = r_sandbox_fopen (str, "r");
|
2016-06-14 00:22:14 +00:00
|
|
|
if (!fd) {
|
2009-09-17 12:02:44 +00:00
|
|
|
return NULL;
|
2016-06-14 00:22:14 +00:00
|
|
|
}
|
|
|
|
(void)fseek (fd, 0, SEEK_END);
|
2010-03-03 10:35:03 +00:00
|
|
|
sz = ftell (fd);
|
2016-06-14 00:22:14 +00:00
|
|
|
(void)fseek (fd, 0, SEEK_SET);
|
2010-03-03 10:35:03 +00:00
|
|
|
ret = (ut8*)malloc ((sz>>1)+1);
|
2014-03-08 06:41:22 +00:00
|
|
|
if (!ret) {
|
|
|
|
fclose (fd);
|
2009-09-17 12:02:44 +00:00
|
|
|
return NULL;
|
2014-03-08 06:41:22 +00:00
|
|
|
}
|
2010-03-03 10:35:03 +00:00
|
|
|
for (;;) {
|
|
|
|
if (fscanf (fd, " #%*[^\n]") == 1)
|
2009-09-17 12:02:44 +00:00
|
|
|
continue;
|
2010-03-03 10:35:03 +00:00
|
|
|
if (fscanf (fd, "%02x", &c) == 1) {
|
2009-09-17 12:02:44 +00:00
|
|
|
ret[bytes++] = c;
|
|
|
|
continue;
|
2011-01-02 13:39:25 +00:00
|
|
|
}
|
2010-03-03 10:35:03 +00:00
|
|
|
if (feof (fd))
|
2009-04-15 18:24:19 +00:00
|
|
|
break;
|
2010-03-03 10:35:03 +00:00
|
|
|
free (ret);
|
2014-03-08 06:41:22 +00:00
|
|
|
fclose (fd);
|
2009-09-17 12:02:44 +00:00
|
|
|
return NULL;
|
2009-04-15 18:24:19 +00:00
|
|
|
}
|
2009-09-17 12:02:44 +00:00
|
|
|
|
|
|
|
ret[bytes] = '\0';
|
2010-03-03 10:35:03 +00:00
|
|
|
fclose (fd);
|
2010-11-16 17:19:51 +00:00
|
|
|
if (usz) *usz = bytes;
|
2009-09-17 12:02:44 +00:00
|
|
|
return ret;
|
2009-04-15 18:24:19 +00:00
|
|
|
}
|
|
|
|
|
2010-04-13 19:19:54 +00:00
|
|
|
R_API char *r_file_slurp_range(const char *str, ut64 off, int sz, int *osz) {
|
2010-04-12 09:46:15 +00:00
|
|
|
char *ret;
|
2014-03-08 06:41:22 +00:00
|
|
|
size_t read_items;
|
2012-10-19 22:31:18 +00:00
|
|
|
FILE *fd = r_sandbox_fopen (str, "rb");
|
2010-04-12 09:46:15 +00:00
|
|
|
if (fd == NULL)
|
|
|
|
return NULL;
|
2012-01-26 02:18:45 +00:00
|
|
|
// XXX handle out of bound reads (eof)
|
2014-03-08 06:41:22 +00:00
|
|
|
if (fseek (fd, off, SEEK_SET) < 0) {
|
|
|
|
fclose (fd);
|
|
|
|
return NULL;
|
|
|
|
}
|
2010-04-12 09:46:15 +00:00
|
|
|
ret = (char *)malloc (sz+1);
|
2010-04-12 00:22:52 +00:00
|
|
|
if (ret != NULL) {
|
2011-02-23 01:10:28 +00:00
|
|
|
if (osz)
|
|
|
|
*osz = (int)(size_t)fread (ret, 1, sz, fd);
|
2014-03-08 06:41:22 +00:00
|
|
|
else {
|
|
|
|
read_items = fread (ret, 1, sz, fd);
|
|
|
|
if (!read_items) {
|
|
|
|
fclose (fd);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
2010-04-12 00:22:52 +00:00
|
|
|
ret[sz] = '\0';
|
|
|
|
}
|
|
|
|
fclose (fd);
|
2010-04-12 09:46:15 +00:00
|
|
|
return ret;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2010-02-28 21:58:21 +00:00
|
|
|
R_API char *r_file_slurp_random_line(const char *file) {
|
2015-01-15 02:12:45 +00:00
|
|
|
int i = 0;
|
|
|
|
return r_file_slurp_random_line_count(file, &i);
|
|
|
|
}
|
|
|
|
|
|
|
|
R_API char *r_file_slurp_random_line_count(const char *file, int *line) {
|
|
|
|
/* Reservoir Sampling */
|
2012-09-26 08:01:43 +00:00
|
|
|
char *ptr = NULL, *str;
|
2015-01-15 02:12:45 +00:00
|
|
|
int sz, i, lines, selection = -1;
|
2009-02-05 21:08:46 +00:00
|
|
|
struct timeval tv;
|
2015-01-15 02:12:45 +00:00
|
|
|
int start = *line;
|
2012-09-26 08:01:43 +00:00
|
|
|
|
|
|
|
if ((str = r_file_slurp (file, &sz))) {
|
2010-03-03 10:35:03 +00:00
|
|
|
gettimeofday (&tv,NULL);
|
|
|
|
srand (getpid()+tv.tv_usec);
|
2015-01-15 02:12:45 +00:00
|
|
|
for (i=0; str[i]; i++) {
|
|
|
|
if (str[i]=='\n') {
|
|
|
|
if (rand() % (++(*line)) == 0) {
|
|
|
|
selection = (*line - 1); /* The line we want. */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((selection < start) || (selection == -1)) {
|
|
|
|
free (str);
|
|
|
|
return NULL;
|
|
|
|
} else {
|
|
|
|
lines = selection - start;
|
|
|
|
}
|
2012-09-26 08:01:43 +00:00
|
|
|
if (lines>0) {
|
|
|
|
for (i=0; str[i] && lines; i++)
|
|
|
|
if (str[i]=='\n')
|
|
|
|
lines--;
|
|
|
|
ptr = str+i;
|
|
|
|
for (i=0; ptr[i]; i++)
|
|
|
|
if (ptr[i]=='\n') {
|
|
|
|
ptr[i]='\0';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
ptr = strdup (ptr);
|
|
|
|
}
|
2010-03-03 10:35:03 +00:00
|
|
|
free (str);
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
2010-02-28 21:58:21 +00:00
|
|
|
R_API char *r_file_slurp_line(const char *file, int line, int context) {
|
2009-03-22 04:37:46 +00:00
|
|
|
int i, lines = 0;
|
2014-09-20 12:43:18 +00:00
|
|
|
int sz;
|
2010-04-20 17:32:04 +00:00
|
|
|
char *ptr = NULL, *str = r_file_slurp (file, &sz);
|
2009-03-22 04:37:46 +00:00
|
|
|
// TODO: Implement context
|
|
|
|
if (str) {
|
2011-09-23 10:25:06 +00:00
|
|
|
for (i=0; str[i]; i++)
|
2009-03-22 04:37:46 +00:00
|
|
|
if (str[i]=='\n')
|
|
|
|
lines++;
|
2010-02-28 21:58:21 +00:00
|
|
|
if (line > lines) {
|
|
|
|
free (str);
|
|
|
|
return NULL;
|
|
|
|
}
|
2014-04-21 15:17:52 +00:00
|
|
|
lines = line - 1;
|
2011-07-05 23:29:18 +00:00
|
|
|
for (i=0; str[i]&&lines; i++)
|
2009-03-22 04:37:46 +00:00
|
|
|
if (str[i]=='\n')
|
|
|
|
lines--;
|
|
|
|
ptr = str+i;
|
2016-06-29 09:35:16 +00:00
|
|
|
for (i=0; ptr[i]; i++) {
|
2010-02-28 21:58:21 +00:00
|
|
|
if (ptr[i]=='\n') {
|
|
|
|
ptr[i]='\0';
|
|
|
|
break;
|
|
|
|
}
|
2016-06-29 09:35:16 +00:00
|
|
|
}
|
2010-02-28 21:58:21 +00:00
|
|
|
ptr = strdup (ptr);
|
|
|
|
free (str);
|
2009-03-22 04:37:46 +00:00
|
|
|
}
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
2013-01-02 23:47:58 +00:00
|
|
|
R_API char *r_file_root(const char *root, const char *path) {
|
|
|
|
char *ret, *s = r_str_replace (strdup (path), "..", "", 1);
|
2013-01-04 09:16:41 +00:00
|
|
|
// XXX ugly hack
|
|
|
|
while (strstr (s, "..")) s = r_str_replace (s, "..", "", 1);
|
|
|
|
while (strstr (s, "./")) s = r_str_replace (s, "./", "", 1);
|
|
|
|
while (strstr (s, "//")) s = r_str_replace (s, "//", "", 1);
|
2015-06-09 11:47:45 +00:00
|
|
|
ret = r_str_concat (strdup (root), R_SYS_DIR);
|
2013-01-02 23:47:58 +00:00
|
|
|
ret = r_str_concat (ret, s);
|
|
|
|
free (s);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-01-03 00:28:02 +00:00
|
|
|
R_API bool r_file_dump(const char *file, const ut8 *buf, int len, int append) {
|
2013-08-28 01:06:10 +00:00
|
|
|
FILE *fd;
|
2016-05-21 13:11:16 +00:00
|
|
|
if (!file || !*file || !buf || len < 0) {
|
2015-07-08 17:13:30 +00:00
|
|
|
eprintf ("r_file_dump file: %s buf: %p\n", file, buf);
|
2016-05-21 13:11:16 +00:00
|
|
|
return false;
|
2015-04-03 02:04:46 +00:00
|
|
|
}
|
|
|
|
if (append) {
|
|
|
|
fd = r_sandbox_fopen (file, "awb");
|
|
|
|
} else {
|
|
|
|
r_sys_truncate (file, 0);
|
|
|
|
fd = r_sandbox_fopen (file, "wb");
|
|
|
|
}
|
2009-02-05 21:08:46 +00:00
|
|
|
if (fd == NULL) {
|
2010-10-27 14:31:51 +00:00
|
|
|
eprintf ("Cannot open '%s' for writing\n", file);
|
2016-05-21 13:11:16 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (len < 0) {
|
|
|
|
len = strlen ((const char *)buf);
|
|
|
|
}
|
|
|
|
if (fwrite (buf, len, 1, fd) != 1) {
|
|
|
|
r_sys_perror ("r_file_dump: fwrite: error\n");
|
|
|
|
fclose (fd);
|
|
|
|
return false;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
2010-10-27 14:31:51 +00:00
|
|
|
fclose (fd);
|
2016-05-21 13:11:16 +00:00
|
|
|
return true;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2016-01-03 00:28:02 +00:00
|
|
|
R_API bool r_file_rm(const char *file) {
|
2016-06-29 09:35:16 +00:00
|
|
|
if (r_sandbox_enable (0)) {
|
|
|
|
return false;
|
|
|
|
}
|
2015-01-21 23:30:19 +00:00
|
|
|
if (r_file_is_directory (file)) {
|
2011-01-02 13:39:25 +00:00
|
|
|
#if __WINDOWS__
|
2016-06-29 09:35:16 +00:00
|
|
|
return !RemoveDirectory (file);
|
2011-01-02 13:39:25 +00:00
|
|
|
#else
|
2016-06-29 09:35:16 +00:00
|
|
|
return !rmdir (file);
|
2015-01-21 23:30:19 +00:00
|
|
|
#endif
|
|
|
|
} else {
|
|
|
|
#if __WINDOWS__
|
2016-06-29 09:35:16 +00:00
|
|
|
return !DeleteFile (file);
|
2015-01-21 23:30:19 +00:00
|
|
|
#else
|
2016-06-29 09:35:16 +00:00
|
|
|
return !unlink (file);
|
2011-01-02 13:39:25 +00:00
|
|
|
#endif
|
2014-03-08 06:41:22 +00:00
|
|
|
}
|
2013-04-18 07:39:37 +00:00
|
|
|
}
|
|
|
|
|
2016-01-03 00:28:02 +00:00
|
|
|
R_API char *r_file_readlink(const char *path) {
|
|
|
|
if (!r_sandbox_enable (0)) {
|
|
|
|
#if __UNIX__
|
|
|
|
int ret;
|
2016-06-14 00:22:14 +00:00
|
|
|
char pathbuf[4096] = {0};
|
|
|
|
strncpy (pathbuf, path, sizeof (pathbuf) - 1);
|
2016-01-03 00:28:02 +00:00
|
|
|
repeat:
|
|
|
|
ret = readlink (path, pathbuf, sizeof (pathbuf)-1);
|
|
|
|
if (ret != -1) {
|
|
|
|
pathbuf[ret] = 0;
|
|
|
|
path = pathbuf;
|
|
|
|
goto repeat;
|
|
|
|
}
|
|
|
|
return strdup (pathbuf);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-03-12 00:50:55 +00:00
|
|
|
R_API int r_file_mmap_write(const char *file, ut64 addr, const ut8 *buf, int len) {
|
|
|
|
#if __WINDOWS__
|
2015-01-22 01:22:29 +00:00
|
|
|
HANDLE fh;
|
2016-02-16 18:21:40 +00:00
|
|
|
DWORD written = 0;
|
2013-03-12 12:24:48 +00:00
|
|
|
if (r_sandbox_enable (0)) return -1;
|
2014-09-15 01:32:43 +00:00
|
|
|
fh = CreateFile (file, GENERIC_READ|GENERIC_WRITE,
|
|
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
|
|
NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
2013-03-12 12:24:48 +00:00
|
|
|
if (fh == INVALID_HANDLE_VALUE) {
|
2014-09-15 01:32:43 +00:00
|
|
|
r_sys_perror ("r_file_mmap_write: CreateFile");
|
2013-03-12 12:24:48 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2014-09-23 08:59:26 +00:00
|
|
|
// no need to overengineer the file write more
|
|
|
|
#if 0
|
2015-01-22 01:22:29 +00:00
|
|
|
HANDLE fm;
|
2013-04-30 23:34:54 +00:00
|
|
|
fm = CreateFileMapping (fh, NULL,
|
|
|
|
PAGE_READWRITE, 0, 0, NULL);
|
2013-03-12 12:24:48 +00:00
|
|
|
if (fm == NULL) {
|
2014-09-15 01:32:43 +00:00
|
|
|
r_sys_perror ("r_file_mmap_write: CreateFileMapping");
|
2013-03-12 12:24:48 +00:00
|
|
|
CloseHandle (fh);
|
|
|
|
return -1;
|
|
|
|
}
|
2013-04-30 23:34:54 +00:00
|
|
|
|
2013-03-12 12:24:48 +00:00
|
|
|
if (fm != INVALID_HANDLE_VALUE) {
|
2014-09-23 08:59:26 +00:00
|
|
|
MEMORY_BASIC_INFORMATION info;
|
2013-04-30 23:34:54 +00:00
|
|
|
ut8 *obuf = MapViewOfFile (fm,
|
2014-09-15 01:32:43 +00:00
|
|
|
FILE_MAP_WRITE,
|
2014-09-23 08:59:26 +00:00
|
|
|
0,0,
|
|
|
|
0);
|
|
|
|
VirtualQuery (obuf, &info, sizeof(info);
|
|
|
|
memcpy (obuf+addr, buf, len);
|
2013-03-12 12:24:48 +00:00
|
|
|
UnmapViewOfFile (obuf);
|
|
|
|
}
|
|
|
|
CloseHandle (fm);
|
2014-09-23 08:59:26 +00:00
|
|
|
#else
|
|
|
|
SetFilePointer (fh, addr, NULL, FILE_BEGIN);
|
2016-02-16 18:21:40 +00:00
|
|
|
if (!WriteFile (fh, buf, len, &written, NULL)) {
|
2014-09-23 08:59:26 +00:00
|
|
|
r_sys_perror ("WriteFile");
|
|
|
|
len = -1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
CloseHandle (fh);
|
2013-08-26 23:18:42 +00:00
|
|
|
return len;
|
2013-03-12 12:24:48 +00:00
|
|
|
#elif __UNIX__
|
|
|
|
int fd = r_sandbox_open (file, O_RDWR|O_SYNC, 0644);
|
2016-02-16 23:38:54 +00:00
|
|
|
const int pagesize = getpagesize ();
|
|
|
|
int mmlen = len + pagesize;
|
|
|
|
int rest = addr % pagesize;
|
2013-03-12 00:50:55 +00:00
|
|
|
ut8 *mmap_buf;
|
|
|
|
if (fd == -1) return -1;
|
2016-02-16 23:38:54 +00:00
|
|
|
if ((st64)addr < 0) return -1;
|
2013-03-12 00:50:55 +00:00
|
|
|
mmap_buf = mmap (NULL, mmlen*2, PROT_READ|PROT_WRITE,
|
2016-02-16 23:38:54 +00:00
|
|
|
MAP_SHARED, fd, (off_t)addr - rest);
|
2013-03-12 00:50:55 +00:00
|
|
|
if (((int)(size_t)mmap_buf)==-1)
|
|
|
|
return -1;
|
|
|
|
memcpy (mmap_buf+rest, buf, len);
|
|
|
|
munmap (mmap_buf, mmlen*2);
|
|
|
|
close (fd);
|
|
|
|
return len;
|
2013-03-12 12:24:48 +00:00
|
|
|
#else
|
|
|
|
return -1;
|
2013-03-12 00:50:55 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
R_API int r_file_mmap_read (const char *file, ut64 addr, ut8 *buf, int len) {
|
|
|
|
#if __WINDOWS__
|
2013-03-12 12:24:48 +00:00
|
|
|
HANDLE fm, fh;
|
2013-04-30 23:34:54 +00:00
|
|
|
|
2013-03-12 12:24:48 +00:00
|
|
|
if (r_sandbox_enable (0)) return -1;
|
2013-04-30 23:34:54 +00:00
|
|
|
fh = CreateFile (file, GENERIC_READ,
|
2013-03-12 12:24:48 +00:00
|
|
|
FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
|
2013-04-30 23:34:54 +00:00
|
|
|
|
2013-03-12 12:24:48 +00:00
|
|
|
if (fh == INVALID_HANDLE_VALUE) {
|
2016-05-12 16:11:59 +00:00
|
|
|
r_sys_perror ("CreateFile");
|
2013-03-12 12:24:48 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2013-04-30 23:34:54 +00:00
|
|
|
|
|
|
|
fm = CreateFileMapping (fh, NULL,
|
|
|
|
PAGE_READONLY, 0, 0, NULL);
|
|
|
|
|
2013-03-12 12:24:48 +00:00
|
|
|
if (fm != INVALID_HANDLE_VALUE) {
|
2013-04-30 23:34:54 +00:00
|
|
|
ut8 *obuf = MapViewOfFile (fm,
|
|
|
|
FILE_MAP_READ,
|
|
|
|
0, 0, len);
|
2013-03-12 12:24:48 +00:00
|
|
|
memcpy (obuf, buf, len);
|
|
|
|
UnmapViewOfFile (obuf);
|
2014-09-15 01:32:43 +00:00
|
|
|
} else {
|
2016-05-12 16:11:59 +00:00
|
|
|
r_sys_perror ("CreateFileMapping");
|
2014-09-15 01:32:43 +00:00
|
|
|
CloseHandle (fh);
|
|
|
|
return -1;
|
2013-03-12 12:24:48 +00:00
|
|
|
}
|
|
|
|
CloseHandle (fh);
|
|
|
|
CloseHandle (fm);
|
2014-09-15 01:32:43 +00:00
|
|
|
return len;
|
2013-03-12 12:24:48 +00:00
|
|
|
#elif __UNIX__
|
2013-03-12 00:50:55 +00:00
|
|
|
int fd = r_sandbox_open (file, O_RDONLY, 0644);
|
|
|
|
const int pagesize = 4096;
|
|
|
|
int mmlen = len+pagesize;
|
|
|
|
int rest = addr%pagesize;
|
|
|
|
ut8 *mmap_buf;
|
|
|
|
if (fd == -1) return -1;
|
|
|
|
mmap_buf = mmap (NULL, mmlen*2, PROT_READ,
|
|
|
|
MAP_SHARED, fd, (off_t)addr-rest);
|
|
|
|
if (((int)(size_t)mmap_buf)==-1)
|
|
|
|
return -1;
|
|
|
|
memcpy (buf, mmap_buf+rest, len);
|
|
|
|
munmap (mmap_buf, mmlen*2);
|
|
|
|
close (fd);
|
|
|
|
return len;
|
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-11-17 20:15:34 +00:00
|
|
|
#if __UNIX__
|
2014-04-29 16:10:35 +00:00
|
|
|
static RMmap *r_file_mmap_unix (RMmap *m, int fd) {
|
|
|
|
ut8 empty = m->len == 0;
|
|
|
|
m->buf = mmap (NULL, (empty?1024:m->len) ,
|
|
|
|
m->rw?PROT_READ|PROT_WRITE:PROT_READ,
|
|
|
|
MAP_SHARED, fd, (off_t)m->base);
|
2013-03-12 12:24:48 +00:00
|
|
|
if (m->buf == MAP_FAILED) {
|
|
|
|
free (m);
|
|
|
|
m = NULL;
|
|
|
|
}
|
2014-04-29 16:10:35 +00:00
|
|
|
return m;
|
|
|
|
}
|
2011-01-02 13:39:25 +00:00
|
|
|
#elif __WINDOWS__
|
2014-05-19 08:54:29 +00:00
|
|
|
static RMmap *r_file_mmap_windows (RMmap *m, const char *file) {
|
2014-09-15 01:32:43 +00:00
|
|
|
m->fh = CreateFile (file, GENERIC_READ | (m->rw?GENERIC_WRITE:0),
|
|
|
|
FILE_SHARE_READ|(m->rw?FILE_SHARE_WRITE:0), NULL,
|
|
|
|
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
2013-03-12 12:24:48 +00:00
|
|
|
if (m->fh == INVALID_HANDLE_VALUE) {
|
2016-05-12 16:11:59 +00:00
|
|
|
r_sys_perror ("CreateFile");
|
2013-03-12 12:24:48 +00:00
|
|
|
free (m);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
m->fm = CreateFileMapping (m->fh, NULL,
|
2014-09-15 01:32:43 +00:00
|
|
|
PAGE_READONLY, 0, 0, NULL);
|
|
|
|
//m->rw?PAGE_READWRITE:PAGE_READONLY, 0, 0, NULL);
|
2013-03-12 12:24:48 +00:00
|
|
|
if (m->fm != INVALID_HANDLE_VALUE) {
|
2014-09-15 01:32:43 +00:00
|
|
|
m->buf = MapViewOfFile (m->fm,
|
|
|
|
// m->rw?(FILE_MAP_READ|FILE_MAP_WRITE):FILE_MAP_READ,
|
|
|
|
FILE_MAP_COPY,
|
2014-04-29 16:10:35 +00:00
|
|
|
UT32_HI (m->base), UT32_LO (m->base), 0);
|
2013-03-12 12:24:48 +00:00
|
|
|
} else {
|
2016-05-12 16:11:59 +00:00
|
|
|
r_sys_perror ("CreateFileMapping");
|
2013-03-12 12:24:48 +00:00
|
|
|
CloseHandle (m->fh);
|
|
|
|
free (m);
|
|
|
|
m = NULL;
|
|
|
|
}
|
2014-04-29 16:10:35 +00:00
|
|
|
return m;
|
|
|
|
}
|
2010-11-17 20:15:34 +00:00
|
|
|
#else
|
2014-04-29 16:10:35 +00:00
|
|
|
static RMmap *r_file_mmap_other (RMmap *m) {
|
|
|
|
ut8 empty = m->len == 0;
|
|
|
|
m->buf = malloc ((empty?1024:m->len));
|
|
|
|
if (!empty && m->buf) {
|
|
|
|
lseek (m->fd, (off_t)0, SEEK_SET);
|
|
|
|
read (m->fd, m->buf, m->len);
|
2013-03-12 12:24:48 +00:00
|
|
|
} else {
|
|
|
|
free (m);
|
|
|
|
m = NULL;
|
2010-11-17 20:15:34 +00:00
|
|
|
}
|
|
|
|
return m;
|
|
|
|
}
|
2014-04-29 16:10:35 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
// TODO: add rwx support?
|
2016-01-03 00:28:02 +00:00
|
|
|
R_API RMmap *r_file_mmap (const char *file, bool rw, ut64 base) {
|
2014-04-29 16:10:35 +00:00
|
|
|
RMmap *m = NULL;
|
|
|
|
int fd = -1;
|
|
|
|
if (!rw && !r_file_exists (file)) return m;
|
|
|
|
fd = r_sandbox_open (file, rw? O_RDWR: O_RDONLY, 0644);
|
|
|
|
if (fd == -1 && !rw) {
|
|
|
|
eprintf ("r_file_mmap: file does not exis.\n");
|
|
|
|
//m->buf = malloc (m->len);
|
|
|
|
return m;
|
|
|
|
}
|
|
|
|
m = R_NEW (RMmap);
|
|
|
|
if (!m) {
|
2014-05-05 03:08:46 +00:00
|
|
|
if (fd != -1) close (fd);
|
2014-04-29 16:10:35 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
m->base = base;
|
|
|
|
m->rw = rw;
|
|
|
|
m->fd = fd;
|
2014-09-20 12:43:18 +00:00
|
|
|
m->len = fd != -1? lseek (fd, (off_t)0, SEEK_END) : 0;
|
2014-04-29 16:10:35 +00:00
|
|
|
|
|
|
|
if (m->fd == -1) {
|
|
|
|
return m;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m->len == (off_t)-1) {
|
|
|
|
close (fd);
|
|
|
|
R_FREE (m);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
#if __UNIX__
|
|
|
|
return r_file_mmap_unix (m, fd);
|
|
|
|
#elif __WINDOWS__
|
|
|
|
close (fd);
|
|
|
|
m->fd = -1;
|
2014-05-19 08:54:29 +00:00
|
|
|
return r_file_mmap_windows (m, file);
|
2014-04-29 16:10:35 +00:00
|
|
|
#else
|
|
|
|
return r_file_mmap_other (m);
|
|
|
|
#endif
|
|
|
|
}
|
2010-11-17 20:15:34 +00:00
|
|
|
|
|
|
|
R_API void r_file_mmap_free (RMmap *m) {
|
2012-08-04 21:48:06 +00:00
|
|
|
if (!m) return;
|
2015-07-22 22:56:22 +00:00
|
|
|
#if __WINDOWS__
|
|
|
|
if (m->fm != INVALID_HANDLE_VALUE)
|
|
|
|
CloseHandle (m->fm);
|
|
|
|
if (m->fh != INVALID_HANDLE_VALUE)
|
|
|
|
CloseHandle (m->fh);
|
2015-07-24 23:57:46 +00:00
|
|
|
if (m->buf)
|
|
|
|
UnmapViewOfFile (m->buf);
|
2015-07-22 22:56:22 +00:00
|
|
|
#endif
|
2014-04-29 16:10:35 +00:00
|
|
|
if (m->fd == -1) {
|
|
|
|
free (m);
|
|
|
|
return;
|
|
|
|
}
|
2010-11-17 20:15:34 +00:00
|
|
|
#if __UNIX__
|
|
|
|
munmap (m->buf, m->len);
|
|
|
|
#endif
|
|
|
|
close (m->fd);
|
|
|
|
free (m);
|
|
|
|
}
|
2011-03-18 08:24:16 +00:00
|
|
|
|
2011-05-22 00:45:59 +00:00
|
|
|
R_API char *r_file_temp (const char *prefix) {
|
2011-07-05 23:29:18 +00:00
|
|
|
int namesz;
|
|
|
|
char *name;
|
2011-08-27 22:01:03 +00:00
|
|
|
char *path = r_file_tmpdir ();
|
2011-07-05 23:29:18 +00:00
|
|
|
namesz = strlen (prefix) + strlen (path) + 32;
|
|
|
|
name = malloc (namesz);
|
|
|
|
snprintf (name, namesz, "%s/%s.%"PFMT64x, path, prefix, r_sys_now ());
|
2011-08-27 22:01:03 +00:00
|
|
|
free (path);
|
2011-05-22 00:45:59 +00:00
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
2011-03-18 08:24:16 +00:00
|
|
|
R_API int r_file_mkstemp (const char *prefix, char **oname) {
|
|
|
|
int h;
|
2011-08-27 22:01:03 +00:00
|
|
|
char *path = r_file_tmpdir ();
|
2012-01-26 02:18:45 +00:00
|
|
|
char name[1024];
|
2011-03-18 08:24:16 +00:00
|
|
|
#if __WINDOWS__
|
|
|
|
if (GetTempFileName (path, prefix, 0, name))
|
2012-10-19 22:31:18 +00:00
|
|
|
h = r_sandbox_open (name, O_RDWR|O_EXCL|O_BINARY, 0644);
|
2011-03-18 08:24:16 +00:00
|
|
|
else h = -1;
|
|
|
|
#else
|
2014-06-25 02:19:23 +00:00
|
|
|
mode_t mask;
|
2012-09-06 10:47:32 +00:00
|
|
|
snprintf (name, sizeof (name), "%s/%sXXXXXX", path, prefix);
|
2014-03-08 20:01:04 +00:00
|
|
|
mask = umask(S_IWGRP | S_IWOTH);
|
2013-09-03 22:35:48 +00:00
|
|
|
h = mkstemp (name);
|
2014-03-08 06:41:22 +00:00
|
|
|
umask(mask);
|
2011-03-18 08:24:16 +00:00
|
|
|
#endif
|
2013-09-03 22:35:48 +00:00
|
|
|
if (oname) *oname = (h!=-1)? strdup (name): NULL;
|
2011-08-27 22:01:03 +00:00
|
|
|
free (path);
|
2011-03-18 08:24:16 +00:00
|
|
|
return h;
|
|
|
|
}
|
2011-05-03 17:36:06 +00:00
|
|
|
|
2011-08-27 22:01:03 +00:00
|
|
|
R_API char *r_file_tmpdir() {
|
2011-05-03 17:36:06 +00:00
|
|
|
#if __WINDOWS__
|
2011-08-27 22:01:03 +00:00
|
|
|
char *path = r_sys_getenv ("TEMP");
|
|
|
|
if (!path) path = strdup ("C:\\WINDOWS\\Temp\\");
|
2012-09-06 10:47:32 +00:00
|
|
|
#elif __ANDROID__
|
2015-04-22 02:50:37 +00:00
|
|
|
char *path = strdup ("/data/data/org.radare2.installer/radare2/tmp");
|
2011-05-03 17:36:06 +00:00
|
|
|
#else
|
2011-08-27 22:01:03 +00:00
|
|
|
char *path = r_sys_getenv ("TMPDIR");
|
2013-09-05 03:10:57 +00:00
|
|
|
if (path && !*path) {
|
|
|
|
free (path);
|
|
|
|
path = NULL;
|
|
|
|
}
|
2011-08-27 22:01:03 +00:00
|
|
|
if (!path) path = strdup ("/tmp");
|
2011-05-03 17:36:06 +00:00
|
|
|
#endif
|
2012-09-06 23:48:09 +00:00
|
|
|
if (!r_file_is_directory (path)) {
|
2012-09-06 10:47:32 +00:00
|
|
|
eprintf ("Cannot find temporary directory '%s'\n", path);
|
|
|
|
}
|
2011-05-03 17:36:06 +00:00
|
|
|
return path;
|
|
|
|
}
|
2011-07-25 21:20:49 +00:00
|
|
|
|