diff --git a/log.h b/log.h index 83234e3e..d3a667a2 100644 --- a/log.h +++ b/log.h @@ -137,6 +137,7 @@ void set_log_implementation(void (*log_function)(int level, struct strbuf *buf)) #define alloca_toprint(dstlen,buf,len) toprint((char *)alloca((dstlen) == -1 ? toprint_len((const char *)(buf),(len), "``") + 1 : (dstlen)), (dstlen), (const char *)(buf), (len), "``") #define alloca_str_toprint(str) toprint_str((char *)alloca(toprint_str_len(str, "``") + 1), -1, (str), "``") +#define alloca_sockaddr(addr) strbuf_str(strbuf_append_sockaddr(strbuf_alloca(40), (const struct sockaddr *)(addr))) #define __HERE__ ((struct __sourceloc){ .file = __FILE__, .line = __LINE__, .function = __FUNCTION__ }) #define __NOWHERE__ ((struct __sourceloc){ .file = NULL, .line = 0, .function = NULL }) diff --git a/strbuf_helpers.c b/strbuf_helpers.c index 9eace1e7..1fc480b4 100644 --- a/strbuf_helpers.c +++ b/strbuf_helpers.c @@ -22,6 +22,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include #include +#ifdef HAVE_NETINET_IN_H +#include +#endif static inline strbuf _toprint(strbuf sb, char c) { @@ -198,3 +201,71 @@ strbuf strbuf_append_exit_status(strbuf sb, int status) #endif return sb; } + +strbuf strbuf_append_sockaddr(strbuf sb, const struct sockaddr *addr) +{ + const char *fam = NULL; + switch (addr->sa_family) { + case AF_UNSPEC: fam = "AF_UNSPEC"; break; + case AF_UNIX: fam = "AF_UNIX"; break; + case AF_INET: fam = "AF_INET"; break; + case AF_AX25: fam = "AF_AX25"; break; + case AF_IPX: fam = "AF_IPX"; break; + case AF_APPLETALK: fam = "AF_APPLETALK"; break; + case AF_NETROM: fam = "AF_NETROM"; break; + case AF_BRIDGE: fam = "AF_BRIDGE"; break; + case AF_ATMPVC: fam = "AF_ATMPVC"; break; + case AF_X25: fam = "AF_X25"; break; + case AF_INET6: fam = "AF_INET6"; break; + case AF_ROSE: fam = "AF_ROSE"; break; + case AF_DECnet: fam = "AF_DECnet"; break; + case AF_NETBEUI: fam = "AF_NETBEUI"; break; + case AF_SECURITY: fam = "AF_SECURITY"; break; + case AF_KEY: fam = "AF_KEY"; break; + case AF_NETLINK: fam = "AF_NETLINK"; break; + case AF_PACKET: fam = "AF_PACKET"; break; + case AF_ASH: fam = "AF_ASH"; break; + case AF_ECONET: fam = "AF_ECONET"; break; + case AF_ATMSVC: fam = "AF_ATMSVC"; break; + case AF_SNA: fam = "AF_SNA"; break; + case AF_IRDA: fam = "AF_IRDA"; break; + case AF_PPPOX: fam = "AF_PPPOX"; break; + case AF_WANPIPE: fam = "AF_WANPIPE"; break; + case AF_LLC: fam = "AF_LLC"; break; + case AF_TIPC: fam = "AF_TIPC"; break; + case AF_BLUETOOTH: fam = "AF_BLUETOOTH"; break; + } + if (fam) + strbuf_puts(sb, fam); + else + strbuf_sprintf(sb, "[%d]", addr->sa_family); + switch (addr->sa_family) { + case AF_UNIX: + strbuf_putc(sb, ' '); + if (addr->sa_data[0]) + strbuf_toprint_quoted_len(sb, addr->sa_data, "\"\"", sizeof addr->sa_data); + else { + strbuf_puts(sb, "abstract "); + strbuf_toprint_quoted_len(sb, addr->sa_data, "\"\"", sizeof addr->sa_data); + } + break; + case AF_INET: { + const struct sockaddr_in *addr_in = (const struct sockaddr_in *) addr; + strbuf_sprintf(sb, " %u.%u.%u.%u:%u", + ((unsigned char *) &addr_in->sin_addr.s_addr)[0], + ((unsigned char *) &addr_in->sin_addr.s_addr)[1], + ((unsigned char *) &addr_in->sin_addr.s_addr)[2], + ((unsigned char *) &addr_in->sin_addr.s_addr)[3], + ntohs(addr_in->sin_port) + ); + } + break; + default: { + int i; + for (i = 0; i < sizeof addr->sa_data; ++i) + strbuf_sprintf(sb, " %02x", addr->sa_data[i]); + } + break; + } + return sb; +} diff --git a/strbuf_helpers.h b/strbuf_helpers.h index 498569ce..2b529c67 100644 --- a/strbuf_helpers.h +++ b/strbuf_helpers.h @@ -80,4 +80,10 @@ strbuf strbuf_append_shell_quotemeta(strbuf sb, const char *word); */ strbuf strbuf_append_exit_status(strbuf sb, int status); +/* Append a textual description of a struct sockaddr_in. + * @author Andrew Bettison + */ +struct sockaddr; +strbuf strbuf_append_sockaddr(strbuf sb, const struct sockaddr *); + #endif //__STRBUF_HELPERS_H__