--- a/common.c Thu Jun 05 23:04:28 2008 +0300
+++ b/common.c Fri Jun 06 03:24:22 2008 +0300
@@ -3,6 +3,7 @@
#include <stdarg.h>
#include <errno.h>
#include <string.h>
+#include <ctype.h>
#include "common.h"
@@ -52,3 +53,98 @@
fprintf(stderr, "\n");
exit(EXIT_FAILURE);
}
+
+int parse_hostport (char *hostport, char **host, char **port) {
+ char *c;
+
+ char brace = 0, colon = 0;
+
+ *host = *port = NULL;
+
+ for (c = hostport; *c != '\0'; c++) {
+ if (isspace(*c))
+ continue;
+
+ switch (*c) {
+ case '[':
+ if (c > hostport) {
+ error("parse_hostport: %c must be first char, if any: %s", *c, hostport);
+ return -1;
+ }
+
+ brace = *c;
+ break;
+
+ case ']':
+ if (!brace) {
+ error("parse_hostport: %c without matching brace: %s", *c, hostport);
+ return -1;
+ }
+
+ if (!*host) {
+ error("parse_hostport: empty hostname: %s", hostport);
+ return -1;
+ }
+
+ brace = 0;
+ break;
+
+ case ':':
+ if (brace) {
+ // colons inside braces are left as-is
+ continue;
+ }
+
+ if (!*host) {
+ error("parse_hostport: colon before hostname: %s", hostport);
+ return -1;
+ }
+
+ if (*port) {
+ error("parse_hostport: colon after port: %s", hostport);
+ return -1;
+ }
+
+ if (colon) {
+ error("parse_hostport: too many colons: %s", hostport);
+ return -1;
+ };
+
+ // finished parsing the host part, move on to the port part
+ colon = ':';
+ *c = '\0';
+ break;
+
+ default:
+ if (!*host) {
+ // first char of the host
+ *host = c;
+
+ } else if (colon && !*port) {
+ // first char of the port
+ *port = c;
+
+ } // else a part of either, don't care about it
+
+ break;
+ }
+ }
+
+ if (!*host) {
+ error("parse_hostport: missing hostname: %s", hostport);
+ return -1;
+ }
+
+ if (brace) {
+ error("parse_hostport: missing close-brace for %c: %s", brace, hostport);
+ return -1;
+ }
+
+ if (colon && !*port) {
+ error("parse_hostport: missing port: %s", hostport);
+ return -1;
+ }
+
+ return 0;
+}
+