#include #include #include #include #include static void print(const char* s) { if (s) { SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromCstr(s) }; SysWriteConsole(&req); } } static void print_char(char c) { SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromParts(&c, 1) }; SysWriteConsole(&req); } static void print_u64(uint64_t v) { char buf[32]; int n = 0; if (v == 0) { print("0"); return; } while (v && n < (int)sizeof(buf)) { buf[n++] = (char)('0' + (v % 10)); v /= 10; } while (n > 0) print_char(buf[--n]); } static void append_char(char* dst, size_t cap, size_t* off, char c) { if (!dst || !off || cap == 0 || *off + 1 >= cap) return; dst[*off] = c; *off += 1; dst[*off] = 0; } static void append_str(char* dst, size_t cap, size_t* off, const char* s) { if (!s) return; while (*s) append_char(dst, cap, off, *s++); } static void append_u8(char* dst, size_t cap, size_t* off, uint8_t v) { if (v >= 100) { append_char(dst, cap, off, (char)('0' + v / 100)); v %= 100; append_char(dst, cap, off, (char)('0' + v / 10)); append_char(dst, cap, off, (char)('0' + v % 10)); } else if (v >= 10) { append_char(dst, cap, off, (char)('0' + v / 10)); append_char(dst, cap, off, (char)('0' + v % 10)); } else { append_char(dst, cap, off, (char)('0' + v)); } } static void format_ipv4(char* dst, size_t cap, const uint8_t ip[4]) { size_t off = 0; if (!dst || cap == 0) return; dst[0] = 0; append_u8(dst, cap, &off, ip[0]); append_char(dst, cap, &off, '.'); append_u8(dst, cap, &off, ip[1]); append_char(dst, cap, &off, '.'); append_u8(dst, cap, &off, ip[2]); append_char(dst, cap, &off, '.'); append_u8(dst, cap, &off, ip[3]); } static bool parse_u8(const char** p, uint8_t* out) { const char* s = *p; uint32_t v = 0; int digits = 0; while (*s >= '0' && *s <= '9') { v = v * 10u + (uint32_t)(*s - '0'); if (v > 255u) return false; s++; digits++; } if (digits == 0) return false; *out = (uint8_t)v; *p = s; return true; } static bool parse_ipv4(const char* s, uint8_t ip[4]) { if (!s || !ip) return false; for (int i = 0; i < 4; i++) { if (!parse_u8(&s, &ip[i])) return false; if (i != 3) { if (*s != '.') return false; s++; } } return *s == 0; } static const char* next_token(const char* s, char* out, size_t outSize) { if (!s || !out || outSize == 0) return NULL; while (*s == ' ' || *s == '\t') s++; if (*s == 0) { out[0] = 0; return NULL; } size_t n = 0; while (*s && *s != ' ' && *s != '\t') { if (n + 1 < outSize) out[n++] = *s; s++; } out[n] = 0; return s; } static void usage(void) { print("usage: httpget.exe [host-or-ipv4] [path]\n"); print("default: httpget.exe 10.0.2.2 /\n"); } static uint32_t resolve_host(const char* host, uint8_t ip[4]) { if (parse_ipv4(host, ip)) return SYS_STATUS_SUCCESS; SYS_SOCKET_ADDRESS_IPV4 resolved; size_t resolvedSize = sizeof(resolved); SYS_RESOLVE_HOST_REQUEST req; memset(&resolved, 0, sizeof(resolved)); memset(&req, 0, sizeof(req)); req.Name = SysSvFromCstr(host); req.Family = SYS_AF_INET; req.AddressOut = &resolved; req.AddressSizeInOut = &resolvedSize; uint32_t st = SysResolveHost(&req); if (st != SYS_STATUS_SUCCESS) return st; if (resolved.Family != SYS_AF_INET) return SYS_STATUS_NOT_FOUND; ip[0] = resolved.Address[0]; ip[1] = resolved.Address[1]; ip[2] = resolved.Address[2]; ip[3] = resolved.Address[3]; return SYS_STATUS_SUCCESS; } int main(void) { uint8_t ip[4] = {10, 0, 2, 2}; char host[256]; char path[128]; strcpy(host, "10.0.2.2"); path[0] = '/'; path[1] = 0; const char* cmd = SysGetPeb()->CommandLine.Data; char tok[256]; cmd = next_token(cmd, tok, sizeof(tok)); // program path if (cmd) { const char* rest = next_token(cmd, tok, sizeof(tok)); if (tok[0]) { if (strlen(tok) >= sizeof(host)) { print("httpget: host too long\n"); SysExitProcess(1); } strcpy(host, tok); cmd = rest; } if (cmd) { (void)next_token(cmd, tok, sizeof(tok)); if (tok[0]) { size_t len = strlen(tok); if (len + 2 > sizeof(path)) { print("httpget: path too long\n"); SysExitProcess(1); } if (tok[0] != '/') { path[0] = '/'; memcpy(path + 1, tok, len + 1); } else { memcpy(path, tok, len + 1); } } } } uint32_t st = resolve_host(host, ip); if (st != SYS_STATUS_SUCCESS) { print("httpget: resolve failed "); print_u64(st); print(" for "); print(host); print("\n"); usage(); SysExitProcess(1); } char ipText[16]; format_ipv4(ipText, sizeof(ipText), ip); print("httpget: GET http://"); print(host); print(path); print(" ("); print(ipText); print(")\n"); uint32_t sock = 0; st = SysSocket(SYS_AF_INET, SYS_SOCK_STREAM, SYS_IPPROTO_TCP, &sock); if (st != SYS_STATUS_SUCCESS) { print("httpget: SysSocket failed "); print_u64(st); print("\n"); SysExitProcess(1); } SYS_SOCKET_ADDRESS_IPV4 addr; memset(&addr, 0, sizeof(addr)); addr.Family = SYS_AF_INET; addr.Port = 80; addr.Address[0] = ip[0]; addr.Address[1] = ip[1]; addr.Address[2] = ip[2]; addr.Address[3] = ip[3]; st = SysConnect(sock, &addr, sizeof(addr)); if (st != SYS_STATUS_SUCCESS) { print("httpget: SysConnect failed "); print_u64(st); print("\n"); SysCloseHandle(sock); SysExitProcess(1); } char request[512]; size_t off = 0; request[0] = 0; append_str(request, sizeof(request), &off, "GET "); append_str(request, sizeof(request), &off, path); append_str(request, sizeof(request), &off, " HTTP/1.0\r\nHost: "); append_str(request, sizeof(request), &off, host); append_str(request, sizeof(request), &off, "\r\nUser-Agent: nt-lite-sys-socket\r\nConnection: close\r\n\r\n"); size_t totalSent = 0; while (totalSent < off) { size_t sent = 0; st = SysSend(sock, request + totalSent, off - totalSent, 0, &sent); if (st != SYS_STATUS_SUCCESS || sent == 0) { print("httpget: SysSend failed "); print_u64(st); print(" sent="); print_u64(sent); print("\n"); SysCloseHandle(sock); SysExitProcess(1); } totalSent += sent; } char buf[513]; size_t total = 0; for (;;) { size_t got = 0; st = SysRecv(sock, buf, sizeof(buf) - 1, 0, &got); if (st != SYS_STATUS_SUCCESS) { print("\nhttpget: SysRecv failed "); print_u64(st); print(" after "); print_u64(total); print(" bytes\n"); SysCloseHandle(sock); SysExitProcess(1); } if (got == 0) break; buf[got] = 0; print(buf); total += got; } print("\nhttpget: done, "); print_u64(total); print(" bytes\n"); SysShutdown(sock, SYS_SHUTDOWN_BOTH); SysCloseHandle(sock); SysExitProcess(0); return 0; }