static bool RlistItemMACLess(void *lhs, void *rhs, ARG_UNUSED void *ctx) { int bytes = 6; unsigned char left[bytes], right[bytes]; int matched_left = 6 == ParseEtherAddress(RlistScalarValue((Rlist*)lhs), left); int matched_right = 6 == ParseEtherAddress(RlistScalarValue((Rlist*)rhs), right); if (matched_left && matched_right) { int difference = memcmp(left, right, bytes); if (difference != 0) return difference < 0; } if (matched_left) { return false; } if (matched_right) { return true; } // neither item matched return RlistItemLess(lhs, rhs, ctx); }
static bool RlistItemNumberLess(void *lhs, void *rhs, ARG_UNUSED void *ctx, bool int_mode) { char remainder[CF_BUFSIZE]; double left; double right; int matched_left = sscanf(RlistScalarValue((Rlist*)lhs), "%lf", &left); int matched_right = sscanf(RlistScalarValue((Rlist*)rhs), "%lf", &right); if (!matched_left) { matched_left = sscanf(RlistScalarValue((Rlist*)lhs), "%lf%s", &left, remainder); } if (!matched_right) { matched_right = sscanf(RlistScalarValue((Rlist*)rhs), "%lf%s", &right, remainder); } if (matched_left && matched_right) { if (int_mode) { return ((long int)left) - ((long int)right) < 0; } else { return left - right < 0; } } if (matched_left) { return false; } if (matched_right) { return true; } // neither item matched return RlistItemLess(lhs, rhs, ctx); }
static bool RlistItemIPLess(void *lhs, void *rhs, ARG_UNUSED void *ctx) { const char *left_item = RlistScalarValue((Rlist*)lhs); const char *right_item = RlistScalarValue((Rlist*)rhs); Buffer *left_buffer = BufferNewFrom(left_item, strlen(left_item)); Buffer *right_buffer = BufferNewFrom(right_item, strlen(right_item)); IPAddress *left = IPAddressNew(left_buffer); IPAddress *right = IPAddressNew(right_buffer); bool matched_left = left != NULL; bool matched_right = right != NULL; BufferDestroy(&left_buffer); BufferDestroy(&right_buffer); if (matched_left && matched_right) { int less = IPAddressCompareLess(left, right); IPAddressDestroy(&left); IPAddressDestroy(&right); return less; } IPAddressDestroy(&left); IPAddressDestroy(&right); if (matched_left) { return false; } if (matched_right) { return true; } // neither item matched return RlistItemLess(lhs, rhs, ctx); }
bool GenericItemLess(const char *sort_type, void *lhs, void *rhs) { if (strcmp(sort_type, "int") == 0) { return RlistItemNumberLess(lhs, rhs, NULL, true); } else if (strcmp(sort_type, "real") == 0) { return RlistItemNumberLess(lhs, rhs, NULL, false); } else if (strcmp(sort_type, "IP") == 0 || strcmp(sort_type, "ip") == 0) { return RlistItemIPLess(lhs, rhs, NULL); } else if (strcmp(sort_type, "MAC") == 0 || strcmp(sort_type, "mac") == 0) { return RlistItemMACLess(lhs, rhs, NULL); } // "lex" return RlistItemLess(lhs, rhs, NULL); }