dynwatch
diff locator.c @ 0:ce3c5e4c75bf
dynwatch DynDNS updater for windows
author | John Tsiombikas <nuclear@siggraph.org> |
---|---|
date | Wed, 18 May 2011 05:53:29 +0300 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/locator.c Wed May 18 05:53:29 2011 +0300 1.3 @@ -0,0 +1,170 @@ 1.4 +/* 1.5 +This is a small cross-platform resource file locator library. 1.6 +Author: John Tsiombikas <nuclear@siggraph.org> 2004 1.7 + 1.8 +This library is public domain, you are free to do whatever you like with it, 1.9 +NO WARANTY whatsoever is provided with this library, use it at your own risk. 1.10 +*/ 1.11 + 1.12 +#include <stdio.h> 1.13 +#include <stdlib.h> 1.14 +#include <string.h> 1.15 +#include "locator.h" 1.16 + 1.17 +#ifdef HAVE_CONFIG 1.18 +#include "config.h" 1.19 +#endif /* HAVE_CONFIG */ 1.20 + 1.21 +#ifdef __unix__ 1.22 +#define __USE_BSD /* to include readlink() prototype */ 1.23 +#include <unistd.h> 1.24 + 1.25 +#define DIR_SEP '/' 1.26 +#define HOME_ENV "HOME" 1.27 + 1.28 +#else /* assume WIN32 */ 1.29 +#include <windows.h> 1.30 + 1.31 +#define DIR_SEP '\\' 1.32 +#define HOME_ENV "USERPROFILE" 1.33 + 1.34 +#endif /* __unix__ */ 1.35 + 1.36 + 1.37 +#ifndef PREFIX 1.38 +#define PREFIX "" 1.39 +#endif /* PREFIX */ 1.40 + 1.41 +#define MAX_PATH 1024 1.42 +#define CONF_ENV "NLOC_CONFIG_PATH" 1.43 +#define DATA_ENV "NLOC_DATA_PATH" 1.44 +#define LOC_FUNC_COUNT 2 1.45 + 1.46 +typedef const char *(*loc_func_type)(const char*); 1.47 + 1.48 +static const char *locate_config(const char *file); 1.49 +static const char *locate_data(const char *file); 1.50 +static const char *exec_path(void); 1.51 + 1.52 +static char path[MAX_PATH]; 1.53 +static loc_func_type loc_func[LOC_FUNC_COUNT] = {locate_config, locate_data}; 1.54 + 1.55 +const char *loc_get_path(const char *file, enum loc_file_type file_type) { 1.56 + if(file_type >= LOC_FUNC_COUNT) return 0; 1.57 + return loc_func[file_type](file); 1.58 +} 1.59 + 1.60 +static const char *locate_config(const char *file) { 1.61 + FILE *fp; 1.62 + char *env, *pptr = path; 1.63 + const char *fptr = file; 1.64 + 1.65 + /* first try $NLOC_CONFIG_PATH/file */ 1.66 + env = getenv(CONF_ENV); 1.67 + if(env) { 1.68 + while(*env) *pptr++ = *env++; 1.69 + if(*(env - 1) != DIR_SEP) *pptr++ = DIR_SEP; 1.70 + while(*fptr) *pptr++ = *fptr++; 1.71 + *pptr++ = 0; 1.72 + 1.73 + fprintf(stderr, "trying: %s\n", path); 1.74 + if((fp = fopen(path, "r"))) { 1.75 + fclose(fp); 1.76 + return path; 1.77 + } 1.78 + } 1.79 + 1.80 + /* then try $HOME/.file */ 1.81 + pptr = path; 1.82 + fptr = file; 1.83 + env = getenv(HOME_ENV); 1.84 + if(env) { 1.85 + while(*env) *pptr++ = *env++; 1.86 + if(*(env - 1) != DIR_SEP) *pptr++ = DIR_SEP; 1.87 +#ifdef __unix__ 1.88 + *pptr++ = '.'; 1.89 +#endif /* __unix__ */ 1.90 + while(*fptr) *pptr++ = *fptr++; 1.91 + *pptr++ = 0; 1.92 + 1.93 + fprintf(stderr, "trying: %s\n", path); 1.94 + if((fp = fopen(path, "r"))) { 1.95 + fclose(fp); 1.96 + return path; 1.97 + } 1.98 + } 1.99 + 1.100 +#ifdef __unix__ 1.101 + /* then PREFIX/etc/file */ 1.102 + strcpy(path, PREFIX); 1.103 + strcat(path, "/etc/"); 1.104 + strcat(path, file); 1.105 + 1.106 + fprintf(stderr, "trying: %s\n", path); 1.107 + if((fp = fopen(path, "r"))) { 1.108 + fclose(fp); 1.109 + return path; 1.110 + } 1.111 +#else 1.112 + /* or something similar on win32 */ 1.113 + env = getenv("ALLUSERSPROFILE"); 1.114 + if(env) { 1.115 + strcpy(path, env); 1.116 + strcat(path, "\\"); 1.117 + strcat(path, file); 1.118 + 1.119 + fprintf(stderr, "trying: %s\n", path); 1.120 + if((fp = fopen(path, "r"))) { 1.121 + fclose(fp); 1.122 + return path; 1.123 + } 1.124 + } 1.125 +#endif /* __unix__ */ 1.126 + 1.127 + 1.128 + /* finally as a last resort try the executable directory, this may not work */ 1.129 + strcpy(path, exec_path()); 1.130 + strcat(path, file); 1.131 + 1.132 + fprintf(stderr, "trying: %s\n", path); 1.133 + if((fp = fopen(path, "r"))) { 1.134 + fclose(fp); 1.135 + return path; 1.136 + } 1.137 + 1.138 + return 0; 1.139 +} 1.140 + 1.141 +/* TODO: not implemented yet */ 1.142 +static const char *locate_data(const char *file) { 1.143 + return 0; 1.144 +} 1.145 + 1.146 +static const char *exec_path(void) { 1.147 + static char path[MAX_PATH]; 1.148 + int ccount = 0; 1.149 + char *ptr; 1.150 + 1.151 +#ifdef __linux__ 1.152 + ccount = readlink("/proc/self/exe", path, MAX_PATH - 1); 1.153 +#endif /* __linux__ */ 1.154 + 1.155 +#ifdef __FreeBSD__ 1.156 + ccount = readlink("/proc/curproc/file", path, MAX_PATH - 1); 1.157 +#endif /* __FreeBSD__ */ 1.158 + 1.159 +#ifdef WIN32 1.160 + ccount = GetModuleFileName(0, path, MAX_PATH - 1); 1.161 +#endif /* WIN32 */ 1.162 + 1.163 + if(!ccount) return 0; 1.164 + 1.165 + path[ccount] = 0; 1.166 + 1.167 + ptr = strrchr(path, DIR_SEP); 1.168 + if(!ptr) return 0; 1.169 + 1.170 + *(ptr + 1) = 0; 1.171 + 1.172 + return path; 1.173 +}