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 +}