/* ************************************************************* RWhois Software Copyright (c) 1994 Scott Williamson and Mark Kosters Copyright (c) 1996-2000 Network Solutions, Inc. See the file LICENSE for conditions of use and distribution. **************************************************************** */ #include "rwhois.h" #include "strutils.h" #define COMPONENT_BUF_LEN 80 void rwhois_set_response(rw_response_struct *response, int status, char *msg) { assert(response); response->status = status; if (STR_EXISTS(msg)) { strncpy(response->msg, msg, sizeof(response->msg) - 1); response->msg[sizeof(response->msg) - 1] = '\0'; } else if (msg) { response->msg[0] = '\0'; } } /* parse URLs of the form: [URL:]scheme://[host[:port]]/otherstuff into scheme, host, port, and other. */ int rwhois_parse_url(char *url, char *schema_buf, size_t schema_buf_len, char *host_buf, size_t host_buf_len, int *port, char *other_buf, size_t other_buf_len) { char *p; char *q; char *term1 = NULL; char *term2 = NULL; /* skip optional URL: */ if (STRN_EQ(url, "url:", 4)) { url += 4; } /* skip to first '/' */ p = strchr(url,'/'); /* all URLs must have a '/' */ if (!p) return RW_ERROR; /* if the next character isn't another '/', error as well */ if (*(p + 1) != '/') return RW_ERROR ; /* extract the schema by looking for the ':' before the first '/' */ *p = '\0'; q = strchr(url, ':'); if (q) { *q = '\0'; strncpy(schema_buf, url, schema_buf_len); *q = ':'; } else { /* no colon before the first '/' */ *p = '/'; return RW_ERROR; } *p = '/'; /* get the host:port by isolating bit between 'schema://' and '/' */ q = p + 2; /* q is just past // */ p = strchr(q,'/'); /* get to / after host:port */ if (p) { /* isolate host:port, anything following is other_buf material */ term1 = p; *p++ = '\0'; strncpy(other_buf, p, other_buf_len); } p = strchr(q, ':'); if (p) { term2 = p; *p++ = '\0'; *port = atoi(p); } /* if url is schema:///, then there is no host string */ if (*q == '/') { host_buf[0] = '\0'; } else { strncpy(host_buf, q, host_buf_len); } if (term1) { *term1 = '/'; } if (term2) { *term2 = ':'; } return RW_OK; } /* parse referral lines of the form: [:port][:scheme][authority area] into scheme, host, port, and other. */ int rwhois_parse_old_style_ref(char *ref, char *scheme_buf, size_t scheme_buf_len, char *host_buf, size_t host_buf_len, int *port, char *other_buf, size_t other_buf_len) { char *p; char *q; char *r; p = strchr(ref, ' '); /* find the space. if there is one, the rest of the string is the 'other' */ if (p) { *p++ = '\0'; strncpy(other_buf, p, other_buf_len); } /* find the colons */ q = strchr(ref, ':'); r = strrchr(ref, ':'); /* if there is no space or colon, this doesn't match old style */ if (!p && !q) { return RW_ERROR; } /* check for one colon */ if (q == r) { *q++ = '\0'; if (is_number_str(q)) { *port = atoi(q); } else { strncpy(scheme_buf, q, scheme_buf_len); } strncpy(host_buf, ref, host_buf_len); *(--q) = ':'; } else { *(q++) = '\0'; *(r++) = '\0'; strncpy(scheme_buf, r, scheme_buf_len); if (is_number_str(q)) { *port = atoi(q); } strncpy(host_buf, ref, host_buf_len); *(--q) = ':'; *(--r) = ':'; } return RW_OK; } rw_referral_struct * rwhois_parse_referral(char *referral_str, rw_server_version_enum version, rw_referral_struct *referral) { char *url; char scheme[COMPONENT_BUF_LEN]; char host[COMPONENT_BUF_LEN]; int port = 0; char auth_area[COMPONENT_BUF_LEN]; assert(referral_str); if (!referral) { referral = (rw_referral_struct *) CALLOC(1, sizeof(*referral)); } url = strchr(referral_str, ' '); if (!url) return NULL; url++; memset(scheme, 0, sizeof(scheme)); memset(host, 0, sizeof(host)); memset(auth_area, 0, sizeof(auth_area)); /* old-style referrals will return an error here */ if (rwhois_parse_url(url, scheme, sizeof(scheme), host, sizeof(host), &port, auth_area, sizeof(auth_area)) >= 0) { referral->url = STRDUP(url); referral->scheme = STRDUP(scheme); referral->host = STRDUP(host); referral->port = port; referral->authority_area = STRDUP(auth_area); } else { /* old-style referral, hopefully */ memset(scheme, 0, sizeof(scheme)); memset(host, 0, sizeof(host)); memset(auth_area, 0, sizeof(auth_area)); if (rwhois_parse_old_style_ref(url, scheme, sizeof(scheme), host, sizeof(host), &port, auth_area, sizeof(auth_area)) >= 0) { referral->url = NULL; referral->old_style_line = STRDUP(url); referral->host = STRDUP(host); referral->port = port; referral->authority_area = STRDUP(auth_area); } else { return NULL; } } return referral; }