+const char* iptobase64(char* buf, const struct irc_in_addr* addr, unsigned int count, int v6_ok)
+{
+ if (irc_in_addr_is_ipv4(addr)) {
+ assert(count >= 6);
+ inttobase64(buf, (ntohs(addr->in6_16[6]) << 16) | ntohs(addr->in6_16[7]), 6);
+ } else if (!v6_ok) {
+ assert(count >= 6);
+ if (addr->in6_16[0] == htons(0x2002))
+ inttobase64(buf, (ntohs(addr->in6_16[1]) << 16) | ntohs(addr->in6_16[2]), 6);
+ else
+ strcpy(buf, "AAAAAA");
+ } else {
+ unsigned int max_start, max_zeros, curr_zeros, zero, ii;
+ char *output = buf;
+
+ assert(count >= 25);
+ /* Can start by printing out the leading non-zero parts. */
+ for (ii = 0; (addr->in6_16[ii]) && (ii < 8); ++ii) {
+ inttobase64(output, ntohs(addr->in6_16[ii]), 3);
+ output += 3;
+ }
+ /* Find the longest run of zeros. */
+ for (max_start = zero = ii, max_zeros = curr_zeros = 0; ii < 8; ++ii) {
+ if (!addr->in6_16[ii])
+ curr_zeros++;
+ else if (curr_zeros > max_zeros) {
+ max_start = ii - curr_zeros;
+ max_zeros = curr_zeros;
+ curr_zeros = 0;
+ }
+ }
+ if (curr_zeros > max_zeros) {
+ max_start = ii - curr_zeros;
+ max_zeros = curr_zeros;
+ curr_zeros = 0;
+ }
+ /* Print the rest of the address */
+ for (ii = zero; ii < 8; ) {
+ if ((ii == max_start) && max_zeros) {
+ *output++ = '_';
+ ii += max_zeros;
+ } else {
+ inttobase64(output, ntohs(addr->in6_16[ii]), 3);
+ output += 3;
+ ii++;
+ }
+ }
+ *output = '\0';
+ }
+ return buf;
+}