From 45d9d4477663635bc77a1f2253535dfb20358821 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Wed, 27 Apr 2005 23:13:11 +0000 Subject: demon's dyndns updater --- Makefile | 8 +++ base64.c | 78 ++++++++++++++++++++++ base64.h | 42 ++++++++++++ connect.c | 57 ++++++++++++++++ connect.h | 26 ++++++++ dddup.c | 70 ++++++++++++++++++++ dddup.conf | 31 +++++++++ ifaddr.c | 55 ++++++++++++++++ ifaddr.h | 25 +++++++ parse.c | 219 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ parse.h | 58 ++++++++++++++++ request.c | 133 +++++++++++++++++++++++++++++++++++++ request.h | 47 +++++++++++++ version.h | 24 +++++++ 14 files changed, 873 insertions(+) create mode 100644 Makefile create mode 100644 base64.c create mode 100644 base64.h create mode 100644 connect.c create mode 100644 connect.h create mode 100644 dddup.c create mode 100644 dddup.conf create mode 100644 ifaddr.c create mode 100644 ifaddr.h create mode 100644 parse.c create mode 100644 parse.h create mode 100644 request.c create mode 100644 request.h create mode 100644 version.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..dfc0a54 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +# $Id$ + +PROG= dddup +SRCS= dddup.c parse.c ifaddr.c base64.c request.c connect.c +NOMAN= +#CFLAGS+= -Wall -ggdb -pedantic + +.include diff --git a/base64.c b/base64.c new file mode 100644 index 0000000..3218aa7 --- /dev/null +++ b/base64.c @@ -0,0 +1,78 @@ +/* $Id$ */ +/* + * Copyright (c) 1995-2001 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include "base64.h" + +static char base64_chars[] = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +int +base64_encode(const void *data, int size, char **str) +{ + char *s, *p; + int i; + int c; + const unsigned char *q; + + p = s = (char *) malloc(size * 4 / 3 + 4); + if (p == NULL) + return -1; + q = (const unsigned char *) data; + i = 0; + for (i = 0; i < size;) { + c = q[i++]; + c *= 256; + if (i < size) + c += q[i]; + i++; + c *= 256; + if (i < size) + c += q[i]; + i++; + p[0] = base64_chars[(c & 0x00fc0000) >> 18]; + p[1] = base64_chars[(c & 0x0003f000) >> 12]; + p[2] = base64_chars[(c & 0x00000fc0) >> 6]; + p[3] = base64_chars[(c & 0x0000003f) >> 0]; + if (i > size) + p[3] = '='; + if (i > size + 1) + p[2] = '='; + p += 4; + } + *p = 0; + *str = s; + return strlen(s); +} diff --git a/base64.h b/base64.h new file mode 100644 index 0000000..2e8cda3 --- /dev/null +++ b/base64.h @@ -0,0 +1,42 @@ +/* $Id$ */ +/* + * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _BASE64_H_ +#define _BASE64_H_ + +__BEGIN_DECLS +int base64_encode(const void *, int, char **); +__END_DECLS + +#endif /* Not _BASE64_H_ */ diff --git a/connect.c b/connect.c new file mode 100644 index 0000000..0566742 --- /dev/null +++ b/connect.c @@ -0,0 +1,57 @@ +/* $Id$ */ +/* + * Copyright (c) 2004 demon + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include "connect.h" + +int +connecttohost(const char *host, const int port) +{ + struct hostent *he; + struct sockaddr_in sin; + int s; + + if ((he = gethostbyname(host)) == NULL) + err(1, "gethostbyname()"); + + sin.sin_family = AF_INET; + sin.sin_port = htons(port); + sin.sin_addr = *(struct in_addr *) he->h_addr; + + if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) + err(1, "socket()"); + + if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) == -1) + err(1, "connect()"); + + return s; +} + +int +transfer(int s, char *buf, int size) +{ + if (send(s, buf, strlen(buf), 0) == -1) + err(1, "send()"); + memset(buf, '\0', size); + if (recv(s, buf, size, 0) == -1) + err(1, "recv()"); + return 0; +} diff --git a/connect.h b/connect.h new file mode 100644 index 0000000..b2b5b63 --- /dev/null +++ b/connect.h @@ -0,0 +1,26 @@ +/* $Id$ */ +/* + * Copyright (c) 2004 demon + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _CONNECT_H_ +#define _CONNECT_H_ + +__BEGIN_DECLS +int connecttohost(const char *, const int); +int transfer(int, char *, int); +__END_DECLS + +#endif /* Not _CONNECT_H_ */ diff --git a/dddup.c b/dddup.c new file mode 100644 index 0000000..612b9c7 --- /dev/null +++ b/dddup.c @@ -0,0 +1,70 @@ +/* $Id$ */ +/* + * Copyright (c) 2004 demon + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include "request.h" +#include "parse.h" +#include "version.h" + +int debug; +int verbose; + +__dead void +usage(void) +{ + extern char *__progname; + + (void) fprintf(stderr, "usage: %s [-dv] [-f config]\n", __progname); + exit(1); +} + +int +main(int argc, char **argv) +{ + struct dd_request **reqv; + char ch; + char *conffile = NULL; + int reqc; + + while ((ch = getopt(argc, argv, "f:dvh")) != -1) + switch (ch) { + case 'f': + conffile = optarg; + break; + case 'd': + debug = 1; + break; + case 'v': + verbose = 1; + break; + case 'h': + /* FALLTHROUGH */ + default: + usage(); + /* NOTREACHED */ + } + + reqv = malloc(sizeof(struct dd_request)); + if ((reqc = parse_config(conffile, reqv)) == 0) + errx(1, "Nothing to do"); + do_request(reqc, reqv); + free_config(reqc, reqv); + free(reqv); + exit(0); +} diff --git a/dddup.conf b/dddup.conf new file mode 100644 index 0000000..91b72e4 --- /dev/null +++ b/dddup.conf @@ -0,0 +1,31 @@ +# $Id$ +# +# dyndns|statdns|custdns +# username=username (required) +# password=password (required) +# hostname=host1.dyndns.org (required) +# myip=1.3.3.7 or interface=tun0 +# wildcard +# mx=mailexchanger (and) backmx +# offline + +all:\ + :dynamic:static:custom: + +dynamic:\ + :dyndns:\ + :interface=lo0:\ + :username=test:password=test:\ + :hostname=test.dyndns.org: + +static:\ + :statdns:\ + :interface=lo0:\ + :username=test:password=test:\ + :hostname=test-static.dyndns.org: + +custom:\ + :custdns:\ + :interface=lo0:\ + :username=test:password=test:\ + :hostname=test1.customtest.dyndns.org: diff --git a/ifaddr.c b/ifaddr.c new file mode 100644 index 0000000..5dbde91 --- /dev/null +++ b/ifaddr.c @@ -0,0 +1,55 @@ +/* $Id$ */ +/* + * Copyright (c) 2004 demon + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ifaddr.h" + +int +if_ntoa(char *if_name, char **if_addr) +{ + struct ifreq ifr; + struct sockaddr_in sin; + int fd; + + memset(&ifr, '\0', sizeof(ifr)); + + strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name) - 1); + + if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + err(1, "socket()"); + + if (ioctl(fd, SIOCGIFADDR, &ifr) < 0) { + close(fd); + err(1, "ioctl()"); + } + + memcpy(&sin, &(ifr.ifr_addr), sizeof(sin)); + + *if_addr = inet_ntoa(sin.sin_addr); + + close(fd); + return 0; +} diff --git a/ifaddr.h b/ifaddr.h new file mode 100644 index 0000000..8c4c710 --- /dev/null +++ b/ifaddr.h @@ -0,0 +1,25 @@ +/* $Id$ */ +/* + * Copyright (c) 2004 demon + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _IF_H_ +#define _IF_H_ + +__BEGIN_DECLS +int if_ntoa(char *if_name, char **if_addr); +__END_DECLS + +#endif /* Not _IF_H_ */ diff --git a/parse.c b/parse.c new file mode 100644 index 0000000..8f6e687 --- /dev/null +++ b/parse.c @@ -0,0 +1,219 @@ +/* $Id$ */ +/* + * Copyright (c) 2004 demon + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include "request.h" +#include "parse.h" +#include "base64.h" +#include "ifaddr.h" + +extern int debug; + +#if DEBUG +static void +print_config(struct dd_request *req) +{ + printf("auth: %s\n", req->auth); + if (req->system != NULL) + printf("syst: %s\n", req->system); + printf("host: %s\n", req->hostname); + if (req->myip != NULL) + printf("myip: %s\n", req->myip); + if (req->wildcard != NULL) + printf("wild: %s\n", req->wildcard); + if (req->mx != NULL) { + printf("mx : %s\n", req->mx); + if (req->backmx != NULL) + printf("back: %s\n", req->backmx); + } + if (req->offline != NULL) + printf("offl: %s\n", req->offline); +} +#endif + +static int +getconf(char **db_array, char *name, struct dd_request *req) +{ + char *buf, *user, *pass, *if_name, *if_addr; + char auth[240]; + + int f_sys = SYS_ALL; + + memset(req, '\0', sizeof(struct dd_request)); + + if (cgetent(&buf, db_array, name) != 0) + errx(1, "Can't find \"%s\" in dddup config", name); + + /* get type of service -- optional */ + if (cgetcap(buf, "dyndns", ':') != NULL) { + req->system = "dyndns"; + f_sys = SYS_DYN; + } + +#define DSCERR "either \"dyndns\" or \"statdns\" or \"custdns\" " \ + "should be specifed" + + if (cgetcap(buf, "statdns", ':') != NULL) { + if (req->system != NULL) + errx(1, DSCERR); + req->system = "statdns"; + f_sys = SYS_STAT; + } + + if (cgetcap(buf, "custdns", ':') != NULL) { + if (req->system != NULL) + errx(1, DSCERR); + req->system = "custdns"; + f_sys = SYS_CUST; + } + + /* get username -- required */ + switch (cgetstr(buf, "username", &user)) { + case -1: + errx(1, "No username"); + case -2: + errx(1, "malloc"); + } + + /* get password -- required */ + switch (cgetstr(buf, "password", &pass)) { + case -1: + errx(1, "No password"); + case -2: + errx(1, "malloc"); + } + + /* encrypt and set "req->auth" */ + snprintf(auth, sizeof(auth), "%s:%s", user, pass); + memset(pass, '\0', strlen(pass)); + base64_encode(auth, strlen(auth), &req->auth); + memset(&auth, '\0', sizeof(auth)); + + /* interface -> set "req->myip" */ + switch (cgetstr(buf, "interface", &if_name)) { + case -1: + if_name = NULL; + break; + case -2: + errx(1, "malloc"); + } + + switch (cgetstr(buf, "myip", &req->myip)) { + case -1: if_addr = NULL; + break; + case -2: + errx(1, "malloc"); + } + + if (if_name != NULL && req->myip != NULL) + errx(1, "either \"interface\" or \"myip\" should be specifed"); + + if (if_name != NULL) + if_ntoa(if_name, &req->myip); + + switch (cgetstr(buf, "hostname", &req->hostname)) { + case -1: + errx(1, "No hostname"); + case -2: + errx(1, "malloc"); + } + + if (f_sys & (SYS_DYN|SYS_STAT)) { + if (cgetcap(buf, "wildcard", ':') != NULL) + req->wildcard = "ON"; + else + req->wildcard = "OFF"; + } + + if (f_sys & (SYS_DYN|SYS_STAT)) { + switch (cgetstr(buf, "mx", &req->mx)) { + case -1: + req->mx = NULL; + break; + case -2: + errx(1, "malloc"); + } + } + + if (f_sys & (SYS_DYN|SYS_STAT) && req->mx != NULL) { + if (cgetcap(buf, "backmx", ':') != NULL) + req->backmx = "YES"; + else + req->backmx = "NO"; + } + + if (f_sys & (SYS_DYN|SYS_CUST)) { + if (cgetcap(buf, "offline", ':') != NULL) + req->offline = "YES"; + else + req->offline = "NO"; + } + + return 0; +} + +int +parse_config(char *file, struct dd_request **req) +{ + + char **db_array, *buf, *name; + int count = 0; + + db_array = malloc(sizeof(char *)); + + if (file == NULL) + file = _PATH_DDDUP; + *db_array = file; + + if (cgetent(&buf, db_array, "all") != 0) + errx(1, "Can't find \"all\" in dddup config"); + + name = strsep(&buf, ": \t"); /* skip "all" at start */ + while ((name = strsep(&buf, ": \t")) != NULL) { + if (*name) { + req[count] = malloc(sizeof(struct dd_request)); + getconf(db_array, name, req[count]); + count++; + } + } + + free(db_array); + +#if DEBUG + if (debug) { + for (i = 0; i < count; i++) { + printf("===> No. %d\n", i); + print_config(req[i]); + } + } +#endif + + return count; +} + +int +free_config(int reqc, struct dd_request **reqv) +{ + int i; + + for (i = 0; i < reqc; i++) + free(reqv[i]); + return 0; +} diff --git a/parse.h b/parse.h new file mode 100644 index 0000000..bb86334 --- /dev/null +++ b/parse.h @@ -0,0 +1,58 @@ +/* $Id$ */ +/* + * Copyright (c) 2004 demon + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _PARSE_H_ +#define _PARSE_H_ + +#define _PATH_DDDUP "dddup.conf" + +#define SYS_DYN 0x1 +#define SYS_STAT 0x2 +#define SYS_CUST 0x4 +#define SYS_ALL SYS_DYN|SYS_STAT|SYS_CUST + +#if 0 +static struct dd_conf { + const char *name; + char *value; + const int system; + const int range; + const int optional; +} conf[] = { + { "username", NULL, SYS_ALL, VAL_STR, OPT_NO }, + { "password", NULL, SYS_ALL, VAL_STR, OPT_NO }, +// { "system", NULL, SYS_ALL, VAL_STR, OPT_YES }, + { "dyndns", NULL, SYS_DYN, VAL_NONE, OPT_YES }, + { "statdns", NULL, SYS_STAT, VAL_NONE, OPT_YES }, + { "custdns", NULL, SYS_CUST, VAL_NONE, OPT_YES }, + { "hostname", NULL, SYS_ALL, VAL_STR, OPT_NO }, + { "myip", NULL, SYS_ALL, VAL_STR, OPT_YES }, + { "intarface", NULL, SYS_ALL, VAL_STR, OPT_YES }, + { "wildcard", NULL, SYS_DYN|SYS_STAT, VAL_WC, OPT_YES }, + { "mx", NULL, SYS_DYN|SYS_STAT, VAL_STR, OPT_YES }, + { "backmx", NULL, SYS_DYN|SYS_STAT, VAL_YN, OPT_YES }, + { "offline", NULL, SYS_DYN|SYS_CUST, VAL_YN, OPT_YES }, + { NULL, NULL, 0, 0, 0 } +}; +#endif + +__BEGIN_DECLS +int parse_config(char *, struct dd_request **); +int free_config(int, struct dd_request **); +__END_DECLS + +#endif /* Not _PARSE_H_ */ diff --git a/request.c b/request.c new file mode 100644 index 0000000..f5d5f77 --- /dev/null +++ b/request.c @@ -0,0 +1,133 @@ +/* $Id$ */ +/* + * Copyright (c) 2004 demon + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include "request.h" +#include "connect.h" +#include "version.h" + +extern int debug; +extern int verbose; + +#define BUFLEN 1024 + +static int +build_request(struct dd_request *req, char *buf) +{ + snprintf(buf, BUFLEN, "GET /nic/update?"); + if (req->system != NULL) + snprintf(buf + strlen(buf), BUFLEN - strlen(buf), + "system=%s&", req->system); + snprintf(buf + strlen(buf), BUFLEN - strlen(buf), + "hostname=%s", req->hostname); + if (req->myip != NULL) + snprintf(buf + strlen(buf), BUFLEN - strlen(buf), + "&myip=%s", req->myip); + if (req->wildcard != NULL) + snprintf(buf + strlen(buf), BUFLEN - strlen(buf), + "&wildcard=%s", req->wildcard); + if (req->mx != NULL) + snprintf(buf + strlen(buf), BUFLEN - strlen(buf), + "&mx=%s", req->mx); + if (req->mx != NULL && req->backmx != NULL) + snprintf(buf + strlen(buf), BUFLEN - strlen(buf), + "&backmx=%s", req->backmx); + if (req->offline != NULL) + snprintf(buf + strlen(buf), BUFLEN - strlen(buf), + "&offline=%s", req->offline); + snprintf(buf + strlen(buf), BUFLEN - strlen(buf), + " HTTP/1.0\r\n" + "Host: %s\r\n" + "Authorization: Basic %s\r\n" + "User-Agent: %s/%s\r\n" + "Connection: close\r\n\r\n", + DYNDNSHOST, req->auth, USERAGENT, VERSION); + + return 0; +} + +#define RET_OK 0 +#define RET_ERR 1 + +static struct dd_retcode retcode[] = { + { "badsys", "bad system parameter", RET_ERR }, + { "badagent", "useragent has been blocked", RET_ERR }, + { "badauth", "bad authorization", RET_ERR }, + { "!donator", "option available only to credited user", RET_ERR }, + { "good", "update was successful", RET_OK }, + { "nochg", "no update required", RET_OK }, + { "notfqdn", "fully-qualified domain name was not provided", RET_ERR }, + { "nohost", "hostname does not exist in database", RET_ERR }, + { "!yours", "hostname does not belong to username", RET_ERR }, + { "abuse", "hostname is blocked for abuse", RET_ERR }, + { "numhost", "too many or too few hosts found", RET_ERR }, + { "dnserr", "DNS error encountered", RET_ERR }, + { "911", "internal server failure", RET_ERR }, + { NULL, NULL, 0 } +}; + +static int +parse_answer(char *buf) +{ + char *p; + int i; + + if (strstr(buf, "HTTP/1.") == NULL) + errx(1, "strange server response"); + + (void) strtok(buf, "\n"); + while ((p = strtok((char *) NULL, "\n")) != NULL) { + for (i = 0; retcode[i].code != NULL; i++) { + if (strstr(p, retcode[i].code)) { + if (verbose) + warnx("%s", retcode[i].message); + return retcode[i].ret; + } + } + } + + return RET_ERR; +} + +int +do_request(int reqc, struct dd_request **reqv) +{ + int i; + int sockfd; + char buf[BUFLEN]; + + for (i = 0; i < reqc; i++) { + sockfd = connecttohost(DYNDNSHOST, DYNDNSPORT); + build_request(reqv[i], buf); + if (debug) + printf("request:\n%s\n", buf); + if (transfer(sockfd, buf, BUFLEN) == -1) + err(1, "transfer error"); + close(sockfd); + if (debug) + printf("response:\n%s\n", buf); + + if (parse_answer(buf) == RET_ERR) + return -1; + } + + return 0; +} diff --git a/request.h b/request.h new file mode 100644 index 0000000..a32d3f4 --- /dev/null +++ b/request.h @@ -0,0 +1,47 @@ +/* $Id$ */ +/* + * Copyright (c) 2004 demon + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _REQUEST_H_ +#define _REQUEST_H_ + +#define DYNDNSHOST "members.dyndns.org" +#define DYNDNSPORT 80 +#define DYNDNSPORT2 8245 + +struct dd_request { +// char *name; + char *auth; + char *system; + char *hostname; + char *myip; + char *wildcard; + char *mx; + char *backmx; + char *offline; +}; + +struct dd_retcode { + const char *code; + const char *message; + const int ret; +}; + +__BEGIN_DECLS +int do_request(int, struct dd_request **); +__END_DECLS + +#endif /* Not _REQUEST_H_ */ diff --git a/version.h b/version.h new file mode 100644 index 0000000..78a919f --- /dev/null +++ b/version.h @@ -0,0 +1,24 @@ +/* $Id$ */ +/* + * Copyright (c) 2004 demon + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _VERSION_H_ +#define _VERSION_H_ + +#define USERAGENT "dddup" +#define VERSION "0.1" + +#endif /* Not _VERSION_H_ */ -- cgit v1.2.3