diff --git a/iputils/iputils.c b/iputils/iputils.c
index 389ea06ea06068bfa2523c6ca16403dceddeb515..0e16de9e96a627a1a61d89a10493d12fb23424e8 100644
--- a/iputils/iputils.c
+++ b/iputils/iputils.c
@@ -8,11 +8,17 @@
 
 static bool LOG_VERBOSE = false;
 
+/**
+ * Set verbose mode
+ */
 void iputils_set_verbose(void)
 {
     LOG_VERBOSE = true;
 }
 
+/**
+ * Reset verbose mode
+ */
 void iputils_reset_verbose(void)
 {
     LOG_VERBOSE = false;
diff --git a/iputils/iputils.h b/iputils/iputils.h
index 3929172c013ee6ea1d43212944980076cab2c29a..244f566801bf73861d27ff8955eba6575db13715 100644
--- a/iputils/iputils.h
+++ b/iputils/iputils.h
@@ -32,12 +32,33 @@ int ping_util6(const char *addr, int count);
 
 
 /**
+ * Tracepath host
  *
+ * @addr[in] host name or IP address
+ * @hops[out] hops count
+ * @time_usec[out] latency in microseconds
+ * @return 0 Ok, -1 error
  */
 int tracepath_util(const char *addr, int *hops, int *time_usec);
+
+/**
+ * Traceroute host
+ *
+ * @addr[in] host name or IP address
+ * @hops[out] hops count
+ * @time_usec[out] latency in microseconds
+ * @return 0 Ok, -1 error
+ */
 int traceroute_util(const char *addr, int *hops, int *time_usec);
 
+
+/**
+ * Set verbose mode
+ */
 void iputils_set_verbose(void);
+/**
+ * Reset verbose mode
+ */
 void iputils_reset_verbose(void);
 
 
@@ -47,7 +68,7 @@ int log_printf(const char *format, ...);
 #define PACKAGE_NAME "iputils"
 #define PACKAGE_VERSION "0.1"
 #define IPUTILS_VERSION(_prog) "%s from %s %s\n", _prog, PACKAGE_NAME, PACKAGE_VERSION
-
+#define UNUSED(x) (void)(x)
 #ifdef __cplusplus
 }
 #endif
diff --git a/iputils/ping.c b/iputils/ping.c
index a5d320a4f8da227896396b2736cbeff3873a48b6..0c3ec725e875fc74aecc6554c3e617473612cb82 100644
--- a/iputils/ping.c
+++ b/iputils/ping.c
@@ -217,8 +217,7 @@ static double ping_strtod(const char *str, const char *err_msg)
     return 0.0;
 }
 
-static int
-ping_main(int argc, char **argv)
+static int ping_main(int argc, char **argv)
 {
     struct addrinfo hints = { .ai_family = AF_UNSPEC, .ai_protocol = IPPROTO_UDP, .ai_socktype = SOCK_DGRAM, .ai_flags =
     getaddrinfo_flags };
diff --git a/iputils/tracepath.c b/iputils/tracepath.c
index 5319e74f4025de42c2726254f5b45d289e8d0e26..7eda079a53be11edd3317acf6f2c9aee5c3ecf67 100755
--- a/iputils/tracepath.c
+++ b/iputils/tracepath.c
@@ -373,6 +373,7 @@ static int recverr(struct run_state * const ctl)
         return 0;
     }
     goto restart;
+    return 0;
 }
 
 static int probe_ttl(struct run_state * const ctl)
@@ -716,6 +717,14 @@ int tracepath_main(int argc, char **argv, struct run_state *ctl)
     return -1; //exit(1);
 }
 
+/**
+ * Tracepath host
+ *
+ * @addr[in] host name or IP address
+ * @hops[out] hops count
+ * @time_usec[out] latency in microseconds
+ * @return 0 Ok, -1 error
+ */
 int tracepath_util(const char *addr, int *hops, int *time_usec)
 {
     int type = 4; // 4 or 6
@@ -761,7 +770,6 @@ int tracepath_util(const char *addr, int *hops, int *time_usec)
              deltatime->tv_sec * 1000000 + deltatime->tv_usec);
              }*/
         }
-    //g_free((char*) argv[2]);
     if(hops) {
         *hops = total_hops;
     }
diff --git a/iputils/traceroute/as_lookups.c b/iputils/traceroute/as_lookups.c
index aedf7e1f2d631f86340102a7b6b3778154e02f71..873180375802bce154e491966ea68f81eab98522 100755
--- a/iputils/traceroute/as_lookups.c
+++ b/iputils/traceroute/as_lookups.c
@@ -66,7 +66,7 @@ const char *get_as_path (const char *query) {
 		goto  err_sk;
 
 	n = snprintf (buf, sizeof (buf), "%s\r\n", query);
-	if (n >= sizeof (buf))  goto err_sk;
+	if (n >= (int)sizeof (buf))  goto err_sk;
 
 	if (write (sk, buf, n) < n)
 		goto err_sk;
diff --git a/iputils/traceroute/clif.c b/iputils/traceroute/clif.c
index 4ef20e454c27f4b7bdaccdcac85f47329ddb232d..4380e8ecd061e5becee1f296c89a8c8bbf127b51 100755
--- a/iputils/traceroute/clif.c
+++ b/iputils/traceroute/clif.c
@@ -1,19 +1,19 @@
 /*
-    Copyright (c)  2000, 2003		Dmitry Butskoy
-					<buc@citadel.stu.neva.ru>
-    License:  LGPL v2.1 or any later
+ Copyright (c)  2000, 2003		Dmitry Butskoy
+ <buc@citadel.stu.neva.ru>
+ License:  LGPL v2.1 or any later
 
-    See COPYING.LIB for the status of this software.
-*/
+ See COPYING.LIB for the status of this software.
+ */
 
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdarg.h>
 
+#include "../iputils.h"
 #include "clif.h"
 
-
 #if 1	/*  Bad idea, anyway...  */
 #define MAX_ARGC_NUMBER	256
 typedef unsigned char _CLIF_index;
@@ -22,1238 +22,1263 @@ typedef unsigned char _CLIF_index;
 typedef unsigned short _CLIF_index;
 #endif
 
-
 /*  This is needed for some print info functions.
-   This is ugly for thread-safe (is it really actual on program invoking?),
-   and for several CLIF_parse_cmdline invoking... But foo on this. Yeah...
-*/
+ This is ugly for thread-safe (is it really actual on program invoking?),
+ and for several CLIF_parse_cmdline invoking... But foo on this. Yeah...
+ */
 static struct {
-	int argc;
-	char **argv;
-	CLIF_option *option_list;
-	CLIF_argument *argument_list;
-	unsigned int parse_flags;
+    int argc;
+    char **argv;
+    CLIF_option *option_list;
+    CLIF_argument *argument_list;
+    unsigned int parse_flags;
 } curr = { 0, };
-	
 
-static void err_report (const char *format, ...) {
-	va_list ap;
+static void err_report(const char *format, ...) {
+    va_list ap;
 
-	if (curr.parse_flags & CLIF_SILENT)
-		return;
+    if(curr.parse_flags & CLIF_SILENT)
+        return;
 
-	va_start (ap, format);
+    va_start(ap, format);
 
-	vfprintf (stderr, format, ap);
+    vfprintf(stderr, format, ap);
 
-	va_end (ap);
+    va_end(ap);
 
-	fprintf (stderr, "\n");
+    fprintf(stderr, "\n");
 
-	return;
+    return;
 }
 
-
 /*  info generation stuff...   */
 
 #define SHORT_PLUS_MINUS	"+/-"
 #define LONG_PLUS_MINUS		"++/--"
 #define EXCL_DLM		" | "
 
-static char *show_short (const CLIF_option *optn) {
-	static char buf[80];
-	char *p = buf;
-	unsigned int flags = optn->flags | curr.parse_flags;
+static char *show_short(const CLIF_option *optn) {
+    static char buf[80];
+    char *p = buf;
+    unsigned int flags = optn->flags | curr.parse_flags;
 
-	if (optn->function_plus) {
-	    if (!optn->function)  *p++ = '+';
-	    else {
-		strcpy (p, SHORT_PLUS_MINUS);
-		p += sizeof (SHORT_PLUS_MINUS) - 1;
-	    }
-	} else
-	    *p++ = '-';
+    if(optn->function_plus) {
+        if(!optn->function)
+            *p++ = '+';
+        else {
+            strcpy(p, SHORT_PLUS_MINUS);
+            p += sizeof(SHORT_PLUS_MINUS) - 1;
+        }
+    } else
+        *p++ = '-';
 
-	*p++ = optn->short_opt[0];
+    *p++ = optn->short_opt[0];
 
-	if (optn->arg_name) {
-	    char *endp = buf + sizeof (buf) - sizeof (",...]");
-	    const char *s;
+    if(optn->arg_name) {
+        char *endp = buf + sizeof(buf) - sizeof(",...]");
+        const char *s;
 
-	    if (!(flags & _CLIF_STRICT_JOIN_ARG))  *p++ = ' ';
-	    if (flags & CLIF_OPTARG)  *p++ = '[';
+        if(!(flags & _CLIF_STRICT_JOIN_ARG))
+            *p++ = ' ';
+        if(flags & CLIF_OPTARG)
+            *p++ = '[';
 
-	    s = optn->arg_name;
-	    while (*s && p < endp)  *p++ = *s++;
+        s = optn->arg_name;
+        while(*s && p < endp)
+            *p++ = *s++;
 
-	    if (flags & CLIF_SEVERAL) {
-		strcpy (p, ",...");
-		p += sizeof (",...") - 1;	/*  last '\0' ...  */
-	    }
+        if(flags & CLIF_SEVERAL) {
+            strcpy(p, ",...");
+            p += sizeof(",...") - 1; /*  last '\0' ...  */
+        }
 
-	    if (flags & CLIF_OPTARG)  *p++ = ']';
-	}
+        if(flags & CLIF_OPTARG)
+            *p++ = ']';
+    }
 
-	*p = '\0';
+    *p = '\0';
 
-	return buf;
+    return buf;
 }
-	
-static char *show_long (const CLIF_option *optn) {
-	static char buf[80];
-	char *p = buf;
-	char *endp;
-	const char *s;
-	unsigned int flags = optn->flags | curr.parse_flags;
-
-
-	if (!(flags & _CLIF_STRICT_KEYWORD)) {
-
-	    if (!(flags & _CLIF_STRICT_ONEDASH)) {
-		if (optn->function_plus) {
-		    if (!optn->function)  {  *p++ = '+'; *p++ = '+';  }
-		    else {
-			strcpy (p, LONG_PLUS_MINUS);
-			p += sizeof (LONG_PLUS_MINUS) - 1;
-		    }
-		} else {  *p++ = '-'; *p++ = '-';  }
-
-	    } else {
-		if (optn->function_plus) {
-		    if (!optn->function)  *p++ = '+';
-		    else {
-			strcpy (p, SHORT_PLUS_MINUS);
-			p += sizeof (SHORT_PLUS_MINUS) - 1;
-		    }
-		} else  *p++ = '-';
-	    }
-	}
-
-	s = optn->long_opt;
-	endp = buf + sizeof (buf) - sizeof (" [");
-	while (*s && p < endp)  *p++ = *s++;
-
-	if (optn->arg_name) {
-
-	    if (flags & _CLIF_STRICT_NOEQUAL) {
-		*p++ = ' ';
-		if (flags & CLIF_OPTARG)  *p++ = '[';
-	    } else {
-		if (flags & CLIF_OPTARG)  *p++ = '[';
-		*p++ = '=';
-	    }
-
-	    s = optn->arg_name;
-	    endp = buf + sizeof (buf) - sizeof (",...]");
-	    while (*s && p < endp)  *p++ = *s++;
-
-	    if (flags & CLIF_SEVERAL) {
-		strcpy (p, ",...");
-		p += sizeof (",...") - 1;	/*  last '\0' ...  */
-	    }
-
-	    if (flags & CLIF_OPTARG)  *p++ = ']';
-	}
-
-	*p = '\0';
-
-	return buf;
+
+static char *show_long(const CLIF_option *optn) {
+    static char buf[80];
+    char *p = buf;
+    char *endp;
+    const char *s;
+    unsigned int flags = optn->flags | curr.parse_flags;
+
+    if(!(flags & _CLIF_STRICT_KEYWORD)) {
+
+        if(!(flags & _CLIF_STRICT_ONEDASH)) {
+            if(optn->function_plus) {
+                if(!optn->function) {
+                    *p++ = '+';
+                    *p++ = '+';
+                }
+                else {
+                    strcpy(p, LONG_PLUS_MINUS);
+                    p += sizeof(LONG_PLUS_MINUS) - 1;
+                }
+            } else {
+                *p++ = '-';
+                *p++ = '-';
+            }
+
+        } else {
+            if(optn->function_plus) {
+                if(!optn->function)
+                    *p++ = '+';
+                else {
+                    strcpy(p, SHORT_PLUS_MINUS);
+                    p += sizeof(SHORT_PLUS_MINUS) - 1;
+                }
+            } else
+                *p++ = '-';
+        }
+    }
+
+    s = optn->long_opt;
+    endp = buf + sizeof(buf) - sizeof(" [");
+    while(*s && p < endp)
+        *p++ = *s++;
+
+    if(optn->arg_name) {
+
+        if(flags & _CLIF_STRICT_NOEQUAL) {
+            *p++ = ' ';
+            if(flags & CLIF_OPTARG)
+                *p++ = '[';
+        } else {
+            if(flags & CLIF_OPTARG)
+                *p++ = '[';
+            *p++ = '=';
+        }
+
+        s = optn->arg_name;
+        endp = buf + sizeof(buf) - sizeof(",...]");
+        while(*s && p < endp)
+            *p++ = *s++;
+
+        if(flags & CLIF_SEVERAL) {
+            strcpy(p, ",...");
+            p += sizeof(",...") - 1; /*  last '\0' ...  */
+        }
+
+        if(flags & CLIF_OPTARG)
+            *p++ = ']';
+    }
+
+    *p = '\0';
+
+    return buf;
 }
 
-static char *show_excl (const CLIF_option *option_list, int *cnt_p) {
-	static char buf[256];
-	const CLIF_option *optn;
-	char *p = buf;
-	char *endp = buf + sizeof (buf) - sizeof (EXCL_DLM);
-	int excl_cnt = 0;
+static char *show_excl(const CLIF_option *option_list, int *cnt_p) {
+    static char buf[256];
+    const CLIF_option *optn;
+    char *p = buf;
+    char *endp = buf + sizeof(buf) - sizeof(EXCL_DLM);
+    int excl_cnt = 0;
 
-	*p = '\0';
-	if (cnt_p)  *cnt_p = 0;
-	if (!option_list)  return buf;
+    *p = '\0';
+    if(cnt_p)
+        *cnt_p = 0;
+    if(!option_list)
+        return buf;
 
-	for (optn = option_list; optn->short_opt || optn->long_opt; optn++) {
-	    char *s;
+    for(optn = option_list; optn->short_opt || optn->long_opt; optn++) {
+        char *s;
 
-	    if (!(optn->flags & CLIF_EXCL))  continue;
+        if(!(optn->flags & CLIF_EXCL))
+            continue;
 
-	    if (optn->short_opt)  s = show_short (optn);
-	    else  s = show_long (optn);
+        if(optn->short_opt)
+            s = show_short(optn);
+        else
+            s = show_long(optn);
 
-	    if (excl_cnt > 0) {	    /*  i.e., second etc...  */
-		    strcpy (p, EXCL_DLM);
-		    p += sizeof (EXCL_DLM) - 1;
-	    }
+        if(excl_cnt > 0) { /*  i.e., second etc...  */
+            strcpy(p, EXCL_DLM);
+            p += sizeof(EXCL_DLM) - 1;
+        }
 
-	    while (*s && p < endp)  *p++ = *s++;
+        while(*s && p < endp)
+            *p++ = *s++;
 
-	    excl_cnt++;
-	}
+        excl_cnt++;
+    }
 
-	*p = '\0';
+    *p = '\0';
 
-	if (cnt_p)  *cnt_p = excl_cnt;
+    if(cnt_p)
+        *cnt_p = excl_cnt;
 
-	return buf;
+    return buf;
 }
 
+static int is_keyword(const CLIF_option *optn) {
+    unsigned int flags = optn->flags | curr.parse_flags;
 
-static int is_keyword (const CLIF_option *optn) {
-	unsigned int flags = optn->flags | curr.parse_flags;
-
-	return  (flags & _CLIF_STRICT_KEYWORD) != 0;
+    return (flags & _CLIF_STRICT_KEYWORD) != 0;
 }
 
-
-static void err_bad_opt (const char *arg, char c, int n) {
-	char sym = (*arg == '+') ? '+' : '-';
-
-	if (c)  err_report ("Bad option `%c%c' (argc %d)", sym, c, n);
-	else {
-	    char *p = strchr (arg, '=');
-	    const char *type = (*arg == sym) ? "option" : "keyword";
-
-	    if (p)
-		err_report ("Bad %s `%s' (with arg `%s') (argc %d)",
-							type, arg, p + 1, n);
-	    else
-		err_report ("Bad %s `%s' (argc %d)", type, arg, n);
-	}
+static void err_bad_opt(const char *arg, char c, int n) {
+    char sym = (*arg == '+') ? '+' : '-';
+
+    if(c)
+        err_report("Bad option `%c%c' (argc %d)", sym, c, n);
+    else {
+        char *p = strchr(arg, '=');
+        const char *type = (*arg == sym) ? "option" : "keyword";
+
+        if(p)
+            err_report("Bad %s `%s' (with arg `%s') (argc %d)",
+                    type, arg, p + 1, n);
+        else
+            err_report("Bad %s `%s' (argc %d)", type, arg, n);
+    }
 }
 
-static void err_bad_arg (const CLIF_option *optn, char c, int n) {
-	CLIF_option tmp = *optn;
-	char ss[80];
-	char *s;
-
-	tmp.arg_name = NULL;
-
-	if (c) {
-	    s = show_short (&tmp);	/*  always without arg...  */
-	    strncpy (ss, s, sizeof (ss));
-	    s = show_short (optn);
-	} else {
-	    s = show_long (&tmp);	/*  always without arg...  */
-	    strncpy (ss, s, sizeof (ss));
-	    s = show_long (optn);
-	}
-
-	err_report ("%s `%s' (argc %d) requires an argument: `%s'",
-		    (c || !is_keyword (optn)) ? "Option" : "Keyword", ss, n, s);
+static void err_bad_arg(const CLIF_option *optn, char c, int n) {
+    CLIF_option tmp = *optn;
+    char ss[80];
+    char *s;
+
+    tmp.arg_name = NULL;
+
+    if(c) {
+        s = show_short(&tmp); /*  always without arg...  */
+        strncpy(ss, s, sizeof(ss));
+        s = show_short(optn);
+    } else {
+        s = show_long(&tmp); /*  always without arg...  */
+        strncpy(ss, s, sizeof(ss));
+        s = show_long(optn);
+    }
+
+    err_report("%s `%s' (argc %d) requires an argument: `%s'",
+            (c || !is_keyword(optn)) ? "Option" : "Keyword", ss, n, s);
 }
-	
-static void err_bad_res (const CLIF_option *optn, char c,
-					const char *opt_arg, int n) {
-	CLIF_option tmp = *optn;
-	char *ss;
-	const char *type;
-
-	tmp.arg_name = NULL;
-
-	if (c) {
-	    ss = show_short (&tmp);
-	    type = "option";
-	} else {
-	    ss = show_long (&tmp);
-	    type = is_keyword (optn) ? "keyword" : "option";
-	}
-
-	if (optn->arg_name)
-	    err_report ("Cannot handle `%s' %s with arg `%s' (argc %d)",
-							ss, type, opt_arg, n);
-	else
-	    err_report ("Cannot handle `%s' %s (argc %d)", ss, type, n);
+
+static void err_bad_res(const CLIF_option *optn, char c,
+        const char *opt_arg, int n) {
+    CLIF_option tmp = *optn;
+    char *ss;
+    const char *type;
+
+    tmp.arg_name = NULL;
+
+    if(c) {
+        ss = show_short(&tmp);
+        type = "option";
+    } else {
+        ss = show_long(&tmp);
+        type = is_keyword(optn) ? "keyword" : "option";
+    }
+
+    if(optn->arg_name)
+        err_report("Cannot handle `%s' %s with arg `%s' (argc %d)",
+                ss, type, opt_arg, n);
+    else
+        err_report("Cannot handle `%s' %s (argc %d)", ss, type, n);
 }
 
-static void err_bad_excl (const CLIF_option *optn, char c, int n) {
-	CLIF_option tmp = *optn;
-	char *ss;
-	char *excl = show_excl (curr.option_list, 0);
-				/*  Note: show_(short|long)() nested!!! */
+static void err_bad_excl(const CLIF_option *optn, char c, int n) {
+    CLIF_option tmp = *optn;
+    char *ss;
+    char *excl = show_excl(curr.option_list, 0);
+    /*  Note: show_(short|long)() nested!!! */
 
-	tmp.arg_name = NULL;
+    tmp.arg_name = NULL;
 
-	if (c)  ss = show_short (&tmp);
-	else  ss = show_long (&tmp);
+    if(c)
+        ss = show_short(&tmp);
+    else
+        ss = show_long(&tmp);
 
-	err_report ("%s `%s' (argc %d): Only one of:\n    %s\n"
-		    "may be specified.",
-		    (c || !is_keyword (optn)) ? "Option" : "Keyword",
-							    ss, n, excl);
+    err_report("%s `%s' (argc %d): Only one of:\n    %s\n"
+            "may be specified.",
+            (c || !is_keyword(optn)) ? "Option" : "Keyword",
+            ss, n, excl);
 }
 
-
-static CLIF_option *find_long (char *arg, char **arg_p,
-				unsigned int match, unsigned int nomatch) {
-	CLIF_option *optn;
-	CLIF_option *abbrev = NULL;
-	char *abbrev_arg = NULL;
-	int abbrev_found = 0;
-
-
-	for (optn = curr.option_list;
-		optn->short_opt || optn->long_opt;
-		    optn++
-	) {
-	    char *a;
-	    const char *o;
-	    unsigned int flags;
-
-	    if (!optn->long_opt)  continue;
-
-	    flags = curr.parse_flags | optn->flags;
-	    if (flags & nomatch)  continue;
-	    if (match && !(flags & match))  continue;	/*  XXX: optimize it */
-
-
-	    for (a = arg, o = optn->long_opt; *o && *a == *o; a++, o++) ;
-
-	    if (*a == '\0' ||
-		(*a == '=' && optn->arg_name && !(flags & _CLIF_STRICT_NOEQUAL))
-	    ) {	    /*  looks like end of option...  */
-
-		if (!*o) {	/*  explicit match found   */
-		    if (*a == '=' && arg_p)  *arg_p = a + 1;
-		    return optn;
-		}
-
-		if ((flags & CLIF_ABBREV) &&
-		    (a - arg >= CLIF_MIN_ABBREV)
-		) {
-		    if (!abbrev_found) {
-			abbrev_found = 1;
-			abbrev = optn;
-			if (*a == '=')  abbrev_arg = a + 1;
-		    } else	/*  several possibility case...  */
-			abbrev = NULL;
-		}
-	    }
-	}
-
-	if (abbrev) {	/*  implicit match found   */
-	    if (abbrev_arg && arg_p)  *arg_p = abbrev_arg;
-	    return abbrev;
-	} else		/*  no match found   */
-	    return NULL;
+static CLIF_option *find_long(char *arg, char **arg_p,
+        unsigned int match, unsigned int nomatch) {
+    CLIF_option *optn;
+    CLIF_option *abbrev = NULL;
+    char *abbrev_arg = NULL;
+    int abbrev_found = 0;
+
+    for(optn = curr.option_list;
+            optn->short_opt || optn->long_opt;
+            optn++
+            ) {
+        char *a;
+        const char *o;
+        unsigned int flags;
+
+        if(!optn->long_opt)
+            continue;
+
+        flags = curr.parse_flags | optn->flags;
+        if(flags & nomatch)
+            continue;
+        if(match && !(flags & match))
+            continue; /*  XXX: optimize it */
+
+        for(a = arg, o = optn->long_opt; *o && *a == *o; a++, o++)
+            ;
+
+        if(*a == '\0' ||
+                (*a == '=' && optn->arg_name && !(flags & _CLIF_STRICT_NOEQUAL))
+                ) { /*  looks like end of option...  */
+
+            if(!*o) { /*  explicit match found   */
+                if(*a == '=' && arg_p)
+                    *arg_p = a + 1;
+                return optn;
+            }
+
+            if((flags & CLIF_ABBREV) &&
+                    (a - arg >= CLIF_MIN_ABBREV)
+                    ) {
+                if(!abbrev_found) {
+                    abbrev_found = 1;
+                    abbrev = optn;
+                    if(*a == '=')
+                        abbrev_arg = a + 1;
+                } else
+                    /*  several possibility case...  */
+                    abbrev = NULL;
+            }
+        }
+    }
+
+    if(abbrev) { /*  implicit match found   */
+        if(abbrev_arg && arg_p)
+            *arg_p = abbrev_arg;
+        return abbrev;
+    } else
+        /*  no match found   */
+        return NULL;
 }
 
-static int check_sym (const CLIF_option *optn, char sym) {
+static int check_sym(const CLIF_option *optn, char sym) {
 
-	if (sym == '+') {
-	    if (!optn->function_plus)  return -1;
-	}
-	else if (sym == '-') {
-	    if (!optn->function && optn->function_plus)
-		    return -1;
-	}
+    if(sym == '+') {
+        if(!optn->function_plus)
+            return -1;
+    }
+    else if(sym == '-') {
+        if(!optn->function && optn->function_plus)
+            return -1;
+    }
 
-	return 0;
+    return 0;
 }
 
-static int call_function (CLIF_option *optn, char *opt_arg, char sym) {
-	int (*function) (CLIF_option *, char *);
-
-	function = (sym == '+') ? optn->function_plus : optn->function;
-
-	if (!function)  return 0;
+static int call_function(CLIF_option *optn, char *opt_arg, char sym) {
+    int (*function)(CLIF_option *, char *);
 
-	if (opt_arg && ((optn->flags | curr.parse_flags) & CLIF_SEVERAL)) {
-	    char tmp[80];
-	    char *t;
-	    char *endt = tmp + sizeof (tmp);
+    function = (sym == '+') ? optn->function_plus : optn->function;
 
-	    while (*opt_arg) {
-    
-		t = tmp;
-		while (t < endt && *opt_arg &&
-		       *opt_arg != ' ' && *opt_arg != '\t' && *opt_arg != ','
-		)  *t++ = *opt_arg++;
+    if(!function)
+        return 0;
 
-		if (t >= endt)  return -1;
-    
-		*t = '\0';
-    
-		if (function (optn, tmp) < 0)  return -1;
-    
-		while (*opt_arg == ' ' || *opt_arg == '\t' || *opt_arg == ',')
-			opt_arg++;
-	    }
+    if(opt_arg && ((optn->flags | curr.parse_flags) & CLIF_SEVERAL)) {
+        char tmp[80];
+        char *t;
+        char *endt = tmp + sizeof(tmp);
 
-	    return 0;
-	}
+        while(*opt_arg) {
 
-	return  function (optn, opt_arg);
-}
+            t = tmp;
+            while(t < endt && *opt_arg &&
+                    *opt_arg != ' ' && *opt_arg != '\t' && *opt_arg != ','
+            )
+                *t++ = *opt_arg++;
 
+            if(t >= endt)
+                return -1;
 
-int CLIF_parse_cmdline (int argc, char *argv[],
-			CLIF_option *option_list,
-			CLIF_argument *argument_list,
-			unsigned int parse_flags) {
-	int i, j;
-	CLIF_option *optn;
-	CLIF_argument *argm;
-	int num_args = 0;
-	int num_argm = 0, strict_beg = 0, strict_end = 0;
-	_CLIF_index arg_n[MAX_ARGC_NUMBER];
-	unsigned int dirty_flags = 0;
-	int dirty_plus = 0;
-	int exclusive_cnt = 0;
-	int posix = getenv ("POSIXLY_CORRECT") != NULL ||
-					    (parse_flags & CLIF_POSIX);
-
-	curr.argc = argc;
-	curr.argv = argv;
-	curr.option_list = option_list;
-	curr.argument_list = argument_list;
-	curr.parse_flags = parse_flags;
-
-	if (argc <= 1 && (parse_flags & CLIF_HELP_EMPTY)) {
-		CLIF_current_help ();
-		exit (0);
-	}
-
-	/*  Scan argument_list for check and some info.  */
-
-	if (argument_list) {
-	    enum stages { STRICT_BEG, OPTIONAL, STRICT_END };
-	    int stage = STRICT_BEG;
-
-	    for (argm = argument_list; argm->name; argm++) {
-		
-		if (argm->flags & CLIF_STRICT) {
-
-		    if (stage == STRICT_BEG)  strict_beg++;
-		    else if (stage == OPTIONAL) {
-			stage = STRICT_END;
-			strict_end++;
-		    }
-		    else if (stage == STRICT_END)
-			    strict_end++;
-		} else {
-		    if (stage == STRICT_BEG)  stage = OPTIONAL;
-		    else if (stage == STRICT_END) {
-			err_report ("Incorrect argument list set in program "
-				    "source: more than one optional area.");
-			return -1;
-		    }
-		}
-
-		num_argm++;
-	    }
-	}
-
-	/*  Scan option_list for some info.  */
-	if (option_list) {
-
-	    dirty_flags = parse_flags;
-
-	    for (optn = option_list;
-		    optn->short_opt || optn->long_opt;
-			optn++
-	    ) {
-		dirty_flags |= optn->flags;
-		if (optn->function_plus)  dirty_plus = 1;
-	    }
-	}
-
-	if (dirty_flags & CLIF_EXCL)
-		exclusive_cnt = 1;	/*  only one is allowed...  */
-
-
-	/*  Go !   Store arguments, parse options.  */
-
-	for (i = 1; i < argc; i++) {
-	    char *arg = argv[i];
-	    char *opt_arg = NULL;
-	    char sym = '-';
-
-	    if (!option_list)
-		    goto  handle_arg;
-
-	    if (*arg == '+' && dirty_plus)
-		    sym = '+';
-
-	    if (*arg != sym) {	/*  argument or keyword   */
-
-		if (dirty_flags & CLIF_MAY_KEYWORD) {
-		    optn = find_long (arg, &opt_arg, CLIF_MAY_KEYWORD, 0);
-		    if (optn)  goto long_found;
-		}
-
-		if (num_args == 0 && (parse_flags & CLIF_FIRST_GROUP)) {
-		    /*  ugly...  */
-		    parse_flags &= ~CLIF_FIRST_GROUP;
-		    dirty_flags &= ~CLIF_FIRST_GROUP;	/*  to be correct   */
-
-		    goto  handle_short;
-		}
-
-		/*  else it is an argument   */
-		goto  handle_arg;
-
-	    }
-	    else if (*++arg == sym) {	/*  `--' - long option   */
-		arg++;
-
-		if (*arg == sym ||	/*  `---' - let it be not option... */
-		    (parse_flags & (_CLIF_STRICT_KEYWORD|_CLIF_STRICT_ONEDASH)) 
-		) {
-		    arg -= 2;
-		    goto  handle_arg;	/*  not option anyway  */
-		}
-	
-		optn = find_long (arg, &opt_arg, 0,
-				_CLIF_STRICT_KEYWORD | _CLIF_STRICT_ONEDASH);
-		if (optn)  goto long_found;
-	
-		/*  XXX: May be allow only for `--', not `++' too...  */
-		if (!*arg && sym == '-') {  /*  `--' and no empty longoption */
-		    option_list = NULL;	    /*  POSIX way...  */
-		    continue;
-		}
-	
-		/*  XXX: or treat as an argument sometimes???  */
-		err_bad_opt (argv[i], 0, i);
-		return -1;
-	    }
-	    else {	/*  short option, or several short options...  */
-
-		if (dirty_flags & CLIF_MAY_ONEDASH) {
-		    optn = find_long (arg, &opt_arg, CLIF_MAY_ONEDASH, 0);
-		    if (optn)  goto long_found;
-		}
-    
-		if (!*arg) {	/*  POSIX say: only "stdout specification"... */
-		    arg--;
-		    goto handle_arg;
-		}
-    
-		goto  handle_short;
-	    }
-
-
-    long_found:	
-	    if (check_sym (optn, sym) < 0) {	/*  Oops...  */
-		err_bad_opt (argv[i], 0, i);
-		return -1;
-	    }
-
-	    if (optn->flags & CLIF_EXCL) {
-		if (!exclusive_cnt) {
-		    err_bad_excl (optn, 0, i);
-		    return -1;
-		}
-		exclusive_cnt--;
-	    }
-		
-	    if (optn->arg_name && !opt_arg) {
-		unsigned int flags = optn->flags | parse_flags;
-
-		if (++i >= argc ||
-		    !(flags & CLIF_MAY_NOEQUAL)
-		) {	/*  missing opt arg   */
-		    i--;
-
-		    if (!(flags & CLIF_OPTARG)) {
-			err_bad_arg (optn, 0, i);
-			return -1;
-		    }
-
-		    opt_arg = NULL;
-		} else
-		    opt_arg = argv[i];
-		   
-	    }
-
-
-	    if (call_function (optn, opt_arg, sym) < 0) {
-		err_bad_res (optn, 0, opt_arg, i);
-		return -1;
-	    }
-
-	    if (optn->flags & CLIF_EXIT)
-		    exit (0);
-
-	    continue;
+            *t = '\0';
 
+            if(function(optn, tmp) < 0)
+                return -1;
 
-    handle_arg:
-	    if (argument_list) {
-		if (i < MAX_ARGC_NUMBER)    /*  XXX: ugly, better report   */
-			arg_n[num_args++] = i;
-	    } else {
-		err_report ("`%s' (argc %d): arguments are not allowed",
-								 argv[i], i);
-		return -1;
-	    }
+            while(*opt_arg == ' ' || *opt_arg == '\t' || *opt_arg == ',')
+                opt_arg++;
+        }
 
-	    /*  POSIX say: No more options after args...  */
-	    if (posix)  option_list = NULL;	/*  geniously...  */
-	
-	    continue;
+        return 0;
+    }
 
+    return function(optn, opt_arg);
+}
 
-    handle_short:
+int CLIF_parse_cmdline (int argc, char *argv[],
+        CLIF_option *option_list,
+        CLIF_argument *argument_list,
+        unsigned int parse_flags){
+int i, j;
+CLIF_option *optn;
+CLIF_argument *argm;
+int num_args = 0;
+int num_argm = 0, strict_beg = 0, strict_end = 0;
+_CLIF_index arg_n[MAX_ARGC_NUMBER];
+unsigned int dirty_flags = 0;
+int dirty_plus = 0;
+int exclusive_cnt = 0;
+int posix = getenv ("POSIXLY_CORRECT") != NULL ||
+(parse_flags & CLIF_POSIX);
+
+curr.argc = argc;
+curr.argv = argv;
+curr.option_list = option_list;
+curr.argument_list = argument_list;
+curr.parse_flags = parse_flags;
+
+if (argc <= 1 && (parse_flags & CLIF_HELP_EMPTY)) {
+    CLIF_current_help ();
+    exit (0);
+}
 
-	    opt_arg = NULL;
-
-	    do {
-
-		for (optn = option_list;
-			optn->short_opt || optn->long_opt;
-			    optn++
-		) {
-		    if (optn->short_opt && optn->short_opt[0] == *arg)
-			    break;
-		}
-		if (!optn->short_opt ||
-		    check_sym (optn, sym) < 0
-		) {
-		    err_bad_opt (argv[i], *arg, i);
-		    return -1;
-		}
-
-		if (optn->flags & CLIF_EXCL) {
-		    if (!exclusive_cnt) {
-			err_bad_excl (optn, *arg, i);
-			return -1;
-		    }
-		    exclusive_cnt--;
-		}
-
-
-		if (optn->arg_name) {
-		    unsigned int flags = parse_flags | optn->flags;
-
-		    if (arg[1] == '\0') {	/*  a last one   */
-
-			/*  POSIX say: an option with arg cannot be grouped. */
-			if (posix && arg != argv[i] && arg[-1] != sym) {
-				err_bad_arg (optn, *arg, i);	/*  good way? */
-				return -1;
-			}
-
-			if (++i >= argc ||
-			    (flags & _CLIF_STRICT_JOIN_ARG)
-			) {
-			    i--;
-
-			    if (!(flags & CLIF_OPTARG)) {
-				err_bad_arg (optn, *arg, i);
-				return -1;
-			    }
-
-			    opt_arg = NULL;
-			} else
-			    opt_arg = argv[i];
-		    }
-		    else if ((arg == argv[i] || arg[-1] == sym) &&	
-			     (flags & CLIF_MAY_JOIN_ARG)
-		    ) {
-			opt_arg = ++arg;
-		    }
-		    else {	/*  inside a group...  */
-			if (!(flags & CLIF_OPTARG) ||
-			    (flags & CLIF_MAY_JOIN_ARG)
-			) {
-			    err_bad_arg (optn, *arg, i);
-			    return -1;
-			}
-
-			opt_arg = NULL;
-		    }
-		}
-
-		if (call_function (optn, opt_arg, sym) < 0) {
-		    err_bad_res (optn, optn->short_opt[0], opt_arg, i);
-		    return -1;
-		}
-
-		if (optn->flags & CLIF_EXIT)
-			exit (0);
-
-	    } while (!opt_arg && *++arg);
-
-	}	/*  for ( ...  )   */
-
-
-	if ((parse_flags & CLIF_STRICT_EXCL) && exclusive_cnt != 0) {
-		err_report ("One of these must be specified:\n    %s\n",
-						    show_excl (option_list, 0));
-		return -1;
-	}
-
-
-	/*  Now, after *ALL* options, handle arguments, if any.  */
-
-	if (num_args < strict_beg + strict_end) {
-	    /*  Missing some needed arguments.  */
-
-	    if (num_args < strict_beg)  argm = argument_list + num_args;
-	    else
-		argm = argument_list +
-			    ((num_args - strict_beg) + (num_argm - strict_end));
-
-	    if (num_args == strict_beg + strict_end - 1)
-		err_report ("Specify \"%s\" missing argument.", argm->name);
-	    else
-		err_report ("Specify \"%s\" and other missing arguments.",
-								    argm->name);
-	    return -1;
-	}
-
-	if (num_args > 0) {
-	    _CLIF_index argm_index[MAX_ARGC_NUMBER];
-
-	    /*  assing argm (by index) for each arg...  */
-		    
-	    for (i = 0, j = 0; i < strict_beg; i++, j++)
-		    argm_index[i] = j;
-	    for (i = num_args - strict_end, j = num_argm - strict_end;
-			i < num_args; i++, j++
-	    )  argm_index[i] = j;
-	    for (i = strict_beg, j = strict_beg;
-		    i < num_args - strict_end && j < num_argm - strict_end;
-			i++
-	    ) {
-		argm_index[i] = j;
-		if (!(argument_list[j].flags & CLIF_MORE))
-			j++;
-	    }
-
-	    if (i < num_args - strict_end) {	/*  there are extra args...  */
-		err_report ("Extra arg `%s' (position %d, argc %d)",
-				    argv[arg_n[i]], i + 1, arg_n[i]);
-		return -1;
-	    }
-
-	    if (j < num_argm - strict_end &&	
-		!(argument_list[j].flags & CLIF_MORE) &&
-		/*  ...i.e, there are some missing optional args...  */
-		(argument_list[j].flags & CLIF_ACC_PREV)
-	    ) {
-		if (j == 0)
-		    err_report ("Incorrect argument list set: first arg "
-				"cannot be `accompanied with previous'.");
-		else
-		    err_report ("Arg \"%s\" must be specified because "
-				"\"%s\" `%s' is used.", argument_list[j].name,
-				argument_list[j - 1].name, argv[arg_n[i - 1]]);
-		return -1;
-	    }
-		
-	    if (argm_index[--i] == j &&
-		    /*  above is true only after OPTIONAL area scan
-		       and when `j' is stopped on CLIF_MORE  */
-		++j < num_argm - strict_end
-		    /*  i.e: there is a *last* one (after CLIF_MORE)
-			in the OPTIONAL area  */
-	    )  argm_index[i] = j;	/*  *last* is better than *more*   */
-		    
-
-	    /*  ...and work now   */
-
-	    for (i = 0; i < num_args; i++) {
-		argm = argument_list + argm_index[i];
-
-		if (argm->function &&
-		    argm->function (argm, argv[arg_n[i]], i) < 0
-		) {
-		    err_report ("Cannot handle \"%s\" cmdline arg `%s' "
-				"on position %d (argc %d)",
-				argm->name, argv[arg_n[i]], i + 1, arg_n[i]);
-		    return -1;
-		}
-	    }
-
-	    /*  That`s all.  */
-	}
-
-	return 0;
+/*  Scan argument_list for check and some info.  */
+
+if (argument_list) {
+    enum stages {STRICT_BEG, OPTIONAL, STRICT_END};
+    int stage = STRICT_BEG;
+
+    for (argm = argument_list; argm->name; argm++) {
+
+        if (argm->flags & CLIF_STRICT) {
+
+            if (stage == STRICT_BEG) strict_beg++;
+            else if (stage == OPTIONAL) {
+                stage = STRICT_END;
+                strict_end++;
+            }
+            else if (stage == STRICT_END)
+            strict_end++;
+        } else {
+            if (stage == STRICT_BEG) stage = OPTIONAL;
+            else if (stage == STRICT_END) {
+                err_report ("Incorrect argument list set in program "
+                        "source: more than one optional area.");
+                return -1;
+            }
+        }
+
+        num_argm++;
+    }
 }
 
+/*  Scan option_list for some info.  */
+if (option_list) {
+
+    dirty_flags = parse_flags;
 
-static void box_output (int start, int left, int width, const char *str,
-							const char *arg_name) {
-	char *p, *endp, *s;
-	int l;
-	char buf[1024];
-	char spacer[128];	/*  assume it is enough   */
-
-	if (left > sizeof (spacer) - 2)  left = sizeof (spacer) - 2;
-	if (width > sizeof (buf) - 1)  width = sizeof (buf) - 1;
-
-	spacer[0] = '\n';
-	memset (spacer + 1, ' ', left);
-	spacer[left + 1] = '\0';
-
-
-	l = left - start;
-	if (l > 0) {
-	    memset (buf, ' ', l);
-	    buf[l] = '\0';
-	    fprintf (stderr, "%s", buf);
-	} else 
-	    fprintf (stderr, "%s", spacer);
-
-
-	endp = buf + width;
-
-	p = buf;
-
-	while (*str) {
-
-	    while (*str && p < endp) {
-    
-		if (*str == '%' && arg_name) {
-		    if (str[1] == '%') {
-			*p++ = '%';
-			str += 2;
-			continue;
-		    } 
-		    else if (str[1] == 's') {
-			const char *a = arg_name;
-    
-			while (*a && p < endp)  *p++ = *a++;
-			str += 2;
-			continue;
-		    } 
-		}
-    
-		*p++ = *str++;
-	    }
-    
-	    *p = '\0';
-    
-	    if (p < endp)  break;
-
-    
-	    while (p > buf && *p != ' ' && *p != '\t')  p--;
-	    if (p <= buf)  return;	/*  foo on you   */
-		    
-	    *p = '\0';
-	    fprintf (stderr, "%s", buf);
-	    fprintf (stderr, "%s", spacer);
-		
-	    p++;
-	    for (s = buf; *p; *s++ = *p++) ;
-	    *s = '\0';
-	    p = s;
-	}
-
-
-	fprintf (stderr, "%s", buf);
-		
-	return;
+    for (optn = option_list;
+            optn->short_opt || optn->long_opt;
+            optn++
+    ) {
+        dirty_flags |= optn->flags;
+        if (optn->function_plus) dirty_plus = 1;
+    }
 }
 
+if (dirty_flags & CLIF_EXCL)
+exclusive_cnt = 1; /*  only one is allowed...  */
+
+/*  Go !   Store arguments, parse options.  */
+
+for (i = 1; i < argc; i++) {
+    char *arg = argv[i];
+    char *opt_arg = NULL;
+    char sym = '-';
+
+    if (!option_list)
+    goto handle_arg;
+
+    if (*arg == '+' && dirty_plus)
+    sym = '+';
+
+    if (*arg != sym) { /*  argument or keyword   */
 
-#define SHORT_LONG_DLM	"  "
-#define OPT_START_DLM	"  "
-#define OPT_FIELD_WIDTH	30
+        if (dirty_flags & CLIF_MAY_KEYWORD) {
+            optn = find_long (arg, &opt_arg, CLIF_MAY_KEYWORD, 0);
+            if (optn) goto long_found;
+        }
 
-#define ARG_MARK_STRICT	"+     "
-#define ARG_MARK_GROUP0	"  .   "
-#define ARG_MARK_GROUP	"  '   "
-#define ARG_MARK_OPT	"      "
-#define ARG_FIELD_WIDTH	20
+        if (num_args == 0 && (parse_flags & CLIF_FIRST_GROUP)) {
+            /*  ugly...  */
+            parse_flags &= ~CLIF_FIRST_GROUP;
+            dirty_flags &= ~CLIF_FIRST_GROUP; /*  to be correct   */
 
-#define SCREEN_WIDTH	80
+            goto handle_short;
+        }
 
+        /*  else it is an argument   */
+        goto handle_arg;
 
-void CLIF_print_options (const char *header,
-				const CLIF_option *option_list) {
-	const CLIF_option *optn;
-	char *excl;
-	int excl_cnt = 0;
+    }
+    else if (*++arg == sym) { /*  `--' - long option   */
+        arg++;
 
-	/*  Print a header string, if present...  */
-	if (header)  fprintf (stderr, "%s\n", header);
+        if (*arg == sym || /*  `---' - let it be not option... */
+                (parse_flags & (_CLIF_STRICT_KEYWORD|_CLIF_STRICT_ONEDASH))
+        ) {
+            arg -= 2;
+            goto handle_arg; /*  not option anyway  */
+        }
 
-	if (!option_list)  return;
+        optn = find_long (arg, &opt_arg, 0,
+                _CLIF_STRICT_KEYWORD | _CLIF_STRICT_ONEDASH);
+        if (optn) goto long_found;
 
+        /*  XXX: May be allow only for `--', not `++' too...  */
+        if (!*arg && sym == '-') { /*  `--' and no empty longoption */
+            option_list = NULL; /*  POSIX way...  */
+            continue;
+        }
 
-	for (optn = option_list; optn->short_opt || optn->long_opt; optn++) {
-	    int len;
+        /*  XXX: or treat as an argument sometimes???  */
+        err_bad_opt (argv[i], 0, i);
+        return -1;
+    }
+    else { /*  short option, or several short options...  */
 
-	    /*  generate and print an option usage   */
+        if (dirty_flags & CLIF_MAY_ONEDASH) {
+            optn = find_long (arg, &opt_arg, CLIF_MAY_ONEDASH, 0);
+            if (optn) goto long_found;
+        }
 
-	    if (optn->short_opt) {
-		if (optn->long_opt)
-		    len = fprintf (stderr, OPT_START_DLM "%s"
-					   SHORT_LONG_DLM "%s",
-					show_short (optn), show_long (optn));
-		else
-		    len = fprintf (stderr, OPT_START_DLM "%s",
-						    show_short (optn));
-	    } else
-		len = fprintf (stderr, OPT_START_DLM "%s", show_long (optn));
+        if (!*arg) { /*  POSIX say: only "stdout specification"... */
+            arg--;
+            goto handle_arg;
+        }
 
+        goto handle_short;
+    }
 
-	    /*  print a help string, if present   */
-	    
-	    if (optn->help_string)
-		    box_output (len, OPT_FIELD_WIDTH,
-				SCREEN_WIDTH - OPT_FIELD_WIDTH,
-				optn->help_string, optn->arg_name);
+    long_found:
+    if (check_sym (optn, sym) < 0) { /*  Oops...  */
+        err_bad_opt (argv[i], 0, i);
+        return -1;
+    }
 
-	    fprintf (stderr, "\n");	/*  a last one   */
-	}
+    if (optn->flags & CLIF_EXCL) {
+        if (!exclusive_cnt) {
+            err_bad_excl (optn, 0, i);
+            return -1;
+        }
+        exclusive_cnt--;
+    }
 
-	excl = show_excl (option_list, &excl_cnt);
-	if (excl_cnt > 0) {
+    if (optn->arg_name && !opt_arg) {
+        unsigned int flags = optn->flags | parse_flags;
 
-	    if (excl_cnt == 1) {
-		if ((curr.parse_flags & CLIF_STRICT_EXCL) &&
-		    curr.option_list == option_list
-		)  fprintf (stderr, "Anyway `%s' must be specified.\n", excl);
-		else  /*  simple ordinary option, because excl_cnt == 1 ... */;
-	    } else
-	        fprintf (stderr, "Only one of these may be specified:\n"
-				 "    %s\n", excl);
-	}
+        if (++i >= argc ||
+                !(flags & CLIF_MAY_NOEQUAL)
+        ) { /*  missing opt arg   */
+            i--;
 
-	return;
-}
-		    
+            if (!(flags & CLIF_OPTARG)) {
+                err_bad_arg (optn, 0, i);
+                return -1;
+            }
+
+            opt_arg = NULL;
+        } else
+        opt_arg = argv[i];
+
+    }
+
+    if (call_function (optn, opt_arg, sym) < 0) {
+        err_bad_res (optn, 0, opt_arg, i);
+        return -1;
+    }
+
+    if (optn->flags & CLIF_EXIT)
+    exit (0);
+
+    continue;
 
-void CLIF_print_arguments (const char *header,
-				const CLIF_argument *argument_list) {
-	const CLIF_argument *argm;
+    handle_arg:
+    if (argument_list) {
+        if (i < MAX_ARGC_NUMBER) /*  XXX: ugly, better report   */
+        arg_n[num_args++] = i;
+    } else {
+        err_report ("`%s' (argc %d): arguments are not allowed",
+                argv[i], i);
+        return -1;
+    }
 
+    /*  POSIX say: No more options after args...  */
+    if (posix) option_list = NULL; /*  geniously...  */
 
-	if (!argument_list)  return;
+    continue;
 
-	/*  Print a header string, if present...  */
-	if (header)  fprintf (stderr, "%s\n", header);
+    handle_short:
 
+    opt_arg = NULL;
+
+    do {
+
+        for (optn = option_list;
+                optn->short_opt || optn->long_opt;
+                optn++
+        ) {
+            if (optn->short_opt && optn->short_opt[0] == *arg)
+            break;
+        }
+        if (!optn->short_opt ||
+                check_sym (optn, sym) < 0
+        ) {
+            err_bad_opt (argv[i], *arg, i);
+            return -1;
+        }
+
+        if (optn->flags & CLIF_EXCL) {
+            if (!exclusive_cnt) {
+                err_bad_excl (optn, *arg, i);
+                return -1;
+            }
+            exclusive_cnt--;
+        }
+
+        if (optn->arg_name) {
+            unsigned int flags = parse_flags | optn->flags;
+
+            if (arg[1] == '\0') { /*  a last one   */
+
+                /*  POSIX say: an option with arg cannot be grouped. */
+                if (posix && arg != argv[i] && arg[-1] != sym) {
+                    err_bad_arg (optn, *arg, i); /*  good way? */
+                    return -1;
+                }
+
+                if (++i >= argc ||
+                        (flags & _CLIF_STRICT_JOIN_ARG)
+                ) {
+                    i--;
+
+                    if (!(flags & CLIF_OPTARG)) {
+                        err_bad_arg (optn, *arg, i);
+                        return -1;
+                    }
+
+                    opt_arg = NULL;
+                } else
+                opt_arg = argv[i];
+            }
+            else if ((arg == argv[i] || arg[-1] == sym) &&
+                    (flags & CLIF_MAY_JOIN_ARG)
+            ) {
+                opt_arg = ++arg;
+            }
+            else { /*  inside a group...  */
+                if (!(flags & CLIF_OPTARG) ||
+                        (flags & CLIF_MAY_JOIN_ARG)
+                ) {
+                    err_bad_arg (optn, *arg, i);
+                    return -1;
+                }
+
+                opt_arg = NULL;
+            }
+        }
+
+        if (call_function (optn, opt_arg, sym) < 0) {
+            err_bad_res (optn, optn->short_opt[0], opt_arg, i);
+            return -1;
+        }
+
+        if (optn->flags & CLIF_EXIT)
+        exit (0);
+
+    }while (!opt_arg && *++arg);
+
+} /*  for ( ...  )   */
+
+if ((parse_flags & CLIF_STRICT_EXCL) && exclusive_cnt != 0) {
+    err_report ("One of these must be specified:\n    %s\n",
+            show_excl (option_list, 0));
+    return -1;
+}
 
-	for (argm = argument_list; argm->name; argm++) {
-	    int len;
+/*  Now, after *ALL* options, handle arguments, if any.  */
 
-	    if (argm->flags & CLIF_STRICT)
-		len = fprintf (stderr, ARG_MARK_STRICT "%s", argm->name);
-	    else if (argm->flags & CLIF_MORE)
-		len = fprintf (stderr, ARG_MARK_OPT "%s ...", argm->name);
-	    else if (argm->flags & CLIF_ACC_PREV)
-		len = fprintf (stderr, ARG_MARK_GROUP "%s", argm->name);
-	    else if ((argm + 1)->name && ((argm + 1)->flags & CLIF_ACC_PREV))
-		len = fprintf (stderr, ARG_MARK_GROUP0 "%s", argm->name);
-	    else
-		len = fprintf (stderr, ARG_MARK_OPT "%s", argm->name);
+if (num_args < strict_beg + strict_end) {
+    /*  Missing some needed arguments.  */
 
-	    if (argm->help_string)
-		    box_output (len, ARG_FIELD_WIDTH,
-				    SCREEN_WIDTH - ARG_FIELD_WIDTH,
-				    argm->help_string, argm->name);
+    if (num_args < strict_beg) argm = argument_list + num_args;
+    else
+    argm = argument_list +
+    ((num_args - strict_beg) + (num_argm - strict_end));
 
-	    fprintf (stderr, "\n");
-	}
+    if (num_args == strict_beg + strict_end - 1)
+    err_report ("Specify \"%s\" missing argument.", argm->name);
+    else
+    err_report ("Specify \"%s\" and other missing arguments.",
+            argm->name);
+    return -1;
+}
 
-	return;
+if (num_args > 0) {
+    _CLIF_index argm_index[MAX_ARGC_NUMBER];
+
+    /*  assing argm (by index) for each arg...  */
+
+    for (i = 0, j = 0; i < strict_beg; i++, j++)
+    argm_index[i] = j;
+    for (i = num_args - strict_end, j = num_argm - strict_end;
+            i < num_args; i++, j++
+    ) argm_index[i] = j;
+    for (i = strict_beg, j = strict_beg;
+            i < num_args - strict_end && j < num_argm - strict_end;
+            i++
+    ) {
+        argm_index[i] = j;
+        if (!(argument_list[j].flags & CLIF_MORE))
+        j++;
+    }
+
+    if (i < num_args - strict_end) { /*  there are extra args...  */
+        err_report ("Extra arg `%s' (position %d, argc %d)",
+                argv[arg_n[i]], i + 1, arg_n[i]);
+        return -1;
+    }
+
+    if (j < num_argm - strict_end &&
+            !(argument_list[j].flags & CLIF_MORE) &&
+            /*  ...i.e, there are some missing optional args...  */
+            (argument_list[j].flags & CLIF_ACC_PREV)
+    ) {
+        if (j == 0)
+        err_report ("Incorrect argument list set: first arg "
+                "cannot be `accompanied with previous'.");
+        else
+        err_report ("Arg \"%s\" must be specified because "
+                "\"%s\" `%s' is used.", argument_list[j].name,
+                argument_list[j - 1].name, argv[arg_n[i - 1]]);
+        return -1;
+    }
+
+    if (argm_index[--i] == j &&
+            /*  above is true only after OPTIONAL area scan
+             and when `j' is stopped on CLIF_MORE  */
+            ++j < num_argm - strict_end
+            /*  i.e: there is a *last* one (after CLIF_MORE)
+             in the OPTIONAL area  */
+    ) argm_index[i] = j; /*  *last* is better than *more*   */
+
+    /*  ...and work now   */
+
+    for (i = 0; i < num_args; i++) {
+        argm = argument_list + argm_index[i];
+
+        if (argm->function &&
+                argm->function (argm, argv[arg_n[i]], i) < 0
+        ) {
+            err_report ("Cannot handle \"%s\" cmdline arg `%s' "
+                    "on position %d (argc %d)",
+                    argm->name, argv[arg_n[i]], i + 1, arg_n[i]);
+            return -1;
+        }
+    }
+
+    /*  That`s all.  */
 }
 
+return 0;
+}
 
-void CLIF_print_usage (const char *header, const char *progname, 
-				const CLIF_option *option_list,
-				const CLIF_argument *argument_list) {
-
-	if (!progname && curr.argv)
-		progname = curr.argv[0];
-
-	if (!header) {
-	    if (progname)
-		fprintf (stderr, "Usage: %s", progname);
-	    else
-		fprintf (stderr, "Command line options:");
-	} else {
-	    if (progname)
-		fprintf (stderr, "%s\n" OPT_START_DLM "%s", header, progname);
-	    else
-		fprintf (stderr, "%s", header);
-	}
-
-
-	if (option_list) {
-	    const CLIF_option *optn;
-	    char m_buf[256], p_buf[256], mp_buf[256];
-	    char *m = m_buf, *p = p_buf, *mp = mp_buf;
-	    char *end_m = m_buf + sizeof (m_buf) - 1;
-	    char *end_p = p_buf + sizeof (p_buf) - 1;
-	    char *end_mp = mp_buf + sizeof (mp_buf) - 1;
-	    char *excl;
-	    int excl_cnt = 0;
-
-
-	    /*  first, show exclusive option list, if any...  */
-
-	    excl = show_excl (option_list, &excl_cnt);
-	    if (excl_cnt > 0) {
-		if ((curr.parse_flags & CLIF_STRICT_EXCL) &&
-		    curr.option_list == option_list
-		) {
-		    if (excl_cnt == 1)
-			    fprintf (stderr, " %s", excl);
-		    else
-			fprintf (stderr, " { %s }", excl);
-		} else
-		    fprintf (stderr, " [ %s ]", excl);
-	    }
-
-
-	    /*  second, find short options without arguments...  */
-
-	    for (optn = option_list;
-		    optn->short_opt || optn->long_opt;
-			optn++
-	    ) {
-		/*  We don`t exclude CLIF_EXTRA hear:
-		   simple one char don`t eat a lot of space...
-		*/
-
-		if (!optn->short_opt ||
-		    optn->arg_name ||
-		    (optn->flags & CLIF_EXCL)
-		)  continue;
-
-		if (optn->function_plus) {
-		    if (optn->function) {
-			if (mp < end_mp)  *mp++ = optn->short_opt[0];
-		    } else {
-			if (p < end_p)  *p++ = optn->short_opt[0];
-		    }
-		} else {
-		    if (m < end_m)  *m++ = optn->short_opt[0];
-		}
-	    }
-
-	    if (m > (char *) m_buf) {
-		*m = '\0';
-		fprintf (stderr, " [ -%s ]", m_buf);
-	    }
-	    if (p > (char *) p_buf) {
-		*p = '\0';
-		fprintf (stderr, " [ +%s ]", p_buf);
-	    }
-	    if (mp > (char *) mp_buf) {
-		*mp = '\0';
-		fprintf (stderr, " [ " SHORT_PLUS_MINUS "%s ]", mp_buf);
-	    }
-
-
-	    /*  third, print all another...  */
-
-	    for (optn = option_list;
-		    optn->short_opt || optn->long_opt;
-			optn++
-	    ) {
-		if (optn->flags & CLIF_EXTRA)  continue;
-
-		if (optn->flags & CLIF_EXCL)
-			continue;	/*  already handled   */
-
-		if (optn->short_opt) {
-		    if (optn->arg_name) 
-			fprintf (stderr, " [ %s ]", show_short (optn));
-		    else
-			/*  already handled   */;
-		} else
-		    fprintf (stderr, " [ %s ]", show_long (optn));
-	    }
-	}
-		        
-
-	if (argument_list) {
-	    const CLIF_argument *argm;
-	    int deep = 0;
-
-	    for (argm = argument_list; argm->name; argm++) {
-
-		if (argm->flags & CLIF_STRICT) {
-		    if (deep > 0) {
-			fputc (' ', stderr);
-			while (deep--)  fputc (']', stderr);
-			deep = 0;
-		    }
-			
-		    fprintf (stderr, " %s", argm->name);
-		} else {
-		    if (argm->flags & CLIF_MORE)
-			    fprintf (stderr, " [ %s ...", argm->name);
-		    else if (argm->flags & CLIF_ACC_PREV) {
-			    fprintf (stderr, " %s", argm->name);
-			    --deep;	/*  ugly, but easy   */
-		    } else
-			fprintf (stderr, " [ %s", argm->name);
-
-		    deep++;
-		}
-	    }
-
-	    if (deep > 0) {
-		fputc (' ', stderr);
-		while (deep--)  fputc (']', stderr);
-	    }
-	}
-
-
-	fprintf (stderr, "\n");
+static void box_output(int start, int left, int width, const char *str,
+        const char *arg_name) {
+    char *p, *endp, *s;
+    int l;
+    char buf[1024];
+    char spacer[128]; /*  assume it is enough   */
+
+    if(left > (int) sizeof(spacer) - 2)
+        left = (int) sizeof(spacer) - 2;
+    if(width > (int) sizeof(buf) - 1)
+        width = (int) sizeof(buf) - 1;
+
+    spacer[0] = '\n';
+    memset(spacer + 1, ' ', left);
+    spacer[left + 1] = '\0';
+
+    l = left - start;
+    if(l > 0) {
+        memset(buf, ' ', l);
+        buf[l] = '\0';
+        fprintf(stderr, "%s", buf);
+    } else
+        fprintf(stderr, "%s", spacer);
+
+    endp = buf + width;
+
+    p = buf;
+
+    while(*str) {
+
+        while(*str && p < endp) {
+
+            if(*str == '%' && arg_name) {
+                if(str[1] == '%') {
+                    *p++ = '%';
+                    str += 2;
+                    continue;
+                }
+                else if(str[1] == 's') {
+                    const char *a = arg_name;
+
+                    while(*a && p < endp)
+                        *p++ = *a++;
+                    str += 2;
+                    continue;
+                }
+            }
+
+            *p++ = *str++;
+        }
+
+        *p = '\0';
+
+        if(p < endp)
+            break;
+
+        while(p > buf && *p != ' ' && *p != '\t')
+            p--;
+        if(p <= buf)
+            return; /*  foo on you   */
+
+        *p = '\0';
+        fprintf(stderr, "%s", buf);
+        fprintf(stderr, "%s", spacer);
+
+        p++;
+        for(s = buf; *p; *s++ = *p++)
+            ;
+        *s = '\0';
+        p = s;
+    }
+
+    fprintf(stderr, "%s", buf);
+
+    return;
 }
 
+#define SHORT_LONG_DLM	"  "
+#define OPT_START_DLM	"  "
+#define OPT_FIELD_WIDTH	30
 
-int CLIF_current_help (void) {
+#define ARG_MARK_STRICT	"+     "
+#define ARG_MARK_GROUP0	"  .   "
+#define ARG_MARK_GROUP	"  '   "
+#define ARG_MARK_OPT	"      "
+#define ARG_FIELD_WIDTH	20
 
-	if (!curr.argc)  return -1;	/*  i.e., not inited...  */
+#define SCREEN_WIDTH	80
 
-	CLIF_print_usage ("Usage:", curr.argv[0], curr.option_list,
-							curr.argument_list);
+void CLIF_print_options(const char *header,
+        const CLIF_option *option_list) {
+    const CLIF_option *optn;
+    char *excl;
+    int excl_cnt = 0;
+
+    /*  Print a header string, if present...  */
+    if(header)
+        fprintf(stderr, "%s\n", header);
+
+    if(!option_list)
+        return;
+
+    for(optn = option_list; optn->short_opt || optn->long_opt; optn++) {
+        int len;
+
+        /*  generate and print an option usage   */
+
+        if(optn->short_opt) {
+            if(optn->long_opt)
+                len = fprintf(stderr, OPT_START_DLM "%s"
+                SHORT_LONG_DLM "%s",
+                        show_short(optn), show_long(optn));
+            else
+                len = fprintf(stderr, OPT_START_DLM "%s",
+                        show_short(optn));
+        } else
+            len = fprintf(stderr, OPT_START_DLM "%s", show_long(optn));
+
+        /*  print a help string, if present   */
+
+        if(optn->help_string)
+            box_output(len, OPT_FIELD_WIDTH,
+            SCREEN_WIDTH - OPT_FIELD_WIDTH,
+                    optn->help_string, optn->arg_name);
+
+        fprintf(stderr, "\n"); /*  a last one   */
+    }
+
+    excl = show_excl(option_list, &excl_cnt);
+    if(excl_cnt > 0) {
+
+        if(excl_cnt == 1) {
+            if((curr.parse_flags & CLIF_STRICT_EXCL) &&
+                    curr.option_list == option_list
+                            )
+                fprintf(stderr, "Anyway `%s' must be specified.\n", excl);
+            //else  /*  simple ordinary option, because excl_cnt == 1 ... */
+        } else
+            fprintf(stderr, "Only one of these may be specified:\n"
+                    "    %s\n", excl);
+    }
+
+    return;
+}
 
-	if (curr.option_list)
-		CLIF_print_options ("Options:", curr.option_list);
-	
-	if (curr.argument_list)
-		CLIF_print_arguments ("\nArguments:", curr.argument_list);
+void CLIF_print_arguments(const char *header,
+        const CLIF_argument *argument_list) {
+    const CLIF_argument *argm;
 
-	return 0;
-}
+    if(!argument_list)
+        return;
 
+    /*  Print a header string, if present...  */
+    if(header)
+        fprintf(stderr, "%s\n", header);
 
-/*  Common useful option handlers.  */
+    for(argm = argument_list; argm->name; argm++) {
+        int len;
 
-int CLIF_version_handler (CLIF_option *optn, char *arg) {
+        if(argm->flags & CLIF_STRICT)
+            len = fprintf(stderr, ARG_MARK_STRICT "%s", argm->name);
+        else if(argm->flags & CLIF_MORE)
+            len = fprintf(stderr, ARG_MARK_OPT "%s ...", argm->name);
+        else if(argm->flags & CLIF_ACC_PREV)
+            len = fprintf(stderr, ARG_MARK_GROUP "%s", argm->name);
+        else if((argm + 1)->name && ((argm + 1)->flags & CLIF_ACC_PREV))
+            len = fprintf(stderr, ARG_MARK_GROUP0 "%s", argm->name);
+        else
+            len = fprintf(stderr, ARG_MARK_OPT "%s", argm->name);
 
-	if (!optn->data)  return -1;
+        if(argm->help_string)
+            box_output(len, ARG_FIELD_WIDTH,
+            SCREEN_WIDTH - ARG_FIELD_WIDTH,
+                    argm->help_string, argm->name);
 
-	fprintf (stderr, "%s\n", ((char *) optn->data));
+        fprintf(stderr, "\n");
+    }
 
-	return 0;	/*  be happy   */
+    return;
 }
-	
 
-int CLIF_set_flag (CLIF_option *optn, char *arg) {
+void CLIF_print_usage(const char *header, const char *progname,
+        const CLIF_option *option_list,
+        const CLIF_argument *argument_list) {
+
+    if(!progname && curr.argv)
+        progname = curr.argv[0];
+
+    if(!header) {
+        if(progname)
+            fprintf(stderr, "Usage: %s", progname);
+        else
+            fprintf(stderr, "Command line options:");
+    } else {
+        if(progname)
+            fprintf(stderr, "%s\n" OPT_START_DLM "%s", header, progname);
+        else
+            fprintf(stderr, "%s", header);
+    }
+
+    if(option_list) {
+        const CLIF_option *optn;
+        char m_buf[256], p_buf[256], mp_buf[256];
+        char *m = m_buf, *p = p_buf, *mp = mp_buf;
+        char *end_m = m_buf + sizeof(m_buf) - 1;
+        char *end_p = p_buf + sizeof(p_buf) - 1;
+        char *end_mp = mp_buf + sizeof(mp_buf) - 1;
+        char *excl;
+        int excl_cnt = 0;
+
+        /*  first, show exclusive option list, if any...  */
+
+        excl = show_excl(option_list, &excl_cnt);
+        if(excl_cnt > 0) {
+            if((curr.parse_flags & CLIF_STRICT_EXCL) &&
+                    curr.option_list == option_list
+                            ) {
+                if(excl_cnt == 1)
+                    fprintf(stderr, " %s", excl);
+                else
+                    fprintf(stderr, " { %s }", excl);
+            } else
+                fprintf(stderr, " [ %s ]", excl);
+        }
+
+        /*  second, find short options without arguments...  */
+
+        for(optn = option_list;
+                optn->short_opt || optn->long_opt;
+                optn++
+                ) {
+            /*  We don`t exclude CLIF_EXTRA hear:
+             simple one char don`t eat a lot of space...
+             */
+
+            if(!optn->short_opt ||
+                    optn->arg_name ||
+                    (optn->flags & CLIF_EXCL)
+                    )
+                continue;
+
+            if(optn->function_plus) {
+                if(optn->function) {
+                    if(mp < end_mp)
+                        *mp++ = optn->short_opt[0];
+                } else {
+                    if(p < end_p)
+                        *p++ = optn->short_opt[0];
+                }
+            } else {
+                if(m < end_m)
+                    *m++ = optn->short_opt[0];
+            }
+        }
+
+        if(m > (char *) m_buf) {
+            *m = '\0';
+            fprintf(stderr, " [ -%s ]", m_buf);
+        }
+        if(p > (char *) p_buf) {
+            *p = '\0';
+            fprintf(stderr, " [ +%s ]", p_buf);
+        }
+        if(mp > (char *) mp_buf) {
+            *mp = '\0';
+            fprintf(stderr, " [ " SHORT_PLUS_MINUS "%s ]", mp_buf);
+        }
+
+        /*  third, print all another...  */
+
+        for(optn = option_list;
+                optn->short_opt || optn->long_opt;
+                optn++
+                ) {
+            if(optn->flags & CLIF_EXTRA)
+                continue;
+
+            if(optn->flags & CLIF_EXCL)
+                continue; /*  already handled   */
+
+            if(optn->short_opt) {
+                if(optn->arg_name)
+                    fprintf(stderr, " [ %s ]", show_short(optn));
+                //else
+                /*  already handled   */
+            } else
+                fprintf(stderr, " [ %s ]", show_long(optn));
+        }
+    }
+
+    if(argument_list) {
+        const CLIF_argument *argm;
+        int deep = 0;
+
+        for(argm = argument_list; argm->name; argm++) {
+
+            if(argm->flags & CLIF_STRICT) {
+                if(deep > 0) {
+                    fputc(' ', stderr);
+                    while(deep--)
+                        fputc(']', stderr);
+                    deep = 0;
+                }
+
+                fprintf(stderr, " %s", argm->name);
+            } else {
+                if(argm->flags & CLIF_MORE)
+                    fprintf(stderr, " [ %s ...", argm->name);
+                else if(argm->flags & CLIF_ACC_PREV) {
+                    fprintf(stderr, " %s", argm->name);
+                    --deep; /*  ugly, but easy   */
+                } else
+                    fprintf(stderr, " [ %s", argm->name);
+
+                deep++;
+            }
+        }
+
+        if(deep > 0) {
+            fputc(' ', stderr);
+            while(deep--)
+                fputc(']', stderr);
+        }
+    }
+
+    fprintf(stderr, "\n");
+}
 
-	if (!optn->data)  return -1;
+int CLIF_current_help(void) {
 
-	*((int *) optn->data) = 1;
+    if(!curr.argc)
+        return -1; /*  i.e., not inited...  */
 
-	return 0;
-}
+    CLIF_print_usage("Usage:", curr.argv[0], curr.option_list,
+            curr.argument_list);
 
+    if(curr.option_list)
+        CLIF_print_options("Options:", curr.option_list);
 
-int CLIF_unset_flag (CLIF_option *optn, char *arg) {
+    if(curr.argument_list)
+        CLIF_print_arguments("\nArguments:", curr.argument_list);
 
-	if (!optn->data)  return -1;
+    return 0;
+}
 
-	*((int *) optn->data) = 0;
+/*  Common useful option handlers.  */
 
-	return 0;
-}
+int CLIF_version_handler(CLIF_option *optn, char *arg) {
+    UNUSED(arg);
+    if(!optn->data)
+        return -1;
 
+    fprintf(stderr, "%s\n", ((char *) optn->data));
 
-static int set_string (char **data, char *arg) {
+    return 0; /*  be happy   */
+}
 
-	if (!data)  return -1;
+int CLIF_set_flag(CLIF_option *optn, char *arg) {
+    UNUSED(arg);
+    if(!optn->data)
+        return -1;
 
-	*data = arg;
+    *((int *) optn->data) = 1;
 
-	return 0;
+    return 0;
 }
 
-int CLIF_set_string (CLIF_option *optn, char *arg) {
+int CLIF_unset_flag(CLIF_option *optn, char *arg) {
+    UNUSED(arg);
+    if(!optn->data)
+        return -1;
+
+    *((int *) optn->data) = 0;
 
-	return  set_string (optn->data, arg);
+    return 0;
 }
 
-int CLIF_arg_string (CLIF_argument *argm, char *arg, int index) {
+static int set_string(char **data, char *arg) {
 
-	return  set_string (argm->data, arg);
-}
+    if(!data)
+        return -1;
 
+    *data = arg;
 
-static int set_int (int *data, char *arg) {
-	char *q;
+    return 0;
+}
 
-	if (!data)  return -1;
+int CLIF_set_string(CLIF_option *optn, char *arg) {
 
-	*data = (int) strtol (arg, &q, 0);
+    return set_string(optn->data, arg);
+}
 
-	return  (q == arg || *q) ? -1 : 0;
+int CLIF_arg_string(CLIF_argument *argm, char *arg, int index) {
+    UNUSED(index);
+    return set_string(argm->data, arg);
 }
 
-static int set_uint (unsigned int *data, char *arg) {
-	char *q;
+static int set_int(int *data, char *arg) {
+    char *q;
 
-	if (!data)  return -1;
+    if(!data)
+        return -1;
 
-	*data = (unsigned int) strtoul (arg, &q, 0);
+    *data = (int) strtol(arg, &q, 0);
 
-	return  (q == arg || *q) ? -1 : 0;
+    return (q == arg || *q) ? -1 : 0;
 }
 
-static int set_double (double *data, char *arg) {
-	char *q;
+static int set_uint(unsigned int *data, char *arg) {
+    char *q;
 
-	if (!data)  return -1;
+    if(!data)
+        return -1;
 
-	*data = strtod (arg, &q);
+    *data = (unsigned int) strtoul(arg, &q, 0);
 
-	return  (q == arg || *q) ? -1 : 0;
+    return (q == arg || *q) ? -1 : 0;
 }
 
+static int set_double(double *data, char *arg) {
+    char *q;
 
-int CLIF_set_int (CLIF_option *optn, char *arg) {
+    if(!data)
+        return -1;
 
-	return  set_int (optn->data, arg);
-}
+    *data = strtod(arg, &q);
 
-int CLIF_set_uint (CLIF_option *optn, char *arg) {
-
-	return  set_uint (optn->data, arg);
+    return (q == arg || *q) ? -1 : 0;
 }
 
-int CLIF_set_double (CLIF_option *optn, char *arg) {
+int CLIF_set_int(CLIF_option *optn, char *arg) {
 
-	return  set_double (optn->data, arg);
+    return set_int(optn->data, arg);
 }
 
-int CLIF_arg_int (CLIF_argument *argm, char *arg, int index) {
+int CLIF_set_uint(CLIF_option *optn, char *arg) {
 
-	return  set_int (argm->data, arg);
+    return set_uint(optn->data, arg);
 }
 
-int CLIF_arg_uint (CLIF_argument *argm, char *arg, int index) {
+int CLIF_set_double(CLIF_option *optn, char *arg) {
 
-	return  set_uint (argm->data, arg);
+    return set_double(optn->data, arg);
 }
 
-int CLIF_arg_double (CLIF_argument *argm, char *arg, int index) {
+int CLIF_arg_int(CLIF_argument *argm, char *arg, int index) {
+    UNUSED(index);
+    return set_int(argm->data, arg);
+}
 
-	return  set_double (argm->data, arg);
+int CLIF_arg_uint(CLIF_argument *argm, char *arg, int index) {
+    UNUSED(index);
+    return set_uint(argm->data, arg);
 }
 
+int CLIF_arg_double(CLIF_argument *argm, char *arg, int index) {
+    UNUSED(index);
+    return set_double(argm->data, arg);
+}
 
-int CLIF_call_func (CLIF_option *optn, char *arg) {
+int CLIF_call_func(CLIF_option *optn, char *arg) {
 
-	if (!optn->data)  return -1;
+    if(!optn->data)
+        return -1;
 
-	if (optn->arg_name) {
-	    int (*func) (char *) = optn->data;
+    if(optn->arg_name) {
+        int (*func)(char *) = optn->data;
 
-	    return  func (arg);
-	} else {
-	    int (*func) (void) = optn->data;
+        return func(arg);
+    } else {
+        int (*func)(void) = optn->data;
 
-	    return  func ();
-	}
+        return func();
+    }
 }
 
-int CLIF_arg_func (CLIF_argument *argm, char *arg, int index) {
-	int (*func) (char *, int);
+int CLIF_arg_func(CLIF_argument *argm, char *arg, int index) {
+    int (*func)(char *, int);
 
-	if (!argm->data)  return -1;
+    if(!argm->data)
+        return -1;
 
-	func = (int (*) (char *, int)) argm->data;
+    func = (int (*)(char *, int)) argm->data;
 
-	return  func (arg, index);
+    return func(arg, index);
 }
 
diff --git a/iputils/traceroute/mod-dccp.c b/iputils/traceroute/mod-dccp.c
index 077c20cef995f935df6b5b1a9613b449c40ada3d..26f2c653bf0fd3af1faeb911cd943e493edd93e9 100755
--- a/iputils/traceroute/mod-dccp.c
+++ b/iputils/traceroute/mod-dccp.c
@@ -230,6 +230,7 @@ static void dccp_send_probe (probe *pb, int ttl) {
 
 static probe *dccp_check_reply (int sk, int err, sockaddr_any *from,
 						    char *buf, size_t len) {
+    UNUSED(sk);
 	probe *pb;
 	struct dccp_hdr *ndh = (struct dccp_hdr *) buf;
 	uint16_t sport, dport;
diff --git a/iputils/traceroute/mod-icmp.c b/iputils/traceroute/mod-icmp.c
index ed13b5096e422c03edc65a3ce4825370b4f8acf2..e2194d9aa4563b22b48d66f324de9f8cedf61b00 100755
--- a/iputils/traceroute/mod-icmp.c
+++ b/iputils/traceroute/mod-icmp.c
@@ -1,10 +1,10 @@
 /*
-    Copyright (c)  2006, 2007		Dmitry Butskoy
-					<buc@citadel.stu.neva.ru>
-    License:  GPL v2 or any later
+ Copyright (c)  2006, 2007		Dmitry Butskoy
+ <buc@citadel.stu.neva.ru>
+ License:  GPL v2 or any later
 
-    See COPYING for the status of this software.
-*/
+ See COPYING for the status of this software.
+ */
 
 #include <stdlib.h>
 #include <unistd.h>
@@ -18,8 +18,7 @@
 
 #include "traceroute.h"
 
-
-static sockaddr_any dest_addr = {{ 0, }, };
+static sockaddr_any dest_addr = { { 0, }, };
 static uint16_t seq = 1;
 static uint16_t ident = 0;
 
@@ -32,219 +31,207 @@ static int last_ttl = 0;
 static int raw = 0;
 static int dgram = 0;
 
-
 static CLIF_option icmp_options[] = {
-        { 0, "raw", 0, "Use raw sockets way only. Default is try this way "
-			"first (probably not allowed for unprivileged users), "
-			"then try dgram",
-				CLIF_set_flag, &raw, 0, CLIF_EXCL },
-        { 0, "dgram", 0, "Use dgram sockets way only. May be not implemented "
-			"by old kernels or restricted by sysadmins",
-				CLIF_set_flag, &dgram, 0, CLIF_EXCL },
-        CLIF_END_OPTION
-};
-
-
-static int icmp_init (const sockaddr_any *dest,
-			    unsigned int port_seq, size_t *packet_len_p) {
-	int i;
-	int af = dest->sa.sa_family;
-	int protocol;
-
-	dest_addr = *dest;
-	dest_addr.sin.sin_port = 0;
-
-	if (port_seq)  seq = port_seq;
-
-	length_p = packet_len_p;
-	if (*length_p < sizeof (struct icmphdr))
-		*length_p = sizeof (struct icmphdr);
-
-	data = malloc (*length_p);
-	if (!data)  error ("malloc");
-
-        for (i = sizeof (struct icmphdr); i < *length_p; i++)
-                data[i] = 0x40 + (i & 0x3f);
-
-
-	protocol = (af == AF_INET) ? IPPROTO_ICMP : IPPROTO_ICMPV6;
-
-	if (!raw) {
-	    icmp_sk = socket (af, SOCK_DGRAM, protocol);
-	    if (icmp_sk < 0 && dgram)
-		    error ("socket");
-	}
-
-	if (!dgram) {
-	    int raw_sk = socket (af, SOCK_RAW, protocol);
-	    if (raw_sk < 0) {
-		if (raw || icmp_sk < 0)
-			error_or_perm ("socket");
-		dgram = 1;
-	    } else {
-		/*  prefer the traditional "raw" way when possible   */
-		close (icmp_sk);
-		icmp_sk = raw_sk;
-	    }
-	}
-
-
-	tune_socket (icmp_sk);
-
-	/*  Don't want to catch packets from another hosts   */
-	if (raw_can_connect () &&
-	    connect (icmp_sk, &dest_addr.sa, sizeof (dest_addr)) < 0
-	)  error ("connect");
-
-	use_recverr (icmp_sk);
-
-
-	if (dgram) {
-	    sockaddr_any addr;
-	    socklen_t len = sizeof (addr);
-
-	    if (getsockname (icmp_sk, &addr.sa, &len) < 0)
-		    error ("getsockname");
-	    ident = ntohs (addr.sin.sin_port);	/*  both IPv4 and IPv6   */
-
-	} else
-	    ident = getpid () & 0xffff;
-
-
-	add_poll (icmp_sk, POLLIN | POLLERR);
- 
-	return 0;
+    { 0, "raw", 0, "Use raw sockets way only. Default is try this way "
+            "first (probably not allowed for unprivileged users), "
+            "then try dgram",
+        CLIF_set_flag, &raw, 0, CLIF_EXCL },
+    { 0, "dgram", 0, "Use dgram sockets way only. May be not implemented "
+            "by old kernels or restricted by sysadmins",
+        CLIF_set_flag, &dgram, 0, CLIF_EXCL },
+    CLIF_END_OPTION
+    };
+
+static int icmp_init(const sockaddr_any *dest,
+        unsigned int port_seq, size_t *packet_len_p) {
+    int i;
+    int af = dest->sa.sa_family;
+    int protocol;
+
+    dest_addr = *dest;
+    dest_addr.sin.sin_port = 0;
+
+    if(port_seq)
+        seq = port_seq;
+
+    length_p = packet_len_p;
+    if(*length_p < sizeof(struct icmphdr))
+        *length_p = sizeof(struct icmphdr);
+
+    data = malloc(*length_p);
+    if(!data)
+        error("malloc");
+
+    for(i = (int) sizeof(struct icmphdr); i < (int)*length_p; i++)
+        data[i] = 0x40 + (i & 0x3f);
+
+    protocol = (af == AF_INET) ? IPPROTO_ICMP : IPPROTO_ICMPV6;
+
+    if(!raw) {
+        icmp_sk = socket(af, SOCK_DGRAM, protocol);
+        if(icmp_sk < 0 && dgram)
+            error("socket");
+    }
+
+    if(!dgram) {
+        int raw_sk = socket(af, SOCK_RAW, protocol);
+        if(raw_sk < 0) {
+            if(raw || icmp_sk < 0)
+                error_or_perm("socket");
+            dgram = 1;
+        } else {
+            /*  prefer the traditional "raw" way when possible   */
+            close(icmp_sk);
+            icmp_sk = raw_sk;
+        }
+    }
+
+    tune_socket(icmp_sk);
+
+    /*  Don't want to catch packets from another hosts   */
+    if(raw_can_connect() &&
+            connect(icmp_sk, &dest_addr.sa, sizeof(dest_addr)) < 0
+                    )
+        error("connect");
+
+    use_recverr(icmp_sk);
+
+    if(dgram) {
+        sockaddr_any addr;
+        socklen_t len = sizeof(addr);
+
+        if(getsockname(icmp_sk, &addr.sa, &len) < 0)
+            error("getsockname");
+        ident = ntohs(addr.sin.sin_port); /*  both IPv4 and IPv6   */
+
+    } else
+        ident = getpid() & 0xffff;
+
+    add_poll(icmp_sk, POLLIN | POLLERR);
+
+    return 0;
 }
 
+static void icmp_send_probe(probe *pb, int ttl) {
+    int af = dest_addr.sa.sa_family;
 
-static void icmp_send_probe (probe *pb, int ttl) {
-	int af = dest_addr.sa.sa_family;
-
-
-	if (ttl != last_ttl) {
-
-	    set_ttl (icmp_sk, ttl);
-
-	    last_ttl = ttl;
-	}
+    if(ttl != last_ttl) {
 
+        set_ttl(icmp_sk, ttl);
 
-	if (af == AF_INET) {
-	    struct icmp *icmp = (struct icmp *) data;
+        last_ttl = ttl;
+    }
 
-	    icmp->icmp_type = ICMP_ECHO;
-	    icmp->icmp_code = 0;
-	    icmp->icmp_cksum = 0;
-	    icmp->icmp_id = htons (ident);
-	    icmp->icmp_seq = htons (seq);
+    if(af == AF_INET) {
+        struct icmp *icmp = (struct icmp *) data;
 
-	    icmp->icmp_cksum = in_csum (data, *length_p);
-	}
-	else if (af == AF_INET6) {
-	    struct icmp6_hdr *icmp6 = (struct icmp6_hdr *) data;
+        icmp->icmp_type = ICMP_ECHO;
+        icmp->icmp_code = 0;
+        icmp->icmp_cksum = 0;
+        icmp->icmp_id = htons(ident);
+        icmp->icmp_seq = htons(seq);
 
-	    icmp6->icmp6_type = ICMP6_ECHO_REQUEST;
-	    icmp6->icmp6_code = 0;
-	    icmp6->icmp6_cksum = 0;
-	    icmp6->icmp6_id = htons (ident);
-	    icmp6->icmp6_seq = htons(seq);
+        icmp->icmp_cksum = in_csum(data, *length_p);
+    }
+    else if(af == AF_INET6) {
+        struct icmp6_hdr *icmp6 = (struct icmp6_hdr *) data;
 
-	    /*  icmp6->icmp6_cksum always computed by kernel internally   */
-	}
+        icmp6->icmp6_type = ICMP6_ECHO_REQUEST;
+        icmp6->icmp6_code = 0;
+        icmp6->icmp6_cksum = 0;
+        icmp6->icmp6_id= htons (ident);
+        icmp6->icmp6_seq= htons(seq);
 
+        /*  icmp6->icmp6_cksum always computed by kernel internally   */
+    }
 
-	pb->send_time = get_time ();
+    pb->send_time = get_time();
 
-	if (do_send (icmp_sk, data, *length_p, &dest_addr) < 0) {
-	    pb->send_time = 0;
-	    return;
-	}
+    if(do_send(icmp_sk, data, *length_p, &dest_addr) < 0) {
+        pb->send_time = 0;
+        return;
+    }
 
+    pb->seq = seq;
 
-	pb->seq = seq;
+    seq++;
 
-	seq++;
-
-	return;
+    return;
 }
 
+static probe *icmp_check_reply(int sk, int err, sockaddr_any *from,
+        char *buf, size_t len) {
+    UNUSED(sk);
+    UNUSED(from);
+    int af = dest_addr.sa.sa_family;
+    int type;
+    uint16_t recv_id, recv_seq;
+    probe *pb;
 
-static probe *icmp_check_reply (int sk, int err, sockaddr_any *from,
-						    char *buf, size_t len) {
-	int af = dest_addr.sa.sa_family;
-	int type;
-	uint16_t recv_id, recv_seq;
-	probe *pb;
-
-
-	if (len < sizeof (struct icmphdr))
-		return NULL;
-
-
-	if (af == AF_INET) {
-	    struct icmp *icmp = (struct icmp *) buf;
+    if(len < sizeof(struct icmphdr))
+        return NULL;
 
-	    type = icmp->icmp_type;
+    if(af == AF_INET) {
+        struct icmp *icmp = (struct icmp *) buf;
 
-	    recv_id = ntohs (icmp->icmp_id);
-	    recv_seq = ntohs (icmp->icmp_seq);
+        type = icmp->icmp_type;
 
-	}
-	else {	    /*  AF_INET6   */
-	    struct icmp6_hdr *icmp6 = (struct icmp6_hdr *) buf;
+        recv_id = ntohs(icmp->icmp_id);
+        recv_seq = ntohs(icmp->icmp_seq);
 
-	    type = icmp6->icmp6_type;
+    }
+    else { /*  AF_INET6   */
+        struct icmp6_hdr *icmp6 = (struct icmp6_hdr *) buf;
 
-	    recv_id = ntohs (icmp6->icmp6_id);
-	    recv_seq = ntohs (icmp6->icmp6_seq);
-	}
+        type = icmp6->icmp6_type;
 
+        recv_id = ntohs(icmp6->icmp6_id);
+        recv_seq = ntohs(icmp6->icmp6_seq);
+    }
 
-	if (recv_id != ident)
-		return NULL;
+    if(recv_id != ident)
+        return NULL;
 
-	pb = probe_by_seq (recv_seq);
-	if (!pb)  return NULL;
+    pb = probe_by_seq(recv_seq);
+    if(!pb)
+        return NULL;
 
+    if(!err) {
 
-	if (!err) {
+        if(!(af == AF_INET && type == ICMP_ECHOREPLY) &&
+                !(af == AF_INET6 && type == ICMP6_ECHO_REPLY)
+                )
+            return NULL;
 
-	    if (!(af == AF_INET && type == ICMP_ECHOREPLY) &&
-		!(af == AF_INET6 && type == ICMP6_ECHO_REPLY)
-	    )  return NULL;
+        pb->final = 1;
+    }
 
-	    pb->final = 1;
-	}
-
-	return pb;
+    return pb;
 }
 
+static void icmp_recv_probe(int sk, int revents) {
 
-static void icmp_recv_probe (int sk, int revents) {
-
-	if (!(revents & (POLLIN | POLLERR)))
-		return;
+    if(!(revents & (POLLIN | POLLERR)))
+        return;
 
-	recv_reply (sk, !!(revents & POLLERR), icmp_check_reply);
+    recv_reply(sk, !!(revents & POLLERR), icmp_check_reply);
 }
 
+static void icmp_expire_probe(probe *pb) {
 
-static void icmp_expire_probe (probe *pb) {
-
-	probe_done (pb);
+    probe_done(pb);
 }
 
-
 static tr_module icmp_ops = {
-	.name = "icmp",
-	.init = icmp_init,
-	.send_probe = icmp_send_probe,
-	.recv_probe = icmp_recv_probe,
-	.expire_probe = icmp_expire_probe,
-	.options = icmp_options,
+    .name = "icmp",
+    .init = icmp_init,
+    .send_probe = icmp_send_probe,
+    .recv_probe = icmp_recv_probe,
+    .expire_probe = icmp_expire_probe,
+    .options = icmp_options,
 };
 
-TR_MODULE (icmp_ops);
+TR_MODULE(icmp_ops);
 
 void tr_module_icmp_insert()
 {
diff --git a/iputils/traceroute/mod-raw.c b/iputils/traceroute/mod-raw.c
index 6a05516ce288db54098e3a49761268bcef4ab8ec..bd9f05ba612569e5fbfdb1a3aec01990a55dd8a0 100755
--- a/iputils/traceroute/mod-raw.c
+++ b/iputils/traceroute/mod-raw.c
@@ -32,7 +32,8 @@ static int seq = 0;
 
 
 static int set_protocol (CLIF_option *optn, char *arg) {
-	char *q;
+    UNUSED(optn);
+    char *q;
 
 	protocol = strtoul (arg, &q, 0);
 	if (q == arg) {
@@ -71,7 +72,7 @@ static int raw_init (const sockaddr_any *dest,
 	    !(data = malloc (*length_p))
 	)  error ("malloc");
 
-        for (i = 0; i < *length_p; i++)
+        for (i = 0; i < (int)*length_p; i++)
                 data[i] = 0x40 + (i & 0x3f);
 
 
@@ -121,7 +122,10 @@ static void raw_send_probe (probe *pb, int ttl) {
 
 static probe *raw_check_reply (int sk, int err, sockaddr_any *from,
 						    char *buf, size_t len) {
-	probe *pb;
+    UNUSED(sk);
+    UNUSED(len);
+    UNUSED(buf);
+    probe *pb;
 
 	if (!equal_addr (&dest_addr, from))
 		return NULL;
diff --git a/iputils/traceroute/mod-tcp.c b/iputils/traceroute/mod-tcp.c
index b5b0ca2d520cd41c0a8a9b81fd1ce2ea644bfb9f..32d2f1027e88db3ff623150cfcca5b7aad7ccf8d 100755
--- a/iputils/traceroute/mod-tcp.c
+++ b/iputils/traceroute/mod-tcp.c
@@ -81,7 +81,7 @@ static char *names_by_flags (unsigned int flags) {
 	char *curr = str;
 	char *end = str + sizeof (str) / sizeof (*str);
 
-	for (i = 0; i < sizeof (tcp_flags) / sizeof (*tcp_flags); i++) {
+	for (i = 0; i < (int)(sizeof (tcp_flags) / sizeof (*tcp_flags)); i++) {
 	    const char *p;
 
 	    if (!(flags & tcp_flags[i].flag))  continue;
@@ -96,9 +96,10 @@ static char *names_by_flags (unsigned int flags) {
 }
 
 static int set_tcp_flag (CLIF_option *optn, char *arg) {
-	int i;
+    UNUSED(arg);
+    int i;
 
-	for (i = 0; i < sizeof (tcp_flags) / sizeof (*tcp_flags); i++) {
+	for (i = 0; i < (int)(sizeof (tcp_flags) / sizeof (*tcp_flags)); i++) {
 	    if (!strcmp (optn->long_opt, tcp_flags[i].name)) {
 		    flags |= tcp_flags[i].flag;
 		    return 0;
@@ -109,7 +110,8 @@ static int set_tcp_flag (CLIF_option *optn, char *arg) {
 }
 
 static int set_tcp_flags (CLIF_option *optn, char *arg) {
-	char *q;
+    UNUSED(optn);
+    char *q;
 	unsigned long value;
 
 	value = strtoul (arg, &q, 0);
@@ -120,7 +122,7 @@ static int set_tcp_flags (CLIF_option *optn, char *arg) {
 }
 
 static int set_flag (CLIF_option *optn, char *arg) {
-
+    UNUSED(arg);
 	flags |= (unsigned long) optn->data;
 
 	return 0;
@@ -318,7 +320,7 @@ static int tcp_init (const sockaddr_any *dest,
 	if (flags & TH_SYN) {
 	    *ptr++ = TCPOPT_MAXSEG;	/*  2   */
 	    *ptr++ = TCPOLEN_MAXSEG;	/*  4   */
-	    *((uint16_t *) ptr) = htons (mss ? mss : mtu);
+	    *((uint16_t *) ptr) = htons (mss ? mss : (unsigned int)mtu);
 	    ptr += sizeof (uint16_t);
 	}
 
@@ -441,6 +443,7 @@ static void tcp_send_probe (probe *pb, int ttl) {
 
 static probe *tcp_check_reply (int sk, int err, sockaddr_any *from,
 						    char *buf, size_t len) {
+    UNUSED(sk);
 	probe *pb;
 	struct tcphdr *tcp = (struct tcphdr *) buf;
 	uint16_t sport, dport;
diff --git a/iputils/traceroute/mod-tcpconn.c b/iputils/traceroute/mod-tcpconn.c
index df37bb556b80d1a78f5f10e19aae056a334289d9..13e239864756de3639330189389933df570e8bf6 100755
--- a/iputils/traceroute/mod-tcpconn.c
+++ b/iputils/traceroute/mod-tcpconn.c
@@ -28,6 +28,7 @@ static int icmp_sk = -1;
 
 static int tcp_init (const sockaddr_any *dest,
 			    unsigned int port_seq, size_t *packet_len_p) {
+    UNUSED(packet_len_p);
 	int af = dest->sa.sa_family;
 
 	dest_addr = *dest;
@@ -94,6 +95,9 @@ static void tcp_send_probe (probe *pb, int ttl) {
 
 static probe *tcp_check_reply (int sk, int err, sockaddr_any *from,
 						    char *buf, size_t len) {
+    UNUSED(sk);
+    UNUSED(err);
+    UNUSED(from);
 	int af = dest_addr.sa.sa_family;
 	int type, code, info;
 	probe *pb;
diff --git a/iputils/traceroute/mod-udp.c b/iputils/traceroute/mod-udp.c
index b2d319d7f8fe791baba3741fad056ee9a73939a6..e24d0271c8c6e60f40592f0be18e3e7c7b482379 100755
--- a/iputils/traceroute/mod-udp.c
+++ b/iputils/traceroute/mod-udp.c
@@ -44,7 +44,7 @@ static void fill_data (size_t *packet_len_p) {
 	    !(data = malloc (*length_p))
 	)  error ("malloc");
 
-        for (i = 0; i < *length_p; i++)
+        for (i = 0; i < (int)*length_p; i++)
                 data[i] = 0x40 + (i & 0x3f);
  
 	return;
@@ -166,7 +166,9 @@ static void udp_send_probe (probe *pb, int ttl) {
 
 static probe *udp_check_reply (int sk, int err, sockaddr_any *from,
 						    char *buf, size_t len) {
-	probe *pb;
+	UNUSED(buf);
+	UNUSED(len);
+    probe *pb;
 
 	pb = probe_by_sk (sk);
 	if (!pb)  return NULL;
diff --git a/iputils/traceroute/poll.c b/iputils/traceroute/poll.c
index 988c456030091f09c3d713dee5994bd04d6e10ef..232a83395bc600ab54bddb1d8ea7c98e3ceb8526 100755
--- a/iputils/traceroute/poll.c
+++ b/iputils/traceroute/poll.c
@@ -22,9 +22,9 @@ static unsigned int num_polls = 0;
 void add_poll (int fd, int events) {
 	int i;
 
-	for (i = 0; i < num_polls && pfd[i].fd > 0; i++) ;
+	for (i = 0; i < (int)num_polls && pfd[i].fd > 0; i++) ;
 
-	if (i == num_polls) {
+	if (i == (int)num_polls) {
 	    pfd = realloc (pfd, ++num_polls * sizeof (*pfd));
 	    if (!pfd)  error ("realloc");
 	}
@@ -37,21 +37,21 @@ void add_poll (int fd, int events) {
 void del_poll (int fd) {
 	int i;
 
-	for (i = 0; i < num_polls && pfd[i].fd != fd; i++) ;
+	for (i = 0; i < (int)num_polls && pfd[i].fd != fd; i++) ;
 
-	if (i < num_polls)  pfd[i].fd = -1;    /*  or just zero it...  */
+	if (i < (int)num_polls)  pfd[i].fd = -1;    /*  or just zero it...  */
 }
 
 
 static int cleanup_polls (void) {
 	int i;
 
-	for (i = 0; i < num_polls && pfd[i].fd > 0; i++) ;
+	for (i = 0; i < (int)num_polls && pfd[i].fd > 0; i++) ;
 
-	if (i < num_polls) {	/*  a hole have found   */
+	if (i < (int)num_polls) {	/*  a hole have found   */
 	    int j;
 
-	    for (j = i + 1; j < num_polls; j++) {
+	    for (j = i + 1; j < (int)num_polls; j++) {
 		if (pfd[j].fd > 0) {
 		    pfd[i++] = pfd[j];
 		    pfd[j].fd = -1;
@@ -78,7 +78,7 @@ void do_poll (double timeout, void (*callback) (int fd, int revents)) {
 		error ("poll");
 	    }
 
-	    for (i = 0; n && i < num_polls; i++) {
+	    for (i = 0; n && i < (int)num_polls; i++) {
 		if (pfd[i].revents) {
 		    callback (pfd[i].fd, pfd[i].revents);
 		    n--;
diff --git a/iputils/traceroute/traceroute.c b/iputils/traceroute/traceroute.c
index b0e92bc0eb9c3b13db9a4d055f336b2352d31474..0142e70948b7c7ffb9645ed39decf915ee7346ae 100755
--- a/iputils/traceroute/traceroute.c
+++ b/iputils/traceroute/traceroute.c
@@ -32,9 +32,7 @@
 #include <stdbool.h>
 #include <glib.h>
 #include "traceroute.h"
-#include "../iputils.h"
 
-#define UNUSED(x) (void)(x)
 
 #ifndef ICMP6_DST_UNREACH_BEYONDSCOPE
 #ifdef ICMP6_DST_UNREACH_NOTNEIGHBOR
@@ -753,8 +751,7 @@ static bool print_addr(sockaddr_any *res) {
 
     if(noresolve) {
         log_printf("%s", str);
-        //ret_str = g_strdup_printf("%s", str);
-        if(!strcmp(dst_name, str))
+        if(str && !strcmp(dst_name, str))
             is_final = true;
     }
     else {
@@ -764,9 +761,11 @@ static bool print_addr(sockaddr_any *res) {
         getnameinfo(&res->sa, sizeof(*res), buf, sizeof(buf),
                 0, 0, NI_IDN);
         log_printf(" %s (%s)", buf[0] ? buf : str, str);
-        //ret_str = g_strdup_printf("%s", buf[0] ? buf : str);
         if(buf[0] && !strcmp(dst_name, buf))
             is_final = true;
+        else
+        if(str && !strcmp(dst_name, str))
+            is_final = true;
     }
 
     if(as_lookups)
@@ -1070,12 +1069,24 @@ static void do_it(void) {
             if(pb->done) {
 
                 if(n == start) { /*  can print it now   */
-                    if(print_probe(pb))
+                    if(print_probe(pb)) {
                         pb->final = 1;
+                    }
                     //log_printf("(host=%s,%s recv_ttl=%d)", dst_name, (host) ? host : "-", pb->recv_ttl);
                     start++;
                 }
 
+                /*                {
+                 char buf[1024];
+                 buf[0] = '\0';
+                 getnameinfo(&(pb->res.sa), sizeof((pb->res)), buf, sizeof(buf),0, 0, NI_IDN);
+                 if(buf[0] && !strcmp(dst_name, buf))
+                 pb->real_final = true;
+                 //else
+                 //if(str && !strcmp(dst_name, str))
+                 //  pb->real_final = true;
+                 }*/
+
                 if(pb->final)
                     end = (n / probes_per_hop + 1) * probes_per_hop;
 
@@ -1694,22 +1705,30 @@ int raw_can_connect(void) {
     return can_connect;
 }
 
+/**
+ * Traceroute host
+ *
+ * @addr[in] host name or IP address
+ * @hops[out] hops count
+ * @time_usec[out] latency in microseconds
+ * @return 0 Ok, -1 error
+ */
 int traceroute_util(const char *addr, int *hops, int *time_usec)
 {
     UNUSED(hops);
-    int type = 6; // 4 or 6
-    //int total_hops = 0;
-    long int total_time_usec = 0; // latency in microseconds
+    int type = 6; // ipv4 or ipv6
     int argc = 3;
     const char *argv[argc];
     if(type != 4)
         argv[0] = "traceroute6";
     else
         argv[0] = "traceroute4";
-    //argv[1] = "-A";
-    argv[1] = "-4"; // -n -m 16
+    argv[1] = "-4"; // ipv4
     argv[2] = addr;
 
+    *hops = 0;
+    *time_usec = 0;
+
     int ret = traceroute_main(argc, (char**) argv);
     if(!ret)
         for(int i = 0; i < (int) num_probes; i++) {
@@ -1717,13 +1736,17 @@ int traceroute_util(const char *addr, int *hops, int *time_usec)
             if(one_probe->done && one_probe->final && one_probe->recv_ttl) {
                 *hops = i / DEF_NUM_PROBES + 1;
                 *time_usec = (int) ((one_probe->recv_time - one_probe->send_time) * 1000000);
-                ret = 1;
+                // if error -> not found host
+                if(!strlen(one_probe->err_str))
+                    ret = 1;
                 break;
             }
             /*if(one_probe->done)
-             printf("%d(%d) dseq=%d sk=%d done=%d final=%d recv_ttl=%d dt=%lf\n", i + 1, i / DEF_NUM_PROBES + 1,
+             printf("%d(%d) dseq=%d sk=%d done=%d final=%d recv_ttl=%d dt=%lf err='%s'\n", i + 1,
+             i / DEF_NUM_PROBES + 1,
              one_probe->seq, one_probe->sk, one_probe->done,
-             one_probe->final, one_probe->recv_ttl, one_probe->recv_time - one_probe->send_time);*/
+             one_probe->final, one_probe->recv_ttl, one_probe->recv_time - one_probe->send_time,
+             one_probe->err_str);*/
         }
     free(probes);
 
diff --git a/iputils/traceroute/traceroute.h b/iputils/traceroute/traceroute.h
index 53dc7933554534c857947bf694a7f83823c2236e..532b7b6f0912d67fb71e2bcac901d7f9da99bb37 100755
--- a/iputils/traceroute/traceroute.h
+++ b/iputils/traceroute/traceroute.h
@@ -9,7 +9,7 @@
 #include <netinet/in.h>
 
 #include <clif.h>
-
+#include "../iputils.h"
 
 union common_sockaddr {
 	struct sockaddr sa;
diff --git a/iputils/traceroute6.c b/iputils/traceroute6.c
deleted file mode 100755
index ffe1d8dfb67be708613cb535eb1a74905f6baa82..0000000000000000000000000000000000000000
--- a/iputils/traceroute6.c
+++ /dev/null
@@ -1,981 +0,0 @@
-/*
- *      Modified for NRL 4.4BSD IPv6 release.
- *      07/31/96 bgp
- *
- *      Search for "#ifdef NRL" to find the changes.
- */
-
-/*
- *	Modified for Linux IPv6 by Pedro Roque <roque@di.fc.ul.pt>
- *	31/07/1996
- *
- *	As ICMP error messages for IPv6 now include more than 8 bytes
- *	UDP datagrams are now sent via an UDP socket instead of magic
- *	RAW socket tricks.
- *
- *	Original copyright and comments left intact. They might not
- *	match the code anymore.
- */
-
-/*-
- * Copyright (c) 1990, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Van Jacobson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-/*
- * traceroute host  - trace the route ip packets follow going to "host".
- *
- * Attempt to trace the route an ip packet would follow to some
- * internet host.  We find out intermediate hops by launching probe
- * packets with a small ttl (time to live) then listening for an
- * icmp "time exceeded" reply from a gateway.  We start our probes
- * with a ttl of one and increase by one until we get an icmp "port
- * unreachable" (which means we got to "host") or hit a max (which
- * defaults to 30 hops & can be changed with the -m flag).  Three
- * probes (change with -q flag) are sent at each ttl setting and a
- * line is printed showing the ttl, address of the gateway and
- * round trip time of each probe.  If the probe answers come from
- * different gateways, the address of each responding system will
- * be printed.  If there is no response within a 5 sec. timeout
- * interval (changed with the -w flag), a "*" is printed for that
- * probe.
- *
- * Probe packets are UDP format.  We don't want the destination
- * host to process them so the destination port is set to an
- * unlikely value (if some clod on the destination is using that
- * value, it can be changed with the -p flag).
- *
- * A sample use might be:
- *
- *     [yak 71]% traceroute nis.nsf.net.
- *     traceroute to nis.nsf.net (35.1.1.48), 30 hops max, 56 byte packet
- *      1  helios.ee.lbl.gov (128.3.112.1)  19 ms  19 ms  0 ms
- *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
- *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
- *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  39 ms
- *      5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  39 ms  39 ms  39 ms
- *      6  128.32.197.4 (128.32.197.4)  40 ms  59 ms  59 ms
- *      7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  59 ms
- *      8  129.140.70.13 (129.140.70.13)  99 ms  99 ms  80 ms
- *      9  129.140.71.6 (129.140.71.6)  139 ms  239 ms  319 ms
- *     10  129.140.81.7 (129.140.81.7)  220 ms  199 ms  199 ms
- *     11  nic.merit.edu (35.1.1.48)  239 ms  239 ms  239 ms
- *
- * Note that lines 2 & 3 are the same.  This is due to a buggy
- * kernel on the 2nd hop system -- lbl-csam.arpa -- that forwards
- * packets with a zero ttl.
- *
- * A more interesting example is:
- *
- *     [yak 72]% traceroute allspice.lcs.mit.edu.
- *     traceroute to allspice.lcs.mit.edu (18.26.0.115), 30 hops max
- *      1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
- *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  19 ms  19 ms
- *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  19 ms
- *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  19 ms  39 ms  39 ms
- *      5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  20 ms  39 ms  39 ms
- *      6  128.32.197.4 (128.32.197.4)  59 ms  119 ms  39 ms
- *      7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  39 ms
- *      8  129.140.70.13 (129.140.70.13)  80 ms  79 ms  99 ms
- *      9  129.140.71.6 (129.140.71.6)  139 ms  139 ms  159 ms
- *     10  129.140.81.7 (129.140.81.7)  199 ms  180 ms  300 ms
- *     11  129.140.72.17 (129.140.72.17)  300 ms  239 ms  239 ms
- *     12  * * *
- *     13  128.121.54.72 (128.121.54.72)  259 ms  499 ms  279 ms
- *     14  * * *
- *     15  * * *
- *     16  * * *
- *     17  * * *
- *     18  ALLSPICE.LCS.MIT.EDU (18.26.0.115)  339 ms  279 ms  279 ms
- *
- * (I start to see why I'm having so much trouble with mail to
- * MIT.)  Note that the gateways 12, 14, 15, 16 & 17 hops away
- * either don't send ICMP "time exceeded" messages or send them
- * with a ttl too small to reach us.  14 - 17 are running the
- * MIT C Gateway code that doesn't send "time exceeded"s.  God
- * only knows what's going on with 12.
- *
- * The silent gateway 12 in the above may be the result of a bug in
- * the 4.[23]BSD network code (and its derivatives):  4.x (x <= 3)
- * sends an unreachable message using whatever ttl remains in the
- * original datagram.  Since, for gateways, the remaining ttl is
- * zero, the icmp "time exceeded" is guaranteed to not make it back
- * to us.  The behavior of this bug is slightly more interesting
- * when it appears on the destination system:
- *
- *      1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
- *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  39 ms
- *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  39 ms  19 ms
- *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  19 ms
- *      5  ccn-nerif35.Berkeley.EDU (128.32.168.35)  39 ms  39 ms  39 ms
- *      6  csgw.Berkeley.EDU (128.32.133.254)  39 ms  59 ms  39 ms
- *      7  * * *
- *      8  * * *
- *      9  * * *
- *     10  * * *
- *     11  * * *
- *     12  * * *
- *     13  rip.Berkeley.EDU (128.32.131.22)  59 ms !  39 ms !  39 ms !
- *
- * Notice that there are 12 "gateways" (13 is the final
- * destination) and exactly the last half of them are "missing".
- * What's really happening is that rip (a Sun-3 running Sun OS3.5)
- * is using the ttl from our arriving datagram as the ttl in its
- * icmp reply.  So, the reply will time out on the return path
- * (with no notice sent to anyone since icmp's aren't sent for
- * icmp's) until we probe with a ttl that's at least twice the path
- * length.  I.e., rip is really only 7 hops away.  A reply that
- * returns with a ttl of 1 is a clue this problem exists.
- * Traceroute prints a "!" after the time if the ttl is <= 1.
- * Since vendors ship a lot of obsolete (DEC's Ultrix, Sun 3.x) or
- * non-standard (HPUX) software, expect to see this problem
- * frequently and/or take care picking the target host of your
- * probes.
- *
- * Other possible annotations after the time are !H, !N, !P (got a host,
- * network or protocol unreachable, respectively), !S or !F (source
- * route failed or fragmentation needed -- neither of these should
- * ever occur and the associated gateway is busted if you see one),
- * !X (communication administratively prohibited). If
- * almost all the probes result in some kind of unreachable, traceroute
- * will give up and exit.
- *
- * Notes
- * -----
- * This program must be run by root or be setuid.  (I suggest that
- * you *don't* make it setuid -- casual use could result in a lot
- * of unnecessary traffic on our poor, congested nets.)
- *
- * This program requires a kernel mod that does not appear in any
- * system available from Berkeley:  A raw ip socket using proto
- * IPPROTO_RAW must interpret the data sent as an ip datagram (as
- * opposed to data to be wrapped in a ip datagram).  See the README
- * file that came with the source to this program for a description
- * of the mods I made to /sys/netinet/raw_ip.c.  Your mileage may
- * vary.  But, again, ANY 4.x (x < 4) BSD KERNEL WILL HAVE TO BE
- * MODIFIED TO RUN THIS PROGRAM.
- *
- * The udp port usage may appear bizarre (well, ok, it is bizarre).
- * The problem is that an icmp message only contains 8 bytes of
- * data from the original datagram.  8 bytes is the size of a udp
- * header so, if we want to associate replies with the original
- * datagram, the necessary information must be encoded into the
- * udp header (the ip id could be used but there's no way to
- * interlock with the kernel's assignment of ip id's and, anyway,
- * it would have taken a lot more kernel hacking to allow this
- * code to set the ip id).  So, to allow two or more users to
- * use traceroute simultaneously, we use this task's pid as the
- * source port (the high bit is set to move the port number out
- * of the "likely" range).  To keep track of which probe is being
- * replied to (so times and/or hop counts don't get confused by a
- * reply that was delayed in transit), we increment the destination
- * port number before each probe.
- *
- * Don't use this as a coding example.  I was trying to find a
- * routing problem and this code sort-of popped out after 48 hours
- * without sleep.  I was amazed it ever compiled, much less ran.
- *
- * I stole the idea for this program from Steve Deering.  Since
- * the first release, I've learned that had I attended the right
- * IETF working group meetings, I also could have stolen it from Guy
- * Almes or Matt Mathis.  I don't know (or care) who came up with
- * the idea first.  I envy the originators' perspicacity and I'm
- * glad they didn't keep the idea a secret.
- *
- * Tim Seaver, Ken Adelman and C. Philip Wood provided bug fixes and/or
- * enhancements to the original distribution.
- *
- * I've hacked up a round-trip-route version of this that works by
- * sending a loose-source-routed udp datagram through the destination
- * back to yourself.  Unfortunately, SO many gateways botch source
- * routing, the thing is almost worthless.  Maybe one day...
- *
- *  -- Van Jacobson (van@helios.ee.lbl.gov)
- *     Tue Dec 20 03:50:13 PST 1988
- */
-
-#include <arpa/inet.h>
-#include <errno.h>
-#include <linux/types.h>
-#include <netdb.h>
-#include <net/if.h>
-#include <netinet/icmp6.h>
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip6.h>
-#include <netinet/ip.h>
-#include <netinet/ip_icmp.h>
-#include <netinet/udp.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <time.h>
-#include <unistd.h>
-#include <glib.h>
-
-#include "iputils.h"
-
-#if __linux__
-# include <endian.h>
-#endif
-
-#ifdef HAVE_LIBCAP
-# include <sys/capability.h>
-#endif
-
-#ifdef USE_IDN
-# include <locale.h>
-# ifndef NI_IDN
-#  define NI_IDN 32
-# endif
-# define ADDRINFO_IDN_FLAGS	AI_IDN
-# define getnameinfo_flags	NI_IDN
-#else
-# define getnameinfo_flags	0
-# define ADDRINFO_IDN_FLAGS	0
-#endif
-
-#ifndef SOL_IPV6
-# define SOL_IPV6 IPPROTO_IPV6
-#endif
-
-enum {
-	DEFAULT_PROBES = 3,
-	DEFAULT_HOPS = 30,
-	DEFAULT_PORT = 32768 + 666,
-	DEFAULT_WAIT = 5,
-	PACKET_SIZE = 512,
-	MAXPACKET = 65535,
-
-	/*
-	 * The following are copy from linux/icmpv6.h that cannot be
-	 * included because icmp6_filter prototype is redefined in
-	 * netinet/icmp6.h header.
-	 */
-	ICMPV6_DEST_UNREACH = 1,
-	ICMPV6_PKT_TOOBIG = 2,
-	ICMPV6_TIME_EXCEED = 3,
-	ICMPV6_PARAMPROB = 4,
-	ICMPV6_ECHO_REQUEST = 128,
-	ICMPV6_ECHO_REPLY = 129,
-	ICMPV6_MGM_QUERY = 130,
-	ICMPV6_MGM_REPORT = 131,
-	ICMPV6_MGM_REDUCTION = 132,
-	ICMPV6_NI_QUERY = 139,
-	ICMPV6_NI_REPLY = 140,
-	ICMPV6_MLD2_REPORT = 143,
-	ICMPV6_DHAAD_REQUEST = 144,
-	ICMPV6_DHAAD_REPLY = 145,
-	ICMPV6_MOBILE_PREFIX_SOL = 146,
-	ICMPV6_MOBILE_PREFIX_ADV = 147,
-
-	/*
-	 * ICMP codes for neighbour discovery messages.  These are from
-	 * linux kernel source include/net/ndisc.h file.  The user api
-	 * includes does not have these values.
-	 */
-	NDISC_ROUTER_SOLICITATION = 133,
-	NDISC_ROUTER_ADVERTISEMENT = 134,
-	NDISC_NEIGHBOUR_SOLICITATION = 135,
-	NDISC_NEIGHBOUR_ADVERTISEMENT = 136,
-	NDISC_REDIRECT = 137,
-};
-
-#ifndef FD_SET
-# define NFDBITS         (8 * sizeof(fd_set))
-# define FD_SETSIZE      NFDBITS
-# define FD_SET(n, p)    ((p)->fds_bits[(n) / NFDBITS] |= (1 << ((n) % NFDBITS)))
-# define FD_CLR(n, p)    ((p)->fds_bits[(n) / NFDBITS] &= ~(1 << ((n) % NFDBITS)))
-# define FD_ISSET(n, p)  ((p)->fds_bits[(n) / NFDBITS] & (1 << ((n) % NFDBITS)))
-# define FD_ZERO(p)      memset((char *)(p), 0, sizeof(*(p)))
-#endif
-
-struct run_state {
-	unsigned char packet[PACKET_SIZE];	/* last inbound (icmp) packet */
-	int icmp_sock;			/* receive (icmp) socket file descriptor */
-	int sndsock;			/* send (udp) socket file descriptor */
-	char *sendbuff;
-	int datalen;
-	struct sockaddr_in6 whereto;	/* Who to try to reach */
-	struct sockaddr_in6 saddr;
-	struct sockaddr_in6 firsthop;
-	char *source;
-	char *device;
-	char *hostname;
-	int nprobes;
-	int max_ttl;
-	pid_t ident;
-	unsigned short port;		/* start udp dest port # for probe packets */
-	int options;			/* socket options */
-	int waittime;			/* time to wait for response (in seconds) */
-	unsigned int
-		nflag:1,		/* print addresses numerically */
-		verbose:1;
-};
-
-struct pkt_format {
-	uint32_t ident;
-	uint32_t seq;
-	struct timespec ts;
-};
-
-/*
- * All includes, definitions, struct declarations, and global variables are
- * above.  After this comment all you can find is functions.
- */
-
-static int wait_for_reply(struct run_state *ctl, struct sockaddr_in6 *from,
-			  struct in6_addr *to, const uint8_t reset_timer)
-{
-	fd_set fds;
-	static struct timeval wait;
-	ssize_t cc = 0;
-	char cbuf[PACKET_SIZE];
-
-	FD_ZERO(&fds);
-	FD_SET(ctl->icmp_sock, &fds);
-	if (reset_timer) {
-		/*
-		 * traceroute could hang if someone else has a ping
-		 * running and our ICMP reply gets dropped but we don't
-		 * realize it because we keep waking up to handle those
-		 * other ICMP packets that keep coming in.  To fix this,
-		 * "reset_timer" will only be true if the last packet that
-		 * came in was for us or if this is the first time we're
-		 * waiting for a reply since sending out a probe.  Note
-		 * that this takes advantage of the select() feature on
-		 * Linux where the remaining timeout is written to the
-		 * struct timeval area.
-		 */
-		wait.tv_sec = ctl->waittime;
-		wait.tv_usec = 0;
-	}
-
-	if (select(ctl->icmp_sock + 1, &fds, NULL, NULL, &wait) > 0) {
-		struct iovec iov = {
-			.iov_base = ctl->packet,
-			.iov_len = sizeof(ctl->packet)
-		};
-		struct msghdr msg = {
-			.msg_name = (void *)from,
-			.msg_namelen = sizeof(*from),
-			.msg_iov = &iov,
-			.msg_iovlen = 1,
-			.msg_control = cbuf,
-			.msg_controllen = sizeof(cbuf),
-			0
-		};
-
-		cc = recvmsg(ctl->icmp_sock, &msg, 0);
-		if (cc >= 0) {
-			struct cmsghdr *cmsg;
-			struct in6_pktinfo *ipi;
-
-			for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
-				if (cmsg->cmsg_level != SOL_IPV6)
-					continue;
-				switch (cmsg->cmsg_type) {
-				case IPV6_PKTINFO:
-#ifdef IPV6_2292PKTINFO
-				case IPV6_2292PKTINFO:
-#endif
-					ipi = (struct in6_pktinfo *)
-					    CMSG_DATA(cmsg);
-					memcpy(to, ipi, sizeof(*to));
-				}
-			}
-		}
-	}
-
-	return (cc);
-}
-
-static void send_probe(struct run_state *ctl, uint32_t seq, int ttl)
-{
-	struct pkt_format *pkt = (struct pkt_format *)ctl->sendbuff;
-	int i;
-
-	pkt->ident = htonl(ctl->ident);
-	pkt->seq = htonl(seq);
-	clock_gettime(CLOCK_MONOTONIC_RAW, &pkt->ts);
-
-	i = setsockopt(ctl->sndsock, SOL_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
-	if (i < 0) {
-		perror("setsockopt");
-		exit(1);
-	}
-
-	do {
-		i = sendto(ctl->sndsock, ctl->sendbuff, ctl->datalen, 0,
-			   (struct sockaddr *)&ctl->whereto, sizeof(ctl->whereto));
-	} while (i < 0 && errno == ECONNREFUSED);
-
-	if (i < 0 || i != ctl->datalen) {
-		if (i < 0)
-			perror("sendto");
-		printf("traceroute: wrote %s %d chars, ret=%d\n", ctl->hostname, ctl->datalen, i);
-		fflush(stdout);
-	}
-}
-
-static double deltaT(struct timespec *a, struct timespec *b)
-{
-	struct timespec c;
-	double dt;
-
-	if ((b->tv_nsec - a->tv_nsec) < 0) {
-		c.tv_sec = b->tv_sec - a->tv_sec - 1UL;
-		c.tv_nsec = b->tv_nsec - a->tv_nsec + 1000000000UL;
-	} else {
-		c.tv_sec = b->tv_sec - a->tv_sec;
-		c.tv_nsec = b->tv_nsec - a->tv_nsec;
-	}
-	dt = (double)(c.tv_sec * 1000.0L) + (double)(c.tv_nsec / 1000000.0L);
-	return (dt);
-}
-
-/*
- * Convert an ICMP "type" field to a printable string.
- */
-static char const *pr_type(const uint8_t t)
-{
-	switch (t) {
-		/* Unknown */
-	case 0:
-		return "Error";
-	case ICMPV6_DEST_UNREACH:
-		return "Destination Unreachable";
-	case ICMPV6_PKT_TOOBIG:
-		return "Packet Too Big";
-	case ICMPV6_TIME_EXCEED:
-		return "Time Exceeded in Transit";
-	case ICMPV6_PARAMPROB:
-		return "Parameter Problem";
-	case ICMPV6_ECHO_REQUEST:
-		return "Echo Request";
-	case ICMPV6_ECHO_REPLY:
-		return "Echo Reply";
-	case ICMPV6_MGM_QUERY:
-		return "Membership Query";
-	case ICMPV6_MGM_REPORT:
-		return "Membership Report";
-	case ICMPV6_MGM_REDUCTION:
-		return "Membership Reduction";
-	case NDISC_ROUTER_SOLICITATION:
-		return "Router Solicitation";
-	case NDISC_ROUTER_ADVERTISEMENT:
-		return "Router Advertisement";
-	case NDISC_NEIGHBOUR_SOLICITATION:
-		return "Neighbor Solicitation";
-	case NDISC_NEIGHBOUR_ADVERTISEMENT:
-		return "Neighbor Advertisement";
-	case NDISC_REDIRECT:
-		return "Redirect";
-	case ICMPV6_NI_QUERY:
-		return "Neighbor Query";
-	case ICMPV6_NI_REPLY:
-		return "Neighbor Reply";
-	case ICMPV6_MLD2_REPORT:
-		return "Multicast Listener Report packet";
-	case ICMPV6_DHAAD_REQUEST:
-		return "Home Agent Address Discovery Request Message";
-	case ICMPV6_DHAAD_REPLY:
-		return "Home Agent Address Discovery Reply message";
-	case ICMPV6_MOBILE_PREFIX_SOL:
-		return "Mobile Prefix Solicitation Message";
-	case ICMPV6_MOBILE_PREFIX_ADV:
-		return "Mobile Prefix Solicitation Advertisement";
-	default:
-		return "OUT-OF-RANGE";
-	}
-	abort();
-}
-
-static int packet_ok(struct run_state *ctl, int cc, struct sockaddr_in6 *from,
-		     struct in6_addr *to, uint32_t seq, struct timespec *ts)
-{
-	struct icmp6_hdr *icp = (struct icmp6_hdr *)ctl->packet;
-	uint8_t type, code;
-
-	type = icp->icmp6_type;
-	code = icp->icmp6_code;
-
-	if ((type == ICMP6_TIME_EXCEEDED && code == ICMP6_TIME_EXCEED_TRANSIT)
-	    || type == ICMP6_DST_UNREACH) {
-		struct ip6_hdr *hip;
-		struct udphdr *up;
-		int nexthdr;
-
-		hip = (struct ip6_hdr *)(icp + 1);
-		up = (struct udphdr *)(hip + 1);
-		nexthdr = hip->ip6_nxt;
-
-		if (nexthdr == 44) {
-			nexthdr = *(unsigned char *)up;
-			up++;
-		}
-		if (nexthdr == IPPROTO_UDP) {
-			struct pkt_format *pkt;
-
-			pkt = (struct pkt_format *)(up + 1);
-
-			if (ntohl(pkt->ident) == (uint32_t) ctl->ident && ntohl(pkt->seq) == seq) {
-				*ts = pkt->ts;
-				return (type == ICMP6_TIME_EXCEEDED ? -1 : code + 1);
-			}
-		}
-
-	}
-
-	if (ctl->verbose) {
-		unsigned char *p;
-		char pa1[NI_MAXHOST];
-		char pa2[NI_MAXHOST];
-		int i;
-
-		p = (unsigned char *)(icp + 1);
-
-		printf("\n%d bytes from %s to %s", cc,
-		       inet_ntop(AF_INET6, &from->sin6_addr, pa1, sizeof(pa1)),
-		       inet_ntop(AF_INET6, to, pa2, sizeof(pa2)));
-
-		printf(": icmp type %d (%s) code %d\n", type, pr_type(type), icp->icmp6_code);
-
-		cc -= sizeof(struct icmp6_hdr);
-		for (i = 0; i < cc; i++) {
-			if (i % 16 == 0)
-				printf("%04x:", i);
-			if (i % 4 == 0)
-				printf(" ");
-			printf("%02x", 0xff & (unsigned)p[i]);
-			if (i % 16 == 15 && i + 1 < cc)
-				printf("\n");
-		}
-		printf("\n");
-	}
-
-	return (0);
-}
-
-static void print(struct run_state *ctl, struct sockaddr_in6 *from)
-{
-	char pa[NI_MAXHOST] = "";
-	char hnamebuf[NI_MAXHOST] = "";
-
-	if (ctl->nflag)
-		printf(" %s", inet_ntop(AF_INET6, &from->sin6_addr, pa, sizeof(pa)));
-	else {
-		inet_ntop(AF_INET6, &from->sin6_addr, pa, sizeof(pa));
-		getnameinfo((struct sockaddr *)from, sizeof *from, hnamebuf,
-			    sizeof hnamebuf, NULL, 0, getnameinfo_flags);
-
-		printf(" %s (%s)", hnamebuf[0] ? hnamebuf : pa, pa);
-	}
-}
-
-static __attribute__((noreturn)) void usage(void)
-{
-	fprintf(stderr,
-		"\nUsage:\n"
-		"  traceroute6 [options] <destination>\n"
-		"\nOptions:\n"
-		"  -d            use SO_DEBUG socket option\n"
-		"  -i <device>   bind to <device>\n"
-		"  -m <hops>     use maximum <hops>\n"
-		"  -n            no dns name resolution\n"
-		"  -p <port>     use destination <port>\n"
-		"  -q <nprobes>  number of probes\n"
-		"  -r            use SO_DONTROUTE socket option\n"
-		"  -s <address>  use source <address>\n"
-		"  -v            verbose output\n"
-		"  -w <timeout>  time to wait for response\n"
-		"\nFor more details see traceroute6(8).\n");
-	exit(1);
-}
-
-static uint16_t get_ip_unprivileged_port_start(const uint16_t fallback)
-{
-	FILE *f;
-	uint16_t nr = fallback;
-
-	f = fopen("/proc/sys/net/ipv4/ip_unprivileged_port_start", "r");
-	if (f) {
-		if (fscanf(f, "%" SCNu16, &nr) != 1)
-			nr = fallback;
-		fclose(f);
-	}
-	return nr;
-}
-
-int traceroute6_main(int argc, char **argv)
-{
-	struct run_state ctl = {
-		.nprobes = DEFAULT_PROBES,
-		.max_ttl = DEFAULT_HOPS,
-		.port = DEFAULT_PORT,
-		.waittime = DEFAULT_WAIT,
-		0
-	};
-	char pa[NI_MAXHOST];
-	extern char *optarg;
-	extern int optind;
-	struct addrinfo hints6 = {
-		.ai_family = AF_INET6,
-		.ai_socktype = SOCK_RAW,
-		.ai_flags = AI_CANONNAME | ADDRINFO_IDN_FLAGS
-	};
-	struct addrinfo *result;
-	int status;
-	struct sockaddr_in6 from;
-	struct sockaddr_in6 *to = (struct sockaddr_in6 *)&ctl.whereto;
-	int ch, i, probe, ttl, on = 1;
-	uint32_t seq = 0;
-	int socket_errno;
-	char *resolved_hostname = NULL;
-
-	ctl.datalen = sizeof(struct pkt_format);
-	ctl.icmp_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
-	socket_errno = errno;
-
-	if (setuid(getuid())) {
-		perror("traceroute6: setuid");
-		exit(-1);
-	}
-#ifdef HAVE_LIBCAP
-	{
-		cap_t caps = cap_init();
-
-		if (cap_set_proc(caps)) {
-			perror("traceroute6: cap_set_proc");
-			exit(-1);
-		}
-		cap_free(caps);
-	}
-#endif
-
-#ifdef USE_IDN
-	setlocale(LC_ALL, "");
-#endif
-	while ((ch = getopt(argc, argv, "dm:np:q:rs:w:vi:V")) != EOF) {
-		switch (ch) {
-		case 'd':
-			ctl.options |= SO_DEBUG;
-			break;
-		case 'm':
-			ctl.max_ttl = atoi(optarg);
-			if (ctl.max_ttl <= 1) {
-				fprintf(stderr, "traceroute: max ttl must be >1.\n");
-				exit(1);
-			}
-			break;
-		case 'n':
-			ctl.nflag = 1;
-			break;
-		case 'p':
-			ctl.port = atoi(optarg);
-			if (ctl.port < 1) {
-				fprintf(stderr, "traceroute: port must be >0.\n");
-				exit(1);
-			}
-			break;
-		case 'q':
-			ctl.nprobes = atoi(optarg);
-			if (ctl.nprobes < 1) {
-				fprintf(stderr, "traceroute: nprobes must be >0.\n");
-				exit(1);
-			}
-			break;
-		case 'r':
-			ctl.options |= SO_DONTROUTE;
-			break;
-		case 's':
-			/*
-			 * set the ip source address of the outbound probe
-			 * (e.g., on a multi-homed host).
-			 */
-			ctl.source = optarg;
-			break;
-		case 'i':
-			ctl.device = optarg;
-			break;
-		case 'v':
-			ctl.verbose = 1;
-			break;
-		case 'w':
-			ctl.waittime = atoi(optarg);
-			if (ctl.waittime <= 1) {
-				fprintf(stderr, "traceroute: wait must be >1 sec.\n");
-				exit(1);
-			}
-			break;
-		case 'V':
-			printf(IPUTILS_VERSION("traceroute6"));
-			exit(0);
-		default:
-			usage();
-		}
-	}
-	argc -= optind;
-	argv += optind;
-	optind = 0;
-
-	if (argc < 1)
-		usage();
-
-	setlinebuf(stdout);
-
-	memset((char *)&ctl.whereto, 0, sizeof(ctl.whereto));
-
-	to->sin6_family = AF_INET6;
-
-	if (inet_pton(AF_INET6, *argv, &to->sin6_addr) > 0) {
-		ctl.hostname = *argv;
-	} else {
-		status = getaddrinfo(*argv, NULL, &hints6, &result);
-		if (status) {
-			fprintf(stderr, "traceroute: %s: %s\n", *argv, gai_strerror(status));
-			exit(1);
-		}
-
-		memcpy(to, result->ai_addr, sizeof *to);
-		resolved_hostname = strdup(result->ai_canonname);
-		if (resolved_hostname == NULL) {
-			fprintf(stderr, "traceroute: cannot allocate memory\n");
-			exit(1);
-		}
-		ctl.hostname = resolved_hostname;
-		freeaddrinfo(result);
-	}
-
-	to->sin6_port = htons(ctl.port);
-
-	ctl.firsthop = *to;
-	if (*++argv) {
-		ctl.datalen = atoi(*argv);
-		/*
-		 * Message for rpm maintainers: have _shame_.  If you want
-		 * to fix something send the patch to me for sanity
-		 * checking.  "datalen" patch is a shit.
-		 */
-		if (ctl.datalen == 0)
-			ctl.datalen = sizeof(struct pkt_format);
-		else if (ctl.datalen < (int)sizeof(struct pkt_format) || ctl.datalen >= MAXPACKET) {
-			fprintf(stderr,
-				"traceroute: packet size must be %d <= s < %d.\n",
-				(int)sizeof(struct pkt_format), MAXPACKET);
-			exit(1);
-		}
-	}
-
-	ctl.ident = getpid();
-
-	ctl.sendbuff = malloc(ctl.datalen);
-	if (ctl.sendbuff == NULL) {
-		fprintf(stderr, "malloc failed\n");
-		exit(1);
-	}
-
-	if (ctl.icmp_sock < 0) {
-		errno = socket_errno;
-		perror("traceroute6: icmp socket");
-		exit(1);
-	}
-#ifdef IPV6_RECVPKTINFO
-	setsockopt(ctl.icmp_sock, SOL_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on));
-	setsockopt(ctl.icmp_sock, SOL_IPV6, IPV6_2292PKTINFO, &on, sizeof(on));
-#else
-	setsockopt(ctl.icmp_sock, SOL_IPV6, IPV6_PKTINFO, &on, sizeof(on));
-#endif
-
-	if (ctl.options & SO_DEBUG)
-		setsockopt(ctl.icmp_sock, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof(on));
-	if (ctl.options & SO_DONTROUTE)
-		setsockopt(ctl.icmp_sock, SOL_SOCKET, SO_DONTROUTE, (char *)&on, sizeof(on));
-
-#ifdef __linux__
-	on = 2;
-	if (setsockopt(ctl.icmp_sock, SOL_RAW, IPV6_CHECKSUM, &on, sizeof(on)) < 0) {
-		/*
-		 * checksum should be enabled by default and setting this
-		 * option might fail anyway.
-		 */
-		fprintf(stderr, "setsockopt(RAW_CHECKSUM) failed - try to continue.");
-	}
-#endif
-
-	if ((ctl.sndsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
-		perror("traceroute: UDP socket");
-		exit(5);
-	}
-#ifdef SO_SNDBUF
-	if (setsockopt(ctl.sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&ctl.datalen,
-		       sizeof(ctl.datalen)) < 0) {
-		perror("traceroute: SO_SNDBUF");
-		exit(6);
-	}
-#endif				/* SO_SNDBUF */
-
-	if (ctl.options & SO_DEBUG)
-		setsockopt(ctl.sndsock, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof(on));
-	if (ctl.options & SO_DONTROUTE)
-		setsockopt(ctl.sndsock, SOL_SOCKET, SO_DONTROUTE, (char *)&on, sizeof(on));
-
-	if (ctl.source == NULL) {
-		socklen_t alen;
-		int probe_fd = socket(AF_INET6, SOCK_DGRAM, 0);
-
-		if (probe_fd < 0) {
-			perror("socket");
-			exit(1);
-		}
-		if (ctl.device) {
-			if (setsockopt
-			    (probe_fd, SOL_SOCKET, SO_BINDTODEVICE, ctl.device,
-			     strlen(ctl.device) + 1) == -1)
-				perror("WARNING: interface is ignored");
-		}
-		ctl.firsthop.sin6_port = htons(get_ip_unprivileged_port_start(1025));
-		if (connect(probe_fd, (struct sockaddr *)&ctl.firsthop,
-			    sizeof(ctl.firsthop)) == -1) {
-			perror("connect");
-			exit(1);
-		}
-		alen = sizeof(ctl.saddr);
-		if (getsockname(probe_fd, (struct sockaddr *)&ctl.saddr, &alen) == -1) {
-			perror("getsockname");
-			exit(1);
-		}
-		ctl.saddr.sin6_port = 0;
-		close(probe_fd);
-	} else {
-		memset((char *)&ctl.saddr, 0, sizeof(ctl.saddr));
-		ctl.saddr.sin6_family = AF_INET6;
-		if (inet_pton(AF_INET6, ctl.source, &ctl.saddr.sin6_addr) <= 0) {
-			printf("traceroute: unknown addr %s\n", ctl.source);
-			exit(1);
-		}
-	}
-
-	if (bind(ctl.sndsock, (struct sockaddr *)&ctl.saddr, sizeof(ctl.saddr)) < 0) {
-		perror("traceroute: bind sending socket");
-		exit(1);
-	}
-	if (bind(ctl.icmp_sock, (struct sockaddr *)&ctl.saddr, sizeof(ctl.saddr)) < 0) {
-		perror("traceroute: bind icmp6 socket");
-		exit(1);
-	}
-
-	fprintf(stderr, "traceroute to %s (%s)", ctl.hostname,
-		inet_ntop(AF_INET6, &to->sin6_addr, pa, sizeof(pa)));
-
-	fprintf(stderr, " from %s", inet_ntop(AF_INET6, &ctl.saddr.sin6_addr, pa, sizeof(pa)));
-	fprintf(stderr, ", %d hops max, %d byte packets\n", ctl.max_ttl, ctl.datalen);
-	fflush(stderr);
-
-	for (ttl = 1; ttl <= ctl.max_ttl; ++ttl) {
-		struct in6_addr lastaddr = { {{0,}} };
-		uint8_t got_there = 0;
-		int unreachable = 0;
-
-		printf("%2d ", ttl);
-		for (probe = 0; probe < ctl.nprobes; ++probe) {
-			ssize_t cc;
-			uint8_t reset_timer = 1;
-			struct timespec t1, t2;
-			struct in6_addr to_addr;
-
-			clock_gettime(CLOCK_MONOTONIC_RAW, &t1);
-			send_probe(&ctl, ++seq, ttl);
-			while ((cc = wait_for_reply(&ctl, &from, &to_addr, reset_timer)) != 0) {
-				clock_gettime(CLOCK_MONOTONIC_RAW, &t2);
-				if ((i = packet_ok(&ctl, cc, &from, &to_addr, seq, &t1))) {
-					if (memcmp(&from.sin6_addr, &lastaddr,
-						   sizeof(from.sin6_addr))) {
-						print(&ctl, &from);
-						memcpy(&lastaddr,
-						       &from.sin6_addr, sizeof(lastaddr));
-					}
-					printf("  %.4f ms", deltaT(&t1, &t2));
-					switch (i - 1) {
-					case ICMP6_DST_UNREACH_NOPORT:
-						got_there = 1;
-						break;
-
-					case ICMP6_DST_UNREACH_NOROUTE:
-						++unreachable;
-						printf(" !N");
-						break;
-					case ICMP6_DST_UNREACH_ADDR:
-						++unreachable;
-						printf(" !H");
-						break;
-
-					case ICMP6_DST_UNREACH_ADMIN:
-						++unreachable;
-						printf(" !X");
-						break;
-					}
-					break;
-				} else
-					reset_timer = 0;
-			}
-			if (cc <= 0)
-				printf(" *");
-			fflush(stdout);
-		}
-		putchar('\n');
-		if (got_there || (unreachable > 0 && unreachable >= ctl.nprobes - 1))
-			break;
-	}
-	free(resolved_hostname);
-	return 0;
-}
-
-int traceroute6_util(const char *addr, int *hops, int *time_usec)
-{
-    int type = 4; // 4 or 6
-    int total_hops = 0;
-    long int total_time_usec = 0; // latency in microseconds
-    int argc = 4;
-    const char *argv[argc];
-    if(type != 4)
-        argv[0] = "raceroute6";
-    else
-        argv[0] = "raceroute4";
-    argv[1] = "-v"; // print both name and ip
-    argv[2] = "-v"; // -n -m 16
-    argv[3] = addr;
-    int ret = traceroute6_main(argc, (char**) argv);
-    return ret;
-}