From 0b6423f9c99d9edf8c96fefd0f6c453859395aa1 Mon Sep 17 00:00:00 2001 From: Holger Weiss Date: Mon, 30 Sep 2013 00:03:24 +0200 Subject: Import Nagios Plugins site Import the Nagios Plugins web site, Cronjobs, infrastructure scripts, and configuration files. --- .../37323-nagiosplugins-cvs-20021210-ipv6.diff | 740 +++++++++++++++++++++ 1 file changed, 740 insertions(+) create mode 100644 web/attachments/37323-nagiosplugins-cvs-20021210-ipv6.diff (limited to 'web/attachments/37323-nagiosplugins-cvs-20021210-ipv6.diff') diff --git a/web/attachments/37323-nagiosplugins-cvs-20021210-ipv6.diff b/web/attachments/37323-nagiosplugins-cvs-20021210-ipv6.diff new file mode 100644 index 0000000..da47ec3 --- /dev/null +++ b/web/attachments/37323-nagiosplugins-cvs-20021210-ipv6.diff @@ -0,0 +1,740 @@ +Index: check_dig.c +=================================================================== +RCS file: /cvsroot/nagiosplug/nagiosplug/plugins/check_dig.c,v +retrieving revision 1.7 +diff -u -r1.7 check_dig.c +--- check_dig.c 21 Nov 2002 12:40:58 -0000 1.7 ++++ check_dig.c 11 Dec 2002 02:39:50 -0000 +@@ -57,7 +57,7 @@ + usage ("Could not parse arguments\n"); + + /* get the command to run */ +- asprintf (&command_line, "%s @%s %s", PATH_TO_DIG, dns_server, query_address); ++ asprintf (&command_line, "%s -t any @%s %s", PATH_TO_DIG, dns_server, query_address); + + alarm (timeout_interval); + time (&start_time); +Index: check_dns.c +=================================================================== +RCS file: /cvsroot/nagiosplug/nagiosplug/plugins/check_dns.c,v +retrieving revision 1.5 +diff -u -r1.5 check_dns.c +--- check_dns.c 14 Nov 2002 02:26:34 -0000 1.5 ++++ check_dns.c 11 Dec 2002 02:39:50 -0000 +@@ -308,7 +308,7 @@ + timeout_interval = atoi (optarg); + break; + case 'H': /* hostname */ +- if (is_host (optarg) == FALSE) { ++ if ((is_host (optarg)) == FALSE) { + printf ("Invalid host name/address\n\n"); + print_usage (); + exit (STATE_UNKNOWN); +@@ -318,7 +318,7 @@ + strcpy (query_address, optarg); + break; + case 's': /* server name */ +- if (is_host (optarg) == FALSE) { ++ if ((is_host (optarg)) == FALSE) { + printf ("Invalid server name/address\n\n"); + print_usage (); + exit (STATE_UNKNOWN); +@@ -328,7 +328,7 @@ + strcpy (dns_server, optarg); + break; + case 'r': /* reverse server name */ +- if (is_host (optarg) == FALSE) { ++ if ((is_host (optarg)) == FALSE) { + printf ("Invalid host name/address\n\n"); + print_usage (); + exit (STATE_UNKNOWN); +@@ -338,7 +338,7 @@ + strcpy (ptr_server, optarg); + break; + case 'a': /* expected address */ +- if (is_dotted_quad (optarg) == FALSE) { ++ if ((is_ipv4_addr (optarg)) == FALSE) { + printf ("Invalid expected address\n\n"); + print_usage (); + exit (STATE_UNKNOWN); +@@ -352,8 +352,8 @@ + } + + c = optind; +- if (query_address[0] == 0) { +- if (is_host (argv[c]) == FALSE) { ++ if (query_address == NULL) { ++ if ((is_host (argv[c])) == FALSE) { + printf ("Invalid name/address: %s\n\n", argv[c]); + return ERROR; + } +@@ -362,8 +362,8 @@ + strcpy (query_address, argv[c++]); + } + +- if (dns_server[0] == 0) { +- if (is_host (argv[c]) == FALSE) { ++ if (dns_server == NULL) { ++ if ((is_host (argv[c])) == FALSE) { + printf ("Invalid name/address: %s\n\n", argv[c]); + return ERROR; + } +Index: check_ldap.c +=================================================================== +RCS file: /cvsroot/nagiosplug/nagiosplug/plugins/check_ldap.c,v +retrieving revision 1.2 +diff -u -r1.2 check_ldap.c +--- check_ldap.c 14 Nov 2002 02:26:34 -0000 1.2 ++++ check_ldap.c 11 Dec 2002 02:39:50 -0000 +@@ -7,7 +7,7 @@ + * + * Last Modified: $Date: 2002/11/14 02:26:34 $ + * +- * Command line: check_ldap -h -b -p -w -w ++ * Command line: check_ldap -H -b -p -w -w + * + * Description: + * +@@ -197,7 +197,7 @@ + crit_time = atoi (optarg); + break; + default: +- usage ("check_ldap: could not parse arguments\n"); ++ usage ("check_ldap: could not parse unknown arguments\n"); + break; + } + } +@@ -253,6 +253,6 @@ + { + printf + ("Usage: %s -H -b -p [-a ] [-D ]\n" +- " [-P ] [-w ] [-c ] [-t timeout]\n" ++ " [-P ] -w -c [-t timeout]\n" + "(Note: all times are in seconds.)\n", PROGNAME); + } +Index: check_ping.c +=================================================================== +RCS file: /cvsroot/nagiosplug/nagiosplug/plugins/check_ping.c,v +retrieving revision 1.10 +diff -u -r1.10 check_ping.c +--- check_ping.c 13 Nov 2002 11:50:54 -0000 1.10 ++++ check_ping.c 11 Dec 2002 02:39:50 -0000 +@@ -88,9 +88,15 @@ + + /* does the host address of number of packets argument come first? */ + #ifdef PING_PACKETS_FIRST +- asprintf (&command_line, PING_COMMAND, max_packets, server_address); ++ if (is_ipv6_addr (server_address)) ++ asprintf (&command_line, PING6_COMMAND, max_packets, server_address); ++ else ++ asprintf (&command_line, PING_COMMAND, max_packets, server_address); + #else +- asprintf (&command_line, PING_COMMAND, server_address, max_packets); ++ if (is_ipv6_addr (server_address)) ++ asprintf (&command_line, PING6_COMMAND, server_address, max_packets); ++ else ++ asprintf (&command_line, PING_COMMAND, server_address, max_packets); + #endif + + /* Set signal handling and alarm */ +Index: check_tcp.c +=================================================================== +RCS file: /cvsroot/nagiosplug/nagiosplug/plugins/check_tcp.c,v +retrieving revision 1.8 +diff -u -r1.8 check_tcp.c +--- check_tcp.c 25 Nov 2002 12:00:17 -0000 1.8 ++++ check_tcp.c 11 Dec 2002 02:39:50 -0000 +@@ -225,8 +225,12 @@ + { + if (PROTOCOL == UDP_PROTOCOL) + result = my_udp_connect (server_address, server_port, &sd); +- else /* default is TCP */ +- result = my_tcp_connect (server_address, server_port, &sd); ++ else ++ /* default is TCP */ ++ // result = my_tcp_connect (server_address, server_port, &sd); ++ result = my_connect (server_address, server_port, &sd, IPPROTO_TCP); ++printf ("Catch value: %d\n", result); ++printf ("XXX: Check valve\n"); + } + + if (result == STATE_CRITICAL) +Index: check_udp.c +=================================================================== +RCS file: /cvsroot/nagiosplug/nagiosplug/plugins/check_udp.c,v +retrieving revision 1.2 +diff -u -r1.2 check_udp.c +--- check_udp.c 30 Oct 2002 18:46:01 -0000 1.2 ++++ check_udp.c 11 Dec 2002 02:39:50 -0000 +@@ -74,9 +74,8 @@ + alarm (socket_timeout); + + time (&start_time); +- result = +- process_udp_request (server_address, server_port, server_send, +- recv_buffer, MAX_INPUT_BUFFER - 1); ++ result = process_udp_request (server_address, server_port, server_send, ++ recv_buffer, MAX_INPUT_BUFFER - 1); + time (&end_time); + + if (result != STATE_OK) { +Index: netutils.c +=================================================================== +RCS file: /cvsroot/nagiosplug/nagiosplug/plugins/netutils.c,v +retrieving revision 1.1.1.1 +diff -u -r1.1.1.1 netutils.c +--- netutils.c 28 Feb 2002 06:42:59 -0000 1.1.1.1 ++++ netutils.c 11 Dec 2002 02:39:50 -0000 +@@ -42,13 +42,11 @@ + int process_tcp_request2 (char *, int, char *, char *, int); + int process_tcp_request (char *, int, char *, char *, int); + int process_udp_request (char *, int, char *, char *, int); +-int process_request (char *, int, char *, char *, char *, int); ++int process_request (char *, int, int, char *, char *, int); + + int my_tcp_connect (char *, int, int *); + int my_udp_connect (char *, int, int *); +-int my_connect (char *, int, int *, char *); +- +-int my_inet_aton (register const char *, struct in_addr *); ++int my_connect (char *, int, int *, int); + + /* handles socket timeouts */ + void +@@ -64,47 +62,29 @@ + /* connects to a host on a specified TCP port, sends a string, + and gets a response */ + int +-process_tcp_request (char *server_address, +- int server_port, +- char *send_buffer, char *recv_buffer, int recv_size) ++process_tcp_request (char *server_address, int server_port, ++ char *send_buffer, char *recv_buffer, int recv_size) + { +- int result; +- char proto[4] = "tcp"; +- +- result = process_request (server_address, +- server_port, +- proto, send_buffer, recv_buffer, recv_size); +- +- return result; ++ return process_request (server_address, server_port, IPPROTO_TCP, ++ send_buffer, recv_buffer, recv_size); + } + +- + /* connects to a host on a specified UDP port, sends a string, and gets a + response */ + int +-process_udp_request (char *server_address, +- int server_port, +- char *send_buffer, char *recv_buffer, int recv_size) ++process_udp_request (char *server_address, int server_port, ++ char *send_buffer, char *recv_buffer, int recv_size) + { +- int result; +- char proto[4] = "udp"; +- +- result = process_request (server_address, +- server_port, +- proto, send_buffer, recv_buffer, recv_size); +- +- return result; ++ return process_request (server_address, server_port, IPPROTO_UDP, ++ send_buffer, recv_buffer, recv_size); + } + +- +- + /* connects to a host on a specified tcp port, sends a string, and gets a + response. loops on select-recv until timeout or eof to get all of a + multi-packet answer */ + int +-process_tcp_request2 (char *server_address, +- int server_port, +- char *send_buffer, char *recv_buffer, int recv_size) ++process_tcp_request2 (char *server_address, int server_port, ++ char *send_buffer, char *recv_buffer, int recv_size) + { + + int result; +@@ -115,7 +95,7 @@ + fd_set readfds; + int recv_length = 0; + +- result = my_connect (server_address, server_port, &sd, "tcp"); ++ result = my_connect (server_address, server_port, &sd, IPPROTO_TCP); + if (result != STATE_OK) + return STATE_CRITICAL; + +@@ -149,24 +129,30 @@ + else { /* it has */ + recv_result = + recv (sd, recv_buffer + recv_length, recv_size - recv_length - 1, 0); +- if (recv_result == -1) { /* recv failed, bail out */ ++ if (recv_result == -1) { ++ /* recv failed, bail out */ + strcpy (recv_buffer + recv_length, ""); + result = STATE_WARNING; + break; + } +- else if (recv_result == 0) { /* end of file ? */ ++ else if (recv_result == 0) { ++ /* end of file ? */ + recv_buffer[recv_length] = 0; + break; + } +- else { /* we got data! */ ++ else { ++ /* we got data! */ + recv_length += recv_result; +- if (recv_length >= recv_size - 1) { /* buffer full, we're done */ ++ if (recv_length >= recv_size - 1) { ++ /* buffer full, we're done */ + recv_buffer[recv_size - 1] = 0; + break; + } + } +- } /* end if(!FD_ISSET(sd,&readfds)) */ +- } /* end while(1) */ ++ } ++ /* end if(!FD_ISSET(sd,&readfds)) */ ++ } ++ /* end while(1) */ + + close (sd); + return result; +@@ -175,10 +161,8 @@ + /* connects to a host on a specified port, sends a string, and gets a + response */ + int +-process_request (char *server_address, +- int server_port, +- char *proto, +- char *send_buffer, char *recv_buffer, int recv_size) ++process_request (char *server_address, int server_port, int proto, ++ char *send_buffer, char *recv_buffer, int recv_size) + { + int result; + int send_result; +@@ -218,7 +202,7 @@ + recv_result = recv (sd, recv_buffer, recv_size - 1, 0); + if (recv_result == -1) { + strcpy (recv_buffer, ""); +- if (!strcmp (proto, "tcp")) ++ if (proto != IPPROTO_TCP) + printf ("recv() failed\n"); + result = STATE_WARNING; + } +@@ -236,196 +220,74 @@ + + + /* opens a connection to a remote host/tcp port */ ++ + int + my_tcp_connect (char *host_name, int port, int *sd) + { +- int result; +- char proto[4] = "tcp"; +- +- result = my_connect (host_name, port, sd, proto); +- +- return result; ++ return my_connect (host_name, port, sd, IPPROTO_TCP); + } + +- + /* opens a connection to a remote host/udp port */ + int + my_udp_connect (char *host_name, int port, int *sd) + { +- int result; +- char proto[4] = "udp"; +- +- result = my_connect (host_name, port, sd, proto); +- +- return result; ++ return my_connect (host_name, port, sd, IPPROTO_UDP); + } + + + /* opens a tcp or udp connection to a remote host */ + int +-my_connect (char *host_name, int port, int *sd, char *proto) +-{ +- struct sockaddr_in servaddr; +- struct hostent *hp; +- struct protoent *ptrp; +- int result; +- +- bzero ((char *) &servaddr, sizeof (servaddr)); +- servaddr.sin_family = AF_INET; +- servaddr.sin_port = htons (port); +- +- /* try to bypass using a DNS lookup if this is just an IP address */ +- if (!my_inet_aton (host_name, &servaddr.sin_addr)) { +- +- /* else do a DNS lookup */ +- hp = gethostbyname ((const char *) host_name); +- if (hp == NULL) { +- printf ("Invalid host name '%s'\n", host_name); +- return STATE_UNKNOWN; +- } +- +- memcpy (&servaddr.sin_addr, hp->h_addr, hp->h_length); +- } +- +- /* map transport protocol name to protocol number */ +- if ((ptrp = getprotobyname (proto)) == NULL) { +- printf ("Cannot map \"%s\" to protocol number\n", proto); +- return STATE_UNKNOWN; +- } +- +- /* create a socket */ +- *sd = +- socket (PF_INET, (!strcmp (proto, "udp")) ? SOCK_DGRAM : SOCK_STREAM, +- ptrp->p_proto); +- if (*sd < 0) { +- printf ("Socket creation failed\n"); +- return STATE_UNKNOWN; +- } +- +- /* open a connection */ +- result = connect (*sd, (struct sockaddr *) &servaddr, sizeof (servaddr)); +- if (result < 0) { +- switch (errno) { +- case ECONNREFUSED: +- printf ("Connection refused by host\n"); +- break; +- case ETIMEDOUT: +- printf ("Timeout while attempting connection\n"); +- break; +- case ENETUNREACH: +- printf ("Network is unreachable\n"); +- break; +- default: +- printf ("Connection refused or timed out\n"); +- } +- +- return STATE_CRITICAL; +- } +- +- return STATE_OK; +-} +- +- +- +-/* This code was taken from Fyodor's nmap utility, which was originally +- taken from the GLIBC 2.0.6 libraries because Solaris doesn't contain +- the inet_aton() funtion. */ +-int +-my_inet_aton (register const char *cp, struct in_addr *addr) ++my_connect (char *host_name, int port, int *sd, int proto) + { +- register unsigned int val; /* changed from u_long --david */ +- register int base, n; +- register char c; +- u_int parts[4]; +- register u_int *pp = parts; +- +- c = *cp; +- +- for (;;) { +- +- /* +- * Collect number up to ``.''. +- * Values are specified as for C: +- * 0x=hex, 0=octal, isdigit=decimal. +- */ +- if (!isdigit ((int) c)) +- return (0); +- val = 0; +- base = 10; +- +- if (c == '0') { +- c = *++cp; +- if (c == 'x' || c == 'X') +- base = 16, c = *++cp; +- else +- base = 8; +- } +- +- for (;;) { +- if (isascii ((int) c) && isdigit ((int) c)) { +- val = (val * base) + (c - '0'); +- c = *++cp; +- } +- else if (base == 16 && isascii ((int) c) && isxdigit ((int) c)) { +- val = (val << 4) | (c + 10 - (islower ((int) c) ? 'a' : 'A')); +- c = *++cp; +- } +- else +- break; +- } +- +- if (c == '.') { +- +- /* +- * Internet format: +- * a.b.c.d +- * a.b.c (with c treated as 16 bits) +- * a.b (with b treated as 24 bits) +- */ +- if (pp >= parts + 3) +- return (0); +- *pp++ = val; +- c = *++cp; +- } +- else +- break; +- } +- +- /* Check for trailing characters */ +- if (c != '\0' && (!isascii ((int) c) || !isspace ((int) c))) +- return (0); +- +- /* Concoct the address according to the number of parts specified */ +- n = pp - parts + 1; +- switch (n) { +- +- case 0: +- return (0); /* initial nondigit */ +- +- case 1: /* a -- 32 bits */ +- break; +- +- case 2: /* a.b -- 8.24 bits */ +- if (val > 0xffffff) +- return (0); +- val |= parts[0] << 24; +- break; +- +- case 3: /* a.b.c -- 8.8.16 bits */ +- if (val > 0xffff) +- return (0); +- val |= (parts[0] << 24) | (parts[1] << 16); +- break; +- +- case 4: /* a.b.c.d -- 8.8.8.8 bits */ +- if (val > 0xff) +- return (0); +- val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); +- break; +- } +- +- if (addr) +- addr->s_addr = htonl (val); +- +- return (1); ++ struct addrinfo hints; ++ struct addrinfo *res; ++ struct protoent *ptrp; ++ char port_str[6]; ++ int result; ++ ++ memset (&hints, 0, sizeof (hints)); ++ hints.ai_family = PF_UNSPEC; ++ hints.ai_protocol = proto; ++ ++ snprintf(port_str, sizeof(port_str), "%d", port); ++ /* nice clean AF-independent code doesn't matter if passed hostname or IP address */ ++ result = getaddrinfo (host_name, port_str, &hints, &res); ++ ++ if (result != 0) ++ { ++ printf ("%s\n", gai_strerror (result)); ++ return STATE_UNKNOWN; ++ } ++ else ++ { ++ while (res) ++ { ++ /* attempt to create a socket */ ++ *sd = socket (res->ai_family, (proto == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM, res->ai_protocol); ++ ++ if (*sd < 0) { ++ printf ("Socket creation failed\n"); ++ freeaddrinfo (res); ++ return STATE_UNKNOWN; ++ } ++ ++ /* attempt to open a connection */ ++ result = connect (*sd, res->ai_addr, res->ai_addrlen); ++ ++ if (result == 0) ++ break; ++ ++ close(*sd); ++ res = res->ai_next; ++ } ++ freeaddrinfo (res); ++ } ++ ++ if (result == 0) ++ return STATE_OK; ++ else ++ { ++ printf ("%s\n", strerror(errno)); ++ return STATE_CRITICAL; ++ } + } +Index: netutils.h.in +=================================================================== +RCS file: /cvsroot/nagiosplug/nagiosplug/plugins/netutils.h.in,v +retrieving revision 1.1.1.1 +diff -u -r1.1.1.1 netutils.h.in +--- netutils.h.in 28 Feb 2002 06:42:59 -0000 1.1.1.1 ++++ netutils.h.in 11 Dec 2002 02:39:50 -0000 +@@ -42,19 +42,17 @@ + void socket_timeout_alarm_handler (int); + + int process_tcp_request2 (char *address, int port, char *sbuffer, +- char *rbuffer, int rsize); ++ char *rbuffer, int rsize); + int process_tcp_request (char *address, int port, char *sbuffer, +- char *rbuffer, int rsize); ++ char *rbuffer, int rsize); + int process_udp_request (char *address, int port, char *sbuffer, +- char *rbuffer, int rsize); +-int process_request (char *address, int port, char *proto, char *sbuffer, +- char *rbuffer, int rsize); ++ char *rbuffer, int rsize); ++int process_request (char *address, int port, int proto, char *sbuffer, ++ char *rbuffer, int rsize); + + int my_tcp_connect (char *address, int port, int *sd); + int my_udp_connect (char *address, int port, int *sd); +-int my_connect (char *address, int port, int *sd, char *proto); +- +-int my_inet_aton (register const char *cp, struct in_addr *addr); ++int my_connect (char *address, int port, int *sd, int proto); + + #ifndef DEFAULT_SOCKET_TIMEOUT + #include "config.h" +Index: utils.c +=================================================================== +RCS file: /cvsroot/nagiosplug/nagiosplug/plugins/utils.c,v +retrieving revision 1.13 +diff -u -r1.13 utils.c +--- utils.c 18 Nov 2002 07:22:28 -0000 1.13 ++++ utils.c 11 Dec 2002 02:39:50 -0000 +@@ -16,6 +16,9 @@ + #include "version.h" + #include + #include ++#include ++#include ++#include + + extern int timeout_interval; + +@@ -27,7 +30,9 @@ + RETSIGTYPE timeout_alarm_handler (int); + + int is_host (char *); +-int is_dotted_quad (char *); ++int resolve_host_or_addr (char *, int); ++int is_ipv4_addr (char *); ++int is_ipv6_addr (char *); + int is_hostname (char *); + + int is_integer (char *); +@@ -154,53 +159,49 @@ + int + is_host (char *address) + { +- if (is_dotted_quad (address) || is_hostname (address)) ++ if (is_ipv4_addr (address) || is_ipv6_addr (address) || ++ is_hostname (address)) + return (TRUE); ++ + return (FALSE); + } + + int +-is_dotted_quad (char *address) ++resolve_host_or_addr (char *address, int family) + { +- int o1, o2, o3, o4; +- char c[1]; ++ struct addrinfo hints; ++ struct addrinfo *res; ++ int retval; + +- if (sscanf (address, "%d.%d.%d.%d%c", &o1, &o2, &o3, &o4, c) != 4) +- return FALSE; +- else if (o1 > 255 || o2 > 255 || o3 > 255 || o4 > 255) +- return FALSE; +- else if (o1 < 0 || o2 < 0 || o3 < 0 || o4 < 0) ++ memset (&hints, 0, sizeof (hints)); ++ hints.ai_family = family; ++ retval = getaddrinfo (address, NULL, &hints, &res); ++ ++ if (retval != 0) + return FALSE; + else ++ { ++ freeaddrinfo (res); + return TRUE; ++ } + } + +-/* from RFC-1035 +- * +- * The labels must follow the rules for ARPANET host names. They must +- * start with a letter, end with a letter or digit, and have as interior +- * characters only letters, digits, and hyphen. There are also some +- * restrictions on the length. Labels must be 63 characters or less. */ ++int ++is_ipv4_addr (char *address) ++{ ++ return resolve_host_or_addr (address, AF_INET); ++} ++ ++int ++is_ipv6_addr (char *address) ++{ ++ return resolve_host_or_addr (address, AF_INET6); ++} + + int + is_hostname (char *s1) + { +- if (strlen (s1) > 63) +- return FALSE; +- if (strcspn +- (s1, +- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUWVXYZ0123456789-.") != +- 0) return FALSE; +- if (strspn (s1, "0123456789-.") == 1) +- return FALSE; +- while ((s1 = index (s1, '.'))) { +- s1++; +- if (strspn (s1, "0123456789-.") == 1) { +- printf ("%s\n", s1); +- return FALSE; +- } +- } +- return TRUE; ++ return resolve_host_or_addr (s1, AF_UNSPEC); + } + + int +Index: utils.h.in +=================================================================== +RCS file: /cvsroot/nagiosplug/nagiosplug/plugins/utils.h.in,v +retrieving revision 1.7 +diff -u -r1.7 utils.h.in +--- utils.h.in 9 Nov 2002 03:39:35 -0000 1.7 ++++ utils.h.in 11 Dec 2002 02:39:50 -0000 +@@ -28,7 +28,8 @@ + /* Test input types */ + + int is_host (char *); +-int is_dotted_quad (char *); ++int is_ipv4_addr (char *); ++int is_ipv6_addr (char *); + int is_hostname (char *); + + int is_integer (char *); -- cgit v1.2.3-74-g34f1