1 /* radare - LGPL - Copyright 2009-2020 - ret2libc */
2 
3 #include <r_types.h>
4 #include <r_util.h>
5 
6 struct buf_file_user {
7 	const char *file;
8 	int perm;
9 	int mode;
10 };
11 
12 struct buf_file_priv {
13 	int fd;
14 	ut8 tmp[8];
15 };
16 
get_priv_file(RBuffer * b)17 static inline struct buf_file_priv *get_priv_file(RBuffer *b) {
18 	struct buf_file_priv *priv = (struct buf_file_priv *)b->priv;
19 	r_warn_if_fail (priv);
20 	return priv;
21 }
22 
buf_file_init(RBuffer * b,const void * user)23 static bool buf_file_init(RBuffer *b, const void *user) {
24 	const struct buf_file_user *u = (const struct buf_file_user *)user;
25 	struct buf_file_priv *priv = R_NEW0 (struct buf_file_priv);
26 	if (!priv) {
27 		return false;
28 	}
29 	int fd = r_sandbox_open (u->file, u->perm, u->mode);
30 	if (fd == -1) {
31 		free (priv);
32 		return false;
33 	}
34 	priv->fd = fd;
35 	b->priv = priv;
36 	return true;
37 }
38 
buf_file_fini(RBuffer * b)39 static bool buf_file_fini(RBuffer *b) {
40 	struct buf_file_priv *priv = get_priv_file (b);
41 	r_sandbox_close (priv->fd);
42 	R_FREE (b->priv);
43 	return true;
44 }
45 
buf_file_get_size(RBuffer * b)46 static ut64 buf_file_get_size(RBuffer *b) {
47 	struct buf_file_priv *priv = get_priv_file (b);
48 	int pos = r_sandbox_lseek (priv->fd, 0, SEEK_CUR);
49 	int res = r_sandbox_lseek (priv->fd, 0, SEEK_END);
50 	r_sandbox_lseek (priv->fd, pos, SEEK_SET);
51 	return (ut64)res;
52 }
53 
buf_file_read(RBuffer * b,ut8 * buf,ut64 len)54 static st64 buf_file_read(RBuffer *b, ut8 *buf, ut64 len) {
55 	struct buf_file_priv *priv = get_priv_file (b);
56 	return r_sandbox_read (priv->fd, buf, len);
57 }
58 
buf_file_write(RBuffer * b,const ut8 * buf,ut64 len)59 static st64 buf_file_write(RBuffer *b, const ut8 *buf, ut64 len) {
60 	struct buf_file_priv *priv = get_priv_file (b);
61 	return r_sandbox_write (priv->fd, buf, len);
62 }
63 
buf_file_seek(RBuffer * b,st64 addr,int whence)64 static st64 buf_file_seek(RBuffer *b, st64 addr, int whence) {
65 	struct buf_file_priv *priv = get_priv_file (b);
66 	switch (whence) {
67 	case R_BUF_CUR: whence = SEEK_CUR; break;
68 	case R_BUF_SET: whence = SEEK_SET; break;
69 	case R_BUF_END: whence = SEEK_END; break;
70 	}
71 	return r_sandbox_lseek (priv->fd, addr, whence);
72 }
73 
buf_file_resize(RBuffer * b,ut64 newsize)74 static bool buf_file_resize(RBuffer *b, ut64 newsize) {
75 	struct buf_file_priv *priv = get_priv_file (b);
76 	return r_sandbox_truncate (priv->fd, newsize) >= 0;
77 }
78 
79 static const RBufferMethods buffer_file_methods = {
80 	.init = buf_file_init,
81 	.fini = buf_file_fini,
82 	.read = buf_file_read,
83 	.write = buf_file_write,
84 	.get_size = buf_file_get_size,
85 	.resize = buf_file_resize,
86 	.seek = buf_file_seek,
87 };
88