// File: /workspace/github_c_makefile_star2_O2/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 $0xa8, %rsp
movq %rsi, %r14
callq 0x23e0
movq %rax, %r13
pushq $0x3a
popq %rbp
pushq $0x1
popq %r15
pushq $0x10
popq %rbx
leaq 0x20(%rsp), %r12
movq %rax, 0x10(%rsp)
testq %r13, %r13
je 0x308f
cmpb $0x0, (%r13)
je 0x308f
movq %r13, %rdi
pushq $0x2c
popq %rsi
callq 0x2160
testq %rax, %rax
je 0x2ecc
movq %rax, %rcx
incq %rcx
movq %rcx, 0x18(%rsp)
movb $0x0, (%rax)
jmp 0x2ed5
movq $0x0, 0x18(%rsp)
movq %r13, %rdi
movl %ebp, %esi
callq 0x2180
movl %ebp, %esi
movq %r13, %rbp
testq %rax, %rax
je 0x304a
movq %rax, %r13
movb $0x0, (%rax)
movq %rbp, %rdi
callq 0x2180
xorps %xmm0, %xmm0
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)
movaps %xmm0, 0x90(%rsp)
testq %rax, %rax
movq %rbp, 0x8(%rsp)
je 0x2ff3
movw $0xa, 0x20(%rsp)
pushq $0xa
popq %rdi
movq %rbp, %rsi
leaq 0x28(%rsp), %rdx
callq 0x2260
testl %eax, %eax
je 0x3079
incq %r13
movq %r13, %rdi
pushq $0x2d
popq %rsi
callq 0x2160
movq %r13, %rdi
testq %rax, %rax
je 0x2f78
movq %rax, %rdi
incq %rdi
movb $0x0, (%rax)
callq 0x2320
movq %rax, %rbp
movq %r13, %rdi
callq 0x2320
movq %rax, %r13
movl $0xffff0000, %ecx       # imm = 0xFFFF0000
addl %ecx, %eax
cmpl %ecx, %eax
jbe 0x3056
leal -0x10000(%rbp), %eax
cmpl $0xffff0001, %eax       # imm = 0xFFFF0001
jae 0x2fe1
jmp 0x3062
movl $0x90, %esi
movq %r15, %rdi
callq 0x21f0
movq %r14, 0x88(%rax)
orl $-0x1, (%rax)
movl %r13d, %edx
rolw $0x8, %dx
leaq 0x8(%rax), %rdi
movq %rbx, %rcx
movq %r12, %rsi
rep  movsq (%rsi), %es:(%rdi)
movw %dx, 0xa(%rax)
incl %r13d
movq %rax, %r14
cmpl %ebp, %r13d
jle 0x2fac
movq 0x18(%rsp), %r13
pushq $0x3a
popq %rbp
jmp 0x2e98
movw $0x2, 0x20(%rsp)
movzbl (%rbp), %eax
testl %eax, %eax
je 0x2f59
cmpl $0x2a, %eax
je 0x2f59
pushq $0x2
popq %rdi
movq 0x8(%rsp), %rsi
leaq 0x24(%rsp), %rdx
callq 0x2260
testl %eax, %eax
jne 0x2f59
movq 0x8(%rsp), %rdi
callq 0x2220
testq %rax, %rax
je 0x30ae
movq 0x18(%rax), %rax
movq (%rax), %rax
movl (%rax), %eax
movl %eax, 0x24(%rsp)
jmp 0x2f59
leaq 0x7161(%rip), %rdi      # 0xa1b2
movq %rbp, %rsi
jmp 0x3085
leaq 0x718e(%rip), %rdi      # 0xa1eb
movl %r13d, %esi
jmp 0x306b
leaq 0x7182(%rip), %rdi      # 0xa1eb
movl %ebp, %esi
movq 0x8(%rsp), %rdx
xorl %eax, %eax
callq 0x29aa
jmp 0x308c
leaq 0x714d(%rip), %rdi      # 0xa1cd
movq 0x8(%rsp), %rsi
xorl %eax, %eax
callq 0x29aa
xorl %r14d, %r14d
movq 0x10(%rsp), %rdi
callq 0x2050
movq %r14, %rax
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x70e2(%rip), %rdi      # 0xa197
jmp 0x3080