dynwatch

changeset 0:ce3c5e4c75bf tip

dynwatch DynDNS updater for windows
author John Tsiombikas <nuclear@siggraph.org>
date Wed, 18 May 2011 05:53:29 +0300
parents
children
files README.txt authors.txt config_parser.c config_parser.h dynwatch.ico dynwatch.rc events.c events.h gui.c gui.h license.txt locator.c locator.h resource.h socklib.c socklib.h tray.c tray.sln tray.vcproj watch.c watch.h
diffstat 21 files changed, 1854 insertions(+), 0 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/README.txt	Wed May 18 05:53:29 2011 +0300
     1.3 @@ -0,0 +1,18 @@
     1.4 +Dynwatch is a system tray applet which automaticaly updates dynamic dns entries
     1.5 +for the quake.gr dyndns service.
     1.6 +(Actually with very little efort, adding one more option to the configuration,
     1.7 +it should be able to work with any dyndns service out there).
     1.8 +
     1.9 +PLEASE NOTE:
    1.10 +This program is free software, released under the GNU General Public License.
    1.11 +This means that you have the right to run this program for any purpose,
    1.12 +distribute it freely, modify it to suit your needs and release any modified
    1.13 +version if you so wish. In order for this to happen you MUST have access to the
    1.14 +source code of this program, which in turn means that anyone who distributes
    1.15 +this program in binary form, must distribute the source code as well in a
    1.16 +similar manner, or provide you with a clear notice which states that they will
    1.17 +provide the source code to you if you ask for it.
    1.18 +If the above conditions are not met, please contact me through email
    1.19 +<nuclear@siggraph.org> and let me know about it.
    1.20 +
    1.21 +Read license.txt for the full text of the General Public License.
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/authors.txt	Wed May 18 05:53:29 2011 +0300
     2.3 @@ -0,0 +1,3 @@
     2.4 +dynwatch was written by:
     2.5 +	John Tsiombikas <nuclear@siggraph.org>
     2.6 +	http://thelab.demoscene.gr/nuclear/
     2.7 \ No newline at end of file
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/config_parser.c	Wed May 18 05:53:29 2011 +0300
     3.3 @@ -0,0 +1,141 @@
     3.4 +/*
     3.5 +This file is part of dynwatch, a win32 system tray applet which
     3.6 +updates automatically the dyndns entry of quake.gr.
     3.7 +
     3.8 +Copyright (c) 2005 John Tsiombikas <nuclear@siggraph.org>
     3.9 +
    3.10 +This program is free software; you can redistribute it and/or modify
    3.11 +it under the terms of the GNU General Public License as published by
    3.12 +the Free Software Foundation; either version 2 of the License, or
    3.13 +(at your option) any later version.
    3.14 +
    3.15 +This program is distributed in the hope that it will be useful,
    3.16 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.17 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.18 +GNU General Public License for more details.
    3.19 +
    3.20 +You should have received a copy of the GNU General Public License
    3.21 +along with this program; if not, write to the Free Software
    3.22 +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    3.23 +*/
    3.24 +#include <stdio.h>
    3.25 +#include <string.h>
    3.26 +#include <stdlib.h>
    3.27 +#include <ctype.h>
    3.28 +#include "config_parser.h"
    3.29 +
    3.30 +/* state variables */
    3.31 +static char sym_assign = '=';
    3.32 +static char sym_comment = ';';
    3.33 +static char max_line_len = 100;
    3.34 +static char seperators[257] = " \t";
    3.35 +static struct ConfigOption cfg_opt;
    3.36 +
    3.37 +static char *config_file, *cfgptr;
    3.38 +
    3.39 +void SetParserState(enum ParserState state, int value) {
    3.40 +	switch(state) {
    3.41 +	case PS_AssignmentSymbol:
    3.42 +		sym_assign = (char)value;
    3.43 +		break;
    3.44 +
    3.45 +	case PS_CommentSymbol:
    3.46 +		sym_comment = (char)value;
    3.47 +		break;
    3.48 +
    3.49 +	case PS_MaxLineLen:
    3.50 +		max_line_len = value;
    3.51 +		break;
    3.52 +
    3.53 +	case PS_Seperators:
    3.54 +		strncpy(seperators, (char*)value, 257);
    3.55 +		break;
    3.56 +	}
    3.57 +}
    3.58 +
    3.59 +int LoadConfigFile(const char *fname) {
    3.60 +	FILE *fp;
    3.61 +	int fsize;
    3.62 +	char *temp;
    3.63 +
    3.64 +	if(!fname) return -1;
    3.65 +	if(!(fp = fopen(fname, "r"))) return -1;
    3.66 +
    3.67 +	fseek(fp, 0, SEEK_END);
    3.68 +	fsize = ftell(fp);
    3.69 +	fseek(fp, 0, SEEK_SET);
    3.70 +
    3.71 +	if(!(temp = realloc(config_file, fsize))) return -1;
    3.72 +	config_file = temp;
    3.73 +
    3.74 +	cfgptr = config_file;
    3.75 +	temp = malloc(max_line_len + 1);
    3.76 +	while(fgets(temp, max_line_len, fp)) {
    3.77 +		char *ptr = temp;
    3.78 +
    3.79 +		if(*ptr == '\n') continue;	/* kill empty lines, they irritate the parser */
    3.80 +
    3.81 +		while(ptr && *ptr && *ptr != sym_comment) {
    3.82 +			if(!strchr(seperators, *ptr)) {	/* not a seperator */
    3.83 +				*cfgptr++ = *ptr;
    3.84 +			}
    3.85 +			ptr++;
    3.86 +		}
    3.87 +
    3.88 +		if(*ptr == sym_comment && ptr != temp) {
    3.89 +			*cfgptr++ = '\n';
    3.90 +		}
    3.91 +	}
    3.92 +
    3.93 +	*cfgptr = 0;
    3.94 +
    3.95 +	memset(&cfg_opt, 0, sizeof(struct ConfigOption));
    3.96 +	cfgptr = config_file;
    3.97 +	free(temp);
    3.98 +	return 0;
    3.99 +}
   3.100 +
   3.101 +const struct ConfigOption *GetNextOption() {
   3.102 +	char *tmpbuf = malloc(max_line_len + 1);
   3.103 +	char *ptr = tmpbuf;
   3.104 +
   3.105 +	if(!(*cfgptr)) {
   3.106 +		free(tmpbuf);
   3.107 +		return 0;
   3.108 +	}
   3.109 +
   3.110 +	while(*cfgptr != '\n') {
   3.111 +		*ptr++ = *cfgptr++;
   3.112 +	}
   3.113 +	*ptr = 0;
   3.114 +	cfgptr++;
   3.115 +
   3.116 +	if(!(ptr = strchr(tmpbuf, sym_assign))) {
   3.117 +		free(tmpbuf);
   3.118 +		return 0;
   3.119 +	}
   3.120 +	*ptr++ = 0;
   3.121 +
   3.122 +	cfg_opt.flags = 0;
   3.123 +
   3.124 +	cfg_opt.option = realloc(cfg_opt.option, strlen(tmpbuf) + 1);
   3.125 +	strcpy(cfg_opt.option, tmpbuf);
   3.126 +
   3.127 +	cfg_opt.str_value = realloc(cfg_opt.str_value, strlen(ptr) + 1);
   3.128 +	strcpy(cfg_opt.str_value, ptr);
   3.129 +
   3.130 +	if(isdigit(cfg_opt.str_value[0])) {
   3.131 +		cfg_opt.flags |= CFGOPT_INT;
   3.132 +		cfg_opt.int_value = atoi(cfg_opt.str_value);
   3.133 +		cfg_opt.flt_value = atof(cfg_opt.str_value);
   3.134 +	}
   3.135 +
   3.136 +	free(tmpbuf);
   3.137 +	return &cfg_opt;
   3.138 +}
   3.139 +
   3.140 +void DestroyConfigParser() {
   3.141 +	if(cfg_opt.str_value) free(cfg_opt.str_value);
   3.142 +	if(cfg_opt.option) free(cfg_opt.option);
   3.143 +	if(config_file) free(config_file);
   3.144 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/config_parser.h	Wed May 18 05:53:29 2011 +0300
     4.3 @@ -0,0 +1,57 @@
     4.4 +/*
     4.5 +This file is part of dynwatch, a win32 system tray applet which
     4.6 +updates automatically the dyndns entry of quake.gr.
     4.7 +
     4.8 +Copyright (c) 2005 John Tsiombikas <nuclear@siggraph.org>
     4.9 +
    4.10 +This program is free software; you can redistribute it and/or modify
    4.11 +it under the terms of the GNU General Public License as published by
    4.12 +the Free Software Foundation; either version 2 of the License, or
    4.13 +(at your option) any later version.
    4.14 +
    4.15 +This program is distributed in the hope that it will be useful,
    4.16 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.17 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.18 +GNU General Public License for more details.
    4.19 +
    4.20 +You should have received a copy of the GNU General Public License
    4.21 +along with this program; if not, write to the Free Software
    4.22 +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    4.23 +*/
    4.24 +#ifndef _CONFIG_PARSER_H_
    4.25 +#define _CONFIG_PARSER_H_
    4.26 +
    4.27 +
    4.28 +#ifdef __cplusplus
    4.29 +extern "C" {
    4.30 +#endif	/* _cplusplus */
    4.31 +
    4.32 +
    4.33 +enum ParserState {
    4.34 +	PS_AssignmentSymbol,
    4.35 +	PS_CommentSymbol,
    4.36 +	PS_Seperators,
    4.37 +	PS_MaxLineLen
    4.38 +};
    4.39 +
    4.40 +#define CFGOPT_INT	1
    4.41 +#define CFGOPT_FLT	2
    4.42 +
    4.43 +struct ConfigOption {
    4.44 +	char *option, *str_value;
    4.45 +	int int_value;
    4.46 +	float flt_value;
    4.47 +	unsigned short flags;
    4.48 +};
    4.49 +
    4.50 +void SetParserState(enum ParserState state, int value);
    4.51 +int LoadConfigFile(const char *fname);
    4.52 +const struct ConfigOption *GetNextOption();
    4.53 +void DestroyConfigParser();
    4.54 +
    4.55 +
    4.56 +#ifdef __cplusplus
    4.57 +}
    4.58 +#endif	/* _cplusplus */
    4.59 +
    4.60 +#endif	/* _CONFIG_PARSER_H_ */
     5.1 Binary file dynwatch.ico has changed
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/dynwatch.rc	Wed May 18 05:53:29 2011 +0300
     6.3 @@ -0,0 +1,3 @@
     6.4 +#include "resource.h"
     6.5 +
     6.6 +ICON_DYNWATCH	ICON	dynwatch.ico
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/events.c	Wed May 18 05:53:29 2011 +0300
     7.3 @@ -0,0 +1,116 @@
     7.4 +/*
     7.5 +This file is part of dynwatch, a win32 system tray applet which
     7.6 +updates automatically the dyndns entry of quake.gr.
     7.7 +
     7.8 +Copyright (c) 2005 John Tsiombikas <nuclear@siggraph.org>
     7.9 +
    7.10 +This program is free software; you can redistribute it and/or modify
    7.11 +it under the terms of the GNU General Public License as published by
    7.12 +the Free Software Foundation; either version 2 of the License, or
    7.13 +(at your option) any later version.
    7.14 +
    7.15 +This program is distributed in the hope that it will be useful,
    7.16 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.17 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    7.18 +GNU General Public License for more details.
    7.19 +
    7.20 +You should have received a copy of the GNU General Public License
    7.21 +along with this program; if not, write to the Free Software
    7.22 +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    7.23 +*/
    7.24 +
    7.25 +#include <windows.h>
    7.26 +#include "watch.h"
    7.27 +#include "gui.h"
    7.28 +
    7.29 +extern int running;
    7.30 +
    7.31 +long CALLBACK win_proc(HWND win, unsigned int msg, unsigned int wparam, long lparam) {
    7.32 +	switch(msg) {
    7.33 +	case WM_CLOSE:
    7.34 +		DestroyWindow(win);
    7.35 +		PostQuitMessage(0);
    7.36 +		return 0;
    7.37 +
    7.38 +	case WM_COMMAND:
    7.39 +		if((HWND)lparam == bn_tray) {
    7.40 +			trayfied = !trayfied;
    7.41 +			if(trayfied && !running) {
    7.42 +				info_msg("If you want to have this program operational, you MUST configure first.\nGoing to the tray but keep in mind that I can't do anything at this point without configuration!");
    7.43 +			}
    7.44 +			tray(trayfied);
    7.45 +		}
    7.46 +
    7.47 +		if((HWND)lparam == bn_exit) {
    7.48 +			DestroyWindow(win);
    7.49 +			PostQuitMessage(0);
    7.50 +		}
    7.51 +
    7.52 +		if((HWND)lparam == bn_config) {
    7.53 +			en_set_text(en_dnshost, dhost);
    7.54 +			en_set_text(en_user, user);
    7.55 +			en_set_text(en_pass, pass);
    7.56 +			en_set_text(en_hosts, hosts);
    7.57 +			ShowWindow(win_cfg, 1);
    7.58 +		}
    7.59 +		return 0;
    7.60 +
    7.61 +	case WM_USER:
    7.62 +		if(lparam == WM_LBUTTONUP) {
    7.63 +			trayfied = !trayfied;
    7.64 +			tray(trayfied);
    7.65 +		}
    7.66 +		return 0;
    7.67 +
    7.68 +	case WM_TIMER:
    7.69 +		if(need_update()) {
    7.70 +			update_dns();
    7.71 +		}
    7.72 +		return 0;
    7.73 +
    7.74 +	default:
    7.75 +		break;
    7.76 +	}
    7.77 +
    7.78 +	return DefWindowProc(win, msg, wparam, lparam);
    7.79 +}
    7.80 +
    7.81 +
    7.82 +int empty_str(const char *str) {
    7.83 +	while(*str) if(isalnum(*str++)) return 0;
    7.84 +	return 1;
    7.85 +}
    7.86 +
    7.87 +long CALLBACK cfg_proc(HWND win, unsigned int msg, unsigned int wparam, long lparam) {
    7.88 +	switch(msg) {
    7.89 +	case WM_COMMAND:
    7.90 +		if((HWND)lparam == bn_ok) {
    7.91 +			if(empty_str(en_get_text(en_dnshost)) ||
    7.92 +				empty_str(en_get_text(en_user)) ||
    7.93 +				empty_str(en_get_text(en_pass)) ||
    7.94 +				empty_str(en_get_text(en_hosts))) {
    7.95 +				err_msg("you must fill all the fields of this configuration dialog!");
    7.96 +				return 0;
    7.97 +			}
    7.98 +
    7.99 +			strncpy(dhost, en_get_text(en_dnshost), 256);
   7.100 +			strncpy(user, en_get_text(en_user), 256);
   7.101 +			strncpy(pass, en_get_text(en_pass), 256);
   7.102 +			strncpy(hosts, en_get_text(en_hosts), 256);
   7.103 +
   7.104 +			save_config();
   7.105 +			running = 1;
   7.106 +			ShowWindow(win_cfg, 0);
   7.107 +		}
   7.108 +
   7.109 +		if((HWND)lparam == bn_cancel) {
   7.110 +			ShowWindow(win_cfg, 0);
   7.111 +		}
   7.112 +		return 0;
   7.113 +
   7.114 +	default:
   7.115 +		break;
   7.116 +	}
   7.117 +
   7.118 +	return DefWindowProc(win, msg, wparam, lparam);
   7.119 +}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/events.h	Wed May 18 05:53:29 2011 +0300
     8.3 @@ -0,0 +1,28 @@
     8.4 +/*
     8.5 +This file is part of dynwatch, a win32 system tray applet which
     8.6 +updates automatically the dyndns entry of quake.gr.
     8.7 +
     8.8 +Copyright (c) 2005 John Tsiombikas <nuclear@siggraph.org>
     8.9 +
    8.10 +This program is free software; you can redistribute it and/or modify
    8.11 +it under the terms of the GNU General Public License as published by
    8.12 +the Free Software Foundation; either version 2 of the License, or
    8.13 +(at your option) any later version.
    8.14 +
    8.15 +This program is distributed in the hope that it will be useful,
    8.16 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.17 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    8.18 +GNU General Public License for more details.
    8.19 +
    8.20 +You should have received a copy of the GNU General Public License
    8.21 +along with this program; if not, write to the Free Software
    8.22 +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    8.23 +*/
    8.24 +
    8.25 +#ifndef _EVENTS_H_
    8.26 +#define _EVENTS_H_
    8.27 +
    8.28 +long CALLBACK win_proc(HWND win, unsigned int msg, unsigned int wparam, long lparam);
    8.29 +long CALLBACK cfg_proc(HWND win, unsigned int msg, unsigned int wparam, long lparam);
    8.30 +
    8.31 +#endif	/* _EVENTS_H_ */
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/gui.c	Wed May 18 05:53:29 2011 +0300
     9.3 @@ -0,0 +1,134 @@
     9.4 +/*
     9.5 +This file is part of dynwatch, a win32 system tray applet which
     9.6 +updates automatically the dyndns entry of quake.gr.
     9.7 +
     9.8 +Copyright (c) 2005 John Tsiombikas <nuclear@siggraph.org>
     9.9 +
    9.10 +This program is free software; you can redistribute it and/or modify
    9.11 +it under the terms of the GNU General Public License as published by
    9.12 +the Free Software Foundation; either version 2 of the License, or
    9.13 +(at your option) any later version.
    9.14 +
    9.15 +This program is distributed in the hope that it will be useful,
    9.16 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    9.17 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    9.18 +GNU General Public License for more details.
    9.19 +
    9.20 +You should have received a copy of the GNU General Public License
    9.21 +along with this program; if not, write to the Free Software
    9.22 +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    9.23 +*/
    9.24 +
    9.25 +#include "gui.h"
    9.26 +#include "events.h"
    9.27 +#include "resource.h"
    9.28 +
    9.29 +HWND win_main, bn_exit, bn_tray, bn_config;
    9.30 +HWND win_cfg, lb_dnshost, lb_user, lb_pass, lb_hosts;
    9.31 +HWND en_dnshost, en_user, en_pass, en_hosts;
    9.32 +HWND bn_ok, bn_cancel;
    9.33 +int trayfied;
    9.34 +
    9.35 +void create_gui(void) {
    9.36 +	static const int lb_xsz = 130;
    9.37 +	static const int lb_ysz = 20;
    9.38 +	static const int en_xsz = 100;
    9.39 +	static const int en_ysz = 20;
    9.40 +	static const int yinc = 25;
    9.41 +	int ypos = 5;
    9.42 +
    9.43 +	reg_win_class("dynwatch", win_proc);
    9.44 +	reg_win_class("dynwatch.config", cfg_proc);
    9.45 +
    9.46 +	win_main = create_window("dynwatch 1.0", 330, 80, "dynwatch");
    9.47 +	bn_config = create_button("Configure", 5, 5, 100, 30, win_main);
    9.48 +	bn_tray = create_button("Send to tray", 110, 5, 100, 30, win_main);
    9.49 +	bn_exit = create_button("Exit", 215, 5, 100, 30, win_main);
    9.50 +	ShowWindow(win_main, 1);
    9.51 +
    9.52 +	win_cfg = create_window("Configuration", 270, 190, "dynwatch.config");
    9.53 +
    9.54 +	lb_dnshost = create_label("dyndns host:", 5, ypos, lb_xsz, lb_ysz, win_cfg);
    9.55 +	en_dnshost = create_entry("", lb_xsz + 10, ypos, en_xsz, en_ysz, win_cfg);
    9.56 +	ypos += yinc;
    9.57 +	lb_user = create_label("user name:", 5, ypos, lb_xsz, lb_ysz, win_cfg);
    9.58 +	en_user = create_entry("", lb_xsz + 10, ypos, en_xsz, en_ysz, win_cfg);
    9.59 +	ypos += yinc;
    9.60 +	lb_pass = create_label("password:", 5, ypos, lb_xsz, lb_ysz, win_cfg);
    9.61 +	en_pass = create_entry("", lb_xsz + 10, ypos, en_xsz, en_ysz, win_cfg);
    9.62 +	ypos += yinc;
    9.63 +	/*lb_hosts = create_label("hosts to update:", 5, ypos, lb_xsz, lb_ysz, win_cfg);
    9.64 +	en_hosts = create_entry("", lb_xsz + 10, ypos, en_xsz, en_ysz, win_cfg);*/
    9.65 +
    9.66 +	ypos += 35;
    9.67 +	bn_ok = create_button("OK", 5, ypos, 100, 25, win_cfg);
    9.68 +	bn_cancel = create_button("Cancel", 140, ypos, 100, 25, win_cfg);
    9.69 +}
    9.70 +
    9.71 +void tray(int trayfy) {
    9.72 +	NOTIFYICONDATA nicon;
    9.73 +	memset(&nicon, 0, sizeof nicon);
    9.74 +	nicon.cbSize = sizeof nicon;
    9.75 +	nicon.hWnd = win_main;
    9.76 +	nicon.uID = 0;
    9.77 +	nicon.uCallbackMessage = WM_USER;
    9.78 +	nicon.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE;
    9.79 +	nicon.hIcon = LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(ICON_DYNWATCH));
    9.80 +	strcpy(nicon.szTip, "Click to open the program window");
    9.81 +
    9.82 +	if(trayfy) {
    9.83 +		ShowWindow(win_main, 0);
    9.84 +        Shell_NotifyIcon(NIM_ADD, &nicon);
    9.85 +	} else {
    9.86 +		Shell_NotifyIcon(NIM_DELETE, &nicon);
    9.87 +		ShowWindow(win_main, 1);
    9.88 +	}
    9.89 +}
    9.90 +
    9.91 +HWND create_window(const char *title, int xsz, int ysz, const char *class_name) {
    9.92 +	int x = (GetSystemMetrics(SM_CXSCREEN) - xsz) / 2;
    9.93 +	int y = (GetSystemMetrics(SM_CYSCREEN) - ysz) / 2;
    9.94 +	unsigned long style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU;
    9.95 +	return CreateWindow(class_name, title, style, x, y, xsz, ysz, 0, 0, GetModuleHandle(0), 0);
    9.96 +}
    9.97 +
    9.98 +HWND create_button(const char *title, int x, int y, int xsz, int ysz, HWND parent) {
    9.99 +	unsigned long style = BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP;
   9.100 +	return CreateWindow("BUTTON", title, style, x, y, xsz, ysz, parent, 0, GetModuleHandle(0), 0);
   9.101 +}
   9.102 +
   9.103 +HWND create_label(const char *text, int x, int y, int xsz, int ysz, HWND parent) {
   9.104 +	unsigned long style = SS_RIGHT | WS_CHILD | WS_VISIBLE;
   9.105 +	return CreateWindow("STATIC", text, style, x, y, xsz, ysz, parent, 0, GetModuleHandle(0), 0);
   9.106 +}
   9.107 +
   9.108 +HWND create_entry(const char *text, int x, int y, int xsz, int ysz, HWND parent) {
   9.109 +	unsigned long style = ES_AUTOHSCROLL | WS_CHILD | WS_BORDER | WS_TABSTOP | WS_VISIBLE;
   9.110 +	return CreateWindow("EDIT", text, style, x, y, xsz, ysz, parent, 0, GetModuleHandle(0), 0);
   9.111 +}
   9.112 +
   9.113 +void en_set_text(HWND entry, const char *text) {
   9.114 +	SendMessage(entry, WM_SETTEXT, 0, (long)text);
   9.115 +}
   9.116 +
   9.117 +const char *en_get_text(HWND entry) {
   9.118 +	static char buf[512];
   9.119 +	SendMessage(entry, WM_GETTEXT, 512, (long)buf);
   9.120 +	return buf;
   9.121 +}
   9.122 +
   9.123 +void reg_win_class(const char *class_name, msg_handler_t handler) {
   9.124 +	WNDCLASSEX wc;
   9.125 +	HINSTANCE pid = GetModuleHandle(0);
   9.126 +
   9.127 +	memset(&wc, 0, sizeof wc);
   9.128 +	wc.cbSize = sizeof wc;
   9.129 +	wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
   9.130 +	wc.hCursor = LoadCursor(pid, MAKEINTRESOURCE(IDC_ARROW));
   9.131 +	wc.hIcon = wc.hIconSm = LoadIcon(pid, MAKEINTRESOURCE(ICON_DYNWATCH));
   9.132 +	wc.hInstance = pid;
   9.133 +	wc.lpfnWndProc = handler;
   9.134 +	wc.lpszClassName = class_name;
   9.135 +	wc.style = CS_HREDRAW | CS_VREDRAW;
   9.136 +	RegisterClassEx(&wc);
   9.137 +}
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/gui.h	Wed May 18 05:53:29 2011 +0300
    10.3 @@ -0,0 +1,51 @@
    10.4 +/*
    10.5 +This file is part of dynwatch, a win32 system tray applet which
    10.6 +updates automatically the dyndns entry of quake.gr.
    10.7 +
    10.8 +Copyright (c) 2005 John Tsiombikas <nuclear@siggraph.org>
    10.9 +
   10.10 +This program is free software; you can redistribute it and/or modify
   10.11 +it under the terms of the GNU General Public License as published by
   10.12 +the Free Software Foundation; either version 2 of the License, or
   10.13 +(at your option) any later version.
   10.14 +
   10.15 +This program is distributed in the hope that it will be useful,
   10.16 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   10.17 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   10.18 +GNU General Public License for more details.
   10.19 +
   10.20 +You should have received a copy of the GNU General Public License
   10.21 +along with this program; if not, write to the Free Software
   10.22 +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   10.23 +*/
   10.24 +
   10.25 +#ifndef _GUI_H_
   10.26 +#define _GUI_H_
   10.27 +
   10.28 +#include <windows.h>
   10.29 +
   10.30 +typedef long (CALLBACK *msg_handler_t)(HWND, unsigned int, unsigned int, long);
   10.31 +
   10.32 +/* widgets */
   10.33 +extern HWND win_main, bn_exit, bn_tray, bn_config;
   10.34 +extern HWND win_cfg, lb_dnshost, lb_user, lb_pass, lb_hosts;
   10.35 +extern HWND en_dnshost, en_user, en_pass, en_hosts;
   10.36 +extern HWND bn_ok, bn_cancel;
   10.37 +
   10.38 +/* state, 1 = minimized to system tray, 0 = window visible */
   10.39 +extern int trayfied;
   10.40 +
   10.41 +void create_gui(void);
   10.42 +
   10.43 +void tray(int trayfy);
   10.44 +HWND create_window(const char *title, int xsz, int ysz, const char *class_name);
   10.45 +HWND create_button(const char *title, int x, int y, int xsz, int ysz, HWND parent);
   10.46 +HWND create_label(const char *text, int x, int y, int xsz, int ysz, HWND parent);
   10.47 +HWND create_entry(const char *text, int x, int y, int xsz, int ysz, HWND parent);
   10.48 +
   10.49 +void en_set_text(HWND entry, const char *text);
   10.50 +const char *en_get_text(HWND entry);
   10.51 +
   10.52 +void reg_win_class(const char *class_name, msg_handler_t handler);
   10.53 +
   10.54 +#endif	/* _GUI_H_ */
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/license.txt	Wed May 18 05:53:29 2011 +0300
    11.3 @@ -0,0 +1,340 @@
    11.4 +		    GNU GENERAL PUBLIC LICENSE
    11.5 +		       Version 2, June 1991
    11.6 +
    11.7 + Copyright (C) 1989, 1991 Free Software Foundation, Inc.
    11.8 +                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    11.9 + Everyone is permitted to copy and distribute verbatim copies
   11.10 + of this license document, but changing it is not allowed.
   11.11 +
   11.12 +			    Preamble
   11.13 +
   11.14 +  The licenses for most software are designed to take away your
   11.15 +freedom to share and change it.  By contrast, the GNU General Public
   11.16 +License is intended to guarantee your freedom to share and change free
   11.17 +software--to make sure the software is free for all its users.  This
   11.18 +General Public License applies to most of the Free Software
   11.19 +Foundation's software and to any other program whose authors commit to
   11.20 +using it.  (Some other Free Software Foundation software is covered by
   11.21 +the GNU Library General Public License instead.)  You can apply it to
   11.22 +your programs, too.
   11.23 +
   11.24 +  When we speak of free software, we are referring to freedom, not
   11.25 +price.  Our General Public Licenses are designed to make sure that you
   11.26 +have the freedom to distribute copies of free software (and charge for
   11.27 +this service if you wish), that you receive source code or can get it
   11.28 +if you want it, that you can change the software or use pieces of it
   11.29 +in new free programs; and that you know you can do these things.
   11.30 +
   11.31 +  To protect your rights, we need to make restrictions that forbid
   11.32 +anyone to deny you these rights or to ask you to surrender the rights.
   11.33 +These restrictions translate to certain responsibilities for you if you
   11.34 +distribute copies of the software, or if you modify it.
   11.35 +
   11.36 +  For example, if you distribute copies of such a program, whether
   11.37 +gratis or for a fee, you must give the recipients all the rights that
   11.38 +you have.  You must make sure that they, too, receive or can get the
   11.39 +source code.  And you must show them these terms so they know their
   11.40 +rights.
   11.41 +
   11.42 +  We protect your rights with two steps: (1) copyright the software, and
   11.43 +(2) offer you this license which gives you legal permission to copy,
   11.44 +distribute and/or modify the software.
   11.45 +
   11.46 +  Also, for each author's protection and ours, we want to make certain
   11.47 +that everyone understands that there is no warranty for this free
   11.48 +software.  If the software is modified by someone else and passed on, we
   11.49 +want its recipients to know that what they have is not the original, so
   11.50 +that any problems introduced by others will not reflect on the original
   11.51 +authors' reputations.
   11.52 +
   11.53 +  Finally, any free program is threatened constantly by software
   11.54 +patents.  We wish to avoid the danger that redistributors of a free
   11.55 +program will individually obtain patent licenses, in effect making the
   11.56 +program proprietary.  To prevent this, we have made it clear that any
   11.57 +patent must be licensed for everyone's free use or not licensed at all.
   11.58 +
   11.59 +  The precise terms and conditions for copying, distribution and
   11.60 +modification follow.
   11.61 +
   11.62 +		    GNU GENERAL PUBLIC LICENSE
   11.63 +   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
   11.64 +
   11.65 +  0. This License applies to any program or other work which contains
   11.66 +a notice placed by the copyright holder saying it may be distributed
   11.67 +under the terms of this General Public License.  The "Program", below,
   11.68 +refers to any such program or work, and a "work based on the Program"
   11.69 +means either the Program or any derivative work under copyright law:
   11.70 +that is to say, a work containing the Program or a portion of it,
   11.71 +either verbatim or with modifications and/or translated into another
   11.72 +language.  (Hereinafter, translation is included without limitation in
   11.73 +the term "modification".)  Each licensee is addressed as "you".
   11.74 +
   11.75 +Activities other than copying, distribution and modification are not
   11.76 +covered by this License; they are outside its scope.  The act of
   11.77 +running the Program is not restricted, and the output from the Program
   11.78 +is covered only if its contents constitute a work based on the
   11.79 +Program (independent of having been made by running the Program).
   11.80 +Whether that is true depends on what the Program does.
   11.81 +
   11.82 +  1. You may copy and distribute verbatim copies of the Program's
   11.83 +source code as you receive it, in any medium, provided that you
   11.84 +conspicuously and appropriately publish on each copy an appropriate
   11.85 +copyright notice and disclaimer of warranty; keep intact all the
   11.86 +notices that refer to this License and to the absence of any warranty;
   11.87 +and give any other recipients of the Program a copy of this License
   11.88 +along with the Program.
   11.89 +
   11.90 +You may charge a fee for the physical act of transferring a copy, and
   11.91 +you may at your option offer warranty protection in exchange for a fee.
   11.92 +
   11.93 +  2. You may modify your copy or copies of the Program or any portion
   11.94 +of it, thus forming a work based on the Program, and copy and
   11.95 +distribute such modifications or work under the terms of Section 1
   11.96 +above, provided that you also meet all of these conditions:
   11.97 +
   11.98 +    a) You must cause the modified files to carry prominent notices
   11.99 +    stating that you changed the files and the date of any change.
  11.100 +
  11.101 +    b) You must cause any work that you distribute or publish, that in
  11.102 +    whole or in part contains or is derived from the Program or any
  11.103 +    part thereof, to be licensed as a whole at no charge to all third
  11.104 +    parties under the terms of this License.
  11.105 +
  11.106 +    c) If the modified program normally reads commands interactively
  11.107 +    when run, you must cause it, when started running for such
  11.108 +    interactive use in the most ordinary way, to print or display an
  11.109 +    announcement including an appropriate copyright notice and a
  11.110 +    notice that there is no warranty (or else, saying that you provide
  11.111 +    a warranty) and that users may redistribute the program under
  11.112 +    these conditions, and telling the user how to view a copy of this
  11.113 +    License.  (Exception: if the Program itself is interactive but
  11.114 +    does not normally print such an announcement, your work based on
  11.115 +    the Program is not required to print an announcement.)
  11.116 +
  11.117 +These requirements apply to the modified work as a whole.  If
  11.118 +identifiable sections of that work are not derived from the Program,
  11.119 +and can be reasonably considered independent and separate works in
  11.120 +themselves, then this License, and its terms, do not apply to those
  11.121 +sections when you distribute them as separate works.  But when you
  11.122 +distribute the same sections as part of a whole which is a work based
  11.123 +on the Program, the distribution of the whole must be on the terms of
  11.124 +this License, whose permissions for other licensees extend to the
  11.125 +entire whole, and thus to each and every part regardless of who wrote it.
  11.126 +
  11.127 +Thus, it is not the intent of this section to claim rights or contest
  11.128 +your rights to work written entirely by you; rather, the intent is to
  11.129 +exercise the right to control the distribution of derivative or
  11.130 +collective works based on the Program.
  11.131 +
  11.132 +In addition, mere aggregation of another work not based on the Program
  11.133 +with the Program (or with a work based on the Program) on a volume of
  11.134 +a storage or distribution medium does not bring the other work under
  11.135 +the scope of this License.
  11.136 +
  11.137 +  3. You may copy and distribute the Program (or a work based on it,
  11.138 +under Section 2) in object code or executable form under the terms of
  11.139 +Sections 1 and 2 above provided that you also do one of the following:
  11.140 +
  11.141 +    a) Accompany it with the complete corresponding machine-readable
  11.142 +    source code, which must be distributed under the terms of Sections
  11.143 +    1 and 2 above on a medium customarily used for software interchange; or,
  11.144 +
  11.145 +    b) Accompany it with a written offer, valid for at least three
  11.146 +    years, to give any third party, for a charge no more than your
  11.147 +    cost of physically performing source distribution, a complete
  11.148 +    machine-readable copy of the corresponding source code, to be
  11.149 +    distributed under the terms of Sections 1 and 2 above on a medium
  11.150 +    customarily used for software interchange; or,
  11.151 +
  11.152 +    c) Accompany it with the information you received as to the offer
  11.153 +    to distribute corresponding source code.  (This alternative is
  11.154 +    allowed only for noncommercial distribution and only if you
  11.155 +    received the program in object code or executable form with such
  11.156 +    an offer, in accord with Subsection b above.)
  11.157 +
  11.158 +The source code for a work means the preferred form of the work for
  11.159 +making modifications to it.  For an executable work, complete source
  11.160 +code means all the source code for all modules it contains, plus any
  11.161 +associated interface definition files, plus the scripts used to
  11.162 +control compilation and installation of the executable.  However, as a
  11.163 +special exception, the source code distributed need not include
  11.164 +anything that is normally distributed (in either source or binary
  11.165 +form) with the major components (compiler, kernel, and so on) of the
  11.166 +operating system on which the executable runs, unless that component
  11.167 +itself accompanies the executable.
  11.168 +
  11.169 +If distribution of executable or object code is made by offering
  11.170 +access to copy from a designated place, then offering equivalent
  11.171 +access to copy the source code from the same place counts as
  11.172 +distribution of the source code, even though third parties are not
  11.173 +compelled to copy the source along with the object code.
  11.174 +
  11.175 +  4. You may not copy, modify, sublicense, or distribute the Program
  11.176 +except as expressly provided under this License.  Any attempt
  11.177 +otherwise to copy, modify, sublicense or distribute the Program is
  11.178 +void, and will automatically terminate your rights under this License.
  11.179 +However, parties who have received copies, or rights, from you under
  11.180 +this License will not have their licenses terminated so long as such
  11.181 +parties remain in full compliance.
  11.182 +
  11.183 +  5. You are not required to accept this License, since you have not
  11.184 +signed it.  However, nothing else grants you permission to modify or
  11.185 +distribute the Program or its derivative works.  These actions are
  11.186 +prohibited by law if you do not accept this License.  Therefore, by
  11.187 +modifying or distributing the Program (or any work based on the
  11.188 +Program), you indicate your acceptance of this License to do so, and
  11.189 +all its terms and conditions for copying, distributing or modifying
  11.190 +the Program or works based on it.
  11.191 +
  11.192 +  6. Each time you redistribute the Program (or any work based on the
  11.193 +Program), the recipient automatically receives a license from the
  11.194 +original licensor to copy, distribute or modify the Program subject to
  11.195 +these terms and conditions.  You may not impose any further
  11.196 +restrictions on the recipients' exercise of the rights granted herein.
  11.197 +You are not responsible for enforcing compliance by third parties to
  11.198 +this License.
  11.199 +
  11.200 +  7. If, as a consequence of a court judgment or allegation of patent
  11.201 +infringement or for any other reason (not limited to patent issues),
  11.202 +conditions are imposed on you (whether by court order, agreement or
  11.203 +otherwise) that contradict the conditions of this License, they do not
  11.204 +excuse you from the conditions of this License.  If you cannot
  11.205 +distribute so as to satisfy simultaneously your obligations under this
  11.206 +License and any other pertinent obligations, then as a consequence you
  11.207 +may not distribute the Program at all.  For example, if a patent
  11.208 +license would not permit royalty-free redistribution of the Program by
  11.209 +all those who receive copies directly or indirectly through you, then
  11.210 +the only way you could satisfy both it and this License would be to
  11.211 +refrain entirely from distribution of the Program.
  11.212 +
  11.213 +If any portion of this section is held invalid or unenforceable under
  11.214 +any particular circumstance, the balance of the section is intended to
  11.215 +apply and the section as a whole is intended to apply in other
  11.216 +circumstances.
  11.217 +
  11.218 +It is not the purpose of this section to induce you to infringe any
  11.219 +patents or other property right claims or to contest validity of any
  11.220 +such claims; this section has the sole purpose of protecting the
  11.221 +integrity of the free software distribution system, which is
  11.222 +implemented by public license practices.  Many people have made
  11.223 +generous contributions to the wide range of software distributed
  11.224 +through that system in reliance on consistent application of that
  11.225 +system; it is up to the author/donor to decide if he or she is willing
  11.226 +to distribute software through any other system and a licensee cannot
  11.227 +impose that choice.
  11.228 +
  11.229 +This section is intended to make thoroughly clear what is believed to
  11.230 +be a consequence of the rest of this License.
  11.231 +
  11.232 +  8. If the distribution and/or use of the Program is restricted in
  11.233 +certain countries either by patents or by copyrighted interfaces, the
  11.234 +original copyright holder who places the Program under this License
  11.235 +may add an explicit geographical distribution limitation excluding
  11.236 +those countries, so that distribution is permitted only in or among
  11.237 +countries not thus excluded.  In such case, this License incorporates
  11.238 +the limitation as if written in the body of this License.
  11.239 +
  11.240 +  9. The Free Software Foundation may publish revised and/or new versions
  11.241 +of the General Public License from time to time.  Such new versions will
  11.242 +be similar in spirit to the present version, but may differ in detail to
  11.243 +address new problems or concerns.
  11.244 +
  11.245 +Each version is given a distinguishing version number.  If the Program
  11.246 +specifies a version number of this License which applies to it and "any
  11.247 +later version", you have the option of following the terms and conditions
  11.248 +either of that version or of any later version published by the Free
  11.249 +Software Foundation.  If the Program does not specify a version number of
  11.250 +this License, you may choose any version ever published by the Free Software
  11.251 +Foundation.
  11.252 +
  11.253 +  10. If you wish to incorporate parts of the Program into other free
  11.254 +programs whose distribution conditions are different, write to the author
  11.255 +to ask for permission.  For software which is copyrighted by the Free
  11.256 +Software Foundation, write to the Free Software Foundation; we sometimes
  11.257 +make exceptions for this.  Our decision will be guided by the two goals
  11.258 +of preserving the free status of all derivatives of our free software and
  11.259 +of promoting the sharing and reuse of software generally.
  11.260 +
  11.261 +			    NO WARRANTY
  11.262 +
  11.263 +  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
  11.264 +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
  11.265 +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
  11.266 +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
  11.267 +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  11.268 +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
  11.269 +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
  11.270 +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
  11.271 +REPAIR OR CORRECTION.
  11.272 +
  11.273 +  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
  11.274 +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
  11.275 +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
  11.276 +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
  11.277 +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
  11.278 +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
  11.279 +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
  11.280 +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
  11.281 +POSSIBILITY OF SUCH DAMAGES.
  11.282 +
  11.283 +		     END OF TERMS AND CONDITIONS
  11.284 +
  11.285 +	    How to Apply These Terms to Your New Programs
  11.286 +
  11.287 +  If you develop a new program, and you want it to be of the greatest
  11.288 +possible use to the public, the best way to achieve this is to make it
  11.289 +free software which everyone can redistribute and change under these terms.
  11.290 +
  11.291 +  To do so, attach the following notices to the program.  It is safest
  11.292 +to attach them to the start of each source file to most effectively
  11.293 +convey the exclusion of warranty; and each file should have at least
  11.294 +the "copyright" line and a pointer to where the full notice is found.
  11.295 +
  11.296 +    <one line to give the program's name and a brief idea of what it does.>
  11.297 +    Copyright (C) <year>  <name of author>
  11.298 +
  11.299 +    This program is free software; you can redistribute it and/or modify
  11.300 +    it under the terms of the GNU General Public License as published by
  11.301 +    the Free Software Foundation; either version 2 of the License, or
  11.302 +    (at your option) any later version.
  11.303 +
  11.304 +    This program is distributed in the hope that it will be useful,
  11.305 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.306 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.307 +    GNU General Public License for more details.
  11.308 +
  11.309 +    You should have received a copy of the GNU General Public License
  11.310 +    along with this program; if not, write to the Free Software
  11.311 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  11.312 +
  11.313 +
  11.314 +Also add information on how to contact you by electronic and paper mail.
  11.315 +
  11.316 +If the program is interactive, make it output a short notice like this
  11.317 +when it starts in an interactive mode:
  11.318 +
  11.319 +    Gnomovision version 69, Copyright (C) year name of author
  11.320 +    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
  11.321 +    This is free software, and you are welcome to redistribute it
  11.322 +    under certain conditions; type `show c' for details.
  11.323 +
  11.324 +The hypothetical commands `show w' and `show c' should show the appropriate
  11.325 +parts of the General Public License.  Of course, the commands you use may
  11.326 +be called something other than `show w' and `show c'; they could even be
  11.327 +mouse-clicks or menu items--whatever suits your program.
  11.328 +
  11.329 +You should also get your employer (if you work as a programmer) or your
  11.330 +school, if any, to sign a "copyright disclaimer" for the program, if
  11.331 +necessary.  Here is a sample; alter the names:
  11.332 +
  11.333 +  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
  11.334 +  `Gnomovision' (which makes passes at compilers) written by James Hacker.
  11.335 +
  11.336 +  <signature of Ty Coon>, 1 April 1989
  11.337 +  Ty Coon, President of Vice
  11.338 +
  11.339 +This General Public License does not permit incorporating your program into
  11.340 +proprietary programs.  If your program is a subroutine library, you may
  11.341 +consider it more useful to permit linking proprietary applications with the
  11.342 +library.  If this is what you want to do, use the GNU Library General
  11.343 +Public License instead of this License.
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/locator.c	Wed May 18 05:53:29 2011 +0300
    12.3 @@ -0,0 +1,170 @@
    12.4 +/*
    12.5 +This is a small cross-platform resource file locator library.
    12.6 +Author: John Tsiombikas <nuclear@siggraph.org> 2004
    12.7 +
    12.8 +This library is public domain, you are free to do whatever you like with it,
    12.9 +NO WARANTY whatsoever is provided with this library, use it at your own risk.
   12.10 +*/
   12.11 +
   12.12 +#include <stdio.h>
   12.13 +#include <stdlib.h>
   12.14 +#include <string.h>
   12.15 +#include "locator.h"
   12.16 +
   12.17 +#ifdef HAVE_CONFIG
   12.18 +#include "config.h"
   12.19 +#endif	/* HAVE_CONFIG */
   12.20 +
   12.21 +#ifdef __unix__
   12.22 +#define __USE_BSD	/* to include readlink() prototype */
   12.23 +#include <unistd.h>
   12.24 +
   12.25 +#define DIR_SEP		'/'
   12.26 +#define HOME_ENV	"HOME"
   12.27 +
   12.28 +#else	/* assume WIN32 */
   12.29 +#include <windows.h>
   12.30 +
   12.31 +#define DIR_SEP		'\\'
   12.32 +#define HOME_ENV	"USERPROFILE"
   12.33 +
   12.34 +#endif	/* __unix__ */
   12.35 +
   12.36 +
   12.37 +#ifndef PREFIX
   12.38 +#define PREFIX	""
   12.39 +#endif	/* PREFIX */
   12.40 +
   12.41 +#define MAX_PATH	1024
   12.42 +#define CONF_ENV	"NLOC_CONFIG_PATH"
   12.43 +#define DATA_ENV	"NLOC_DATA_PATH"
   12.44 +#define LOC_FUNC_COUNT	2
   12.45 +
   12.46 +typedef const char *(*loc_func_type)(const char*);
   12.47 +
   12.48 +static const char *locate_config(const char *file);
   12.49 +static const char *locate_data(const char *file);
   12.50 +static const char *exec_path(void);
   12.51 +
   12.52 +static char path[MAX_PATH];
   12.53 +static loc_func_type loc_func[LOC_FUNC_COUNT] = {locate_config, locate_data};
   12.54 +
   12.55 +const char *loc_get_path(const char *file, enum loc_file_type file_type) {
   12.56 +	if(file_type >= LOC_FUNC_COUNT) return 0;
   12.57 +	return loc_func[file_type](file);
   12.58 +}
   12.59 +
   12.60 +static const char *locate_config(const char *file) {
   12.61 +	FILE *fp;
   12.62 +	char *env, *pptr = path;
   12.63 +	const char *fptr = file;
   12.64 +
   12.65 +	/* first try $NLOC_CONFIG_PATH/file */
   12.66 +	env = getenv(CONF_ENV);
   12.67 +	if(env) {
   12.68 +		while(*env) *pptr++ = *env++;
   12.69 +		if(*(env - 1) != DIR_SEP) *pptr++ = DIR_SEP;
   12.70 +		while(*fptr) *pptr++ = *fptr++;
   12.71 +		*pptr++ = 0;
   12.72 +
   12.73 +		fprintf(stderr, "trying: %s\n", path);
   12.74 +		if((fp = fopen(path, "r"))) {
   12.75 +			fclose(fp);
   12.76 +			return path;
   12.77 +		}
   12.78 +	}
   12.79 +
   12.80 +	/* then try $HOME/.file */
   12.81 +	pptr = path;
   12.82 +	fptr = file;
   12.83 +	env = getenv(HOME_ENV);
   12.84 +	if(env) {
   12.85 +		while(*env) *pptr++ = *env++;
   12.86 +		if(*(env - 1) != DIR_SEP) *pptr++ = DIR_SEP;
   12.87 +#ifdef __unix__
   12.88 +		*pptr++ = '.';
   12.89 +#endif	/* __unix__ */
   12.90 +		while(*fptr) *pptr++ = *fptr++;
   12.91 +		*pptr++ = 0;
   12.92 +
   12.93 +		fprintf(stderr, "trying: %s\n", path);
   12.94 +		if((fp = fopen(path, "r"))) {
   12.95 +			fclose(fp);
   12.96 +			return path;
   12.97 +		}
   12.98 +	}
   12.99 +
  12.100 +#ifdef __unix__
  12.101 +	/* then PREFIX/etc/file */
  12.102 +	strcpy(path, PREFIX);
  12.103 +	strcat(path, "/etc/");
  12.104 +	strcat(path, file);
  12.105 +
  12.106 +	fprintf(stderr, "trying: %s\n", path);
  12.107 +	if((fp = fopen(path, "r"))) {
  12.108 +		fclose(fp);
  12.109 +		return path;
  12.110 +	}
  12.111 +#else
  12.112 +	/* or something similar on win32 */
  12.113 +	env = getenv("ALLUSERSPROFILE");
  12.114 +	if(env) {
  12.115 +		strcpy(path, env);
  12.116 +		strcat(path, "\\");
  12.117 +		strcat(path, file);
  12.118 +
  12.119 +		fprintf(stderr, "trying: %s\n", path);
  12.120 +		if((fp = fopen(path, "r"))) {
  12.121 +			fclose(fp);
  12.122 +			return path;
  12.123 +		}
  12.124 +	}
  12.125 +#endif	/* __unix__ */
  12.126 +
  12.127 +
  12.128 +	/* finally as a last resort try the executable directory, this may not work */
  12.129 +	strcpy(path, exec_path());
  12.130 +	strcat(path, file);
  12.131 +
  12.132 +	fprintf(stderr, "trying: %s\n", path);
  12.133 +	if((fp = fopen(path, "r"))) {
  12.134 +		fclose(fp);
  12.135 +		return path;
  12.136 +	}
  12.137 +
  12.138 +	return 0;
  12.139 +}
  12.140 +
  12.141 +/* TODO: not implemented yet */
  12.142 +static const char *locate_data(const char *file) {
  12.143 +	return 0;
  12.144 +}
  12.145 +
  12.146 +static const char *exec_path(void) {
  12.147 +	static char path[MAX_PATH];
  12.148 +	int ccount = 0;
  12.149 +	char *ptr;
  12.150 +
  12.151 +#ifdef __linux__
  12.152 +	ccount = readlink("/proc/self/exe", path, MAX_PATH - 1);
  12.153 +#endif	/* __linux__ */
  12.154 +
  12.155 +#ifdef __FreeBSD__
  12.156 +	ccount = readlink("/proc/curproc/file", path, MAX_PATH - 1);
  12.157 +#endif	/* __FreeBSD__ */
  12.158 +
  12.159 +#ifdef WIN32
  12.160 +	ccount = GetModuleFileName(0, path, MAX_PATH - 1);
  12.161 +#endif	/* WIN32 */
  12.162 +
  12.163 +	if(!ccount) return 0;
  12.164 +
  12.165 +	path[ccount] = 0;
  12.166 +
  12.167 +	ptr = strrchr(path, DIR_SEP);
  12.168 +	if(!ptr) return 0;
  12.169 +
  12.170 +	*(ptr + 1) = 0;
  12.171 +
  12.172 +	return path;
  12.173 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/locator.h	Wed May 18 05:53:29 2011 +0300
    13.3 @@ -0,0 +1,27 @@
    13.4 +/*
    13.5 +This is a small cross-platform resource file locator library.
    13.6 +Author: John Tsiombikas <nuclear@siggraph.org> 2004
    13.7 +
    13.8 +This library is public domain, you are free to do whatever you like with it,
    13.9 +NO WARANTY whatsoever is provided with this library, use it at your own risk.
   13.10 +*/
   13.11 +
   13.12 +#ifndef _LOCATOR_H_
   13.13 +#define _LOCATOR_H_
   13.14 +
   13.15 +enum loc_file_type {
   13.16 +	LOC_FILE_CONFIG,
   13.17 +	LOC_FILE_DATA
   13.18 +};
   13.19 +
   13.20 +#ifdef __cplusplus
   13.21 +extern "C" {
   13.22 +#endif	/* __cplusplus */
   13.23 +
   13.24 +const char *loc_get_path(const char *file, enum loc_file_type file_type);
   13.25 +
   13.26 +#ifdef __cplusplus
   13.27 +}
   13.28 +#endif	/* __cplusplus */
   13.29 +
   13.30 +#endif	/* _LOCATOR_H_ */
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/resource.h	Wed May 18 05:53:29 2011 +0300
    14.3 @@ -0,0 +1,1 @@
    14.4 +#define ICON_DYNWATCH	100
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/socklib.c	Wed May 18 05:53:29 2011 +0300
    15.3 @@ -0,0 +1,246 @@
    15.4 +/*
    15.5 +This file is part of socklib, a cross-platform socket library.
    15.6 +
    15.7 +Copyright (c) 2004 John Tsiombikas <nuclear@siggraph.org>
    15.8 +
    15.9 +This library is free software; you can redistribute it and/or modify
   15.10 +it under the terms of the GNU General Public License as published by
   15.11 +the Free Software Foundation; either version 2 of the License, or
   15.12 +(at your option) any later version.
   15.13 +
   15.14 +This library is distributed in the hope that it will be useful,
   15.15 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   15.16 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15.17 +GNU General Public License for more details.
   15.18 +
   15.19 +You should have received a copy of the GNU General Public License
   15.20 +along with this library; if not, write to the Free Software
   15.21 +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   15.22 +*/
   15.23 +
   15.24 +#include <stdio.h>
   15.25 +#include <stdlib.h>
   15.26 +#include <string.h>
   15.27 +#include <errno.h>
   15.28 +
   15.29 +#ifdef __unix__
   15.30 +#define __USE_BSD
   15.31 +#include <unistd.h>
   15.32 +#include <fcntl.h>
   15.33 +#include <sys/types.h>
   15.34 +#include <sys/socket.h>
   15.35 +#include <sys/ioctl.h>
   15.36 +#include <sys/param.h>
   15.37 +#include <sys/select.h>
   15.38 +#include <netdb.h>
   15.39 +#include <netinet/in.h>
   15.40 +#include <arpa/inet.h>
   15.41 +
   15.42 +#else	/* assume win32 if not unix */
   15.43 +
   15.44 +#include <winsock2.h>
   15.45 +
   15.46 +#define MAXHOSTNAMELEN	255
   15.47 +#define close(s)	closesocket(s)
   15.48 +
   15.49 +static int winsock_initialized;
   15.50 +#endif	/* __unix__ */
   15.51 +
   15.52 +#include "socklib.h"
   15.53 +
   15.54 +#ifdef _MSC_VER
   15.55 +#define __func__	__FUNCTION__
   15.56 +#endif	/* _MSC_VER */
   15.57 +
   15.58 +static int verbose = 1;
   15.59 +
   15.60 +int sl_listen(int port) {
   15.61 +	int s;
   15.62 +	struct sockaddr_in addr;
   15.63 +	struct hostent *host;
   15.64 +	char host_name[MAXHOSTNAMELEN+1];
   15.65 +
   15.66 +#ifndef __unix__
   15.67 +	if(!winsock_initialized) {
   15.68 +        WSADATA wsa_data;
   15.69 +		WSAStartup(MAKEWORD(1, 1), &wsa_data);
   15.70 +		winsock_initialized = 1;
   15.71 +	}
   15.72 +#endif	/* __unix__ */
   15.73 +
   15.74 +	if(gethostname(host_name, MAXHOSTNAMELEN+1) == -1) {
   15.75 +		if(verbose) perror("socklib error @ gethostname");
   15.76 +		return -1;
   15.77 +	}
   15.78 +
   15.79 +	if(!(host = gethostbyname(host_name))) {
   15.80 +		if(verbose) perror("socklib error @ gethostbyname");
   15.81 +		return -1;
   15.82 +	}
   15.83 +
   15.84 +	memset(&addr, 0, sizeof(struct sockaddr_in));
   15.85 +	addr.sin_family = host->h_addrtype;
   15.86 +	addr.sin_port = htons(port);
   15.87 +	addr.sin_addr.s_addr = INADDR_ANY;
   15.88 +
   15.89 +	if((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
   15.90 +		if(verbose) perror("socklib error @ socket");
   15.91 +		return -1;
   15.92 +	}
   15.93 +
   15.94 +	if(bind(s, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)) == -1) {
   15.95 +		if(verbose) perror("socklib error @ bind");
   15.96 +		close(s);
   15.97 +		return -1;
   15.98 +	}
   15.99 +
  15.100 +	if(listen(s, 5) == -1) {
  15.101 +		if(verbose) perror("socklib error @ listen");
  15.102 +		close(s);
  15.103 +		return -1;
  15.104 +	}
  15.105 +
  15.106 +	return s;
  15.107 +}
  15.108 +
  15.109 +
  15.110 +int sl_accept(int listening_socket) {
  15.111 +	return accept(listening_socket, 0, 0);
  15.112 +}
  15.113 +
  15.114 +int sl_connect_tcp(char *ipaddr, const char *hostname, int port) {
  15.115 +	int s, must_free_ipaddr = 0;
  15.116 +	struct sockaddr_in addr;
  15.117 +	struct hostent *host;
  15.118 +
  15.119 +#ifndef __unix__
  15.120 +	if(!winsock_initialized) {
  15.121 +        WSADATA wsa_data;
  15.122 +		WSAStartup(MAKEWORD(1, 1), &wsa_data);
  15.123 +		winsock_initialized = 1;
  15.124 +	}
  15.125 +#endif	/* __unix__ */
  15.126 +
  15.127 +	if((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
  15.128 +		if(verbose) perror("socklib error @ socket");
  15.129 +		return -1;
  15.130 +	}
  15.131 +
  15.132 +	if(!ipaddr) {
  15.133 +		if(!hostname) return -1;
  15.134 +
  15.135 +		ipaddr = malloc(20);
  15.136 +		must_free_ipaddr = 1;
  15.137 +		host = gethostbyname(hostname);
  15.138 +
  15.139 +		if(!host) {
  15.140 +			if(verbose) perror("socklib error @ gethostbyname");
  15.141 +			free(ipaddr);
  15.142 +			return -1;
  15.143 +		}
  15.144 +
  15.145 +		strcpy(ipaddr, inet_ntoa(*((struct in_addr*)host->h_addr)));
  15.146 +	}
  15.147 +
  15.148 +	memset(&addr, 0, sizeof(struct sockaddr_in));
  15.149 +	addr.sin_family = AF_INET;
  15.150 +	addr.sin_port = htons(port);
  15.151 +	addr.sin_addr.s_addr = inet_addr(ipaddr);
  15.152 +
  15.153 +	if((connect(s, (struct sockaddr*)&addr, sizeof(struct sockaddr))) == -1) {
  15.154 +		if(verbose) perror("socklib error @ connect");
  15.155 +		if(must_free_ipaddr) free(ipaddr);
  15.156 +		return -1;
  15.157 +	}
  15.158 +
  15.159 +	if(must_free_ipaddr) free(ipaddr);
  15.160 +	return s;
  15.161 +}
  15.162 +
  15.163 +
  15.164 +void sl_close_socket(int s) {
  15.165 +	char buffer[128];
  15.166 +
  15.167 +	shutdown(s, 1);
  15.168 +	while(recv(s, buffer, 128, 0));
  15.169 +	close(s);
  15.170 +}
  15.171 +
  15.172 +int sl_send_data(int s, const char *buffer, int size) {
  15.173 +	const char *ptr = buffer;
  15.174 +	const char *end = buffer + size;
  15.175 +
  15.176 +	while(ptr < end) {
  15.177 +		int bytes = send(s, ptr, end - ptr, 0);
  15.178 +		if(bytes == -1) {
  15.179 +			if(verbose) {
  15.180 +				char errstr[80];
  15.181 +				sprintf(errstr, "socklib error @ %s", __func__);
  15.182 +				perror(errstr);
  15.183 +			}
  15.184 +			return -1;
  15.185 +		}
  15.186 +		ptr += bytes;
  15.187 +	}
  15.188 +
  15.189 +	return size;
  15.190 +}
  15.191 +
  15.192 +int sl_recv_data(int s, char *buffer, int size) {
  15.193 +	int bytes = recv(s, buffer, size, 0);
  15.194 +	if(bytes == -1) {
  15.195 +		if(verbose) {
  15.196 +			char errstr[80];
  15.197 +			sprintf(errstr, "socklib error @ %s", __func__);
  15.198 +			perror(errstr);
  15.199 +		}
  15.200 +		return -1;
  15.201 +	}
  15.202 +	return bytes;
  15.203 +}
  15.204 +
  15.205 +
  15.206 +/* if SL_CHK_IMMED is NOT specified then:
  15.207 + * if timeout is 0: block forever, else block for so many milliseconds.
  15.208 + */
  15.209 +int sl_check_socket(int s, int flags, unsigned int timeout) {
  15.210 +	int res;
  15.211 +	fd_set rfds, wfds;
  15.212 +	struct timeval tv, *tvptr;
  15.213 +	tv.tv_sec = tv.tv_usec = 0;
  15.214 +
  15.215 +	tvptr = (flags & SL_CHK_IMMED) ? &tv : 0;
  15.216 +
  15.217 +	if(flags & SL_CHK_IMMED) {
  15.218 +		tvptr = &tv;
  15.219 +	} else {
  15.220 +		tvptr = timeout > 0 ? &tv : 0;
  15.221 +
  15.222 +		tv.tv_sec = timeout / 1000;
  15.223 +		tv.tv_usec = (timeout - tv.tv_sec * 1000) * 1000;
  15.224 +	}
  15.225 +
  15.226 +
  15.227 +	FD_ZERO(&rfds);
  15.228 +	FD_ZERO(&wfds);
  15.229 +
  15.230 +	if(flags & SL_CHK_READ) {
  15.231 +		FD_SET(s, &rfds);
  15.232 +		if((res = select(s+1, &rfds, 0, 0, tvptr)) == -1) {
  15.233 +			return -1;
  15.234 +		}
  15.235 +		return FD_ISSET(s, &rfds) ? 1 : 0;
  15.236 +	} else if(flags & SL_CHK_WRITE) {
  15.237 +		FD_SET(s, &wfds);
  15.238 +		if((res = select(s+1, 0, &wfds, 0, tvptr)) == -1) {
  15.239 +			return -1;
  15.240 +		}
  15.241 +		return FD_ISSET(s, &wfds) ? 1 : 0;
  15.242 +	}
  15.243 +
  15.244 +	return -1;
  15.245 +}
  15.246 +
  15.247 +void sl_set_verbosity(int vlevel) {
  15.248 +	verbose = vlevel;
  15.249 +}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/socklib.h	Wed May 18 05:53:29 2011 +0300
    16.3 @@ -0,0 +1,48 @@
    16.4 +/*
    16.5 +This file is part of socklib, a cross-platform socket library.
    16.6 +
    16.7 +Copyright (c) 2004 John Tsiombikas <nuclear@siggraph.org>
    16.8 +
    16.9 +This library is free software; you can redistribute it and/or modify
   16.10 +it under the terms of the GNU General Public License as published by
   16.11 +the Free Software Foundation; either version 2 of the License, or
   16.12 +(at your option) any later version.
   16.13 +
   16.14 +This library is distributed in the hope that it will be useful,
   16.15 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   16.16 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16.17 +GNU General Public License for more details.
   16.18 +
   16.19 +You should have received a copy of the GNU General Public License
   16.20 +along with this library; if not, write to the Free Software
   16.21 +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   16.22 +*/
   16.23 +
   16.24 +#ifndef _SOCKLIB_H_
   16.25 +#define _SOCKLIB_H_
   16.26 +
   16.27 +
   16.28 +#define SL_CHK_BLOCK	0
   16.29 +#define SL_CHK_IMMED	1
   16.30 +#define SL_CHK_READ		2
   16.31 +#define SL_CHK_WRITE	4
   16.32 +
   16.33 +
   16.34 +#ifdef __cplusplus
   16.35 +extern "C" {
   16.36 +#endif	/* __cplusplus */
   16.37 +
   16.38 +int sl_listen(int port);
   16.39 +int sl_accept(int listening_socket);
   16.40 +int sl_connect_tcp(char *ipaddr, const char *hostname, int port);
   16.41 +void sl_close_socket(int s);
   16.42 +int sl_send_data(int s, const char *buffer, int size);
   16.43 +int sl_recv_data(int s, char *buffer, int size);
   16.44 +int sl_check_socket(int s, int flags, unsigned int timeout);
   16.45 +void sl_set_verbosity(int vlevel);
   16.46 +
   16.47 +#ifdef __cplusplus
   16.48 +}
   16.49 +#endif	/* __cplusplus */
   16.50 +
   16.51 +#endif	/* _SOCKLIB_H_ */
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/tray.c	Wed May 18 05:53:29 2011 +0300
    17.3 @@ -0,0 +1,46 @@
    17.4 +/*
    17.5 +This file is part of dynwatch, a win32 system tray applet which
    17.6 +updates automatically the dyndns entry of quake.gr.
    17.7 +
    17.8 +Copyright (c) 2005 John Tsiombikas <nuclear@siggraph.org>
    17.9 +
   17.10 +This program is free software; you can redistribute it and/or modify
   17.11 +it under the terms of the GNU General Public License as published by
   17.12 +the Free Software Foundation; either version 2 of the License, or
   17.13 +(at your option) any later version.
   17.14 +
   17.15 +This program is distributed in the hope that it will be useful,
   17.16 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   17.17 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17.18 +GNU General Public License for more details.
   17.19 +
   17.20 +You should have received a copy of the GNU General Public License
   17.21 +along with this program; if not, write to the Free Software
   17.22 +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   17.23 +*/
   17.24 +
   17.25 +#include <windows.h>
   17.26 +#include "gui.h"
   17.27 +#include "watch.h"
   17.28 +
   17.29 +/* when this is true, the program checks periodically for
   17.30 + * connection status and updates the dynamic dns entry
   17.31 + */
   17.32 +int running;
   17.33 +
   17.34 +int WINAPI WinMain(HINSTANCE proc_handle, HINSTANCE prev, char *args, int show) {
   17.35 +	MSG msg;
   17.36 +
   17.37 +	init();
   17.38 +	create_gui();
   17.39 +
   17.40 +	SetTimer(win_main, 0, 20000, 0);
   17.41 +
   17.42 +	while(GetMessage(&msg, 0, 0, 0)) {
   17.43 +		TranslateMessage(&msg);
   17.44 +		DispatchMessage(&msg);
   17.45 +	}
   17.46 +
   17.47 +	return 0;
   17.48 +}
   17.49 +
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/tray.sln	Wed May 18 05:53:29 2011 +0300
    18.3 @@ -0,0 +1,21 @@
    18.4 +Microsoft Visual Studio Solution File, Format Version 7.00
    18.5 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tray", "tray.vcproj", "{219EB00A-2B8C-46A5-8E5C-73C7B43BF060}"
    18.6 +EndProject
    18.7 +Global
    18.8 +	GlobalSection(SolutionConfiguration) = preSolution
    18.9 +		ConfigName.0 = Debug
   18.10 +		ConfigName.1 = Release
   18.11 +	EndGlobalSection
   18.12 +	GlobalSection(ProjectDependencies) = postSolution
   18.13 +	EndGlobalSection
   18.14 +	GlobalSection(ProjectConfiguration) = postSolution
   18.15 +		{219EB00A-2B8C-46A5-8E5C-73C7B43BF060}.Debug.ActiveCfg = Debug|Win32
   18.16 +		{219EB00A-2B8C-46A5-8E5C-73C7B43BF060}.Debug.Build.0 = Debug|Win32
   18.17 +		{219EB00A-2B8C-46A5-8E5C-73C7B43BF060}.Release.ActiveCfg = Release|Win32
   18.18 +		{219EB00A-2B8C-46A5-8E5C-73C7B43BF060}.Release.Build.0 = Release|Win32
   18.19 +	EndGlobalSection
   18.20 +	GlobalSection(ExtensibilityGlobals) = postSolution
   18.21 +	EndGlobalSection
   18.22 +	GlobalSection(ExtensibilityAddIns) = postSolution
   18.23 +	EndGlobalSection
   18.24 +EndGlobal
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/tray.vcproj	Wed May 18 05:53:29 2011 +0300
    19.3 @@ -0,0 +1,171 @@
    19.4 +<?xml version="1.0" encoding = "Windows-1252"?>
    19.5 +<VisualStudioProject
    19.6 +	ProjectType="Visual C++"
    19.7 +	Version="7.00"
    19.8 +	Name="tray"
    19.9 +	ProjectGUID="{219EB00A-2B8C-46A5-8E5C-73C7B43BF060}"
   19.10 +	Keyword="Win32Proj">
   19.11 +	<Platforms>
   19.12 +		<Platform
   19.13 +			Name="Win32"/>
   19.14 +	</Platforms>
   19.15 +	<Configurations>
   19.16 +		<Configuration
   19.17 +			Name="Debug|Win32"
   19.18 +			OutputDirectory="Debug"
   19.19 +			IntermediateDirectory="Debug"
   19.20 +			ConfigurationType="1"
   19.21 +			CharacterSet="2">
   19.22 +			<Tool
   19.23 +				Name="VCCLCompilerTool"
   19.24 +				Optimization="0"
   19.25 +				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
   19.26 +				MinimalRebuild="TRUE"
   19.27 +				BasicRuntimeChecks="3"
   19.28 +				RuntimeLibrary="5"
   19.29 +				UsePrecompiledHeader="0"
   19.30 +				WarningLevel="3"
   19.31 +				Detect64BitPortabilityProblems="TRUE"
   19.32 +				DebugInformationFormat="4"/>
   19.33 +			<Tool
   19.34 +				Name="VCCustomBuildTool"/>
   19.35 +			<Tool
   19.36 +				Name="VCLinkerTool"
   19.37 +				OutputFile="$(OutDir)/tray.exe"
   19.38 +				LinkIncremental="2"
   19.39 +				GenerateDebugInformation="TRUE"
   19.40 +				ProgramDatabaseFile="$(OutDir)/tray.pdb"
   19.41 +				SubSystem="2"
   19.42 +				TargetMachine="1"/>
   19.43 +			<Tool
   19.44 +				Name="VCMIDLTool"/>
   19.45 +			<Tool
   19.46 +				Name="VCPostBuildEventTool"/>
   19.47 +			<Tool
   19.48 +				Name="VCPreBuildEventTool"/>
   19.49 +			<Tool
   19.50 +				Name="VCPreLinkEventTool"/>
   19.51 +			<Tool
   19.52 +				Name="VCResourceCompilerTool"/>
   19.53 +			<Tool
   19.54 +				Name="VCWebServiceProxyGeneratorTool"/>
   19.55 +			<Tool
   19.56 +				Name="VCWebDeploymentTool"/>
   19.57 +		</Configuration>
   19.58 +		<Configuration
   19.59 +			Name="Release|Win32"
   19.60 +			OutputDirectory="Release"
   19.61 +			IntermediateDirectory="Release"
   19.62 +			ConfigurationType="1"
   19.63 +			CharacterSet="2">
   19.64 +			<Tool
   19.65 +				Name="VCCLCompilerTool"
   19.66 +				Optimization="2"
   19.67 +				InlineFunctionExpansion="1"
   19.68 +				OmitFramePointers="TRUE"
   19.69 +				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
   19.70 +				StringPooling="TRUE"
   19.71 +				RuntimeLibrary="4"
   19.72 +				EnableFunctionLevelLinking="TRUE"
   19.73 +				UsePrecompiledHeader="0"
   19.74 +				WarningLevel="3"
   19.75 +				Detect64BitPortabilityProblems="TRUE"
   19.76 +				DebugInformationFormat="3"/>
   19.77 +			<Tool
   19.78 +				Name="VCCustomBuildTool"/>
   19.79 +			<Tool
   19.80 +				Name="VCLinkerTool"
   19.81 +				OutputFile="$(OutDir)/tray.exe"
   19.82 +				LinkIncremental="1"
   19.83 +				GenerateDebugInformation="TRUE"
   19.84 +				SubSystem="2"
   19.85 +				OptimizeReferences="2"
   19.86 +				EnableCOMDATFolding="2"
   19.87 +				TargetMachine="1"/>
   19.88 +			<Tool
   19.89 +				Name="VCMIDLTool"/>
   19.90 +			<Tool
   19.91 +				Name="VCPostBuildEventTool"/>
   19.92 +			<Tool
   19.93 +				Name="VCPreBuildEventTool"/>
   19.94 +			<Tool
   19.95 +				Name="VCPreLinkEventTool"/>
   19.96 +			<Tool
   19.97 +				Name="VCResourceCompilerTool"/>
   19.98 +			<Tool
   19.99 +				Name="VCWebServiceProxyGeneratorTool"/>
  19.100 +			<Tool
  19.101 +				Name="VCWebDeploymentTool"/>
  19.102 +		</Configuration>
  19.103 +	</Configurations>
  19.104 +	<Files>
  19.105 +		<Filter
  19.106 +			Name="Source Files"
  19.107 +			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
  19.108 +			<File
  19.109 +				RelativePath="config_parser.c">
  19.110 +			</File>
  19.111 +			<File
  19.112 +				RelativePath="events.c">
  19.113 +			</File>
  19.114 +			<File
  19.115 +				RelativePath="gui.c">
  19.116 +			</File>
  19.117 +			<File
  19.118 +				RelativePath="locator.c">
  19.119 +			</File>
  19.120 +			<File
  19.121 +				RelativePath="socklib.c">
  19.122 +			</File>
  19.123 +			<File
  19.124 +				RelativePath="tray.c">
  19.125 +			</File>
  19.126 +			<File
  19.127 +				RelativePath="watch.c">
  19.128 +			</File>
  19.129 +		</Filter>
  19.130 +		<Filter
  19.131 +			Name="Header Files"
  19.132 +			Filter="h;hpp;hxx;hm;inl;inc">
  19.133 +			<File
  19.134 +				RelativePath="config_parser.h">
  19.135 +			</File>
  19.136 +			<File
  19.137 +				RelativePath="events.h">
  19.138 +			</File>
  19.139 +			<File
  19.140 +				RelativePath="gui.h">
  19.141 +			</File>
  19.142 +			<File
  19.143 +				RelativePath="locator.h">
  19.144 +			</File>
  19.145 +			<File
  19.146 +				RelativePath="resource.h">
  19.147 +			</File>
  19.148 +			<File
  19.149 +				RelativePath="socklib.h">
  19.150 +			</File>
  19.151 +			<File
  19.152 +				RelativePath="watch.h">
  19.153 +			</File>
  19.154 +		</Filter>
  19.155 +		<Filter
  19.156 +			Name="Resource Files"
  19.157 +			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
  19.158 +			<File
  19.159 +				RelativePath="dynwatch.ico">
  19.160 +			</File>
  19.161 +			<File
  19.162 +				RelativePath="dynwatch.rc">
  19.163 +			</File>
  19.164 +		</Filter>
  19.165 +		<File
  19.166 +			RelativePath="..\..\..\Program Files\Microsoft Visual Studio .NET\Vc7\PlatformSDK\lib\SensAPI.Lib">
  19.167 +		</File>
  19.168 +		<File
  19.169 +			RelativePath="..\..\..\Program Files\Microsoft Visual Studio .NET\Vc7\PlatformSDK\lib\WS2_32.Lib">
  19.170 +		</File>
  19.171 +	</Files>
  19.172 +	<Globals>
  19.173 +	</Globals>
  19.174 +</VisualStudioProject>
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/watch.c	Wed May 18 05:53:29 2011 +0300
    20.3 @@ -0,0 +1,197 @@
    20.4 +/*
    20.5 +This file is part of dynwatch, a win32 system tray applet which
    20.6 +updates automatically the dyndns entry of quake.gr.
    20.7 +
    20.8 +Copyright (c) 2005 John Tsiombikas <nuclear@siggraph.org>
    20.9 +
   20.10 +This program is free software; you can redistribute it and/or modify
   20.11 +it under the terms of the GNU General Public License as published by
   20.12 +the Free Software Foundation; either version 2 of the License, or
   20.13 +(at your option) any later version.
   20.14 +
   20.15 +This program is distributed in the hope that it will be useful,
   20.16 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   20.17 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   20.18 +GNU General Public License for more details.
   20.19 +
   20.20 +You should have received a copy of the GNU General Public License
   20.21 +along with this program; if not, write to the Free Software
   20.22 +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   20.23 +*/
   20.24 +
   20.25 +#include <stdio.h>
   20.26 +#include <string.h>
   20.27 +#include <stdlib.h>
   20.28 +#include <windows.h>
   20.29 +#include <sensapi.h>
   20.30 +#include "socklib.h"
   20.31 +#include "watch.h"
   20.32 +#include "config_parser.h"
   20.33 +#include "locator.h"
   20.34 +
   20.35 +int empty_str(const char *str);
   20.36 +
   20.37 +static const char *cfg_fname = "dynwatch.conf";
   20.38 +char user[256], pass[256], dhost[256], hosts[256];
   20.39 +extern int running;
   20.40 +
   20.41 +static int connected;
   20.42 +
   20.43 +void init(void) {
   20.44 +	const struct ConfigOption *opt;
   20.45 +
   20.46 +	SetParserState(PS_AssignmentSymbol, ':');
   20.47 +	SetParserState(PS_CommentSymbol, '#');
   20.48 +
   20.49 +	if(LoadConfigFile(loc_get_path(cfg_fname, LOC_FILE_CONFIG)) == -1) {
   20.50 +		err_msg("Could not load config file, please reconfigure");
   20.51 +	} else {
   20.52 +
   20.53 +        while((opt = GetNextOption())) {
   20.54 +			if(!strcmp(opt->option, "user")) {
   20.55 +				strncpy(user, opt->str_value, 256);
   20.56 +			} else if(!strcmp(opt->option, "pass")) {
   20.57 +				strncpy(pass, opt->str_value, 256);
   20.58 +			} else if(!strcmp(opt->option, "dns-host")) {
   20.59 +				strncpy(dhost, opt->str_value, 256);
   20.60 +			} else if(!strcmp(opt->option, "hosts")) {
   20.61 +				strncpy(hosts, opt->str_value, 256);
   20.62 +			} else {
   20.63 +				err_msg("Error parsing config file, please reconfigure");
   20.64 +				user[0] = pass[0] = dhost[0] = hosts[0] = 0;
   20.65 +			}
   20.66 +		}
   20.67 +
   20.68 +		if(!empty_str(user) && !empty_str(pass) && !empty_str(dhost) && !empty_str(hosts)) {
   20.69 +			running = 1;
   20.70 +		}
   20.71 +	}
   20.72 +
   20.73 +	DestroyConfigParser();
   20.74 +
   20.75 +	/* force a wsastartup call */
   20.76 +	sl_set_verbosity(0);
   20.77 +	sl_connect_tcp("0.0.0.0", 0, 0);
   20.78 +	sl_set_verbosity(1);
   20.79 +}
   20.80 +
   20.81 +void get_ip_address(struct in_addr *addr) {
   20.82 +	struct hostent *host;
   20.83 +	char **str_ptr;
   20.84 +	static char hostname[512];
   20.85 +
   20.86 +	if(gethostname(hostname, 512) == -1) {
   20.87 +		err_msg("gethostname() failed\n");
   20.88 +	}
   20.89 +
   20.90 +	if(!(host = gethostbyname(hostname))) {
   20.91 +		err_msg("gethostbyname() failed\n");
   20.92 +	}
   20.93 +
   20.94 +	*addr = *(struct in_addr*)host->h_addr_list[0];
   20.95 +}
   20.96 +
   20.97 +int need_update(void) {
   20.98 +	unsigned long flags;
   20.99 +	static struct in_addr addr;
  20.100 +
  20.101 +	if(IsNetworkAlive(&flags)) {
  20.102 +		/* it was not connected before, we need to update */
  20.103 +		if(!connected) {
  20.104 +			get_ip_address(&addr);
  20.105 +			connected = 1;
  20.106 +			return 1;
  20.107 +		}
  20.108 +
  20.109 +		/* it was connected before, but we may have missed a short
  20.110 +		 * disconnect. Check to see if we still have the same ip (not fullproof)
  20.111 +		 */
  20.112 +		{
  20.113 +			struct in_addr tmp;
  20.114 +			get_ip_address(&tmp);
  20.115 +
  20.116 +			if(addr.S_un.S_addr != tmp.S_un.S_addr) {
  20.117 +				addr = tmp;
  20.118 +				return 1;
  20.119 +			}
  20.120 +		}
  20.121 +
  20.122 +	} else {
  20.123 +		connected = 0;
  20.124 +	}
  20.125 +	return 0;
  20.126 +}
  20.127 +
  20.128 +
  20.129 +int update_dns(void) {
  20.130 +	int s, bytes;
  20.131 +	static char http_req[512];
  20.132 +	char *buf, *ptr;
  20.133 +
  20.134 +	if(empty_str(user) || empty_str(pass) || empty_str(dhost) || empty_str(hosts)) {
  20.135 +		err_msg("missing configuration data, please reconfigure");
  20.136 +		return -1;
  20.137 +	}
  20.138 +
  20.139 +	if((s = sl_connect_tcp(0, dhost, 80)) == -1) {
  20.140 +		connected = 0;
  20.141 +		return -1;
  20.142 +	}
  20.143 +
  20.144 +	buf = malloc(4096);
  20.145 +
  20.146 +	sprintf(buf, "update.php?rid=%s&token=%s", user, pass);
  20.147 +	sprintf(http_req, "GET http://%s/%s HTTP/1.0\r\nUser-Agent: dynwatch/1.0\r\n\r\n", dhost, buf);
  20.148 +
  20.149 +	sl_send_data(s, http_req, strlen(http_req));
  20.150 +	while((bytes = sl_recv_data(s, buf, 4096))) {
  20.151 +		if(bytes == -1) break;
  20.152 +
  20.153 +		ptr = strstr(buf, "Updated");
  20.154 +		if(ptr) {
  20.155 +			free(buf);
  20.156 +			info_msg("dns update complete");
  20.157 +			sl_close_socket(s);
  20.158 +			return 0;
  20.159 +		}
  20.160 +	}
  20.161 +
  20.162 +	free(buf);
  20.163 +	err_msg("dns update failed");
  20.164 +	sl_close_socket(s);
  20.165 +	return -1;
  20.166 +}
  20.167 +
  20.168 +#define HOME_ENV	"USERPROFILE"
  20.169 +#define DIR_SEP		'\\'
  20.170 +#define MAX_PATH	512
  20.171 +
  20.172 +void save_config(void) {
  20.173 +	FILE *fp;
  20.174 +	static char path[MAX_PATH];
  20.175 +	const char *fptr = cfg_fname;
  20.176 +	char *env, *pptr = path;
  20.177 +
  20.178 +	env = getenv(HOME_ENV);
  20.179 +	if(env) {
  20.180 +		while(*env) *pptr++ = *env++;
  20.181 +		if(*(env - 1) != DIR_SEP) *pptr++ = DIR_SEP;
  20.182 +		while(*fptr) *pptr++ = *fptr++;
  20.183 +		*pptr++ = 0;
  20.184 +	} else {
  20.185 +		strcpy(path, cfg_fname);
  20.186 +		info_msg("warning: no USERPROFILE variable found, saving config to the current dir.");
  20.187 +	}
  20.188 +
  20.189 +	if(!(fp = fopen(path, "w"))) {
  20.190 +		err_msg("could not save config file!");
  20.191 +		return;
  20.192 +	}
  20.193 +
  20.194 +	fprintf(fp, "dns-host: %s\n", dhost);
  20.195 +	fprintf(fp, "user: %s\n", user);
  20.196 +	fprintf(fp, "pass: %s\n", pass);
  20.197 +	fprintf(fp, "hosts: %s\n", hosts);
  20.198 +
  20.199 +	fclose(fp);
  20.200 +}
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/watch.h	Wed May 18 05:53:29 2011 +0300
    21.3 @@ -0,0 +1,36 @@
    21.4 +/*
    21.5 +This file is part of dynwatch, a win32 system tray applet which
    21.6 +updates automatically the dyndns entry of quake.gr.
    21.7 +
    21.8 +Copyright (c) 2005 John Tsiombikas <nuclear@siggraph.org>
    21.9 +
   21.10 +This program is free software; you can redistribute it and/or modify
   21.11 +it under the terms of the GNU General Public License as published by
   21.12 +the Free Software Foundation; either version 2 of the License, or
   21.13 +(at your option) any later version.
   21.14 +
   21.15 +This program is distributed in the hope that it will be useful,
   21.16 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   21.17 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   21.18 +GNU General Public License for more details.
   21.19 +
   21.20 +You should have received a copy of the GNU General Public License
   21.21 +along with this program; if not, write to the Free Software
   21.22 +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   21.23 +*/
   21.24 +
   21.25 +#ifndef _WATCH_H_
   21.26 +#define _WATCH_H_
   21.27 +
   21.28 +#define info_msg(x)	MessageBox(0, x, "dynwatch info", MB_ICONINFORMATION | MB_OK)
   21.29 +#define err_msg(x)	MessageBox(0, x, "dynwatch error", MB_ICONSTOP | MB_OK)
   21.30 +
   21.31 +extern char user[256], pass[256], dhost[256], hosts[256];
   21.32 +
   21.33 +void init(void);
   21.34 +int need_update(void);
   21.35 +int update_dns(void);
   21.36 +
   21.37 +void save_config(void);
   21.38 +
   21.39 +#endif	/* _WATCH_H_ */