1 /* radare2 - LGPL - Copyright 2013-2020 - pancake */
2 
3 #if __UNIX__
4 #include <unistd.h>
5 #elif __WINDOWS__
6 #include <windows.h>
7 #endif
8 #include "spp.h"
9 #include "r_api.h"
10 
r_strbuf_new(const char * str)11 SStrBuf *r_strbuf_new(const char *str) {
12 	SStrBuf *s = R_NEW0 (SStrBuf);
13 	if (str) r_strbuf_set (s, str);
14 	return s;
15 }
16 
r_strbuf_init(SStrBuf * sb)17 void r_strbuf_init(SStrBuf *sb) {
18 	memset (sb, 0, sizeof (SStrBuf));
19 }
20 
r_strbuf_set(SStrBuf * sb,const char * s)21 bool r_strbuf_set(SStrBuf *sb, const char *s) {
22 	int l;
23 	if (!sb) return false;
24 	if (!s) {
25 		r_strbuf_init (sb);
26 		return true;
27 	}
28 	l = strlen (s);
29 	if (l >= sizeof (sb->buf)) {
30 		char *ptr = sb->ptr;
31 		if (!ptr || l+1 > sb->ptrlen) {
32 			ptr = malloc (l + 1);
33 			if (!ptr) return false;
34 			sb->ptrlen = l + 1;
35 			sb->ptr = ptr;
36 		}
37 		memcpy (ptr, s, l+1);
38 	} else {
39 		sb->ptr = NULL;
40 		memcpy (sb->buf, s, l+1);
41 	}
42 	sb->len = l;
43 	return true;
44 }
45 
r_strbuf_append(SStrBuf * sb,const char * s)46 bool r_strbuf_append(SStrBuf *sb, const char *s) {
47 	int l = strlen (s);
48 	if (l < 1) {
49 		return false;
50 	}
51 	if ((sb->len + l + 1) < sizeof (sb->buf)) {
52 		memcpy (sb->buf + sb->len, s, l + 1);
53 		R_FREE (sb->ptr);
54 	} else {
55 		int newlen = sb->len + l + 128;
56 		char *p = sb->ptr;
57 		bool allocated = true;
58 		if (!sb->ptr) {
59 			p = malloc (newlen);
60 			if (p && sb->len > 0) {
61 				memcpy (p, sb->buf, sb->len);
62 			}
63 		} else if (sb->len + l + 1 > sb->ptrlen) {
64 			p = realloc (sb->ptr, newlen);
65 		} else {
66 			allocated = false;
67 		}
68 		if (allocated) {
69 			if (!p) return false;
70 			sb->ptr = p;
71 			sb->ptrlen = newlen;
72 		}
73 		memcpy (p + sb->len, s, l + 1);
74 	}
75 	sb->len += l;
76 	return true;
77 }
78 
r_strbuf_get(SStrBuf * sb)79 char *r_strbuf_get(SStrBuf *sb) {
80 	return sb? (sb->ptr? sb->ptr: sb->buf) : NULL;
81 }
82 
r_strbuf_drain(SStrBuf * sb)83 char *r_strbuf_drain(SStrBuf *sb) {
84 	char *res = sb->ptr? sb->ptr: strdup (sb->buf);
85 	sb->ptr = NULL;
86 	r_strbuf_fini (sb);
87 	free (sb);
88 	return res;
89 }
90 
r_strbuf_free(SStrBuf * sb)91 void r_strbuf_free(SStrBuf *sb) {
92 	r_strbuf_fini (sb);
93 	free (sb);
94 }
95 
r_strbuf_fini(SStrBuf * sb)96 void r_strbuf_fini(SStrBuf *sb) {
97 	if (sb && sb->ptr)
98 		R_FREE (sb->ptr);
99 }
100 
101 /* --------- */
r_sys_setenv(const char * key,const char * value)102 int r_sys_setenv(const char *key, const char *value) {
103 	if (!key) {
104 		return 0;
105 	}
106 #if __UNIX__
107 	if (!value) {
108 		unsetenv (key);
109 		return 0;
110 	}
111 	return setenv (key, value, 1);
112 #elif __WINDOWS__
113 	int ret = SetEnvironmentVariableA (key, value);
114 	return ret ? 0 : -1;
115 #else
116 #warning r_sys_setenv : unimplemented for this platform
117 	return 0;
118 #endif
119 }
120 
r_sys_getenv(const char * key)121 char *r_sys_getenv(const char *key) {
122 #if __WINDOWS__
123 	DWORD dwRet;
124 	char *envbuf = NULL, *tmp_ptr;
125 	char *val = NULL;
126 	const int TMP_BUFSIZE = 4096;
127 	if (!key) {
128 		return NULL;
129 	}
130 	envbuf = malloc (sizeof (envbuf) * TMP_BUFSIZE);
131 	if (!envbuf) {
132 		goto err_r_sys_get_env;
133 	}
134 	dwRet = GetEnvironmentVariableA (key, envbuf, TMP_BUFSIZE);
135 	if (dwRet == 0) {
136 		if (GetLastError () == ERROR_ENVVAR_NOT_FOUND) {
137 			goto err_r_sys_get_env;
138 		}
139 	} else if (TMP_BUFSIZE < dwRet) {
140 		tmp_ptr = realloc (envbuf, dwRet);
141 		if (!tmp_ptr) {
142 			goto err_r_sys_get_env;
143 		}
144 		envbuf = tmp_ptr;
145 		dwRet = GetEnvironmentVariableA (key, envbuf, dwRet);
146 		if (!dwRet) {
147 			goto err_r_sys_get_env;
148 		}
149 	}
150 	val = strdup (envbuf);
151 err_r_sys_get_env:
152 	free (envbuf);
153 	return val;
154 #else
155 	char *b;
156 	if (!key) {
157 		return NULL;
158 	}
159 	b = getenv (key);
160 	return b? strdup (b): NULL;
161 #endif
162 }
163 
r_sys_getpid()164 int r_sys_getpid() {
165 #if __UNIX__
166 	return getpid();
167 #elif __WINDOWS__
168 	return GetCurrentProcessId();
169 #else
170 #warning r_sys_getpid not implemented for this platform
171 	return -1;
172 #endif
173 }
174