// File: /workspace/github_c_makefile_star2_O3/wtarreau[P]httpterm/httpterm.c
// Function: str2listener
struct listener *str2listener(char *str, struct listener *tail) {
    struct listener *l;
    char *c, *next, *range, *dupstr;
    int port, end;

    next = dupstr = strdup(str);
    
    while (next && *next) {
	struct sockaddr_storage ss;

	str = next;
	/* 1) look for the end of the first address */
	if ((next = strchr(str, ',')) != NULL) {
	    *next++ = 0;
	}

	/* 2) look for the addr/port delimiter, it's the last colon. */
	if ((range = strrchr(str, ':')) == NULL) {
	    Alert("Missing port number: '%s'\n", str);
	    goto fail;
	}	    

	*range++ = 0;

	if (strrchr(str, ':') != NULL) {
	    /* IPv6 address contains ':' */
	    memset(&ss, 0, sizeof(ss));
	    ss.ss_family = AF_INET6;

	    if (!inet_pton(ss.ss_family, str, &((struct sockaddr_in6 *)&ss)->sin6_addr)) {
		Alert("Invalid server address: '%s'\n", str);
		goto fail;
	    }
	}
	else {
	    memset(&ss, 0, sizeof(ss));
	    ss.ss_family = AF_INET;

	    if (*str == '*' || *str == '\0') { /* INADDR_ANY */
		((struct sockaddr_in *)&ss)->sin_addr.s_addr = INADDR_ANY;
	    }
	    else if (!inet_pton(ss.ss_family, str, &((struct sockaddr_in *)&ss)->sin_addr)) {
		struct hostent *he;
		
		if ((he = gethostbyname(str)) == NULL) {
		    Alert("Invalid server name: '%s'\n", str);
		    goto fail;
		}
		else
		    ((struct sockaddr_in *)&ss)->sin_addr =
			*(struct in_addr *) *(he->h_addr_list);
	    }
	}

	/* 3) look for the port-end delimiter */
	if ((c = strchr(range, '-')) != NULL) {
	    *c++ = 0;
	    end = atol(c);
	}
	else {
	    end = atol(range);
	}

	port = atol(range);

	if (port < 1 || port > 65535) {
	    Alert("Invalid port '%d' specified for address '%s'.\n", port, str);
	    goto fail;
	}

	if (end < 1 || end > 65535) {
	    Alert("Invalid port '%d' specified for address '%s'.\n", end, str);
	    goto fail;
	}

	for (; port <= end; port++) {
	    l = (struct listener *)calloc(1, sizeof(struct listener));
	    l->next = tail;
	    tail = l;

	    l->fd = -1;
	    l->addr = ss;
	    if (ss.ss_family == AF_INET6)
		((struct sockaddr_in6 *)(&l->addr))->sin6_port = htons(port);
	    else
		((struct sockaddr_in *)(&l->addr))->sin_port = htons(port);

	} /* end for(port) */
    } /* end while(next) */
    free(dupstr);
    return tail;
 fail:
    free(dupstr);
    return NULL;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movq %rsi, %rbx
callq 0x23e0
testq %rax, %rax
movq %rax, 0x8(%rsp)
je 0x30bc
leaq 0x10(%rsp), %r13
movq %rax, %rbp
cmpb $0x0, (%rbp)
je 0x30bc
movq %rbp, %rdi
movl $0x2c, %esi
callq 0x2160
testq %rax, %rax
je 0x2f27
movq %rax, %r12
incq %r12
movb $0x0, (%rax)
jmp 0x2f2a
xorl %r12d, %r12d
movq %rbp, %rdi
movl $0x3a, %esi
callq 0x2180
testq %rax, %rax
je 0x30c1
movq %rax, %r15
movb $0x0, (%rax)
movq %rbp, %rdi
movl $0x3a, %esi
callq 0x2180
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
movaps %xmm0, 0x20(%rsp)
movaps %xmm0, 0x30(%rsp)
movaps %xmm0, 0x40(%rsp)
movaps %xmm0, 0x50(%rsp)
movaps %xmm0, 0x60(%rsp)
movaps %xmm0, 0x70(%rsp)
movaps %xmm0, 0x80(%rsp)
testq %rax, %rax
je 0x3067
movw $0xa, 0x10(%rsp)
movl $0xa, %edi
movq %rbp, %rsi
leaq 0x18(%rsp), %rdx
callq 0x2260
testl %eax, %eax
je 0x30ec
incq %r15
movq %r15, %rdi
movl $0x2d, %esi
callq 0x2160
movq %r15, %rdi
testq %rax, %rax
je 0x2fcc
movq %rax, %rdi
incq %rdi
movb $0x0, (%rax)
callq 0x2320
movq %rax, %r14
movq %r15, %rdi
callq 0x2320
movq %rax, %r15
movl $0xffff0000, %ecx       # imm = 0xFFFF0000
addl %ecx, %eax
cmpl %ecx, %eax
jbe 0x30ca
leal -0x10000(%r14), %eax
cmpl $0xffff0001, %eax       # imm = 0xFFFF0001
jb 0x30d6
movq %r12, %rbp
cmpl %r14d, %r15d
jbe 0x300d
movq %rbx, %r12
jmp 0x3056
incl %r14d
movl $0x1, %edi
movl $0x90, %esi
callq 0x21f0
movq %rax, %r12
movq %rbx, 0x88(%rax)
movl $0xffffffff, (%rax)     # imm = 0xFFFFFFFF
leaq 0x8(%rax), %rdi
movl $0x10, %ecx
movq %r13, %rsi
rep  movsq (%rsi), %es:(%rdi)
movl %r15d, %eax
rolw $0x8, %ax
movw %ax, 0xa(%r12)
incl %r15d
movq %r12, %rbx
cmpl %r15d, %r14d
jne 0x3010
movq %r12, %rbx
testq %rbp, %rbp
jne 0x2f00
jmp 0x3100
movw $0x2, 0x10(%rsp)
movzbl (%rbp), %eax
testl %eax, %eax
je 0x2fab
cmpl $0x2a, %eax
je 0x2fab
movl $0x2, %edi
movq %rbp, %rsi
leaq 0x14(%rsp), %rdx
callq 0x2260
testl %eax, %eax
jne 0x2fab
movq %rbp, %rdi
callq 0x2220
testq %rax, %rax
je 0x311f
movq 0x18(%rax), %rax
movq (%rax), %rax
movl (%rax), %eax
movl %eax, 0x14(%rsp)
jmp 0x2fab
movq %rbx, %r12
jmp 0x3100
leaq 0x71da(%rip), %rdi      # 0xa2a2
jmp 0x30f3
leaq 0x720a(%rip), %rdi      # 0xa2db
movl %r15d, %esi
jmp 0x30e0
leaq 0x71fe(%rip), %rdi      # 0xa2db
movl %r14d, %esi
movq %rbp, %rdx
xorl %eax, %eax
callq 0x29fa
jmp 0x30fd
leaq 0x71ca(%rip), %rdi      # 0xa2bd
movq %rbp, %rsi
xorl %eax, %eax
callq 0x29fa
xorl %r12d, %r12d
movq 0x8(%rsp), %rdi
callq 0x2050
movq %r12, %rax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x7161(%rip), %rdi      # 0xa287
jmp 0x30f3