# HG changeset patch # User John Tsiombikas # Date 1305687209 -10800 # Node ID ce3c5e4c75bfd5e866617f06e1e0a279179f91c0 dynwatch DynDNS updater for windows diff -r 000000000000 -r ce3c5e4c75bf README.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README.txt Wed May 18 05:53:29 2011 +0300 @@ -0,0 +1,18 @@ +Dynwatch is a system tray applet which automaticaly updates dynamic dns entries +for the quake.gr dyndns service. +(Actually with very little efort, adding one more option to the configuration, +it should be able to work with any dyndns service out there). + +PLEASE NOTE: +This program is free software, released under the GNU General Public License. +This means that you have the right to run this program for any purpose, +distribute it freely, modify it to suit your needs and release any modified +version if you so wish. In order for this to happen you MUST have access to the +source code of this program, which in turn means that anyone who distributes +this program in binary form, must distribute the source code as well in a +similar manner, or provide you with a clear notice which states that they will +provide the source code to you if you ask for it. +If the above conditions are not met, please contact me through email + and let me know about it. + +Read license.txt for the full text of the General Public License. diff -r 000000000000 -r ce3c5e4c75bf authors.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/authors.txt Wed May 18 05:53:29 2011 +0300 @@ -0,0 +1,3 @@ +dynwatch was written by: + John Tsiombikas + http://thelab.demoscene.gr/nuclear/ \ No newline at end of file diff -r 000000000000 -r ce3c5e4c75bf config_parser.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config_parser.c Wed May 18 05:53:29 2011 +0300 @@ -0,0 +1,141 @@ +/* +This file is part of dynwatch, a win32 system tray applet which +updates automatically the dyndns entry of quake.gr. + +Copyright (c) 2005 John Tsiombikas + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include +#include +#include +#include +#include "config_parser.h" + +/* state variables */ +static char sym_assign = '='; +static char sym_comment = ';'; +static char max_line_len = 100; +static char seperators[257] = " \t"; +static struct ConfigOption cfg_opt; + +static char *config_file, *cfgptr; + +void SetParserState(enum ParserState state, int value) { + switch(state) { + case PS_AssignmentSymbol: + sym_assign = (char)value; + break; + + case PS_CommentSymbol: + sym_comment = (char)value; + break; + + case PS_MaxLineLen: + max_line_len = value; + break; + + case PS_Seperators: + strncpy(seperators, (char*)value, 257); + break; + } +} + +int LoadConfigFile(const char *fname) { + FILE *fp; + int fsize; + char *temp; + + if(!fname) return -1; + if(!(fp = fopen(fname, "r"))) return -1; + + fseek(fp, 0, SEEK_END); + fsize = ftell(fp); + fseek(fp, 0, SEEK_SET); + + if(!(temp = realloc(config_file, fsize))) return -1; + config_file = temp; + + cfgptr = config_file; + temp = malloc(max_line_len + 1); + while(fgets(temp, max_line_len, fp)) { + char *ptr = temp; + + if(*ptr == '\n') continue; /* kill empty lines, they irritate the parser */ + + while(ptr && *ptr && *ptr != sym_comment) { + if(!strchr(seperators, *ptr)) { /* not a seperator */ + *cfgptr++ = *ptr; + } + ptr++; + } + + if(*ptr == sym_comment && ptr != temp) { + *cfgptr++ = '\n'; + } + } + + *cfgptr = 0; + + memset(&cfg_opt, 0, sizeof(struct ConfigOption)); + cfgptr = config_file; + free(temp); + return 0; +} + +const struct ConfigOption *GetNextOption() { + char *tmpbuf = malloc(max_line_len + 1); + char *ptr = tmpbuf; + + if(!(*cfgptr)) { + free(tmpbuf); + return 0; + } + + while(*cfgptr != '\n') { + *ptr++ = *cfgptr++; + } + *ptr = 0; + cfgptr++; + + if(!(ptr = strchr(tmpbuf, sym_assign))) { + free(tmpbuf); + return 0; + } + *ptr++ = 0; + + cfg_opt.flags = 0; + + cfg_opt.option = realloc(cfg_opt.option, strlen(tmpbuf) + 1); + strcpy(cfg_opt.option, tmpbuf); + + cfg_opt.str_value = realloc(cfg_opt.str_value, strlen(ptr) + 1); + strcpy(cfg_opt.str_value, ptr); + + if(isdigit(cfg_opt.str_value[0])) { + cfg_opt.flags |= CFGOPT_INT; + cfg_opt.int_value = atoi(cfg_opt.str_value); + cfg_opt.flt_value = atof(cfg_opt.str_value); + } + + free(tmpbuf); + return &cfg_opt; +} + +void DestroyConfigParser() { + if(cfg_opt.str_value) free(cfg_opt.str_value); + if(cfg_opt.option) free(cfg_opt.option); + if(config_file) free(config_file); +} diff -r 000000000000 -r ce3c5e4c75bf config_parser.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config_parser.h Wed May 18 05:53:29 2011 +0300 @@ -0,0 +1,57 @@ +/* +This file is part of dynwatch, a win32 system tray applet which +updates automatically the dyndns entry of quake.gr. + +Copyright (c) 2005 John Tsiombikas + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#ifndef _CONFIG_PARSER_H_ +#define _CONFIG_PARSER_H_ + + +#ifdef __cplusplus +extern "C" { +#endif /* _cplusplus */ + + +enum ParserState { + PS_AssignmentSymbol, + PS_CommentSymbol, + PS_Seperators, + PS_MaxLineLen +}; + +#define CFGOPT_INT 1 +#define CFGOPT_FLT 2 + +struct ConfigOption { + char *option, *str_value; + int int_value; + float flt_value; + unsigned short flags; +}; + +void SetParserState(enum ParserState state, int value); +int LoadConfigFile(const char *fname); +const struct ConfigOption *GetNextOption(); +void DestroyConfigParser(); + + +#ifdef __cplusplus +} +#endif /* _cplusplus */ + +#endif /* _CONFIG_PARSER_H_ */ diff -r 000000000000 -r ce3c5e4c75bf dynwatch.ico Binary file dynwatch.ico has changed diff -r 000000000000 -r ce3c5e4c75bf dynwatch.rc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dynwatch.rc Wed May 18 05:53:29 2011 +0300 @@ -0,0 +1,3 @@ +#include "resource.h" + +ICON_DYNWATCH ICON dynwatch.ico diff -r 000000000000 -r ce3c5e4c75bf events.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/events.c Wed May 18 05:53:29 2011 +0300 @@ -0,0 +1,116 @@ +/* +This file is part of dynwatch, a win32 system tray applet which +updates automatically the dyndns entry of quake.gr. + +Copyright (c) 2005 John Tsiombikas + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include "watch.h" +#include "gui.h" + +extern int running; + +long CALLBACK win_proc(HWND win, unsigned int msg, unsigned int wparam, long lparam) { + switch(msg) { + case WM_CLOSE: + DestroyWindow(win); + PostQuitMessage(0); + return 0; + + case WM_COMMAND: + if((HWND)lparam == bn_tray) { + trayfied = !trayfied; + if(trayfied && !running) { + 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!"); + } + tray(trayfied); + } + + if((HWND)lparam == bn_exit) { + DestroyWindow(win); + PostQuitMessage(0); + } + + if((HWND)lparam == bn_config) { + en_set_text(en_dnshost, dhost); + en_set_text(en_user, user); + en_set_text(en_pass, pass); + en_set_text(en_hosts, hosts); + ShowWindow(win_cfg, 1); + } + return 0; + + case WM_USER: + if(lparam == WM_LBUTTONUP) { + trayfied = !trayfied; + tray(trayfied); + } + return 0; + + case WM_TIMER: + if(need_update()) { + update_dns(); + } + return 0; + + default: + break; + } + + return DefWindowProc(win, msg, wparam, lparam); +} + + +int empty_str(const char *str) { + while(*str) if(isalnum(*str++)) return 0; + return 1; +} + +long CALLBACK cfg_proc(HWND win, unsigned int msg, unsigned int wparam, long lparam) { + switch(msg) { + case WM_COMMAND: + if((HWND)lparam == bn_ok) { + if(empty_str(en_get_text(en_dnshost)) || + empty_str(en_get_text(en_user)) || + empty_str(en_get_text(en_pass)) || + empty_str(en_get_text(en_hosts))) { + err_msg("you must fill all the fields of this configuration dialog!"); + return 0; + } + + strncpy(dhost, en_get_text(en_dnshost), 256); + strncpy(user, en_get_text(en_user), 256); + strncpy(pass, en_get_text(en_pass), 256); + strncpy(hosts, en_get_text(en_hosts), 256); + + save_config(); + running = 1; + ShowWindow(win_cfg, 0); + } + + if((HWND)lparam == bn_cancel) { + ShowWindow(win_cfg, 0); + } + return 0; + + default: + break; + } + + return DefWindowProc(win, msg, wparam, lparam); +} diff -r 000000000000 -r ce3c5e4c75bf events.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/events.h Wed May 18 05:53:29 2011 +0300 @@ -0,0 +1,28 @@ +/* +This file is part of dynwatch, a win32 system tray applet which +updates automatically the dyndns entry of quake.gr. + +Copyright (c) 2005 John Tsiombikas + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _EVENTS_H_ +#define _EVENTS_H_ + +long CALLBACK win_proc(HWND win, unsigned int msg, unsigned int wparam, long lparam); +long CALLBACK cfg_proc(HWND win, unsigned int msg, unsigned int wparam, long lparam); + +#endif /* _EVENTS_H_ */ diff -r 000000000000 -r ce3c5e4c75bf gui.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gui.c Wed May 18 05:53:29 2011 +0300 @@ -0,0 +1,134 @@ +/* +This file is part of dynwatch, a win32 system tray applet which +updates automatically the dyndns entry of quake.gr. + +Copyright (c) 2005 John Tsiombikas + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "gui.h" +#include "events.h" +#include "resource.h" + +HWND win_main, bn_exit, bn_tray, bn_config; +HWND win_cfg, lb_dnshost, lb_user, lb_pass, lb_hosts; +HWND en_dnshost, en_user, en_pass, en_hosts; +HWND bn_ok, bn_cancel; +int trayfied; + +void create_gui(void) { + static const int lb_xsz = 130; + static const int lb_ysz = 20; + static const int en_xsz = 100; + static const int en_ysz = 20; + static const int yinc = 25; + int ypos = 5; + + reg_win_class("dynwatch", win_proc); + reg_win_class("dynwatch.config", cfg_proc); + + win_main = create_window("dynwatch 1.0", 330, 80, "dynwatch"); + bn_config = create_button("Configure", 5, 5, 100, 30, win_main); + bn_tray = create_button("Send to tray", 110, 5, 100, 30, win_main); + bn_exit = create_button("Exit", 215, 5, 100, 30, win_main); + ShowWindow(win_main, 1); + + win_cfg = create_window("Configuration", 270, 190, "dynwatch.config"); + + lb_dnshost = create_label("dyndns host:", 5, ypos, lb_xsz, lb_ysz, win_cfg); + en_dnshost = create_entry("", lb_xsz + 10, ypos, en_xsz, en_ysz, win_cfg); + ypos += yinc; + lb_user = create_label("user name:", 5, ypos, lb_xsz, lb_ysz, win_cfg); + en_user = create_entry("", lb_xsz + 10, ypos, en_xsz, en_ysz, win_cfg); + ypos += yinc; + lb_pass = create_label("password:", 5, ypos, lb_xsz, lb_ysz, win_cfg); + en_pass = create_entry("", lb_xsz + 10, ypos, en_xsz, en_ysz, win_cfg); + ypos += yinc; + /*lb_hosts = create_label("hosts to update:", 5, ypos, lb_xsz, lb_ysz, win_cfg); + en_hosts = create_entry("", lb_xsz + 10, ypos, en_xsz, en_ysz, win_cfg);*/ + + ypos += 35; + bn_ok = create_button("OK", 5, ypos, 100, 25, win_cfg); + bn_cancel = create_button("Cancel", 140, ypos, 100, 25, win_cfg); +} + +void tray(int trayfy) { + NOTIFYICONDATA nicon; + memset(&nicon, 0, sizeof nicon); + nicon.cbSize = sizeof nicon; + nicon.hWnd = win_main; + nicon.uID = 0; + nicon.uCallbackMessage = WM_USER; + nicon.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE; + nicon.hIcon = LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(ICON_DYNWATCH)); + strcpy(nicon.szTip, "Click to open the program window"); + + if(trayfy) { + ShowWindow(win_main, 0); + Shell_NotifyIcon(NIM_ADD, &nicon); + } else { + Shell_NotifyIcon(NIM_DELETE, &nicon); + ShowWindow(win_main, 1); + } +} + +HWND create_window(const char *title, int xsz, int ysz, const char *class_name) { + int x = (GetSystemMetrics(SM_CXSCREEN) - xsz) / 2; + int y = (GetSystemMetrics(SM_CYSCREEN) - ysz) / 2; + unsigned long style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU; + return CreateWindow(class_name, title, style, x, y, xsz, ysz, 0, 0, GetModuleHandle(0), 0); +} + +HWND create_button(const char *title, int x, int y, int xsz, int ysz, HWND parent) { + unsigned long style = BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP; + return CreateWindow("BUTTON", title, style, x, y, xsz, ysz, parent, 0, GetModuleHandle(0), 0); +} + +HWND create_label(const char *text, int x, int y, int xsz, int ysz, HWND parent) { + unsigned long style = SS_RIGHT | WS_CHILD | WS_VISIBLE; + return CreateWindow("STATIC", text, style, x, y, xsz, ysz, parent, 0, GetModuleHandle(0), 0); +} + +HWND create_entry(const char *text, int x, int y, int xsz, int ysz, HWND parent) { + unsigned long style = ES_AUTOHSCROLL | WS_CHILD | WS_BORDER | WS_TABSTOP | WS_VISIBLE; + return CreateWindow("EDIT", text, style, x, y, xsz, ysz, parent, 0, GetModuleHandle(0), 0); +} + +void en_set_text(HWND entry, const char *text) { + SendMessage(entry, WM_SETTEXT, 0, (long)text); +} + +const char *en_get_text(HWND entry) { + static char buf[512]; + SendMessage(entry, WM_GETTEXT, 512, (long)buf); + return buf; +} + +void reg_win_class(const char *class_name, msg_handler_t handler) { + WNDCLASSEX wc; + HINSTANCE pid = GetModuleHandle(0); + + memset(&wc, 0, sizeof wc); + wc.cbSize = sizeof wc; + wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); + wc.hCursor = LoadCursor(pid, MAKEINTRESOURCE(IDC_ARROW)); + wc.hIcon = wc.hIconSm = LoadIcon(pid, MAKEINTRESOURCE(ICON_DYNWATCH)); + wc.hInstance = pid; + wc.lpfnWndProc = handler; + wc.lpszClassName = class_name; + wc.style = CS_HREDRAW | CS_VREDRAW; + RegisterClassEx(&wc); +} diff -r 000000000000 -r ce3c5e4c75bf gui.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gui.h Wed May 18 05:53:29 2011 +0300 @@ -0,0 +1,51 @@ +/* +This file is part of dynwatch, a win32 system tray applet which +updates automatically the dyndns entry of quake.gr. + +Copyright (c) 2005 John Tsiombikas + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _GUI_H_ +#define _GUI_H_ + +#include + +typedef long (CALLBACK *msg_handler_t)(HWND, unsigned int, unsigned int, long); + +/* widgets */ +extern HWND win_main, bn_exit, bn_tray, bn_config; +extern HWND win_cfg, lb_dnshost, lb_user, lb_pass, lb_hosts; +extern HWND en_dnshost, en_user, en_pass, en_hosts; +extern HWND bn_ok, bn_cancel; + +/* state, 1 = minimized to system tray, 0 = window visible */ +extern int trayfied; + +void create_gui(void); + +void tray(int trayfy); +HWND create_window(const char *title, int xsz, int ysz, const char *class_name); +HWND create_button(const char *title, int x, int y, int xsz, int ysz, HWND parent); +HWND create_label(const char *text, int x, int y, int xsz, int ysz, HWND parent); +HWND create_entry(const char *text, int x, int y, int xsz, int ysz, HWND parent); + +void en_set_text(HWND entry, const char *text); +const char *en_get_text(HWND entry); + +void reg_win_class(const char *class_name, msg_handler_t handler); + +#endif /* _GUI_H_ */ diff -r 000000000000 -r ce3c5e4c75bf license.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/license.txt Wed May 18 05:53:29 2011 +0300 @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff -r 000000000000 -r ce3c5e4c75bf locator.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/locator.c Wed May 18 05:53:29 2011 +0300 @@ -0,0 +1,170 @@ +/* +This is a small cross-platform resource file locator library. +Author: John Tsiombikas 2004 + +This library is public domain, you are free to do whatever you like with it, +NO WARANTY whatsoever is provided with this library, use it at your own risk. +*/ + +#include +#include +#include +#include "locator.h" + +#ifdef HAVE_CONFIG +#include "config.h" +#endif /* HAVE_CONFIG */ + +#ifdef __unix__ +#define __USE_BSD /* to include readlink() prototype */ +#include + +#define DIR_SEP '/' +#define HOME_ENV "HOME" + +#else /* assume WIN32 */ +#include + +#define DIR_SEP '\\' +#define HOME_ENV "USERPROFILE" + +#endif /* __unix__ */ + + +#ifndef PREFIX +#define PREFIX "" +#endif /* PREFIX */ + +#define MAX_PATH 1024 +#define CONF_ENV "NLOC_CONFIG_PATH" +#define DATA_ENV "NLOC_DATA_PATH" +#define LOC_FUNC_COUNT 2 + +typedef const char *(*loc_func_type)(const char*); + +static const char *locate_config(const char *file); +static const char *locate_data(const char *file); +static const char *exec_path(void); + +static char path[MAX_PATH]; +static loc_func_type loc_func[LOC_FUNC_COUNT] = {locate_config, locate_data}; + +const char *loc_get_path(const char *file, enum loc_file_type file_type) { + if(file_type >= LOC_FUNC_COUNT) return 0; + return loc_func[file_type](file); +} + +static const char *locate_config(const char *file) { + FILE *fp; + char *env, *pptr = path; + const char *fptr = file; + + /* first try $NLOC_CONFIG_PATH/file */ + env = getenv(CONF_ENV); + if(env) { + while(*env) *pptr++ = *env++; + if(*(env - 1) != DIR_SEP) *pptr++ = DIR_SEP; + while(*fptr) *pptr++ = *fptr++; + *pptr++ = 0; + + fprintf(stderr, "trying: %s\n", path); + if((fp = fopen(path, "r"))) { + fclose(fp); + return path; + } + } + + /* then try $HOME/.file */ + pptr = path; + fptr = file; + env = getenv(HOME_ENV); + if(env) { + while(*env) *pptr++ = *env++; + if(*(env - 1) != DIR_SEP) *pptr++ = DIR_SEP; +#ifdef __unix__ + *pptr++ = '.'; +#endif /* __unix__ */ + while(*fptr) *pptr++ = *fptr++; + *pptr++ = 0; + + fprintf(stderr, "trying: %s\n", path); + if((fp = fopen(path, "r"))) { + fclose(fp); + return path; + } + } + +#ifdef __unix__ + /* then PREFIX/etc/file */ + strcpy(path, PREFIX); + strcat(path, "/etc/"); + strcat(path, file); + + fprintf(stderr, "trying: %s\n", path); + if((fp = fopen(path, "r"))) { + fclose(fp); + return path; + } +#else + /* or something similar on win32 */ + env = getenv("ALLUSERSPROFILE"); + if(env) { + strcpy(path, env); + strcat(path, "\\"); + strcat(path, file); + + fprintf(stderr, "trying: %s\n", path); + if((fp = fopen(path, "r"))) { + fclose(fp); + return path; + } + } +#endif /* __unix__ */ + + + /* finally as a last resort try the executable directory, this may not work */ + strcpy(path, exec_path()); + strcat(path, file); + + fprintf(stderr, "trying: %s\n", path); + if((fp = fopen(path, "r"))) { + fclose(fp); + return path; + } + + return 0; +} + +/* TODO: not implemented yet */ +static const char *locate_data(const char *file) { + return 0; +} + +static const char *exec_path(void) { + static char path[MAX_PATH]; + int ccount = 0; + char *ptr; + +#ifdef __linux__ + ccount = readlink("/proc/self/exe", path, MAX_PATH - 1); +#endif /* __linux__ */ + +#ifdef __FreeBSD__ + ccount = readlink("/proc/curproc/file", path, MAX_PATH - 1); +#endif /* __FreeBSD__ */ + +#ifdef WIN32 + ccount = GetModuleFileName(0, path, MAX_PATH - 1); +#endif /* WIN32 */ + + if(!ccount) return 0; + + path[ccount] = 0; + + ptr = strrchr(path, DIR_SEP); + if(!ptr) return 0; + + *(ptr + 1) = 0; + + return path; +} diff -r 000000000000 -r ce3c5e4c75bf locator.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/locator.h Wed May 18 05:53:29 2011 +0300 @@ -0,0 +1,27 @@ +/* +This is a small cross-platform resource file locator library. +Author: John Tsiombikas 2004 + +This library is public domain, you are free to do whatever you like with it, +NO WARANTY whatsoever is provided with this library, use it at your own risk. +*/ + +#ifndef _LOCATOR_H_ +#define _LOCATOR_H_ + +enum loc_file_type { + LOC_FILE_CONFIG, + LOC_FILE_DATA +}; + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +const char *loc_get_path(const char *file, enum loc_file_type file_type); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _LOCATOR_H_ */ diff -r 000000000000 -r ce3c5e4c75bf resource.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/resource.h Wed May 18 05:53:29 2011 +0300 @@ -0,0 +1,1 @@ +#define ICON_DYNWATCH 100 diff -r 000000000000 -r ce3c5e4c75bf socklib.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/socklib.c Wed May 18 05:53:29 2011 +0300 @@ -0,0 +1,246 @@ +/* +This file is part of socklib, a cross-platform socket library. + +Copyright (c) 2004 John Tsiombikas + +This library is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include + +#ifdef __unix__ +#define __USE_BSD +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#else /* assume win32 if not unix */ + +#include + +#define MAXHOSTNAMELEN 255 +#define close(s) closesocket(s) + +static int winsock_initialized; +#endif /* __unix__ */ + +#include "socklib.h" + +#ifdef _MSC_VER +#define __func__ __FUNCTION__ +#endif /* _MSC_VER */ + +static int verbose = 1; + +int sl_listen(int port) { + int s; + struct sockaddr_in addr; + struct hostent *host; + char host_name[MAXHOSTNAMELEN+1]; + +#ifndef __unix__ + if(!winsock_initialized) { + WSADATA wsa_data; + WSAStartup(MAKEWORD(1, 1), &wsa_data); + winsock_initialized = 1; + } +#endif /* __unix__ */ + + if(gethostname(host_name, MAXHOSTNAMELEN+1) == -1) { + if(verbose) perror("socklib error @ gethostname"); + return -1; + } + + if(!(host = gethostbyname(host_name))) { + if(verbose) perror("socklib error @ gethostbyname"); + return -1; + } + + memset(&addr, 0, sizeof(struct sockaddr_in)); + addr.sin_family = host->h_addrtype; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = INADDR_ANY; + + if((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + if(verbose) perror("socklib error @ socket"); + return -1; + } + + if(bind(s, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)) == -1) { + if(verbose) perror("socklib error @ bind"); + close(s); + return -1; + } + + if(listen(s, 5) == -1) { + if(verbose) perror("socklib error @ listen"); + close(s); + return -1; + } + + return s; +} + + +int sl_accept(int listening_socket) { + return accept(listening_socket, 0, 0); +} + +int sl_connect_tcp(char *ipaddr, const char *hostname, int port) { + int s, must_free_ipaddr = 0; + struct sockaddr_in addr; + struct hostent *host; + +#ifndef __unix__ + if(!winsock_initialized) { + WSADATA wsa_data; + WSAStartup(MAKEWORD(1, 1), &wsa_data); + winsock_initialized = 1; + } +#endif /* __unix__ */ + + if((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + if(verbose) perror("socklib error @ socket"); + return -1; + } + + if(!ipaddr) { + if(!hostname) return -1; + + ipaddr = malloc(20); + must_free_ipaddr = 1; + host = gethostbyname(hostname); + + if(!host) { + if(verbose) perror("socklib error @ gethostbyname"); + free(ipaddr); + return -1; + } + + strcpy(ipaddr, inet_ntoa(*((struct in_addr*)host->h_addr))); + } + + memset(&addr, 0, sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = inet_addr(ipaddr); + + if((connect(s, (struct sockaddr*)&addr, sizeof(struct sockaddr))) == -1) { + if(verbose) perror("socklib error @ connect"); + if(must_free_ipaddr) free(ipaddr); + return -1; + } + + if(must_free_ipaddr) free(ipaddr); + return s; +} + + +void sl_close_socket(int s) { + char buffer[128]; + + shutdown(s, 1); + while(recv(s, buffer, 128, 0)); + close(s); +} + +int sl_send_data(int s, const char *buffer, int size) { + const char *ptr = buffer; + const char *end = buffer + size; + + while(ptr < end) { + int bytes = send(s, ptr, end - ptr, 0); + if(bytes == -1) { + if(verbose) { + char errstr[80]; + sprintf(errstr, "socklib error @ %s", __func__); + perror(errstr); + } + return -1; + } + ptr += bytes; + } + + return size; +} + +int sl_recv_data(int s, char *buffer, int size) { + int bytes = recv(s, buffer, size, 0); + if(bytes == -1) { + if(verbose) { + char errstr[80]; + sprintf(errstr, "socklib error @ %s", __func__); + perror(errstr); + } + return -1; + } + return bytes; +} + + +/* if SL_CHK_IMMED is NOT specified then: + * if timeout is 0: block forever, else block for so many milliseconds. + */ +int sl_check_socket(int s, int flags, unsigned int timeout) { + int res; + fd_set rfds, wfds; + struct timeval tv, *tvptr; + tv.tv_sec = tv.tv_usec = 0; + + tvptr = (flags & SL_CHK_IMMED) ? &tv : 0; + + if(flags & SL_CHK_IMMED) { + tvptr = &tv; + } else { + tvptr = timeout > 0 ? &tv : 0; + + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout - tv.tv_sec * 1000) * 1000; + } + + + FD_ZERO(&rfds); + FD_ZERO(&wfds); + + if(flags & SL_CHK_READ) { + FD_SET(s, &rfds); + if((res = select(s+1, &rfds, 0, 0, tvptr)) == -1) { + return -1; + } + return FD_ISSET(s, &rfds) ? 1 : 0; + } else if(flags & SL_CHK_WRITE) { + FD_SET(s, &wfds); + if((res = select(s+1, 0, &wfds, 0, tvptr)) == -1) { + return -1; + } + return FD_ISSET(s, &wfds) ? 1 : 0; + } + + return -1; +} + +void sl_set_verbosity(int vlevel) { + verbose = vlevel; +} diff -r 000000000000 -r ce3c5e4c75bf socklib.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/socklib.h Wed May 18 05:53:29 2011 +0300 @@ -0,0 +1,48 @@ +/* +This file is part of socklib, a cross-platform socket library. + +Copyright (c) 2004 John Tsiombikas + +This library is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _SOCKLIB_H_ +#define _SOCKLIB_H_ + + +#define SL_CHK_BLOCK 0 +#define SL_CHK_IMMED 1 +#define SL_CHK_READ 2 +#define SL_CHK_WRITE 4 + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +int sl_listen(int port); +int sl_accept(int listening_socket); +int sl_connect_tcp(char *ipaddr, const char *hostname, int port); +void sl_close_socket(int s); +int sl_send_data(int s, const char *buffer, int size); +int sl_recv_data(int s, char *buffer, int size); +int sl_check_socket(int s, int flags, unsigned int timeout); +void sl_set_verbosity(int vlevel); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SOCKLIB_H_ */ diff -r 000000000000 -r ce3c5e4c75bf tray.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tray.c Wed May 18 05:53:29 2011 +0300 @@ -0,0 +1,46 @@ +/* +This file is part of dynwatch, a win32 system tray applet which +updates automatically the dyndns entry of quake.gr. + +Copyright (c) 2005 John Tsiombikas + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include "gui.h" +#include "watch.h" + +/* when this is true, the program checks periodically for + * connection status and updates the dynamic dns entry + */ +int running; + +int WINAPI WinMain(HINSTANCE proc_handle, HINSTANCE prev, char *args, int show) { + MSG msg; + + init(); + create_gui(); + + SetTimer(win_main, 0, 20000, 0); + + while(GetMessage(&msg, 0, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + return 0; +} + diff -r 000000000000 -r ce3c5e4c75bf tray.sln --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tray.sln Wed May 18 05:53:29 2011 +0300 @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 7.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tray", "tray.vcproj", "{219EB00A-2B8C-46A5-8E5C-73C7B43BF060}" +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + ConfigName.0 = Debug + ConfigName.1 = Release + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {219EB00A-2B8C-46A5-8E5C-73C7B43BF060}.Debug.ActiveCfg = Debug|Win32 + {219EB00A-2B8C-46A5-8E5C-73C7B43BF060}.Debug.Build.0 = Debug|Win32 + {219EB00A-2B8C-46A5-8E5C-73C7B43BF060}.Release.ActiveCfg = Release|Win32 + {219EB00A-2B8C-46A5-8E5C-73C7B43BF060}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff -r 000000000000 -r ce3c5e4c75bf tray.vcproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tray.vcproj Wed May 18 05:53:29 2011 +0300 @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 000000000000 -r ce3c5e4c75bf watch.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/watch.c Wed May 18 05:53:29 2011 +0300 @@ -0,0 +1,197 @@ +/* +This file is part of dynwatch, a win32 system tray applet which +updates automatically the dyndns entry of quake.gr. + +Copyright (c) 2005 John Tsiombikas + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include +#include "socklib.h" +#include "watch.h" +#include "config_parser.h" +#include "locator.h" + +int empty_str(const char *str); + +static const char *cfg_fname = "dynwatch.conf"; +char user[256], pass[256], dhost[256], hosts[256]; +extern int running; + +static int connected; + +void init(void) { + const struct ConfigOption *opt; + + SetParserState(PS_AssignmentSymbol, ':'); + SetParserState(PS_CommentSymbol, '#'); + + if(LoadConfigFile(loc_get_path(cfg_fname, LOC_FILE_CONFIG)) == -1) { + err_msg("Could not load config file, please reconfigure"); + } else { + + while((opt = GetNextOption())) { + if(!strcmp(opt->option, "user")) { + strncpy(user, opt->str_value, 256); + } else if(!strcmp(opt->option, "pass")) { + strncpy(pass, opt->str_value, 256); + } else if(!strcmp(opt->option, "dns-host")) { + strncpy(dhost, opt->str_value, 256); + } else if(!strcmp(opt->option, "hosts")) { + strncpy(hosts, opt->str_value, 256); + } else { + err_msg("Error parsing config file, please reconfigure"); + user[0] = pass[0] = dhost[0] = hosts[0] = 0; + } + } + + if(!empty_str(user) && !empty_str(pass) && !empty_str(dhost) && !empty_str(hosts)) { + running = 1; + } + } + + DestroyConfigParser(); + + /* force a wsastartup call */ + sl_set_verbosity(0); + sl_connect_tcp("0.0.0.0", 0, 0); + sl_set_verbosity(1); +} + +void get_ip_address(struct in_addr *addr) { + struct hostent *host; + char **str_ptr; + static char hostname[512]; + + if(gethostname(hostname, 512) == -1) { + err_msg("gethostname() failed\n"); + } + + if(!(host = gethostbyname(hostname))) { + err_msg("gethostbyname() failed\n"); + } + + *addr = *(struct in_addr*)host->h_addr_list[0]; +} + +int need_update(void) { + unsigned long flags; + static struct in_addr addr; + + if(IsNetworkAlive(&flags)) { + /* it was not connected before, we need to update */ + if(!connected) { + get_ip_address(&addr); + connected = 1; + return 1; + } + + /* it was connected before, but we may have missed a short + * disconnect. Check to see if we still have the same ip (not fullproof) + */ + { + struct in_addr tmp; + get_ip_address(&tmp); + + if(addr.S_un.S_addr != tmp.S_un.S_addr) { + addr = tmp; + return 1; + } + } + + } else { + connected = 0; + } + return 0; +} + + +int update_dns(void) { + int s, bytes; + static char http_req[512]; + char *buf, *ptr; + + if(empty_str(user) || empty_str(pass) || empty_str(dhost) || empty_str(hosts)) { + err_msg("missing configuration data, please reconfigure"); + return -1; + } + + if((s = sl_connect_tcp(0, dhost, 80)) == -1) { + connected = 0; + return -1; + } + + buf = malloc(4096); + + sprintf(buf, "update.php?rid=%s&token=%s", user, pass); + sprintf(http_req, "GET http://%s/%s HTTP/1.0\r\nUser-Agent: dynwatch/1.0\r\n\r\n", dhost, buf); + + sl_send_data(s, http_req, strlen(http_req)); + while((bytes = sl_recv_data(s, buf, 4096))) { + if(bytes == -1) break; + + ptr = strstr(buf, "Updated"); + if(ptr) { + free(buf); + info_msg("dns update complete"); + sl_close_socket(s); + return 0; + } + } + + free(buf); + err_msg("dns update failed"); + sl_close_socket(s); + return -1; +} + +#define HOME_ENV "USERPROFILE" +#define DIR_SEP '\\' +#define MAX_PATH 512 + +void save_config(void) { + FILE *fp; + static char path[MAX_PATH]; + const char *fptr = cfg_fname; + char *env, *pptr = path; + + env = getenv(HOME_ENV); + if(env) { + while(*env) *pptr++ = *env++; + if(*(env - 1) != DIR_SEP) *pptr++ = DIR_SEP; + while(*fptr) *pptr++ = *fptr++; + *pptr++ = 0; + } else { + strcpy(path, cfg_fname); + info_msg("warning: no USERPROFILE variable found, saving config to the current dir."); + } + + if(!(fp = fopen(path, "w"))) { + err_msg("could not save config file!"); + return; + } + + fprintf(fp, "dns-host: %s\n", dhost); + fprintf(fp, "user: %s\n", user); + fprintf(fp, "pass: %s\n", pass); + fprintf(fp, "hosts: %s\n", hosts); + + fclose(fp); +} diff -r 000000000000 -r ce3c5e4c75bf watch.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/watch.h Wed May 18 05:53:29 2011 +0300 @@ -0,0 +1,36 @@ +/* +This file is part of dynwatch, a win32 system tray applet which +updates automatically the dyndns entry of quake.gr. + +Copyright (c) 2005 John Tsiombikas + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _WATCH_H_ +#define _WATCH_H_ + +#define info_msg(x) MessageBox(0, x, "dynwatch info", MB_ICONINFORMATION | MB_OK) +#define err_msg(x) MessageBox(0, x, "dynwatch error", MB_ICONSTOP | MB_OK) + +extern char user[256], pass[256], dhost[256], hosts[256]; + +void init(void); +int need_update(void); +int update_dns(void); + +void save_config(void); + +#endif /* _WATCH_H_ */