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 --- request.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 request.c (limited to 'request.c') 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; +} -- cgit v1.2.3