int conn_comm_get_server_address(struct sockaddr_in *addr, const char *hostname) { int ret; DEBUGASSERT(addr && hostname); con_dbg("Getting IP address for '%s'\n", hostname); ret = dns_gethostip(hostname, &addr->sin_addr.s_addr); if (ret != OK) { con_dbg("Failed to get address for '%s'\n", hostname); return ret; } addr->sin_family = AF_INET; con_dbg("Got address %d.%d.%d.%d for '%s'\n", addr->sin_addr.s_addr & 0xff, (addr->sin_addr.s_addr >> 8) & 0xff, (addr->sin_addr.s_addr >> 16) & 0xff, addr->sin_addr.s_addr >> 24, hostname); return OK; }
static int wget_base(FAR const char *url, FAR char *buffer, int buflen, wget_callback_t callback, FAR void *arg, FAR const char *posts, uint8_t mode) { struct sockaddr_in server; struct wget_s ws; struct timeval tv; bool redirected; char *dest,post_size[8]; int sockfd; int len,post_len; int ret; /* Initialize the state structure */ memset(&ws, 0, sizeof(struct wget_s)); ws.buffer = buffer; ws.buflen = buflen; ws.port = 80; /* Parse the hostname (with optional port number) and filename from the URL */ ret = netlib_parsehttpurl(url, &ws.port, ws.hostname, CONFIG_WEBCLIENT_MAXHOSTNAME, ws.filename, CONFIG_WEBCLIENT_MAXFILENAME); if (ret != 0) { ndbg("ERROR: Malformed HTTP URL: %s\n", url); set_errno(-ret); return ERROR; } nvdbg("hostname='%s' filename='%s'\n", ws.hostname, ws.filename); /* The following sequence may repeat indefinitely if we are redirected */ do { /* Re-initialize portions of the state structure that could have * been left from the previous time through the loop and should not * persist with the new connection. */ ws.httpstatus = HTTPSTATUS_NONE; ws.offset = 0; ws.datend = 0; ws.ndx = 0; /* Create a socket */ sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { /* socket failed. It will set the errno appropriately */ ndbg("ERROR: socket failed: %d\n", errno); return ERROR; } /* Set send and receive timeout values */ tv.tv_sec = CONFIG_WEBCLIENT_TIMEOUT; tv.tv_usec = 0; (void)setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (FAR const void *)&tv, sizeof(struct timeval)); (void)setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (FAR const void *)&tv, sizeof(struct timeval)); /* Get the server address from the host name */ server.sin_family = AF_INET; server.sin_port = htons(ws.port); ret = dns_gethostip(ws.hostname, &server.sin_addr.s_addr); if (ret < 0) { /* Could not resolve host (or malformed IP address) */ ndbg("ERROR: Failed to resolve hostname\n"); ret = -EHOSTUNREACH; goto errout_with_errno; } /* Connect to server. First we have to set some fields in the * 'server' address structure. The system will assign me an arbitrary * local port that is not in use. */ ret = connect(sockfd, (struct sockaddr *)&server, sizeof(struct sockaddr_in)); if (ret < 0) { ndbg("ERROR: connect failed: %d\n", errno); goto errout; } /* Send the GET request */ dest = ws.buffer; if (mode == WGET_MODE_POST) { dest = wget_strcpy(dest, g_httppost); } else { dest = wget_strcpy(dest, g_httpget); } #ifndef WGET_USE_URLENCODE dest = wget_strcpy(dest, ws.filename); #else //dest = wget_urlencode_strcpy(dest, ws.filename); dest = wget_strcpy(dest, ws.filename); #endif *dest++ = ISO_space; dest = wget_strcpy(dest, g_http10); dest = wget_strcpy(dest, g_httpcrnl); dest = wget_strcpy(dest, g_httphost); dest = wget_strcpy(dest, ws.hostname); dest = wget_strcpy(dest, g_httpcrnl); if (mode == WGET_MODE_POST) { dest = wget_strcpy(dest, g_httpform); dest = wget_strcpy(dest, g_httpcrnl); dest = wget_strcpy(dest, g_httpcontsize); /* Post content size */ post_len = strlen((char *)posts); sprintf(post_size,"%d", post_len); dest = wget_strcpy(dest, post_size); dest = wget_strcpy(dest, g_httpcrnl); } dest = wget_strcpy(dest, g_httpuseragentfields); if (mode == WGET_MODE_POST) { dest = wget_strcpy(dest, (char *)posts); } len = dest - buffer; ret = send(sockfd, buffer, len, 0); if (ret < 0) { ndbg("ERROR: send failed: %d\n", errno); goto errout; } /* Now loop to get the file sent in response to the GET. This * loop continues until either we read the end of file (nbytes == 0) * or until we detect that we have been redirected. */ ws.state = WEBCLIENT_STATE_STATUSLINE; redirected = false; for (;;) { ws.datend = recv(sockfd, ws.buffer, ws.buflen, 0); if (ws.datend < 0) { ndbg("ERROR: recv failed: %d\n", errno); ret = ws.datend; goto errout_with_errno; } else if (ws.datend == 0) { nvdbg("Connection lost\n"); close(sockfd); break; } /* Handle initial parsing of the status line */ ws.offset = 0; if (ws.state == WEBCLIENT_STATE_STATUSLINE) { ret = wget_parsestatus(&ws); if (ret < 0) { goto errout_with_errno; } } /* Parse the HTTP data */ if (ws.state == WEBCLIENT_STATE_HEADERS) { ret = wget_parseheaders(&ws); if (ret < 0) { goto errout_with_errno; } } /* Dispose of the data payload */ if (ws.state == WEBCLIENT_STATE_DATA) { if (ws.httpstatus != HTTPSTATUS_MOVED) { /* Let the client decide what to do with the received file */ callback(&ws.buffer, ws.offset, ws.datend, &buflen, arg); } else { redirected = true; close(sockfd); break; } } } } while (redirected); return OK; errout_with_errno: set_errno(-ret); errout: close(sockfd); return ERROR; }