aboutsummaryrefslogtreecommitdiffstats
path: root/src/libmdsclient/address.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libmdsclient/address.c')
-rw-r--r--src/libmdsclient/address.c297
1 files changed, 153 insertions, 144 deletions
diff --git a/src/libmdsclient/address.c b/src/libmdsclient/address.c
index baa9798..a50bbaf 100644
--- a/src/libmdsclient/address.c
+++ b/src/libmdsclient/address.c
@@ -40,13 +40,13 @@
* @param str The string
* @return Whether a string is a radix-10 non-negative integer
*/
-__attribute__((nonnull))
-static int is_pzinteger(const char* restrict str)
+static int __attribute__((nonnull))
+is_pzinteger(const char *restrict str)
{
- for (; *str; str++)
- if (('0' > *str) || (*str > '9'))
- return 0;
- return 1;
+ for (; *str; str++)
+ if ('0' > *str || *str > '9')
+ return 0;
+ return 1;
}
@@ -64,32 +64,32 @@ static int is_pzinteger(const char* restrict str)
* RLIMIT_AS or RLIMIT_DATA limit described in getrlimit(2).
* @throws ENAMETOOLONG The filename of the target socket is too long
*/
-__attribute__((nonnull, format(gnu_printf, 3, 4)))
-static int set_af_unix(struct sockaddr** restrict out_address, ssize_t* pathlen, const char* format, ...)
-#define set_af_unix(a, f, ...) ((set_af_unix)(a, &pathlen, f "%zn", __VA_ARGS__, &pathlen))
+static int __attribute__((nonnull, format(gnu_printf, 3, 4)))
+set_af_unix(struct sockaddr **restrict out_address, ssize_t *pathlen, const char *format, ...)
+#define set_af_unix(a, f, ...) ((set_af_unix)(a, &pathlen, f "%zn", __VA_ARGS__, &pathlen))
{
- struct sockaddr_un* address;
- size_t maxlen;
- va_list args;
-
- address = malloc(sizeof(struct sockaddr_un));
- *out_address = (struct sockaddr*)address;
- if (address == NULL)
- return -1;
-
- maxlen = sizeof(address->sun_path) / sizeof(address->sun_path[0]);
-
- va_start(args, format);
-
- address->sun_family = AF_UNIX;
- vsnprintf(address->sun_path, maxlen, format, args);
-
- va_end(args);
-
- if ((size_t)*pathlen > maxlen)
- return errno = ENAMETOOLONG, -1;
-
- return 0;
+ struct sockaddr_un *address;
+ size_t maxlen;
+ va_list args;
+
+ address = malloc(sizeof(struct sockaddr_un));
+ *out_address = (struct sockaddr*)address;
+ if (!address)
+ return -1;
+
+ maxlen = sizeof(address->sun_path) / sizeof(address->sun_path[0]);
+
+ va_start(args, format);
+
+ address->sun_family = AF_UNIX;
+ vsnprintf(address->sun_path, maxlen, format, args);
+
+ va_end(args);
+
+ if ((size_t)*pathlen > maxlen)
+ return errno = ENAMETOOLONG, -1;
+
+ return 0;
}
@@ -112,36 +112,36 @@ static int set_af_unix(struct sockaddr** restrict out_address, ssize_t* pathlen,
* @throws ENOMEM Out of memory. Possibly, the application hit the
* RLIMIT_AS or RLIMIT_DATA limit described in getrlimit(2).
*/
-__attribute__((nonnull))
-static int set_af_inet(struct sockaddr** restrict out_address, socklen_t* restrict out_address_len,
- int* restrict out_gai_error, int* restrict out_domain, int address_family,
- const char* restrict host, const char* restrict port)
+static int __attribute__((nonnull))
+set_af_inet(struct sockaddr **restrict out_address, socklen_t *restrict out_address_len,
+ int *restrict out_gai_error, int *restrict out_domain, int address_family,
+ const char *restrict host, const char *restrict port)
{
- struct addrinfo hints;
- struct addrinfo* result;
- int saved_errno;
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = address_family;
-
- *out_gai_error = getaddrinfo(host, port, &hints, &result);
- if (*out_gai_error)
- return 0;
-
- *out_address = malloc(result->ai_addrlen);
- if (*out_address == NULL)
- return saved_errno = errno, freeaddrinfo(result), errno = saved_errno, -1;
- memcpy(*out_address, result->ai_addr, result->ai_addrlen);
-
- *out_address_len = result->ai_addrlen;
- *out_domain =
- result->ai_family == AF_UNSPEC ? PF_UNSPEC :
- result->ai_family == AF_INET ? PF_INET :
- result->ai_family == AF_INET6 ? PF_INET6 :
- result->ai_family;
-
- freeaddrinfo(result);
- return 0;
+ struct addrinfo hints;
+ struct addrinfo *result;
+ int saved_errno;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = address_family;
+
+ *out_gai_error = getaddrinfo(host, port, &hints, &result);
+ if (*out_gai_error)
+ return 0;
+
+ *out_address = malloc(result->ai_addrlen);
+ if (!*out_address)
+ return saved_errno = errno, freeaddrinfo(result), errno = saved_errno, -1;
+ memcpy(*out_address, result->ai_addr, result->ai_addrlen);
+
+ *out_address_len = result->ai_addrlen;
+ *out_domain =
+ result->ai_family == AF_UNSPEC ? PF_UNSPEC :
+ result->ai_family == AF_INET ? PF_INET :
+ result->ai_family == AF_INET6 ? PF_INET6 :
+ result->ai_family;
+
+ freeaddrinfo(result);
+ return 0;
}
@@ -157,91 +157,100 @@ static int set_af_inet(struct sockaddr** restrict out_address, socklen_t* restri
* RLIMIT_AS or RLIMIT_DATA limit described in getrlimit(2).
* @throws ENAMETOOLONG The filename of the target socket is too long
*/
-int libmds_parse_display_address(const char* restrict display, libmds_display_address_t* restrict address)
+int
+libmds_parse_display_address(const char *restrict display, libmds_display_address_t *restrict address)
{
- ssize_t pathlen = 0;
- char* host;
- char* port;
- char* params;
- size_t i = 0;
- char c;
- int esc = 0;
- int colesc = 0;
-
- address->domain = -1;
- address->type = -1;
- address->protocol = -1;
- address->address = NULL;
- address->address_len = 0;
- address->gai_error = 0;
-
- if (strchr(display, ':') == NULL)
- return 0;
-
- if (*display == ':')
- {
- address->domain = PF_UNIX;
- address->type = SOCK_STREAM;
- address->protocol = 0;
- address->address_len = sizeof(struct sockaddr_un);
-
- if (strstr(display, ":file:") == display)
- return set_af_unix(&(address->address), "%s", display + 6);
- else if (display[1] && is_pzinteger(display + 1))
- return set_af_unix(&(address->address), "%s/%s.socket",
- MDS_RUNTIME_ROOT_DIRECTORY, display + 1);
- return 0;
- }
-
- host = alloca((strlen(display) + 1) * sizeof(char));
-
- if (*display == '[')
- colesc = 1, i++;
- for (; (c = display[i]); i++)
- if (esc) host[pathlen++] = c, esc = 0;
- else if (c == '\\') esc = 1;
- else if (c == ']')
- if (colesc) { i++; break; }
- else host[pathlen++] = c;
- else if (c == ':')
- if (colesc) host[pathlen++] = c;
- else break;
- else host[pathlen++] = c;
- if (esc || (display[i++] != ':'))
- return 0;
- host[pathlen++] = '\0';
-
- port = host + pathlen;
- memcpy(port, display + i, (strlen(display) + 1 - i) * sizeof(char));
- params = strchr(port, ':');
- if (params != NULL)
- *params++ = '\0';
-
-#define param_test(f, n, a, b, c) \
- ((n >= 3) && (!strcasecmp(params, a ":" b ":" c))) || \
- ((n >= 2) && (!strcasecmp(params, a ":" b))) || \
- ((n >= 1) && (!strcasecmp(params, a))) || \
- (f == NULL ? 0 : !strcasecmp(params, f))
-#define set(d, t, p) \
- address->domain = (d), address->type = (t), address->protocol = (p)
-
- if (params == NULL) set(PF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
- else if (param_test("ip/tcp", 1, "ip", "stream", "tcp")) set(PF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
- else if (param_test("ipv4/tcp", 1, "ipv4", "stream", "tcp")) set(PF_INET, SOCK_STREAM, IPPROTO_TCP);
- else if (param_test("ipv6/tcp", 1, "ipv6", "stream", "tcp")) set(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
- else if (param_test("inet/tcp", 1, "inet", "stream", "tcp")) set(PF_INET, SOCK_STREAM, IPPROTO_TCP);
- else if (param_test("inet6/tcp", 1, "inet6", "stream", "tcp")) set(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
- else
- return 0;
-
+ ssize_t pathlen = 0;
+ char *host;
+ char *port;
+ char *params;
+ size_t i = 0;
+ char c;
+ int esc = 0;
+ int colesc = 0;
+
+ address->domain = -1;
+ address->type = -1;
+ address->protocol = -1;
+ address->address = NULL;
+ address->address_len = 0;
+ address->gai_error = 0;
+
+ if (!strchr(display, ':'))
+ return 0;
+
+ if (*display == ':') {
+ address->domain = PF_UNIX;
+ address->type = SOCK_STREAM;
+ address->protocol = 0;
+ address->address_len = sizeof(struct sockaddr_un);
+
+ if (strstr(display, ":file:") == display)
+ return set_af_unix(&(address->address), "%s", display + 6);
+ else if (display[1] && is_pzinteger(display + 1))
+ return set_af_unix(&(address->address), "%s/%s.socket",
+ MDS_RUNTIME_ROOT_DIRECTORY, display + 1);
+ return 0;
+ }
+
+ host = alloca((strlen(display) + 1) * sizeof(char));
+
+ if (*display == '[')
+ colesc = 1, i++;
+ for (; (c = display[i]); i++) {
+ if (esc) {
+ host[pathlen++] = c;
+ esc = 0;
+ } else if (c == '\\') {
+ esc = 1;
+ } else if (c == ']') {
+ if (colesc)
+ { i++; break; }
+ else
+ host[pathlen++] = c;
+ } else if (c == ':') {
+ if (colesc)
+ host[pathlen++] = c;
+ else
+ break;
+ } else {
+ host[pathlen++] = c;
+ }
+ }
+ if (esc || display[i++] != ':')
+ return 0;
+ host[pathlen++] = '\0';
+
+ port = host + pathlen;
+ memcpy(port, display + i, (strlen(display) + 1 - i) * sizeof(char));
+ params = strchr(port, ':');
+ if (params)
+ *params++ = '\0';
+
+#define param_test(f, n, a, b, c)\
+ ((n >= 3 && !strcasecmp(params, a ":" b ":" c)) ||\
+ (n >= 2 && !strcasecmp(params, a ":" b)) ||\
+ (n >= 1 && !strcasecmp(params, a)) ||\
+ (!f ? 0 : !strcasecmp(params, f)))
+#define set(d, t, p)\
+ (address->domain = (d), address->type = (t), address->protocol = (p))
+
+ if (!params) set(PF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
+ else if (param_test("ip/tcp", 1, "ip", "stream", "tcp")) set(PF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
+ else if (param_test("ipv4/tcp", 1, "ipv4", "stream", "tcp")) set(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ else if (param_test("ipv6/tcp", 1, "ipv6", "stream", "tcp")) set(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
+ else if (param_test("inet/tcp", 1, "inet", "stream", "tcp")) set(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ else if (param_test("inet6/tcp", 1, "inet6", "stream", "tcp")) set(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
+ else
+ return 0;
+
#undef set
#undef param_test
-
- return set_af_inet(&(address->address), &(address->address_len),
- &(address->gai_error), &(address->domain),
- address->domain == PF_UNSPEC ? AF_UNSPEC :
- address->domain == PF_INET ? AF_INET :
- address->domain == PF_INET6 ? AF_INET6 :
- address->domain, host, port);
-}
+ return set_af_inet(&(address->address), &(address->address_len),
+ &(address->gai_error), &(address->domain),
+ address->domain == PF_UNSPEC ? AF_UNSPEC :
+ address->domain == PF_INET ? AF_INET :
+ address->domain == PF_INET6 ? AF_INET6 :
+ address->domain, host, port);
+}