+ return attach_conf(cptr, aconf);
+ }
+ return ACR_NO_AUTHORIZATION;
+}
+
+/** Interpret \a client as a client specifier and show which Client
+ * block(s) match that client.
+ *
+ * The client specifier may contain an IP address, hostname, listener
+ * port, or a combination of those separated by commas. IP addresses
+ * and hostnamese may be preceded by "username@"; the last given
+ * username will be used for the match.
+ *
+ * @param[in] client Client specifier.
+ * @return Matching Client block structure.
+ */
+struct ConfItem *conf_debug_iline(const char *client)
+{
+ struct irc_in_addr address;
+ struct ConfItem *aconf;
+ struct DenyConf *deny;
+ char *sep;
+ unsigned short listener;
+ char username[USERLEN+1], hostname[HOSTLEN+1], realname[REALLEN+1];
+
+ /* Initialize variables. */
+ listener = 0;
+ memset(&address, 0, sizeof(address));
+ memset(&username, 0, sizeof(username));
+ memset(&hostname, 0, sizeof(hostname));
+ memset(&realname, 0, sizeof(realname));
+
+ /* Parse client specifier. */
+ while (*client) {
+ struct irc_in_addr tmpaddr;
+ long tmp;
+
+ /* Try to parse as listener port number first. */
+ tmp = strtol(client, &sep, 10);
+ if (tmp && (*sep == '\0' || *sep == ',')) {
+ listener = tmp;
+ client = sep + (*sep != '\0');
+ continue;
+ }
+
+ /* Maybe username@ before an IP address or hostname? */
+ tmp = strcspn(client, ",@");
+ if (client[tmp] == '@') {
+ if (tmp > USERLEN)
+ tmp = USERLEN;
+ ircd_strncpy(username, client, tmp);
+ /* and fall through */
+ client += tmp + 1;
+ }
+
+ /* Looks like an IP address? */
+ tmp = ircd_aton(&tmpaddr, client);
+ if (tmp && (client[tmp] == '\0' || client[tmp] == ',')) {
+ memcpy(&address, &tmpaddr, sizeof(address));
+ client += tmp + (client[tmp] != '\0');