2011-03-13 20:00:46 +00:00
|
|
|
/* radare - LGPL - Copyright 2007-2011 pancake<nopcode.org> */
|
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
|
|
|
|
2010-03-03 10:35:03 +00:00
|
|
|
R_API const char *r_file_basename (const char *path) {
|
|
|
|
const char *ptr = strrchr (path, '/');
|
2010-11-16 17:19:51 +00:00
|
|
|
if (ptr) path = ptr + 1;
|
2010-03-03 10:35:03 +00:00
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
2010-11-16 17:19:51 +00:00
|
|
|
R_API boolt r_file_exist(const char *str) {
|
2009-02-05 21:08:46 +00:00
|
|
|
struct stat buf;
|
2010-06-24 21:14:12 +00:00
|
|
|
if (stat (str, &buf)==-1)
|
|
|
|
return R_FALSE;
|
2010-11-16 17:19:51 +00:00
|
|
|
return (S_ISREG (buf.st_mode))?R_TRUE:R_FALSE;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2010-11-17 20:15:34 +00:00
|
|
|
R_API char *r_file_abspath(const char *file) {
|
2010-02-20 05:40:02 +00:00
|
|
|
#if __UNIX__
|
|
|
|
if (file[0] != '/')
|
|
|
|
return r_str_dup_printf ("%s/%s", r_sys_getcwd (), file);
|
|
|
|
#elif __WINDOWS__
|
|
|
|
if (!strchr (file, ':'))
|
|
|
|
return r_str_dup_printf ("%s/%s", r_sys_getcwd (), file);
|
|
|
|
#endif
|
2010-11-17 20:15:34 +00:00
|
|
|
return strdup (file);
|
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];
|
2010-04-12 00:22:52 +00:00
|
|
|
char *path_env = (char *)r_sys_getenv ("PATH");
|
2009-02-09 00:54:09 +00:00
|
|
|
char *path = NULL;
|
|
|
|
char *str, *ptr;
|
|
|
|
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) {
|
|
|
|
ptr[0]='\0';
|
2010-03-03 10:35:03 +00:00
|
|
|
snprintf (file, 1023, "%s/%s", str, bin);
|
|
|
|
if (r_file_exist (file)) {
|
|
|
|
free (path);
|
|
|
|
return strdup (file);
|
2009-02-09 00:54:09 +00:00
|
|
|
}
|
|
|
|
str = ptr+1;
|
|
|
|
}
|
2010-03-03 10:35:03 +00:00
|
|
|
} while (ptr);
|
|
|
|
} else return strdup (bin);
|
|
|
|
free (path);
|
|
|
|
return strdup (bin);
|
2009-02-09 00:54:09 +00:00
|
|
|
}
|
|
|
|
|
2010-03-03 10:35:03 +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;
|
|
|
|
long sz;
|
2010-06-24 21:14:12 +00:00
|
|
|
if (!r_file_exist (str))
|
|
|
|
return NULL;
|
|
|
|
fd = fopen (str, "rb");
|
2010-10-27 14:53:06 +00:00
|
|
|
if (fd == NULL)
|
|
|
|
return NULL;
|
|
|
|
fseek (fd, 0, SEEK_END);
|
|
|
|
sz = ftell (fd);
|
|
|
|
fseek (fd, 0, SEEK_SET);
|
|
|
|
ret = (char *)malloc (sz+1);
|
|
|
|
rsz = fread (ret, 1, sz, fd);
|
|
|
|
if (rsz != sz)
|
2010-10-27 14:31:51 +00:00
|
|
|
eprintf ("r_file_slurp: fread: error\n");
|
|
|
|
fclose (fd);
|
2011-05-21 12:27:46 +00:00
|
|
|
ret[sz]='\0';
|
2009-02-05 21:08:46 +00:00
|
|
|
if (usz)
|
2009-07-08 11:49:55 +00:00
|
|
|
*usz = (ut32)sz;
|
2010-10-27 14:53:06 +00:00
|
|
|
return ret;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
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;
|
2010-03-03 10:35:03 +00:00
|
|
|
FILE *fd = fopen (str, "r");
|
2009-09-17 12:02:44 +00:00
|
|
|
if (fd == NULL)
|
|
|
|
return NULL;
|
2010-03-03 10:35:03 +00:00
|
|
|
fseek (fd, 0, SEEK_END);
|
|
|
|
sz = ftell (fd);
|
|
|
|
fseek (fd, 0, SEEK_SET);
|
|
|
|
ret = (ut8*)malloc ((sz>>1)+1);
|
2011-01-02 13:39:25 +00:00
|
|
|
if (!ret)
|
2009-09-17 12:02:44 +00:00
|
|
|
return NULL;
|
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);
|
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;
|
|
|
|
FILE *fd = fopen (str, "rb");
|
|
|
|
if (fd == NULL)
|
|
|
|
return NULL;
|
|
|
|
fseek (fd, off, SEEK_SET);
|
|
|
|
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);
|
|
|
|
else fread (ret, 1, sz, fd);
|
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) {
|
2009-02-05 21:08:46 +00:00
|
|
|
int i, lines = 0;
|
|
|
|
struct timeval tv;
|
2009-03-06 00:00:41 +00:00
|
|
|
int sz;
|
2009-04-20 10:31:12 +00:00
|
|
|
char *ptr = NULL;
|
2010-03-03 10:35:03 +00:00
|
|
|
char *str = r_file_slurp (file, &sz);
|
2009-02-05 21:08:46 +00:00
|
|
|
if (str) {
|
2010-03-03 10:35:03 +00:00
|
|
|
gettimeofday (&tv,NULL);
|
|
|
|
srand (getpid()+tv.tv_usec);
|
|
|
|
for(i=0; str[i]; i++)
|
2009-02-05 21:08:46 +00:00
|
|
|
if (str[i]=='\n')
|
|
|
|
lines++;
|
|
|
|
lines = (rand()%lines);
|
2010-03-03 10:35:03 +00:00
|
|
|
for(i=0; str[i]&&lines; i++)
|
2009-02-05 21:08:46 +00:00
|
|
|
if (str[i]=='\n')
|
|
|
|
lines--;
|
|
|
|
ptr = str+i;
|
2010-03-03 10:35:03 +00:00
|
|
|
for (i=0; ptr[i]; i++)
|
|
|
|
if (ptr[i]=='\n') {
|
|
|
|
ptr[i]='\0';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
ptr = strdup (ptr);
|
|
|
|
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;
|
|
|
|
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) {
|
2010-02-28 21:58:21 +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;
|
|
|
|
}
|
2009-03-22 04:37:46 +00:00
|
|
|
lines = line;
|
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;
|
2010-02-28 21:58:21 +00:00
|
|
|
for (i=0; ptr[i]; i++)
|
|
|
|
if (ptr[i]=='\n') {
|
|
|
|
ptr[i]='\0';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
ptr = strdup (ptr);
|
|
|
|
free (str);
|
2009-03-22 04:37:46 +00:00
|
|
|
}
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
2010-11-16 17:19:51 +00:00
|
|
|
R_API boolt r_file_dump(const char *file, const ut8 *buf, int len) {
|
2010-10-27 14:31:51 +00:00
|
|
|
int ret;
|
2009-02-05 21:08:46 +00:00
|
|
|
FILE *fd = fopen(file, "wb");
|
|
|
|
if (fd == NULL) {
|
2010-10-27 14:31:51 +00:00
|
|
|
eprintf ("Cannot open '%s' for writing\n", file);
|
2009-02-05 21:08:46 +00:00
|
|
|
return R_FALSE;
|
|
|
|
}
|
2010-11-09 17:09:37 +00:00
|
|
|
ret = fwrite (buf, 1, len, fd) == len;
|
2010-10-27 14:31:51 +00:00
|
|
|
if (!ret)
|
|
|
|
eprintf ("r_file_dump: fwrite: error\n");
|
|
|
|
fclose (fd);
|
|
|
|
return ret;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2010-11-16 17:19:51 +00:00
|
|
|
R_API boolt r_file_rm(const char *file) {
|
2011-01-02 13:39:25 +00:00
|
|
|
#if __WINDOWS__
|
2011-07-05 23:29:18 +00:00
|
|
|
return (DeleteFile (file)==0)? R_TRUE: R_FALSE;
|
2011-01-02 13:39:25 +00:00
|
|
|
#else
|
2011-07-05 23:29:18 +00:00
|
|
|
return (unlink (file)==0)? R_TRUE: R_FALSE;
|
2011-01-02 13:39:25 +00:00
|
|
|
#endif
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
2010-11-17 20:15:34 +00:00
|
|
|
|
2011-01-06 23:42:27 +00:00
|
|
|
// TODO: add rwx support?
|
|
|
|
R_API RMmap *r_file_mmap (const char *file, boolt rw) {
|
2010-11-17 20:15:34 +00:00
|
|
|
RMmap *m = NULL;
|
2010-12-16 12:55:20 +00:00
|
|
|
#if __WINDOWS__
|
|
|
|
int fd = open (file, 0);
|
|
|
|
#else
|
2011-01-06 23:42:27 +00:00
|
|
|
int fd = open (file, rw?O_RDWR:O_RDONLY);
|
2010-12-16 12:55:20 +00:00
|
|
|
#endif
|
2010-11-17 20:15:34 +00:00
|
|
|
if (fd != -1) {
|
|
|
|
m = R_NEW (RMmap);
|
2011-01-06 23:42:27 +00:00
|
|
|
if (!m) {
|
|
|
|
close (fd);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
m->rw = rw;
|
2010-11-17 20:15:34 +00:00
|
|
|
m->fd = fd;
|
|
|
|
m->len = lseek (fd, (off_t)0, SEEK_END);
|
|
|
|
#if __UNIX__
|
2011-01-06 23:42:27 +00:00
|
|
|
m->buf = mmap (NULL, m->len, rw?PROT_READ|PROT_WRITE:PROT_READ,
|
|
|
|
MAP_SHARED, fd, (off_t)0);
|
2011-01-02 13:45:36 +00:00
|
|
|
if (!m->buf) {
|
2011-01-02 13:39:25 +00:00
|
|
|
free (m);
|
|
|
|
m = NULL;
|
|
|
|
}
|
|
|
|
#elif __WINDOWS__
|
2011-01-06 23:42:27 +00:00
|
|
|
close (fd);
|
|
|
|
m->fh = CreateFile (file, rw?GENERIC_WRITE:GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
|
|
|
|
if (m->fh == NULL) {
|
|
|
|
free (m);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
m->fm = CreateFileMapping (m->fh, NULL,
|
|
|
|
rw?PAGE_READWRITE:PAGE_READONLY, 0, 0, NULL);
|
|
|
|
if (m->fm == NULL) {
|
|
|
|
CloseHandle (m->fh);
|
|
|
|
free (m);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (m->fm != INVALID_HANDLE_VALUE) {
|
|
|
|
m->buf = MapViewOfFile (m->fm, rw?FILE_MAP_READ|FILE_MAP_WRITE:FILE_MAP_READ, 0, 0, 0);
|
2011-01-02 13:39:25 +00:00
|
|
|
} else {
|
2011-01-06 23:42:27 +00:00
|
|
|
CloseHandle (m->fh);
|
2011-01-02 13:39:25 +00:00
|
|
|
free (m);
|
|
|
|
m = NULL;
|
|
|
|
}
|
2010-11-17 20:15:34 +00:00
|
|
|
#else
|
2011-01-02 13:39:25 +00:00
|
|
|
m->buf = malloc (m->len);
|
2010-11-17 20:15:34 +00:00
|
|
|
if (m->buf) {
|
|
|
|
lseek (fd, (off_t)0, SEEK_SET);
|
|
|
|
read (fd, m->buf, m->len);
|
|
|
|
} else {
|
|
|
|
free (m);
|
|
|
|
m = NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
return m;
|
|
|
|
}
|
|
|
|
|
|
|
|
R_API void r_file_mmap_free (RMmap *m) {
|
|
|
|
#if __UNIX__
|
|
|
|
munmap (m->buf, m->len);
|
2011-01-02 13:39:25 +00:00
|
|
|
#elif __WINDOWS__
|
2011-01-06 23:42:27 +00:00
|
|
|
CloseHandle (m->fm);
|
|
|
|
CloseHandle (m->fh);
|
2011-01-02 13:39:25 +00:00
|
|
|
UnmapViewOfFile (m->buf);
|
2010-11-17 20:15:34 +00:00
|
|
|
#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-05-22 00:45:59 +00:00
|
|
|
const 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-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-05-03 17:36:06 +00:00
|
|
|
const char *path = r_file_tmpdir ();
|
2011-03-18 08:24:16 +00:00
|
|
|
char *name = malloc (1024);
|
|
|
|
#if __WINDOWS__
|
|
|
|
if (GetTempFileName (path, prefix, 0, name))
|
|
|
|
h = open (name, O_RDWR|O_EXCL);
|
|
|
|
else h = -1;
|
|
|
|
#else
|
|
|
|
h = snprintf (name, 1024, "%s/%sXXXXXX", path, prefix);
|
|
|
|
if (h<1024)
|
|
|
|
h = mkstemp (name);
|
|
|
|
else h = -1;
|
|
|
|
#endif
|
|
|
|
if (oname && h!=-1) *oname = name;
|
|
|
|
else free (name);
|
|
|
|
return h;
|
|
|
|
}
|
2011-05-03 17:36:06 +00:00
|
|
|
|
|
|
|
R_API const char *r_file_tmpdir() {
|
|
|
|
const char *path;
|
|
|
|
#if __WINDOWS__
|
|
|
|
path = r_sys_getenv ("TEMP");
|
|
|
|
if (!path) path = "C:\\WINDOWS\\Temp\\";
|
|
|
|
#else
|
|
|
|
path = r_sys_getenv ("TMPDIR");
|
|
|
|
if (!path) path = "/tmp";
|
|
|
|
#endif
|
|
|
|
return path;
|
|
|
|
}
|