Add "sort=addr" option to mrulist to sort by remote address.
Remove check for qsort() using other than void *, ANSI C is
required and it ensures void * for qsort().
bk: 4b95aa1fOMFPCGd0Zk9j24_ilbKz8Q
AC_DEFINE(HAVE_SETPGRP_0, 1, [define if setpgrp takes 0 arguments])
fi
-save_CFLAGS=$CFLAGS
-CFLAGS="$CFLAGS -I$srcdir/include"
-
-AC_CACHE_CHECK([argument pointer type of qsort()'s compare function and base],
-ac_cv_func_qsort_argtype,
-[AC_TRY_COMPILE([
-#include "l_stdlib.h"
-
-extern void *base;
-extern sortfunc (const void *, const void *);
-int sortfunc(a, b)
- const void *a;
- const void *b; { return 0; }
-],[
-qsort(base, 2, sizeof(char *), sortfunc);
-],
- ac_cv_func_qsort_argtype=void, ac_cv_func_qsort_argtype=char)
-])
-case "$ac_cv_func_qsort_argtype" in
- void)
- AC_DEFINE(QSORT_USES_VOID_P, 1, [Does qsort expect to work on "void *" stuff?])
- ;;
-esac
-
-CFLAGS=$save_CFLAGS
-
AC_CACHE_CHECK([if we need to declare 'errno'], ac_cv_decl_errno,
[AC_TRY_COMPILE([#ifdef HAVE_ERRNO_H
#include <errno.h>
? IN_CLASSD(SRCADR(psau)) \
: IN6_IS_ADDR_MULTICAST(PSOCK_ADDR6(psau)))
+#define SIZEOF_INADDR(fam) \
+ ((AF_INET == (fam)) \
+ ? sizeof(struct in_addr) \
+ : sizeof(struct in6_addr))
+
#define SIZEOF_SOCKADDR(fam) \
((AF_INET == (fam)) \
? sizeof(struct sockaddr_in) \
#include "ntp_parser.h"
-#ifdef QSORT_USES_VOID_P
-typedef const void * QSORTP;
-#else
-typedef char * QSORTP;
-#endif
-
/* Define a structure to hold a (keyword, token) pair */
struct key_tok {
char * key; /* Keyword */
static void generate_token_text (void);
static int create_keyword_scanner (void);
static int create_scan_states (char *, int, follby, int);
-int compare_key_tok_id (QSORTP, QSORTP);
-int compare_key_tok_text (QSORTP, QSORTP);
+int compare_key_tok_id (const void *, const void *);
+int compare_key_tok_text (const void *, const void *);
void populate_symb (char *);
const char * symbname (int);
int
compare_key_tok_id(
- QSORTP a1,
- QSORTP a2
+ const void *a1,
+ const void *a2
)
{
- const struct key_tok *p1 = (const void *)a1;
- const struct key_tok *p2 = (const void *)a2;
+ const struct key_tok *p1 = a1;
+ const struct key_tok *p2 = a2;
if (p1->token == p2->token)
return 0;
int
compare_key_tok_text(
- QSORTP a1,
- QSORTP a2
+ const void *a1,
+ const void *a2
)
{
- const struct key_tok *p1 = (const void *)a1;
- const struct key_tok *p2 = (const void *)a2;
+ const struct key_tok *p1 = a1;
+ const struct key_tok *p2 = a2;
return strcmp(p1->key, p2->key);
}
/*
* Forward declarations
*/
-#ifdef QSORT_USES_VOID_P
static int refclock_cmpl_fp (const void *, const void *);
-#else
-static int refclock_cmpl_fp (const double *, const double *);
-#endif /* QSORT_USES_VOID_P */
static int refclock_sample (struct refclockproc *);
/*
* Compare two doubles - used with qsort()
*/
-#ifdef QSORT_USES_VOID_P
static int
refclock_cmpl_fp(
const void *p1,
return (0);
}
-#else
-static int
-refclock_cmpl_fp(
- const double *dp1,
- const double *dp2
- )
-{
- if (*dp1 < *dp2)
- return (-1);
-
- if (*dp1 > *dp2)
- return (1);
-
- return (0);
-}
-#endif /* QSORT_USES_VOID_P */
-
/*
* refclock_process_offset - update median filter
return (0);
if (n > 1)
- qsort(
-#ifdef QSORT_USES_VOID_P
- (void *)
-#else
- (char *)
-#endif
- off, (size_t)n, sizeof(double), refclock_cmpl_fp);
+ qsort(off, (size_t)n, sizeof(off[0]), refclock_cmpl_fp);
/*
* Reject the furthest from the median of the samples until
static void ees_report_event P((struct eesunit *ees, int code));
static void ees_receive P((struct recvbuf *rbufp));
static void ees_process P((struct eesunit *ees));
-#ifdef QSORT_USES_VOID_P
static int offcompare P((const void *va, const void *vb));
-#else
-static int offcompare P((const l_fp *a, const l_fp *b));
-#endif /* QSORT_USES_VOID_P */
/*
/* offcompare - auxiliary comparison routine for offset sort */
-#ifdef QSORT_USES_VOID_P
static int
offcompare(
const void *va,
const l_fp *b = (const l_fp *)vb;
return(L_ISGEQ(a, b) ? (L_ISEQU(a, b) ? 0 : 1) : -1);
}
-#else
-static int
-offcompare(
- const l_fp *a,
- const l_fp *b
- )
-{
- return(L_ISGEQ(a, b) ? (L_ISEQU(a, b) ? 0 : 1) : -1);
-}
-#endif /* QSORT_USES_VOID_P */
/* ees_process - process a pile of samples from the clock */
if (samples < 1) return;
/* If requested, dump the raw data we have in the buffer */
- if (ees->dump_vals) dump_buf(coffs, 0, samples, "Raw data is:");
+ if (ees->dump_vals)
+ dump_buf(coffs, 0, samples, "Raw data is:");
/* Sort the offsets, trim off the extremes, then choose one. */
- qsort(
-#ifdef QSORT_USES_VOID_P
- (void *)
-#else
- (char *)
-#endif
- coffs, (size_t)samples, sizeof(l_fp), offcompare);
+ qsort(coffs, (size_t)samples, sizeof(coffs[0]), offcompare);
noff = samples;
i = 0;
static char * mx4200_parse_t (struct peer *);
static char * mx4200_parse_p (struct peer *);
static char * mx4200_parse_s (struct peer *);
-#ifdef QSORT_USES_VOID_P
int mx4200_cmpl_fp (const void *, const void *);
-#else
-int mx4200_cmpl_fp (const l_fp *, const l_fp *);
-#endif /* not QSORT_USES_VOID_P */
static int mx4200_config (struct peer *);
static void mx4200_ref (struct peer *);
static void mx4200_send (struct peer *, char *, ...)
static int getarg (char *, int, arg_v *);
static int getnetnum (const char *, sockaddr_u *, char *, int);
static void help (struct parse *, FILE *);
-#ifdef QSORT_USES_VOID_P
static int helpsort (const void *, const void *);
-#else
-static int helpsort (char **, char **);
-#endif
static void printusage (struct xcmd *, FILE *);
static void timeout (struct parse *, FILE *);
static void my_delay (struct parse *, FILE *);
struct xcmd *xcp;
char *cmd;
const char *list[100];
- int word, words;
- int row, rows;
+ int word, words;
+ int row, rows;
int col, cols;
if (pcmd->nargs == 0) {
words = 0;
for (xcp = builtins; xcp->keyword != 0; xcp++) {
- if (*(xcp->keyword) != '?')
- list[words++] = xcp->keyword;
+ if (*(xcp->keyword) != '?' &&
+ words < COUNTOF(list))
+ list[words++] = xcp->keyword;
}
- for (xcp = opcmds; xcp->keyword != 0; xcp++)
- list[words++] = xcp->keyword;
+ for (xcp = opcmds; xcp->keyword != 0; xcp++)
+ if (words < COUNTOF(list))
+ list[words++] = xcp->keyword;
- qsort(
-#ifdef QSORT_USES_VOID_P
- (void *)
-#else
- (char *)
-#endif
- (list), (size_t)(words), sizeof(char *), helpsort);
+ qsort((void *)&list, (size_t)words, sizeof(list[0]), helpsort);
col = 0;
for (word = 0; word < words; word++) {
int length = strlen(list[word]);
- if (col < length) {
- col = length;
- }
+ if (col < length)
+ col = length;
}
cols = SCREENWIDTH / ++col;
- rows = (words + cols - 1) / cols;
+ rows = (words + cols - 1) / cols;
- (void) fprintf(fp, "ntpdc commands:\n");
+ fprintf(fp, "ntpdc commands:\n");
for (row = 0; row < rows; row++) {
- for (word = row; word < words; word += rows) {
- (void) fprintf(fp, "%-*.*s", col, col-1, list[word]);
- }
- (void) fprintf(fp, "\n");
+ for (word = row; word < words; word += rows)
+ fprintf(fp, "%-*.*s", col, col-1, list[word]);
+ fprintf(fp, "\n");
}
} else {
cmd = pcmd->argval[0].string;
words = findcmd(cmd, builtins, opcmds, &xcp);
if (words == 0) {
- (void) fprintf(stderr,
- "Command `%s' is unknown\n", cmd);
+ fprintf(stderr,
+ "Command `%s' is unknown\n", cmd);
return;
} else if (words >= 2) {
- (void) fprintf(stderr,
- "Command `%s' is ambiguous\n", cmd);
+ fprintf(stderr,
+ "Command `%s' is ambiguous\n", cmd);
return;
}
- (void) fprintf(fp, "function: %s\n", xcp->comment);
+ fprintf(fp, "function: %s\n", xcp->comment);
printusage(xcp, fp);
}
}
/*
* helpsort - do hostname qsort comparisons
*/
-#ifdef QSORT_USES_VOID_P
static int
helpsort(
const void *t1,
return strcmp(*name1, *name2);
}
-#else
-static int
-helpsort(
- char **name1,
- char **name2
- )
-{
- return strcmp(*name1, *name2);
-}
-#endif
/*
u_short rs;
sockaddr_u addr;
};
-static mru mru_list; /* listhead */
-static mru **hash_table;
+static u_int mru_count;
+static mru mru_list; /* listhead */
+static mru ** hash_table;
/*
* other static function prototypes
*/
static mru * add_mru(mru *);
static int collect_mru_list(const char *, l_fp *);
+static int qcmp_mru_avgint(const void *, const void *);
+static int qcmp_mru_addr(const void *, const void *);
/*
}
LINK_DLIST(mru_list, add, mlink);
LINK_SLIST(hash_table[hash], add, hlink);
- if (NULL == mon)
+ if (NULL == mon) {
mon = emalloc(sizeof(*mon));
+ mru_count++;
+ }
memset(mon, 0, sizeof(*mon));
return mon;
}
u_short hash;
mru *unlinked;
+ mru_count = 0;
+ INIT_DLIST(mru_list, mlink);
+ cb = NTP_HASH_SIZE * sizeof(*hash_table);
+ hash_table = emalloc(cb);
+ memset(hash_table, 0, cb);
+
c_mru_l_rc = FALSE;
list_complete = FALSE;
have_now = FALSE;
if (debug)
fprintf(stderr, "READ_MRU: %s\n", req_buf);
// if (debug) !!!!!
- fprintf(stderr, "attempting next %d\n", limit);
+ fprintf(stderr, "%d ", limit);
qres = doqueryex(CTL_OP_READ_MRU, 0, 0, strlen(req_buf),
req_buf, &rstatus, &rsize, &rdata, TRUE);
if (2 != sscanf(val, ts_fmt,
&newest.l_ui,
&newest.l_uf) ||
- !L_ISEQU(&newest, &head->last)) {
+ !L_ISEQU(&newest,
+ &head->last)) {
fprintf(stderr,
"last.newest %s mismatches %08x.%08x",
- val, head->last.l_ui, head->last.l_uf);
+ val,
+ head->last.l_ui,
+ head->last.l_uf);
goto cleanup_return;
}
}
ri++, recent = NEXT_DLIST(mru_list, recent, mlink)) {
snprintf(buf, sizeof(buf),
- ", addr.%d=%s, last.%d=0x%08x.%08x",
- ri, sptoa(&recent->addr), ri,
- recent->last.l_ui,
- recent->last.l_uf);
+ ", addr.%d=%s, last.%d=0x%08x.%08x",
+ ri, sptoa(&recent->addr), ri,
+ recent->last.l_ui, recent->last.l_uf);
chars = strlen(buf);
if (REQ_ROOM - chars < 1)
break;
NTP_INSIST(ri > 0 || NULL == recent);
}
+ // if (debug) !!!!!
+ fprintf(stderr, "\n");
+
c_mru_l_rc = TRUE;
cleanup_return:
}
+/*
+ * qcmp_mru_addr - sort MRU entries by remote address.
+ *
+ * All IPv4 addresses sort before any IPv6, addresses are sorted by
+ * value within address family.
+ */
+static int
+qcmp_mru_addr(
+ const void *v1,
+ const void *v2
+ )
+{
+ const mru * const * ppm1 = v1;
+ const mru * const * ppm2 = v2;
+ const mru * pm1;
+ const mru * pm2;
+ u_short af1;
+ u_short af2;
+ size_t cmplen;
+ size_t addr_off;
+
+ pm1 = *ppm1;
+ pm2 = *ppm2;
+
+ af1 = AF(&pm1->addr);
+ af2 = AF(&pm2->addr);
+
+ if (af1 != af2)
+ return (AF_INET == af1)
+ ? -1
+ : 1;
+
+ cmplen = SIZEOF_INADDR(af1);
+ addr_off = (AF_INET == af1)
+ ? offsetof(struct sockaddr_in, sin_addr)
+ : offsetof(struct sockaddr_in6, sin6_addr);
+
+ return memcmp((const char *)&pm1->addr + addr_off,
+ (const char *)&pm2->addr + addr_off,
+ cmplen);
+}
+
+
+/*
+ * qcmp_mru_avgint - sort MRU entries by average interval.
+ */
+static int
+qcmp_mru_avgint(
+ const void *v1,
+ const void *v2
+ )
+{
+ const mru * const * ppm1 = v1;
+ const mru * const * ppm2 = v2;
+ const mru * pm1;
+ const mru * pm2;
+ l_fp interval;
+ double avg1;
+ double avg2;
+
+ pm1 = *ppm1;
+ pm2 = *ppm2;
+
+ interval = pm1->last;
+ L_SUB(&interval, &pm1->first);
+ LFPTOD(&interval, avg1);
+ avg1 /= pm1->count;
+
+ interval = pm2->last;
+ L_SUB(&interval, &pm2->first);
+ LFPTOD(&interval, avg2);
+ avg2 /= pm2->count;
+
+ if (avg1 < avg2)
+ return -1;
+ else if (avg1 > avg2)
+ return 1;
+
+ /* secondary sort on lstint - rarely tested */
+ if (L_ISEQU(&pm1->last, &pm2->last))
+ return 0;
+ else if (L_ISGEQ(&pm1->last, &pm2->last))
+ return -1;
+ else
+ return 1;
+}
+
+
/*
* mrulist - ntpq's mrulist command to fetch an arbitrarily large Most
* Recently Used (seen) remote address list from ntpd.
*
* See ntpd/ntp_control.c read_mru_list() for comments on the way
* CTL_OP_READ_MRU is designed to be used.
+ *
+ * mrulist intentionally differs from monlist in the way the avgint
+ * column is calculated. monlist includes the time after the last
+ * packet from the client until the monlist query time in the average,
+ * while mrulist excludes it. That is, monlist's average interval grows
+ * over time for remote addresses not heard from in some time, while it
+ * remains unchanged in mrulist. This also affects the avgint value for
+ * entries representing a single packet, with identical first and last
+ * timestamps. mrulist shows 0 avgint, monlist shows a value identical
+ * to lstint.
*/
static void
mrulist(
const char resall_eq[] = "resall=";
const char resany_eq[] = "resany=";
const char laddr_eq[] = "laddr=";
+ const char sort_eq[] = "sort=";
+ const char avgint_text[] = "avgint";
+ const char addr_text[] = "addr";
+ typedef enum sort_order_tag {
+ MRUSORT_DEF, /* lstint ascending essentially */
+ MRUSORT_AVGINT, /* avgint ascending */
+ MRUSORT_ADDR, /* IPv4 asc. then IPv6 asc. */
+ } sort_order;
+ sort_order order;
char parms_buf[128];
char *parms;
char *arg;
size_t cb;
+ mru **sorted;
+ mru **ppentry;
mru *recent;
l_fp now;
l_fp interval;
int lstint;
int i;
+ order = MRUSORT_DEF;
parms_buf[0] = '\0';
parms = parms_buf;
for (i = 0; i < pcmd->nargs; i++) {
|| !strncmp(laddr_eq, arg, sizeof(laddr_eq)
- 1)) && parms + cb + 2 <= parms_buf +
sizeof(parms_buf)) {
+ /* these are passed intact to ntpd */
memcpy(parms, ", ", 2);
parms += 2;
memcpy(parms, arg, cb);
parms += cb - 1;
+ } else if (!strncmp(sort_eq, arg,
+ sizeof(sort_eq) - 1)) {
+ arg += sizeof(sort_eq) - 1;
+ if (!strcmp(avgint_text, arg))
+ order = MRUSORT_AVGINT;
+ if (!strcmp(addr_text, arg))
+ order = MRUSORT_ADDR;
} else
fprintf(stderr,
"ignoring unrecognized mrulist parameter: %s\n",
}
parms = parms_buf;
- INIT_DLIST(mru_list, mlink);
- cb = NTP_HASH_SIZE * sizeof(*hash_table);
- hash_table = emalloc(cb);
- memset(hash_table, 0, cb);
-
if (!collect_mru_list(parms, &now))
return;
if (rawmode)
goto cleanup_return;
+ /* construct an array of entry pointers in default order */
+ sorted = emalloc(mru_count * sizeof(*sorted));
+ ppentry = sorted;
+ ITER_DLIST_BEGIN(mru_list, recent, mlink, mru)
+ NTP_INSIST(ppentry < sorted + mru_count);
+ *ppentry = recent;
+ ppentry++;
+ ITER_DLIST_END()
+
+ /* re-sort sorted[] if non-default */
+ if (MRUSORT_DEF != order)
+ qsort(sorted, mru_count, sizeof(sorted[0]),
+ (MRUSORT_ADDR == order)
+ ? &qcmp_mru_addr
+ : &qcmp_mru_avgint);
+
printf( "lstint avgint rstr m v count rport remote address\n"
"==============================================================================\n");
/* '-' x 78 */
- ITER_DLIST_BEGIN(mru_list, recent, mlink, mru)
+ for (ppentry = sorted; ppentry < sorted + mru_count; ppentry++) {
+ recent = *ppentry;
interval = now;
L_SUB(&interval, &recent->last);
LFPTOD(&interval, flstint);
lstint, avgint, recent->rs, (int)recent->mode,
(int)recent->ver, recent->count,
SRCPORT(&recent->addr), nntohost(&recent->addr));
- ITER_DLIST_END()
+ }
+ free(sorted);
cleanup_return:
ITER_DLIST_BEGIN(mru_list, recent, mlink, mru)
static int rtdatetolfp (char *, l_fp *);
static int decodearr (char *, int *, l_fp *);
static void help (struct parse *, FILE *);
-#ifdef QSORT_USES_VOID_P
static int helpsort (const void *, const void *);
-#else
-static int helpsort (char **, char **);
-#endif
static void printusage (struct xcmd *, FILE *);
static void timeout (struct parse *, FILE *);
static void auth_delay (struct parse *, FILE *);
static void output (FILE *, char *, char *);
static void endoutput (FILE *);
static void outputarr (FILE *, char *, int, l_fp *);
-#ifdef QSORT_USES_VOID_P
static int assoccmp (const void *, const void *);
-#else
-static int assoccmp (struct association *, struct association *);
-#endif /* sgi || bsdi */
void ntpq_custom_opt_handler (tOptions *, tOptDesc *);
int word, words;
int row, rows;
int col, cols;
+ int length;
if (pcmd->nargs == 0) {
words = 0;
for (xcp = builtins; xcp->keyword != 0; xcp++) {
- if (*(xcp->keyword) != '?')
+ if (*(xcp->keyword) != '?' &&
+ words < COUNTOF(list))
list[words++] = xcp->keyword;
}
for (xcp = opcmds; xcp->keyword != 0; xcp++)
- list[words++] = xcp->keyword;
+ if (words < COUNTOF(list))
+ list[words++] = xcp->keyword;
- qsort(
-#ifdef QSORT_USES_VOID_P
- (void *)
-#else
- (char *)
-#endif
- (list), (size_t)(words), sizeof(char *), helpsort);
+ qsort((void *)&list, (size_t)words, sizeof(list[0]), &helpsort);
col = 0;
for (word = 0; word < words; word++) {
- int length = strlen(list[word]);
+ length = strlen(list[word]);
if (col < length) {
col = length;
}
cols = SCREENWIDTH / ++col;
rows = (words + cols - 1) / cols;
- (void) fprintf(fp, "ntpq commands:\n");
+ fprintf(fp, "ntpq commands:\n");
for (row = 0; row < rows; row++) {
for (word = row; word < words; word += rows) {
/*
* helpsort - do hostname qsort comparisons
*/
-#ifdef QSORT_USES_VOID_P
static int
helpsort(
const void *t1,
return strcmp(*name1, *name2);
}
-#else
-static int
-helpsort(
- char **name1,
- char **name2
- )
-{
- return strcmp(*name1, *name2);
-}
-#endif
/*
* printusage - print usage information for a command
sortassoc(void)
{
if (numassoc > 1)
- qsort(
-#ifdef QSORT_USES_VOID_P
- (void *)
-#else
- (char *)
-#endif
- assoc_cache, (size_t)numassoc,
- sizeof(struct association), assoccmp);
+ qsort(assoc_cache, (size_t)numassoc,
+ sizeof(assoc_cache[0]), &assoccmp);
}
/*
* assoccmp - compare two associations
*/
-#ifdef QSORT_USES_VOID_P
static int
assoccmp(
const void *t1,
return 1;
return 0;
}
-#else
-static int
-assoccmp(
- struct association *ass1,
- struct association *ass2
- )
-{
- if (ass1->assid < ass2->assid)
- return -1;
- if (ass1->assid > ass2->assid)
- return 1;
- return 0;
-}
-#endif /* not QSORT_USES_VOID_P */
+
/*
* ntpq_custom_opt_handler - autoopts handler for -c and -p
# define SIZEOF_SIGNED_CHAR 1
# define SIZEOF_INT 4 /* for ntp_types.h */
-# define QSORT_USES_VOID_P
# define HAVE_SETVBUF
# define HAVE_VSPRINTF
# define HAVE_SNPRINTF
# define HAVE_VPRINTF
#define HAVE_LIMITS_H 1
-#define HAVE_STRDUP 1
+#define HAVE_STRDUP
+#define HAVE_STRCHR
#define HAVE_FCNTL_H 1
#define HAVE_SYS_RESOURCE_H
#define HAVE_BSD_NICE /* emulate BSD setpriority() */
#define NSRT 20000 /* size of overflow histogram */
#define NCNT (600 * 1000000) /* sample interval (us) */
-int col (long *, long *);
+int col (const void *, const void *);
int
main(
* Force pages into memory
*/
for (i = 0; i < NBUF; i++)
- gtod[i] = 0;
+ gtod[i] = 0;
for (i = 0; i < NSRT; i++)
- ovfl[i] = 0;
+ ovfl[i] = 0;
/*
* Construct histogram
gettimeofday(&tr, &tzp);
u = tr.tv_sec * 1000000 + tr.tv_usec;
if (u - v > NCNT)
- break;
+ break;
w = u - t;
if (w <= 0) {
/*
} else if (w > NBUF - 1) {
ovfl[n] = w;
if (n < NSRT - 1)
- n++;
+ n++;
} else {
gtod[w]++;
}
*/
for (i = 0; i < NBUF - 1; i++) {
if (gtod[i] > 0)
- printf("%ld %ld\n", i, gtod[i]);
+ printf("%ld %ld\n", i, gtod[i]);
}
if (n == 0)
- return;
- qsort(
-#ifdef QSORT_USES_VOID_P
- (void *)
-#else
- (char *)
-#endif
- ovfl, (size_t)n, sizeof(long), col);
+ return;
+ qsort(&ovfl, (size_t)n, sizeof(ovfl[0]), col);
w = 0;
j = 0;
for (i = 0; i < n; i++) {
if (ovfl[i] != w) {
if (j > 0)
- printf("%ld %ld\n", w, j);
+ printf("%ld %ld\n", w, j);
w = ovfl[i];
j = 1;
} else
- j++;
+ j++;
}
if (j > 0)
- printf("%ld %ld\n", w, j);
+ printf("%ld %ld\n", w, j);
exit(0);
}
int
col(
- long *x,
- long *y
+ const void *vx,
+ const void *vy
)
{
+ const long *x = vx;
+ const long *y = vy;
+
return (*x - *y);
}