github.com/afumu/libc@v0.0.6/musl/src/network/inet_ntop.c (about)

     1  #include <sys/socket.h>
     2  #include <arpa/inet.h>
     3  #include <errno.h>
     4  #include <stdio.h>
     5  #include <string.h>
     6  
     7  const char *inet_ntop(int af, const void *restrict a0, char *restrict s, socklen_t l)
     8  {
     9  	const unsigned char *a = a0;
    10  	int i, j, max, best;
    11  	char buf[100];
    12  
    13  	switch (af) {
    14  	case AF_INET:
    15  		if (snprintf(s, l, "%d.%d.%d.%d", a[0],a[1],a[2],a[3]) < l)
    16  			return s;
    17  		break;
    18  	case AF_INET6:
    19  		if (memcmp(a, "\0\0\0\0\0\0\0\0\0\0\377\377", 12))
    20  			snprintf(buf, sizeof buf,
    21  				"%x:%x:%x:%x:%x:%x:%x:%x",
    22  				256*a[0]+a[1],256*a[2]+a[3],
    23  				256*a[4]+a[5],256*a[6]+a[7],
    24  				256*a[8]+a[9],256*a[10]+a[11],
    25  				256*a[12]+a[13],256*a[14]+a[15]);
    26  		else
    27  			snprintf(buf, sizeof buf,
    28  				"%x:%x:%x:%x:%x:%x:%d.%d.%d.%d",
    29  				256*a[0]+a[1],256*a[2]+a[3],
    30  				256*a[4]+a[5],256*a[6]+a[7],
    31  				256*a[8]+a[9],256*a[10]+a[11],
    32  				a[12],a[13],a[14],a[15]);
    33  		/* Replace longest /(^0|:)[:0]{2,}/ with "::" */
    34  		for (i=best=0, max=2; buf[i]; i++) {
    35  			if (i && buf[i] != ':') continue;
    36  			j = strspn(buf+i, ":0");
    37  			if (j>max) best=i, max=j;
    38  		}
    39  		if (max>3) {
    40  			buf[best] = buf[best+1] = ':';
    41  			memmove(buf+best+2, buf+best+max, i-best-max+1);
    42  		}
    43  		if (strlen(buf) < l) {
    44  			strcpy(s, buf);
    45  			return s;
    46  		}
    47  		break;
    48  	default:
    49  		errno = EAFNOSUPPORT;
    50  		return 0;
    51  	}
    52  	errno = ENOSPC;
    53  	return 0;
    54  }