]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/whereami.c
1 // (‑●‑●)> released under the WTFPL v2 license, by Gregory Pakosz (@gpakosz)
2 // https://github.com/gpakosz/whereami
4 // in case you want to #include "whereami.c" in a larger compilation unit
5 #if !defined(WHEREAMI_H)
13 #if defined(__linux__)
14 // make realpath() available:
15 #define _DEFAULT_SOURCE
18 #if !defined(WAI_MALLOC) || !defined(WAI_FREE) || !defined(WAI_REALLOC)
22 #if !defined(WAI_MALLOC)
23 #define WAI_MALLOC(size) malloc(size)
26 #if !defined(WAI_FREE)
27 #define WAI_FREE(p) free(p)
30 #if !defined(WAI_REALLOC)
31 #define WAI_REALLOC(p, size) realloc(p, size)
36 #define WAI_NOINLINE __declspec(noinline)
37 #elif defined(__GNUC__)
38 #define WAI_NOINLINE __attribute__((noinline))
40 #error unsupported compiler
45 #define WAI_RETURN_ADDRESS() _ReturnAddress()
46 #elif defined(__GNUC__)
47 #define WAI_RETURN_ADDRESS() __builtin_extract_return_addr(__builtin_return_address(0))
49 #error unsupported compiler
54 #define WIN32_LEAN_AND_MEAN
56 #pragma warning(push, 3)
63 static int WAI_PREFIX(getModulePath_
)(HMODULE module
, char* out
, int capacity
, int* dirname_length
)
65 wchar_t buffer1
[MAX_PATH
];
66 wchar_t buffer2
[MAX_PATH
];
73 int length_
, length__
;
75 size
= GetModuleFileNameW(module
, buffer1
, sizeof(buffer1
) / sizeof(buffer1
[0]));
79 else if (size
== (DWORD
)(sizeof(buffer1
) / sizeof(buffer1
[0])))
86 path_
= (wchar_t*)WAI_REALLOC(path
, sizeof(wchar_t) * size_
* 2);
91 size
= GetModuleFileNameW(module
, path
, size_
);
93 while (size
== size_
);
101 if (!_wfullpath(buffer2
, path
, MAX_PATH
))
103 length_
= (int)wcslen(buffer2
);
104 length__
= WideCharToMultiByte(CP_UTF8
, 0, buffer2
, length_
, out
, capacity
, NULL
, NULL
);
107 length__
= WideCharToMultiByte(CP_UTF8
, 0, buffer2
, length_
, NULL
, 0, NULL
, NULL
);
111 if (length__
<= capacity
&& dirname_length
)
115 for (i
= length__
- 1; i
>= 0; --i
)
138 int WAI_PREFIX(getExecutablePath
)(char* out
, int capacity
, int* dirname_length
)
140 return WAI_PREFIX(getModulePath_
)(NULL
, out
, capacity
, dirname_length
);
146 int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
151 #if defined(_MSC_VER)
152 #pragma warning(push)
153 #pragma warning(disable: 4054)
155 if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCTSTR)WAI_RETURN_ADDRESS(), &module))
156 #if defined(_MSC_VER)
160 length = WAI_PREFIX(getModulePath_)(module, out, capacity, dirname_length);
167 #elif defined(__linux__)
171 #include <linux/limits.h>
172 #ifndef __STDC_FORMAT_MACROS
173 #define __STDC_FORMAT_MACROS
175 #include <inttypes.h>
177 #if !defined(WAI_PROC_SELF_EXE)
178 #define WAI_PROC_SELF_EXE "/proc/self/exe"
182 int WAI_PREFIX(getExecutablePath
)(char* out
, int capacity
, int* dirname_length
)
184 char buffer
[PATH_MAX
];
185 char* resolved
= NULL
;
190 resolved
= realpath(WAI_PROC_SELF_EXE
, buffer
);
194 length
= (int)strlen(resolved
);
195 if (length
<= capacity
)
197 memcpy(out
, resolved
, length
);
203 for (i
= length
- 1; i
>= 0; --i
)
220 #if !defined(WAI_PROC_SELF_MAPS_RETRY)
221 #define WAI_PROC_SELF_MAPS_RETRY 5
224 #if !defined(WAI_PROC_SELF_MAPS)
225 #define WAI_PROC_SELF_MAPS "/proc/self/maps"
228 #if defined(__ANDROID__) || defined(ANDROID)
230 #include <sys/mman.h>
235 int WAI_PREFIX(getModulePath
)(char* out
, int capacity
, int* dirname_length
)
241 for (i
= 0; i
< WAI_PROC_SELF_MAPS_RETRY
; ++i
)
243 maps
= fopen(WAI_PROC_SELF_MAPS
, "r");
249 char buffer
[PATH_MAX
< 1024 ? 1024 : PATH_MAX
];
253 uint32_t major
, minor
;
257 if (!fgets(buffer
, sizeof(buffer
), maps
))
260 if (sscanf(buffer
, "%" PRIx64
"-%" PRIx64
" %s %" PRIx64
" %x:%x %u %s\n", &low
, &high
, perms
, &offset
, &major
, &minor
, &inode
, path
) == 8)
262 uint64_t addr
= (uint64_t)(uintptr_t)WAI_RETURN_ADDRESS();
263 if (low
<= addr
&& addr
<= high
)
267 resolved
= realpath(path
, buffer
);
271 length
= (int)strlen(resolved
);
272 #if defined(__ANDROID__) || defined(ANDROID)
274 &&buffer
[length
- 1] == 'k'
275 &&buffer
[length
- 2] == 'p'
276 &&buffer
[length
- 3] == 'a'
277 &&buffer
[length
- 4] == '.')
279 int fd
= open(path
, O_RDONLY
);
283 begin
= (char*)mmap(0, offset
, PROT_READ
, MAP_SHARED
, fd
, 0);
286 while (p
>= begin
) // scan backwards
288 if (*((uint32_t*)p
) == 0x04034b50UL
) // local file header found
290 uint16_t length_
= *((uint16_t*)(p
+ 26));
292 if (length
+ 2 + length_
< (int)sizeof(buffer
))
294 memcpy(&buffer
[length
], "!/", 2);
295 memcpy(&buffer
[length
+ 2], p
+ 30, length_
);
296 length
+= 2 + length_
;
305 munmap(begin
, offset
);
309 if (length
<= capacity
)
311 memcpy(out
, resolved
, length
);
317 for (i
= length
- 1; i
>= 0; --i
)
342 #elif defined(__APPLE__)
344 #define _DARWIN_BETTER_REALPATH
345 #include <mach-o/dyld.h>
352 int WAI_PREFIX(getExecutablePath
)(char* out
, int capacity
, int* dirname_length
)
354 char buffer1
[PATH_MAX
];
355 char buffer2
[PATH_MAX
];
356 char* path
= buffer1
;
357 char* resolved
= NULL
;
362 uint32_t size
= (uint32_t)sizeof(buffer1
);
363 if (_NSGetExecutablePath(path
, &size
) == -1)
365 path
= (char*)WAI_MALLOC(size
);
366 if (!_NSGetExecutablePath(path
, &size
))
370 resolved
= realpath(path
, buffer2
);
374 length
= (int)strlen(resolved
);
375 if (length
<= capacity
)
377 memcpy(out
, resolved
, length
);
383 for (i
= length
- 1; i
>= 0; --i
)
405 int WAI_PREFIX(getModulePath
)(char* out
, int capacity
, int* dirname_length
)
407 char buffer
[PATH_MAX
];
408 char* resolved
= NULL
;
415 if (dladdr(WAI_RETURN_ADDRESS(), &info
))
417 resolved
= realpath(info
.dli_fname
, buffer
);
421 length
= (int)strlen(resolved
);
422 if (length
<= capacity
)
424 memcpy(out
, resolved
, length
);
430 for (i
= length
- 1; i
>= 0; --i
)
448 #elif defined(__QNXNTO__)
456 #if !defined(WAI_PROC_SELF_EXE)
457 #define WAI_PROC_SELF_EXE "/proc/self/exefile"
461 int WAI_PREFIX(getExecutablePath
)(char* out
, int capacity
, int* dirname_length
)
463 char buffer1
[PATH_MAX
];
464 char buffer2
[PATH_MAX
];
465 char* resolved
= NULL
;
466 FILE* self_exe
= NULL
;
471 self_exe
= fopen(WAI_PROC_SELF_EXE
, "r");
475 if (!fgets(buffer1
, sizeof(buffer1
), self_exe
))
478 resolved
= realpath(buffer1
, buffer2
);
482 length
= (int)strlen(resolved
);
483 if (length
<= capacity
)
485 memcpy(out
, resolved
, length
);
491 for (i
= length
- 1; i
>= 0; --i
)
511 int WAI_PREFIX(getModulePath
)(char* out
, int capacity
, int* dirname_length
)
513 char buffer
[PATH_MAX
];
514 char* resolved
= NULL
;
521 if (dladdr(WAI_RETURN_ADDRESS(), &info
))
523 resolved
= realpath(info
.dli_fname
, buffer
);
527 length
= (int)strlen(resolved
);
528 if (length
<= capacity
)
530 memcpy(out
, resolved
, length
);
536 for (i
= length
- 1; i
>= 0; --i
)
554 #elif defined(__DragonFly__) || defined(__FreeBSD__) || \
555 defined(__FreeBSD_kernel__) || defined(__NetBSD__)
560 #include <sys/types.h>
561 #include <sys/sysctl.h>
565 int WAI_PREFIX(getExecutablePath
)(char* out
, int capacity
, int* dirname_length
)
567 char buffer1
[PATH_MAX
];
568 char buffer2
[PATH_MAX
];
569 char* path
= buffer1
;
570 char* resolved
= NULL
;
575 int mib
[4] = { CTL_KERN
, KERN_PROC
, KERN_PROC_PATHNAME
, -1 };
576 size_t size
= sizeof(buffer1
);
578 if (sysctl(mib
, (u_int
)(sizeof(mib
) / sizeof(mib
[0])), path
, &size
, NULL
, 0) != 0)
581 resolved
= realpath(path
, buffer2
);
585 length
= (int)strlen(resolved
);
586 if (length
<= capacity
)
588 memcpy(out
, resolved
, length
);
594 for (i
= length
- 1; i
>= 0; --i
)
616 int WAI_PREFIX(getModulePath
)(char* out
, int capacity
, int* dirname_length
)
618 char buffer
[PATH_MAX
];
619 char* resolved
= NULL
;
626 if (dladdr(WAI_RETURN_ADDRESS(), &info
))
628 resolved
= realpath(info
.dli_fname
, buffer
);
632 length
= (int)strlen(resolved
);
633 if (length
<= capacity
)
635 memcpy(out
, resolved
, length
);
641 for (i
= length
- 1; i
>= 0; --i
)
661 #error unsupported platform