2017-02-03 09:47:36 +00:00
|
|
|
/* radare - LGPL - Copyright 2007-2017 - pancake */
|
2009-02-05 21:08:46 +00:00
|
|
|
|
|
|
|
#include "r_types.h"
|
|
|
|
#include "r_util.h"
|
|
|
|
#include <stdio.h>
|
2017-05-09 21:53:20 +00:00
|
|
|
#include <sys/time.h>
|
2009-02-05 21:08:46 +00:00
|
|
|
#include <time.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
2017-05-09 21:53:20 +00:00
|
|
|
#include <unistd.h>
|
2011-03-13 20:00:46 +00:00
|
|
|
#include <fcntl.h>
|
2017-07-16 08:13:29 +00:00
|
|
|
#include <r_lib.h>
|
2011-03-18 08:24:16 +00:00
|
|
|
#if __UNIX__
|
2010-11-17 20:15:34 +00:00
|
|
|
#include <sys/mman.h>
|
|
|
|
#endif
|
2017-02-03 09:47:36 +00:00
|
|
|
#if __APPLE__
|
|
|
|
#include <copyfile.h>
|
|
|
|
#endif
|
2017-05-09 21:53:20 +00:00
|
|
|
#if _MSC_VER
|
|
|
|
#include <process.h>
|
|
|
|
#endif
|
2017-07-10 09:20:03 +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
|
2016-10-17 21:58:39 +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;
|
|
|
|
}
|
2017-05-09 12:25:57 +00:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
_chsize (fd, newsize);
|
|
|
|
#else
|
2014-04-29 16:10:35 +00:00
|
|
|
ftruncate (fd, newsize);
|
2017-05-09 12:25:57 +00:00
|
|
|
#endif
|
2014-04-29 16:10:35 +00:00
|
|
|
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 {
|
2016-10-17 21:58:39 +00:00
|
|
|
if ((ptr = r_str_rchr (path, NULL, '\\'))) {
|
|
|
|
path = ptr + 1;
|
|
|
|
}
|
2014-12-12 12:59:39 +00:00
|
|
|
}
|
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) {
|
2016-10-26 21:22:04 +00:00
|
|
|
if (!path) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2014-12-12 12:59:39 +00:00
|
|
|
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;
|
|
|
|
}
|
2016-10-02 00:05:23 +00:00
|
|
|
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};
|
2016-10-17 21:58:39 +00:00
|
|
|
if (!str || !*str) {
|
2016-06-29 09:35:16 +00:00
|
|
|
return false;
|
2016-10-02 00:05:23 +00:00
|
|
|
}
|
|
|
|
if (stat (str, &buf) == -1) {
|
2016-06-29 09:35:16 +00:00
|
|
|
return false;
|
2016-10-02 00:05:23 +00:00
|
|
|
}
|
2017-05-09 12:25:57 +00:00
|
|
|
#ifdef S_IFBLK
|
2016-10-02 00:05:23 +00:00
|
|
|
if ((S_IFBLK & buf.st_mode) == S_IFBLK) {
|
2016-06-29 09:35:16 +00:00
|
|
|
return false;
|
2016-10-02 00:05:23 +00:00
|
|
|
}
|
2017-05-09 12:25:57 +00:00
|
|
|
#endif
|
2016-10-02 00:05:23 +00:00
|
|
|
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};
|
2016-10-20 13:02:25 +00:00
|
|
|
if (!str || !*str) {
|
|
|
|
return false;
|
|
|
|
}
|
2017-07-20 12:49:45 +00:00
|
|
|
if (strncmp (str, "/usr/bin", 8)) {
|
|
|
|
if (str && !r_sandbox_check_path (str)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2017-05-09 12:25:57 +00:00
|
|
|
#ifdef _MSC_VER
|
2017-05-09 21:53:20 +00:00
|
|
|
WIN32_FIND_DATAA FindFileData;
|
|
|
|
HANDLE handle = FindFirstFileA (str, &FindFileData);
|
2017-05-09 12:25:57 +00:00
|
|
|
int found = handle != INVALID_HANDLE_VALUE;
|
|
|
|
if (found) {
|
|
|
|
FindClose (handle);
|
|
|
|
}
|
|
|
|
return found > 0;
|
|
|
|
#else
|
2016-10-20 13:02:25 +00:00
|
|
|
if (stat (str, &buf) == -1) {
|
2016-06-29 09:35:16 +00:00
|
|
|
return false;
|
2016-10-02 00:05:23 +00:00
|
|
|
}
|
2016-06-29 09:35:16 +00:00
|
|
|
return (S_ISREG (buf.st_mode))? true: false;
|
2017-05-09 12:25:57 +00:00
|
|
|
#endif
|
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};
|
2016-10-02 00:05:23 +00:00
|
|
|
if (stat (str, &buf) == -1) {
|
2011-12-01 09:53:02 +00:00
|
|
|
return 0;
|
2016-10-02 00:05:23 +00:00
|
|
|
}
|
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__
|
2017-07-15 13:54:55 +00:00
|
|
|
// Network path
|
|
|
|
if (!strncmp (file, "\\\\", 2)) {
|
|
|
|
return strdup (file);
|
|
|
|
}
|
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);
|
2016-10-02 00:05:23 +00:00
|
|
|
if (!ret) {
|
|
|
|
ret = strdup (file);
|
|
|
|
}
|
2015-05-19 13:35:08 +00:00
|
|
|
#if __UNIX__
|
2017-07-10 09:20:03 +00:00
|
|
|
char *abspath = realpath (ret, NULL);
|
|
|
|
if (abspath) {
|
|
|
|
free (ret);
|
|
|
|
ret = abspath;
|
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;
|
2016-09-15 10:52:50 +00:00
|
|
|
if (!bin) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (!strncmp (bin, "./", 2)) {
|
|
|
|
if (r_file_exists (bin)) {
|
|
|
|
return r_file_abspath (bin);
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
2015-03-22 21:41:46 +00:00
|
|
|
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;
|
2016-10-17 21:58:39 +00:00
|
|
|
if ((newfd = dup (0)) < 0) {
|
2015-01-14 01:53:34 +00:00
|
|
|
return NULL;
|
2016-10-02 00:05:23 +00:00
|
|
|
}
|
2015-01-14 01:53:34 +00:00
|
|
|
buf = malloc (BS);
|
2017-07-10 07:52:00 +00:00
|
|
|
if (!buf) {
|
2016-10-02 00:05:23 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
for (i = ret = 0; ; i += ret) {
|
|
|
|
char *new = realloc (buf, i + BS);
|
2015-02-19 23:58:12 +00:00
|
|
|
if (!new) {
|
|
|
|
eprintf ("Cannot realloc to %d\n", i+BS);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
buf = new;
|
2016-10-02 00:05:23 +00:00
|
|
|
ret = read (0, buf + i, BS);
|
|
|
|
if (ret < 1) {
|
2014-10-19 22:42:45 +00:00
|
|
|
break;
|
2016-10-02 00:05:23 +00:00
|
|
|
}
|
2014-10-19 22:42:45 +00:00
|
|
|
}
|
|
|
|
buf[i] = 0;
|
|
|
|
dup2 (newfd, 0);
|
|
|
|
close (newfd);
|
2016-10-02 00:05:23 +00:00
|
|
|
if (sz) {
|
2014-10-19 22:42:45 +00:00
|
|
|
*sz = i;
|
2016-10-02 00:05:23 +00:00
|
|
|
}
|
|
|
|
if (!i) {
|
2014-10-19 22:42:45 +00:00
|
|
|
R_FREE (buf);
|
|
|
|
}
|
|
|
|
return buf;
|
|
|
|
#else
|
2017-05-09 21:53:20 +00:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
#pragma message (" TODO r_stdin_slurp")
|
|
|
|
#else
|
|
|
|
#warning TODO r_stdin_slurp
|
2017-05-09 12:25:57 +00:00
|
|
|
#endif
|
2014-10-19 22:42:45 +00:00
|
|
|
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;
|
2016-10-02 00:05:23 +00:00
|
|
|
if (!r_file_exists (str)) {
|
2010-06-24 21:14:12 +00:00
|
|
|
return NULL;
|
2016-10-02 00:05:23 +00:00
|
|
|
}
|
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
|
|
|
}
|
2017-04-26 13:31:27 +00:00
|
|
|
|
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-10-02 00:05:23 +00:00
|
|
|
if (!sz) {
|
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);
|
2016-10-02 00:05:23 +00:00
|
|
|
if (!sz) {
|
|
|
|
sz = -1;
|
|
|
|
}
|
2016-06-09 20:23:39 +00:00
|
|
|
} 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;
|
|
|
|
}
|
2016-12-19 03:21:56 +00:00
|
|
|
(void)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;
|
2016-10-02 00:05:23 +00:00
|
|
|
if (outlen) {
|
|
|
|
*outlen = 0;
|
|
|
|
}
|
2014-08-10 16:24:00 +00:00
|
|
|
in = (ut8*)r_file_slurp (str, &sz);
|
2016-10-02 00:05:23 +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
|
|
|
}
|
2016-10-17 21:58:39 +00:00
|
|
|
(void) fseek (fd, 0, SEEK_END);
|
2010-03-03 10:35:03 +00:00
|
|
|
sz = ftell (fd);
|
2016-10-17 21:58:39 +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 (;;) {
|
2016-10-02 00:05:23 +00:00
|
|
|
if (fscanf (fd, " #%*[^\n]") == 1) {
|
2009-09-17 12:02:44 +00:00
|
|
|
continue;
|
2016-10-02 00:05:23 +00:00
|
|
|
}
|
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
|
|
|
}
|
2016-10-02 00:05:23 +00:00
|
|
|
if (feof (fd)) {
|
2009-04-15 18:24:19 +00:00
|
|
|
break;
|
2016-10-02 00:05:23 +00:00
|
|
|
}
|
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);
|
2016-10-02 00:05:23 +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");
|
2016-10-02 00:05:23 +00:00
|
|
|
if (!fd) {
|
2010-04-12 09:46:15 +00:00
|
|
|
return NULL;
|
2016-10-02 00:05:23 +00:00
|
|
|
}
|
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;
|
|
|
|
}
|
2016-10-17 21:58:39 +00:00
|
|
|
ret = (char *) malloc (sz + 1);
|
2016-10-02 00:05:23 +00:00
|
|
|
if (ret) {
|
|
|
|
if (osz) {
|
2016-10-17 21:58:39 +00:00
|
|
|
*osz = (int)(size_t) fread (ret, 1, sz, fd);
|
2016-10-02 00:05:23 +00:00
|
|
|
} else {
|
2014-03-08 06:41:22 +00:00
|
|
|
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) {
|
2016-10-17 21:58:39 +00:00
|
|
|
int i = 0;
|
|
|
|
return r_file_slurp_random_line_count (file, &i);
|
2015-01-15 02:12:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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))) {
|
2016-10-02 00:05:23 +00:00
|
|
|
gettimeofday (&tv, NULL);
|
|
|
|
srand (getpid() + tv.tv_usec);
|
|
|
|
for (i = 0; str[i]; i++) {
|
|
|
|
if (str[i] == '\n') {
|
2016-12-19 16:10:52 +00:00
|
|
|
//here rand doesn't have any security implication
|
|
|
|
// https://www.securecoding.cert.org/confluence/display/c/MSC30-C.+Do+not+use+the+rand()+function+for+generating+pseudorandom+numbers
|
2016-10-02 00:05:23 +00:00
|
|
|
if (!(rand() % (++(*line)))) {
|
2015-01-15 02:12:45 +00:00
|
|
|
selection = (*line - 1); /* The line we want. */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((selection < start) || (selection == -1)) {
|
|
|
|
free (str);
|
|
|
|
return NULL;
|
|
|
|
} else {
|
|
|
|
lines = selection - start;
|
|
|
|
}
|
2016-10-02 00:05:23 +00:00
|
|
|
if (lines > 0) {
|
|
|
|
for (i = 0; str[i] && lines; i++) {
|
|
|
|
if (str[i] == '\n') {
|
2012-09-26 08:01:43 +00:00
|
|
|
lines--;
|
2016-10-02 00:05:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
ptr = str + i;
|
|
|
|
for (i = 0; ptr[i]; i++)
|
|
|
|
if (ptr[i] == '\n') {
|
|
|
|
ptr[i] = '\0';
|
2012-09-26 08:01:43 +00:00
|
|
|
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) {
|
2016-10-02 00:05:23 +00:00
|
|
|
for (i = 0; str[i]; i++) {
|
|
|
|
if (str[i] == '\n') {
|
2009-03-22 04:37:46 +00:00
|
|
|
lines++;
|
2016-10-02 00:05:23 +00:00
|
|
|
}
|
|
|
|
}
|
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;
|
2016-10-02 00:05:23 +00:00
|
|
|
for (i = 0; str[i]&&lines; i++) {
|
|
|
|
if (str[i] == '\n') {
|
2009-03-22 04:37:46 +00:00
|
|
|
lines--;
|
2016-10-02 00:05:23 +00:00
|
|
|
}
|
|
|
|
}
|
2009-03-22 04:37:46 +00:00
|
|
|
ptr = str+i;
|
2016-10-02 00:05:23 +00:00
|
|
|
for (i = 0; ptr[i]; i++) {
|
|
|
|
if (ptr[i] == '\n') {
|
|
|
|
ptr[i] = '\0';
|
2010-02-28 21:58:21 +00:00
|
|
|
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
|
2016-10-02 00:05:23 +00:00
|
|
|
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);
|
|
|
|
}
|
2017-03-16 21:29:49 +00:00
|
|
|
ret = r_str_append (strdup (root), R_SYS_DIR);
|
|
|
|
ret = r_str_append (ret, s);
|
2013-01-02 23:47:58 +00:00
|
|
|
free (s);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-01-09 02:18:14 +00:00
|
|
|
R_API bool r_file_hexdump(const char *file, const ut8 *buf, int len, int append) {
|
|
|
|
FILE *fd;
|
|
|
|
int i,j;
|
|
|
|
if (!file || !*file || !buf || len < 0) {
|
|
|
|
eprintf ("r_file_hexdump file: %s buf: %p\n", file, buf);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (append) {
|
|
|
|
fd = r_sandbox_fopen (file, "awb");
|
|
|
|
} else {
|
|
|
|
r_sys_truncate (file, 0);
|
|
|
|
fd = r_sandbox_fopen (file, "wb");
|
|
|
|
}
|
|
|
|
if (!fd) {
|
|
|
|
eprintf ("Cannot open '%s' for writing\n", file);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
for (i = 0; i< len; i+= 16) {
|
|
|
|
fprintf (fd, "0x%08"PFMT64x" ", (ut64)i);
|
|
|
|
for (j = 0; j<16; j+=2) {
|
|
|
|
fprintf (fd, "%02x%02x ", buf[i +j], buf[i+j+1]);
|
|
|
|
}
|
2017-01-11 15:54:06 +00:00
|
|
|
for (j = 0; j < 16; j++) {
|
|
|
|
fprintf (fd, "%c", IS_PRINTABLE (buf[i + j])? buf[i+j]: '.');
|
2017-01-09 02:18:14 +00:00
|
|
|
}
|
|
|
|
fprintf (fd, "\n");
|
|
|
|
}
|
|
|
|
fclose (fd);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
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");
|
|
|
|
}
|
2016-09-19 12:44:47 +00:00
|
|
|
if (!fd) {
|
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__
|
2017-05-09 21:53:20 +00:00
|
|
|
return !RemoveDirectoryA (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__
|
2017-05-09 21:53:20 +00:00
|
|
|
return !DeleteFileA (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;
|
2017-05-09 21:53:20 +00:00
|
|
|
fh = CreateFileA (file, GENERIC_READ|GENERIC_WRITE,
|
2014-09-15 01:32:43 +00:00
|
|
|
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
|
|
|
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;
|
|
|
|
}
|
|
|
|
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;
|
2016-10-02 00:05:23 +00:00
|
|
|
if (fd == -1) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if ((st64)addr < 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
mmap_buf = mmap (NULL, mmlen*2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, (off_t)addr - rest);
|
|
|
|
if (((int)(size_t)mmap_buf) == -1) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
memcpy (mmap_buf+rest, buf, len);
|
|
|
|
munmap (mmap_buf, mmlen*2);
|
2013-03-12 00:50:55 +00:00
|
|
|
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;
|
2016-10-02 00:05:23 +00:00
|
|
|
if (r_sandbox_enable (0)) {
|
|
|
|
return -1;
|
|
|
|
}
|
2017-05-09 21:53:20 +00:00
|
|
|
fh = CreateFileA (file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
|
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;
|
|
|
|
}
|
2017-05-09 21:53:20 +00:00
|
|
|
fm = CreateFileMappingA (fh, NULL, PAGE_READONLY, 0, 0, NULL);
|
2013-03-12 12:24:48 +00:00
|
|
|
if (fm != INVALID_HANDLE_VALUE) {
|
2016-10-02 00:05:23 +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;
|
2016-10-02 00:05:23 +00:00
|
|
|
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);
|
2013-03-12 00:50:55 +00:00
|
|
|
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) {
|
2017-05-09 21:53:20 +00:00
|
|
|
m->fh = CreateFileA (file, GENERIC_READ | (m->rw?GENERIC_WRITE:0),
|
2014-09-15 01:32:43 +00:00
|
|
|
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;
|
|
|
|
}
|
2017-05-09 21:53:20 +00:00
|
|
|
m->fm = CreateFileMappingA (m->fh, NULL, PAGE_READONLY, 0, 0, NULL);
|
2014-09-15 01:32:43 +00:00
|
|
|
//m->rw?PAGE_READWRITE:PAGE_READONLY, 0, 0, NULL);
|
2013-03-12 12:24:48 +00:00
|
|
|
if (m->fm != INVALID_HANDLE_VALUE) {
|
2017-07-10 07:52:00 +00:00
|
|
|
m->buf = MapViewOfFile (m->fm,
|
2014-09-15 01:32:43 +00:00
|
|
|
// 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) {
|
2016-10-02 00:05:23 +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) {
|
2016-10-02 00:05:23 +00:00
|
|
|
if (!m) {
|
|
|
|
return;
|
|
|
|
}
|
2015-07-22 22:56:22 +00:00
|
|
|
#if __WINDOWS__
|
2016-10-02 00:05:23 +00:00
|
|
|
if (m->fm != INVALID_HANDLE_VALUE) {
|
2015-07-22 22:56:22 +00:00
|
|
|
CloseHandle (m->fm);
|
2016-10-02 00:05:23 +00:00
|
|
|
}
|
|
|
|
if (m->fh != INVALID_HANDLE_VALUE) {
|
2015-07-22 22:56:22 +00:00
|
|
|
CloseHandle (m->fh);
|
2016-10-02 00:05:23 +00:00
|
|
|
}
|
|
|
|
if (m->buf) {
|
2015-07-24 23:57:46 +00:00
|
|
|
UnmapViewOfFile (m->buf);
|
2016-10-02 00:05:23 +00:00
|
|
|
}
|
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 ();
|
2017-04-26 17:35:37 +00:00
|
|
|
if (!prefix) {
|
|
|
|
prefix = "";
|
|
|
|
}
|
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;
|
|
|
|
}
|
|
|
|
|
2017-01-28 15:55:06 +00:00
|
|
|
R_API int r_file_mkstemp(const char *prefix, char **oname) {
|
2011-03-18 08:24:16 +00:00
|
|
|
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__
|
2016-10-02 00:05:23 +00:00
|
|
|
h = -1;
|
2017-05-09 21:53:20 +00:00
|
|
|
if (GetTempFileNameA (path, prefix, 0, name)) {
|
2012-10-19 22:31:18 +00:00
|
|
|
h = r_sandbox_open (name, O_RDWR|O_EXCL|O_BINARY, 0644);
|
2016-10-02 00:05:23 +00:00
|
|
|
}
|
2011-03-18 08:24:16 +00:00
|
|
|
#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
|
2016-10-02 00:05:23 +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__
|
2017-07-10 07:52:00 +00:00
|
|
|
TCHAR tmpdir[MAX_PATH];
|
|
|
|
char *path = NULL;
|
|
|
|
|
|
|
|
if (GetTempPath (sizeof (tmpdir), tmpdir) == 0) {
|
|
|
|
path = r_sys_getenv ("TEMP");
|
|
|
|
if (!path) {
|
|
|
|
path = strdup ("C:\\WINDOWS\\Temp\\");
|
|
|
|
}
|
|
|
|
} else {
|
2017-07-18 08:22:35 +00:00
|
|
|
void (*glpn)(TCHAR *, TCHAR *, size_t) = (void*)r_lib_dl_sym (GetModuleHandle (TEXT ("kernel32.dll")), "GetLongPathNameW");
|
2017-07-16 08:13:29 +00:00
|
|
|
if (glpn) {
|
|
|
|
// Windows XP sometimes returns short path name
|
|
|
|
glpn (tmpdir, tmpdir, sizeof (tmpdir));
|
|
|
|
}
|
2017-07-10 07:52:00 +00:00
|
|
|
path = strdup (tmpdir);
|
2016-10-02 00:05:23 +00:00
|
|
|
}
|
2012-09-06 10:47:32 +00:00
|
|
|
#elif __ANDROID__
|
2016-11-07 21:51:23 +00:00
|
|
|
char *path = strdup ("/data/data/org.radare.radare2installer/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;
|
|
|
|
}
|
2016-10-02 00:05:23 +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;
|
|
|
|
}
|
2016-10-17 21:58:39 +00:00
|
|
|
|
|
|
|
R_API bool r_file_copy (const char *src, const char *dst) {
|
|
|
|
/* TODO: implement in C */
|
|
|
|
/* TODO: Use NO_CACHE for iOS dyldcache copying */
|
2017-02-03 09:47:36 +00:00
|
|
|
#if __APPLE__
|
|
|
|
return copyfile (src, dst, 0, 0) != -1;
|
|
|
|
#elif __WINDOWS__
|
2016-10-17 21:58:39 +00:00
|
|
|
return r_sys_cmdf ("copy %s %s", src, dst);
|
|
|
|
#else
|
|
|
|
char *src2 = r_str_replace (strdup (src), "'", "\\'", 1);
|
|
|
|
char *dst2 = r_str_replace (strdup (dst), "'", "\\'", 1);
|
|
|
|
int rc = r_sys_cmdf ("cp -f '%s' '%s'", src2, dst2);
|
|
|
|
free (src2);
|
|
|
|
free (dst2);
|
|
|
|
return rc == 0;
|
|
|
|
#endif
|
|
|
|
}
|