int pqt_get_lseg(PGtypeArgs *args) { DECLVALUE(args); unsigned int *v; PGlseg *lseg = va_arg(args->ap, PGlseg *); CHKGETVALS(args, lseg); if (args->format == TEXTFMT) { PGpoint *pts = (PGpoint *)lseg; if (*value++ != '[' || !text2point(pts, value, &value) || *value++ != ',' || !text2point(pts + 1, value, &value) || *value != ']') RERR_STR2INT(args); return 0; } v = (unsigned int *) value; pqt_swap8(&lseg->pts[0].x, v, 0); pqt_swap8(&lseg->pts[0].y, v + 2, 0); pqt_swap8(&lseg->pts[1].x, v + 4, 0); pqt_swap8(&lseg->pts[1].y, v + 6, 0); return 0; }
int pqt_get_circle(PGtypeArgs *args) { DECLVALUE(args); unsigned int *v; PGcircle *circle = va_arg(args->ap, PGcircle *); CHKGETVALS(args, circle); if (args->format == TEXTFMT) { if (*value++ != '<' || !text2point((PGpoint *)circle, value, &value) || *value++ != ',' || !pqt_text_to_float8(&circle->radius, value, &value) || *value != '>') RERR_STR2INT(args); return 0; } v = (unsigned int *) value; pqt_swap8(&circle->center.x, v, 0); pqt_swap8(&circle->center.y, v + 2, 0); pqt_swap8(&circle->radius, v + 4, 0); return 0; }
int pqt_get_box(PGtypeArgs *args) { DECLVALUE(args); unsigned int *v; PGbox *box = va_arg(args->ap, PGbox *); CHKGETVALS(args, box); if (args->format == TEXTFMT) { PGpoint *pts = (PGpoint *)box; if (!text2point(pts, value, &value) || *value++ != ',' || !text2point(pts + 1, value, NULL)) RERR_STR2INT(args); return 0; } v = (unsigned int *) value; pqt_swap8(&box->high.x, v, 0); pqt_swap8(&box->high.y, v + 2, 0); pqt_swap8(&box->low.x, v + 4, 0); pqt_swap8(&box->low.y, v + 6, 0); return 0; }
int pqt_get_point(PGtypeArgs *args) { DECLVALUE(args); PGpoint *pt = va_arg(args->ap, PGpoint *); CHKGETVALS(args, pt); if (args->format == TEXTFMT) { if (!text2point(pt, value, NULL)) RERR_STR2INT(args); return 0; } pqt_swap8(&pt->x, (unsigned int *) value, 0); pqt_swap8(&pt->y, ((unsigned int *) (value)) + 2, 0); return 0; }
static int get_inet2(PGtypeArgs *args, int is_cidr) { DECLVALUE(args); unsigned short family; PGinet *inet = va_arg(args->ap, PGinet *); CHKGETVALS(args, inet); if (args->format == TEXTFMT) { int r; char *p; char ipstr[80]; struct addrinfo *ai = NULL; struct addrinfo hints; pqt_strcpy(ipstr, sizeof(ipstr), value); if ((p = strrchr(ipstr, '/'))) { *p = 0; inet->mask = atoi(p+1); } else { inet->mask = 32; } inet->is_cidr = is_cidr; /* suppress hostname lookups */ memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_NUMERICHOST; /* Without this, windows chokes with WSAHOST_NOT_FOUND */ #ifdef PQT_WIN32 hints.ai_family = AF_INET; #endif if ((r = getaddrinfo(ipstr, NULL, &hints, &ai)) || !ai) { if(r == EAI_BADFLAGS) { hints.ai_flags = 0; r = getaddrinfo(ipstr, NULL, &hints, &ai); } /* Another WSAHOST_NOT_FOUND work around, but for IPv6 */ #if defined(PQT_WIN32) && defined(AF_INET6) else if(r == WSAHOST_NOT_FOUND) { hints.ai_flags = 0; hints.ai_family = AF_INET6; r = getaddrinfo(ipstr, NULL, &hints, &ai); } #endif if(r) RERR_STR2INT(args); } inet->sa_buf_len = (int) ai->ai_addrlen; memcpy(inet->sa_buf, ai->ai_addr, inet->sa_buf_len); /* Some platforms, lika AIX 4.3, do not zero this structure properly. * The family and port are dirty, so set the first 4 bytes to 0 and * then re-set the family. I saw "0x1002" as the first 2 bytes of * this structure (dumb getaddrinfo), it should be "0x0002" for AF_INET. */ memset(inet->sa_buf, 0, 4); ((struct sockaddr *)inet->sa_buf)->sa_family = ai->ai_addr->sa_family; /* Uninitialized memory, postgres inet/cidr types don't store this. * Make sure its set to 0. Another AIX problem (maybe other platforms). */ #ifdef AF_INET6 if (ai->ai_addr->sa_family == AF_INET6) ((struct sockaddr_in6 *)inet->sa_buf)->sin6_flowinfo = 0; #endif freeaddrinfo(ai); return 0; } family = (unsigned short) *value++; if (family == PGSQL_AF_INET) { struct sockaddr_in *sa = (struct sockaddr_in *) inet->sa_buf; sa->sin_family = AF_INET; inet->mask = (unsigned char) *value++; inet->is_cidr = *value++; memcpy(&sa->sin_addr, value + 1, *value); inet->sa_buf_len = (int) sizeof(struct sockaddr_in); } #ifdef AF_INET6 else if (family == PGSQL_AF_INET6) { struct sockaddr_in6 *sa = (struct sockaddr_in6 *) inet->sa_buf; sa->sin6_family = AF_INET6; inet->mask = (unsigned char) *value++; inet->is_cidr = *value++; memcpy(&sa->sin6_addr, value + 1, *value); inet->sa_buf_len = (int) sizeof(struct sockaddr_in6); } #endif else { return args->errorf(args, "Unknown inet address family %d", family); } return 0; }