/************************************************* * Exim - an Internet mail transport agent * *************************************************/ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include "exim.h" /************************************************* * Extract port from address string * *************************************************/ /* In the spool file, and in the -oMa and -oMi options, a host plus port is given as an IP address followed by a dot and a port number. This function decodes this. An alternative format for the -oMa and -oMi options is [ip address]:port which is what Exim 4 uses for output, because it seems to becoming commonly used, whereas the dot form confuses some programs/people. So we recognize that form too. Argument: address points to the string; if there is a port, the '.' in the string is overwritten with zero to terminate the address; if the string is in the [xxx]:ppp format, the address is shifted left and the brackets are removed Returns: 0 if there is no port, else the port number. If there's a syntax error, leave the incoming address alone, and return 0. */ int host_address_extract_port(uschar * address) { int port = 0; uschar *endptr; /* Handle the "bracketed with colon on the end" format */ if (*address == '[') { uschar *rb = address + 1; while (*rb != 0 && *rb != ']') rb++; if (*rb++ == 0) return 0; /* Missing ]; leave invalid address */ if (*rb == ':') { port = Ustrtol(rb + 1, &endptr, 10); if (*endptr != 0) return 0; /* Invalid port; leave invalid address */ } else if (*rb != 0) return 0; /* Bad syntax; leave invalid address */ memmove(address, address + 1, rb - address - 2); rb[-2] = 0; } /* Handle the "dot on the end" format */ else { int skip = -3; /* Skip 3 dots in IPv4 addresses */ address--; while (*(++address) != 0) { int ch = *address; if (ch == ':') skip = 0; /* Skip 0 dots in IPv6 addresses */ else if (ch == '.' && skip++ >= 0) break; } if (*address == 0) return 0; port = Ustrtol(address + 1, &endptr, 10); if (*endptr != 0) return 0; /* Invalid port; leave invalid address */ *address = 0; } return port; } /* vi: aw ai sw=2 */ /* End of host.c */