Merge branch 'master' into pass-os

This commit is contained in:
Jōshin 2023-12-30 22:34:58 -05:00
commit fc8bcd5cd5
No known key found for this signature in database
637 changed files with 5166 additions and 9120 deletions

View file

@ -198,9 +198,9 @@ include third_party/nsync/mem/BUILD.mk # │ You can now use stdio
include libc/proc/BUILD.mk # │ You can now use threads include libc/proc/BUILD.mk # │ You can now use threads
include libc/dlopen/BUILD.mk # │ You can now use processes include libc/dlopen/BUILD.mk # │ You can now use processes
include libc/thread/BUILD.mk # │ You can finally call malloc() include libc/thread/BUILD.mk # │ You can finally call malloc()
include tool/hello/BUILD.mk # │
include third_party/zlib/BUILD.mk # │ include third_party/zlib/BUILD.mk # │
include libc/stdio/BUILD.mk # │ include libc/stdio/BUILD.mk # │
include tool/hello/BUILD.mk # │
include libc/time/BUILD.mk # │ include libc/time/BUILD.mk # │
include net/BUILD.mk # │ include net/BUILD.mk # │
include third_party/vqsort/BUILD.mk # │ include third_party/vqsort/BUILD.mk # │
@ -213,9 +213,8 @@ include third_party/intel/BUILD.mk # │
include third_party/aarch64/BUILD.mk # │ include third_party/aarch64/BUILD.mk # │
include libc/BUILD.mk #─┘ include libc/BUILD.mk #─┘
include libc/sock/BUILD.mk #─┐ include libc/sock/BUILD.mk #─┐
include libc/dns/BUILD.mk # ├──ONLINE RUNTIME include net/http/BUILD.mk # ├──ONLINE RUNTIME
include net/http/BUILD.mk # │ You can communicate with the network include third_party/musl/BUILD.mk # │ You can communicate with the network
include third_party/musl/BUILD.mk # │
include libc/x/BUILD.mk # │ include libc/x/BUILD.mk # │
include dsp/scale/BUILD.mk # │ include dsp/scale/BUILD.mk # │
include dsp/mpeg/BUILD.mk # │ include dsp/mpeg/BUILD.mk # │
@ -297,7 +296,6 @@ include test/libc/calls/BUILD.mk
include test/libc/x/BUILD.mk include test/libc/x/BUILD.mk
include test/libc/xed/BUILD.mk include test/libc/xed/BUILD.mk
include test/libc/fmt/BUILD.mk include test/libc/fmt/BUILD.mk
include test/libc/dns/BUILD.mk
include test/libc/time/BUILD.mk include test/libc/time/BUILD.mk
include test/libc/proc/BUILD.mk include test/libc/proc/BUILD.mk
include test/libc/stdio/BUILD.mk include test/libc/stdio/BUILD.mk
@ -373,7 +371,6 @@ loc: o/$(MODE)/tool/build/summy.com
COSMOPOLITAN_OBJECTS = \ COSMOPOLITAN_OBJECTS = \
TOOL_ARGS \ TOOL_ARGS \
NET_HTTP \ NET_HTTP \
LIBC_DNS \
LIBC_SOCK \ LIBC_SOCK \
LIBC_NT_WS2_32 \ LIBC_NT_WS2_32 \
LIBC_NT_IPHLPAPI \ LIBC_NT_IPHLPAPI \
@ -424,7 +421,6 @@ COSMOPOLITAN_H_PKGS = \
APE \ APE \
LIBC \ LIBC \
LIBC_CALLS \ LIBC_CALLS \
LIBC_DNS \
LIBC_ELF \ LIBC_ELF \
LIBC_FMT \ LIBC_FMT \
LIBC_DLOPEN \ LIBC_DLOPEN \

View file

@ -78,7 +78,8 @@ APE_LOADER_FLAGS = \
$< $<
o/$(MODE)/ape/ape.elf: o/$(MODE)/ape/ape.elf.dbg o/$(MODE)/ape/ape.elf: o/$(MODE)/ape/ape.elf.dbg
$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -g $< $@ @$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -g $< $@
@$(COMPILE) -AFIXUPOBJ -wT$@ $(FIXUPOBJ) $@
o/$(MODE)/ape/ape.elf.dbg: \ o/$(MODE)/ape/ape.elf.dbg: \
o/$(MODE)/ape/start.o \ o/$(MODE)/ape/start.o \
@ -88,7 +89,7 @@ o/$(MODE)/ape/ape.elf.dbg: \
@$(COMPILE) -ALINK.elf $(LD) $(APE_LOADER_LDFLAGS) -o $@ $(patsubst %.lds,-T %.lds,$^) @$(COMPILE) -ALINK.elf $(LD) $(APE_LOADER_LDFLAGS) -o $@ $(patsubst %.lds,-T %.lds,$^)
o/$(MODE)/ape/loader.o: ape/loader.c ape/ape.h o/$(MODE)/ape/loader.o: ape/loader.c ape/ape.h
@$(COMPILE) -AOBJECTIFY.c $(CC) -DSUPPORT_VECTOR=1 -g $(APE_LOADER_FLAGS) @$(COMPILE) -AOBJECTIFY.c $(CC) -DSUPPORT_VECTOR=33 -g $(APE_LOADER_FLAGS)
o/$(MODE)/ape/start.o: ape/start.S o/$(MODE)/ape/start.o: ape/start.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $< @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/ape/launch.o: ape/launch.S o/$(MODE)/ape/launch.o: ape/launch.S

View file

@ -224,8 +224,8 @@ struct ApeLoader {
}; };
EXTERN_C long SystemCall(long, long, long, long, long, long, long, int); EXTERN_C long SystemCall(long, long, long, long, long, long, long, int);
EXTERN_C void EXTERN_C void Launch(void *, long, void *, int, void *)
Launch(void *, long, void *, int, void *) __attribute__((__noreturn__)); __attribute__((__noreturn__));
extern char __executable_start[]; extern char __executable_start[];
extern char _end[]; extern char _end[];

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -86,7 +86,7 @@ IGNORE := $(shell $(MKDIR) $(TMPDIR))
ifneq ($(findstring aarch64,$(MODE)),) ifneq ($(findstring aarch64,$(MODE)),)
ARCH = aarch64 ARCH = aarch64
HOSTS ?= pi silicon HOSTS ?= pi studio freebsdarm
else else
ARCH = x86_64 ARCH = x86_64
HOSTS ?= freebsd rhel7 xnu win10 openbsd netbsd HOSTS ?= freebsd rhel7 xnu win10 openbsd netbsd

View file

@ -9,8 +9,9 @@ int mulaw(int);
int unmulaw(int); int unmulaw(int);
void *double2byte(long, const void *, double, double) vallocesque; void *double2byte(long, const void *, double, double) vallocesque;
void *byte2double(long, const void *, double, double) vallocesque; void *byte2double(long, const void *, double, double) vallocesque;
void *dct(float[8][8], float, float, float, float, float); void *dct(float[restrict hasatleast 8][8], unsigned,
void *dctjpeg(float[8][8]); float, float, float, float, float);
void *dctjpeg(float[restrict hasatleast 8][8], unsigned);
double det3(const double[3][3]) nosideeffect; double det3(const double[3][3]) nosideeffect;
void *inv3(double[restrict 3][3], const double[restrict 3][3], double); void *inv3(double[restrict 3][3], const double[restrict 3][3], double);
void *matmul3(double[restrict 3][3], const double[3][3], const double[3][3]); void *matmul3(double[restrict 3][3], const double[3][3], const double[3][3]);

View file

@ -65,20 +65,21 @@
* *
* @cost ~100ns * @cost ~100ns
*/ */
void *dct(float M[8][8], float c0, float c1, float c2, float c3, float c4) { void *dct(float M[restrict hasatleast 8][8], unsigned stride,
float c0, float c1, float c2, float c3, float c4) {
unsigned y, x; unsigned y, x;
for (y = 0; y < 8; ++y) { for (y = 0; y < stride * 8; y += stride) {
DCT(M[y][0], M[y][1], M[y][2], M[y][3], M[y][4], M[y][5], M[y][6], M[y][7], DCT(M[y][0], M[y][1], M[y][2], M[y][3], M[y][4], M[y][5], M[y][6], M[y][7],
float, c0, c1, c2, c3, c4); float, c0, c1, c2, c3, c4);
} }
for (x = 0; x < 8; ++x) { for (x = 0; x < stride * 8; x += stride) {
DCT(M[0][x], M[1][x], M[2][x], M[3][x], M[4][x], M[5][x], M[6][x], M[7][x], DCT(M[0][x], M[1][x], M[2][x], M[3][x], M[4][x], M[5][x], M[6][x], M[7][x],
float, c0, c1, c2, c3, c4); float, c0, c1, c2, c3, c4);
} }
return M; return M;
} }
void *dctjpeg(float M[8][8]) { void *dctjpeg(float M[restrict hasatleast 8][8], unsigned stride) {
return dct(M, .707106781f, .382683433f, .541196100f, 1.306562965f, return dct(M, stride, .707106781f, .382683433f, .541196100f, 1.306562965f,
.707106781f); .707106781f);
} }

View file

@ -3,8 +3,6 @@
#include "dsp/mpeg/mpeg.h" #include "dsp/mpeg/mpeg.h"
COSMOPOLITAN_C_START_ COSMOPOLITAN_C_START_
struct FILE;
enum plm_buffer_mode { enum plm_buffer_mode {
PLM_BUFFER_MODE_FILE, PLM_BUFFER_MODE_FILE,
PLM_BUFFER_MODE_FIXED_MEM, PLM_BUFFER_MODE_FIXED_MEM,
@ -17,7 +15,7 @@ typedef struct plm_buffer_t {
unsigned length; unsigned length;
int free_when_done; int free_when_done;
int close_when_done; int close_when_done;
struct FILE *fh; FILE *fh;
plm_buffer_load_callback load_callback; plm_buffer_load_callback load_callback;
void *load_callback_user_data; void *load_callback_user_data;
unsigned char *bytes; unsigned char *bytes;

View file

@ -1,9 +1,8 @@
#ifndef COSMOPOLITAN_DSP_MPEG_MPEG_H_ #ifndef COSMOPOLITAN_DSP_MPEG_MPEG_H_
#define COSMOPOLITAN_DSP_MPEG_MPEG_H_ #define COSMOPOLITAN_DSP_MPEG_MPEG_H_
#include "libc/stdio/stdio.h"
COSMOPOLITAN_C_START_ COSMOPOLITAN_C_START_
struct FILE;
typedef struct plm_t plm_t; typedef struct plm_t plm_t;
typedef struct plm_buffer_t plm_buffer_t; typedef struct plm_buffer_t plm_buffer_t;
typedef struct plm_demux_t plm_demux_t; typedef struct plm_demux_t plm_demux_t;
@ -112,7 +111,7 @@ plm_t *plm_create_with_filename(const char *filename);
* to let plmpeg call fclose() on the handle when plm_destroy() is * to let plmpeg call fclose() on the handle when plm_destroy() is
* called. * called.
*/ */
plm_t *plm_create_with_file(struct FILE *fh, int close_when_done); plm_t *plm_create_with_file(FILE *fh, int close_when_done);
/** /**
* Create a plmpeg instance with pointer to memory as source. This assumes the * Create a plmpeg instance with pointer to memory as source. This assumes the
@ -257,7 +256,7 @@ plm_buffer_t *plm_buffer_create_with_filename(const char *filename);
* to let plmpeg call fclose() on the handle when plm_destroy() is * to let plmpeg call fclose() on the handle when plm_destroy() is
* called. * called.
*/ */
plm_buffer_t *plm_buffer_create_with_file(struct FILE *fh, int close_when_done); plm_buffer_t *plm_buffer_create_with_file(FILE *fh, int close_when_done);
/** /**
* Create a buffer instance with a pointer to memory as source. This assumes * Create a buffer instance with a pointer to memory as source. This assumes

View file

@ -5,7 +5,6 @@
COSMOPOLITAN_C_START_ COSMOPOLITAN_C_START_
struct FILE;
struct termios; struct termios;
struct TtyIdent { struct TtyIdent {

View file

@ -44,7 +44,6 @@ EXAMPLES_DIRECTDEPS = \
DSP_TTY \ DSP_TTY \
LIBC_CALLS \ LIBC_CALLS \
LIBC_DLOPEN \ LIBC_DLOPEN \
LIBC_DNS \
LIBC_FMT \ LIBC_FMT \
LIBC_INTRIN \ LIBC_INTRIN \
LIBC_IRQ \ LIBC_IRQ \

23
examples/crashreport2.cc Normal file
View file

@ -0,0 +1,23 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
To the extent possible under law, Justine Tunney has waived
all copyright and related or neighboring rights to this file,
as it is written in the following disclaimers:
http://unlicense.org/ │
http://creativecommons.org/publicdomain/zero/1.0/ │
*/
#endif
#include "libc/math.h"
#include "libc/runtime/runtime.h"
void crash(long x0, long x1, long x2, //
double v0, double v1, double v2) {
__builtin_trap();
}
void (*pCrash)(long, long, long, double, double, double) = crash;
int main(int argc, char *argv[]) {
ShowCrashReports();
pCrash(1, 2, 3, NAN, NAN, NAN);
}

View file

@ -8,7 +8,6 @@
*/ */
#endif #endif
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/dns/dns.h"
#include "libc/fmt/conv.h" #include "libc/fmt/conv.h"
#include "libc/log/log.h" #include "libc/log/log.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
@ -26,6 +25,7 @@
#include "libc/sysv/consts/sock.h" #include "libc/sysv/consts/sock.h"
#include "libc/sysv/consts/sol.h" #include "libc/sysv/consts/sol.h"
#include "third_party/getopt/getopt.internal.h" #include "third_party/getopt/getopt.internal.h"
#include "third_party/musl/netdb.h"
/** /**
* @fileoverview netcat clone * @fileoverview netcat clone
@ -60,9 +60,7 @@ int main(int argc, char *argv[]) {
halfclose = false; halfclose = false;
break; break;
case 'h': case 'h':
fputs("Usage: ", stdout); tinyprint(1, "Usage: ", argv[0], " [-hH] IP PORT\n", NULL);
fputs(argv[0], stdout);
fputs(" [-hH] IP PORT\n", stdout);
exit(0); exit(0);
default: default:
fprintf(stderr, "bad option %d\n", opt); fprintf(stderr, "bad option %d\n", opt);
@ -76,16 +74,8 @@ int main(int argc, char *argv[]) {
host = argv[optind + 0]; host = argv[optind + 0];
port = argv[optind + 1]; port = argv[optind + 1];
switch ((rc = getaddrinfo(host, port, &hint, &ai))) { if ((rc = getaddrinfo(host, port, &hint, &ai))) {
case EAI_SUCCESS: tinyprint(2, host, ": ", gai_strerror(rc), "\n", NULL);
break;
case EAI_SYSTEM:
perror("getaddrinfo");
exit(1);
default:
fputs("EAI_", stderr);
fputs(gai_strerror(rc), stderr);
fputs("\n", stderr);
exit(1); exit(1);
} }
@ -95,12 +85,12 @@ int main(int argc, char *argv[]) {
} }
if (setsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)) == -1) { if (setsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)) == -1) {
perror("setsockopt(SO_LINGER)"); perror("SO_LINGER");
exit(1); exit(1);
} }
if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) { if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
perror("connect"); perror(host);
exit(1); exit(1);
} }

View file

@ -30,12 +30,13 @@
*/ */
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/weirdtypes.h" #include "libc/calls/weirdtypes.h"
#include "libc/dns/dns.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/log/bsd.h" #include "libc/log/bsd.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/sock/sock.h"
#include "libc/sock/struct/pollfd.h" #include "libc/sock/struct/pollfd.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/sysv/consts/af.h" #include "libc/sysv/consts/af.h"
#include "libc/sysv/consts/ex.h" #include "libc/sysv/consts/ex.h"
@ -44,6 +45,7 @@
#include "libc/sysv/consts/poll.h" #include "libc/sysv/consts/poll.h"
#include "libc/sysv/consts/sock.h" #include "libc/sysv/consts/sock.h"
#include "third_party/getopt/getopt.internal.h" #include "third_party/getopt/getopt.internal.h"
#include "third_party/musl/netdb.h"
// clang-format off // clang-format off
asm(".ident\t\"\\n\\n\ asm(".ident\t\"\\n\\n\

View file

@ -276,7 +276,6 @@ LIBC_FILES := $(wildcard libc/*)
o/$(MODE)/libc: o/$(MODE)/libc/calls \ o/$(MODE)/libc: o/$(MODE)/libc/calls \
o/$(MODE)/libc/crt \ o/$(MODE)/libc/crt \
o/$(MODE)/libc/dlopen \ o/$(MODE)/libc/dlopen \
o/$(MODE)/libc/dns \
o/$(MODE)/libc/elf \ o/$(MODE)/libc/elf \
o/$(MODE)/libc/fmt \ o/$(MODE)/libc/fmt \
o/$(MODE)/libc/intrin \ o/$(MODE)/libc/intrin \

View file

@ -1,7 +1,7 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ /*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney Copyright 2023 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the any purpose with or without fee is hereby granted, provided that the
@ -16,11 +16,13 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/dns/ent.h" #include "libc/calls/sysdir.internal.h"
#include "libc/dce.h"
// error number global for gethostbyname*(), gethostbyaddr*(), etc. const char *GetHostsTxtPath(char *path, size_t size) {
static _Thread_local int __h_errno; if (!IsWindows()) {
return "/etc/hosts";
errno_t *__h_errno_location(void) { } else {
return &__h_errno; return GetSystemDirectoryPath(path, "drivers\\etc\\hosts", size);
}
} }

View file

@ -1,7 +1,7 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ /*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney Copyright 2023 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the any purpose with or without fee is hereby granted, provided that the
@ -16,18 +16,13 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/dns/dns.h" #include "libc/calls/sysdir.internal.h"
#include "libc/mem/mem.h" #include "libc/dce.h"
/** const char *GetProtocolsTxtPath(char *buf, size_t size) {
* Frees addresses returned by getaddrinfo(). if (!IsWindows()) {
*/ return "/etc/protocols";
void freeaddrinfo(struct addrinfo *ai) { } else {
struct addrinfo *next; return GetSystemDirectoryPath(buf, "drivers\\etc\\protocol", size);
while (ai) {
/* we assume ai_addr and ai_canonname are shoehorned */
next = ai->ai_next;
free(ai);
ai = next;
} }
} }

View file

@ -1,7 +1,7 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ /*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney Copyright 2023 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the any purpose with or without fee is hereby granted, provided that the
@ -16,22 +16,13 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/dns/ent.h" #include "libc/calls/sysdir.internal.h"
#include "libc/dce.h"
/** const char *GetServicesTxtPath(char *path, size_t size) {
* Turns `h_errno` value into string. if (!IsWindows()) {
*/ return "/etc/services";
const char *hstrerror(int err) { } else {
switch (err) { return GetSystemDirectoryPath(path, "drivers\\etc\\services", size);
case HOST_NOT_FOUND:
return "HOST_NOT_FOUND";
case TRY_AGAIN:
return "TRY_AGAIN";
case NO_RECOVERY:
return "NO_RECOVERY";
case NO_DATA:
return "NO_DATA";
default:
return "UNKNOWN";
} }
} }

View file

@ -16,19 +16,16 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/dns/dns.h"
#include "libc/nt/systeminfo.h" #include "libc/nt/systeminfo.h"
#include "libc/str/str.h" #include "libc/str/str.h"
// e.g. GetSystemDirectoryPath(buf, size, "FOO") → "C:\WINDOWS\SYSTEM32\FOO" // e.g. GetSystemDirectoryPath(buf, "FOO", size) → "C:\WINDOWS\SYSTEM32\FOO"
textwindows char *GetSystemDirectoryPath(char *buf, size_t size, textwindows char *GetSystemDirectoryPath(char *buf, const char *path,
const char *path) { size_t size) {
uint32_t syslen = GetSystemDirectoryA(buf, size); uint32_t syslen = GetSystemDirectoryA(buf, size);
size_t pathlen = strlen(path); size_t pathlen = strlen(path);
if (syslen && syslen + pathlen + 1 < size) { if (syslen && syslen + pathlen + 1 < size) {
if (buf[syslen] == '\\') { if (buf[syslen] == '\\') --syslen;
--syslen;
}
memcpy(buf + syslen, path, pathlen + 1); memcpy(buf + syslen, path, pathlen + 1);
return buf; return buf;
} else { } else {

View file

@ -17,46 +17,43 @@
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/calls/syscall_support-nt.internal.h" #include "libc/calls/syscall_support-nt.internal.h"
#include "libc/macros.internal.h"
#include "libc/nt/enum/offerpriority.h" #include "libc/nt/enum/offerpriority.h"
#include "libc/nt/memory.h"
#include "libc/nt/runtime.h" #include "libc/nt/runtime.h"
#include "libc/nt/struct/memoryrangeentry.h" #include "libc/nt/struct/memoryrangeentry.h"
#include "libc/sysv/consts/madv.h" #include "libc/sysv/consts/madv.h"
#include "libc/sysv/errfuns.h" #include "libc/sysv/errfuns.h"
forceinline typeof(PrefetchVirtualMemory) *GetPrefetchVirtualMemory(void) { typedef bool32 (*__msabi PrefetchVirtualMemoryPtr)(
static bool once; int64_t hProcess, uintptr_t NumberOfEntries,
static typeof(PrefetchVirtualMemory) *PrefetchVirtualMemory_; struct NtMemoryRangeEntry *VirtualAddresses, uint32_t reserved_Flags);
if (!once) {
textwindows static PrefetchVirtualMemoryPtr GetPrefetchVirtualMemory(void) {
static PrefetchVirtualMemoryPtr PrefetchVirtualMemory_;
if (!PrefetchVirtualMemory_) {
PrefetchVirtualMemory_ = /* win8.1+ */ PrefetchVirtualMemory_ = /* win8.1+ */
GetProcAddressModule("Kernel32.dll", "PrefetchVirtualMemory"); GetProcAddressModule("Kernel32.dll", "PrefetchVirtualMemory");
once = true;
} }
return PrefetchVirtualMemory_; return PrefetchVirtualMemory_;
} }
forceinline typeof(OfferVirtualMemory) *GetOfferVirtualMemory(void) { typedef bool32 (*__msabi OfferVirtualMemoryPtr)(void *inout_VirtualAddress,
static bool once; size_t Size, int Priority);
static typeof(OfferVirtualMemory) *OfferVirtualMemory_;
if (!once) { textwindows static OfferVirtualMemoryPtr GetOfferVirtualMemory(void) {
static OfferVirtualMemoryPtr OfferVirtualMemory_;
if (!OfferVirtualMemory_) {
OfferVirtualMemory_ = /* win8.1+ */ OfferVirtualMemory_ = /* win8.1+ */
GetProcAddressModule("Kernel32.dll", "OfferVirtualMemory"); GetProcAddressModule("Kernel32.dll", "OfferVirtualMemory");
once = true;
} }
return OfferVirtualMemory_; return OfferVirtualMemory_;
} }
textwindows int sys_madvise_nt(void *addr, size_t length, int advice) { textwindows int sys_madvise_nt(void *addr, size_t length, int advice) {
uint32_t rangecount;
struct NtMemoryRangeEntry ranges[1];
if (advice == MADV_WILLNEED || advice == MADV_SEQUENTIAL) { if (advice == MADV_WILLNEED || advice == MADV_SEQUENTIAL) {
typeof(PrefetchVirtualMemory) *fn = GetPrefetchVirtualMemory(); PrefetchVirtualMemoryPtr fn = GetPrefetchVirtualMemory();
if (fn) { if (fn) {
ranges[0].VirtualAddress = addr; if (fn(GetCurrentProcess(), 1, &(struct NtMemoryRangeEntry){addr, length},
ranges[0].NumberOfBytes = length; 0)) {
rangecount = ARRAYLEN(ranges);
if (fn(GetCurrentProcess(), &rangecount, ranges, 0)) {
return 0; return 0;
} else { } else {
return __winerr(); return __winerr();
@ -65,7 +62,7 @@ textwindows int sys_madvise_nt(void *addr, size_t length, int advice) {
return enosys(); return enosys();
} }
} else if (advice == MADV_FREE) { } else if (advice == MADV_FREE) {
typeof(OfferVirtualMemory) *fn = GetOfferVirtualMemory(); OfferVirtualMemoryPtr fn = GetOfferVirtualMemory();
if (fn) { if (fn) {
if (fn(addr, length, kNtVmOfferPriorityNormal)) { if (fn(addr, length, kNtVmOfferPriorityNormal)) {
return 0; return 0;

View file

@ -29,12 +29,15 @@
* *
* @param advice can be MADV_WILLNEED, MADV_SEQUENTIAL, MADV_FREE, etc. * @param advice can be MADV_WILLNEED, MADV_SEQUENTIAL, MADV_FREE, etc.
* @return 0 on success, or -1 w/ errno * @return 0 on success, or -1 w/ errno
* @raise EINVAL if `advice` isn't valid or supported by system
* @raise EINVAL on Linux if addr/length isn't page size aligned with
* respect to `getauxval(AT_PAGESZ)`
* @raise ENOMEM on Linux if addr/length overlaps unmapped regions
* @see libc/sysv/consts.sh * @see libc/sysv/consts.sh
* @see fadvise() * @see fadvise()
*/ */
int madvise(void *addr, size_t length, int advice) { int madvise(void *addr, size_t length, int advice) {
int rc; int rc;
if (advice != 127 /* see consts.sh */) {
if (IsAsan() && !__asan_is_valid(addr, length)) { if (IsAsan() && !__asan_is_valid(addr, length)) {
rc = efault(); rc = efault();
} else if (!IsWindows()) { } else if (!IsWindows()) {
@ -42,9 +45,6 @@ int madvise(void *addr, size_t length, int advice) {
} else { } else {
rc = sys_madvise_nt(addr, length, advice); rc = sys_madvise_nt(addr, length, advice);
} }
} else {
rc = einval();
}
STRACE("madvise(%p, %'zu, %d) → %d% m", addr, length, advice, rc); STRACE("madvise(%p, %'zu, %d) → %d% m", addr, length, advice, rc);
return rc; return rc;
} }

View file

@ -23,6 +23,10 @@
* Advises kernel about memory intentions, the POSIX way. * Advises kernel about memory intentions, the POSIX way.
* *
* @return 0 on success, or errno on error * @return 0 on success, or errno on error
* @raise EINVAL if `advice` isn't valid or supported by system
* @raise EINVAL on Linux if addr/length isn't page size aligned with
* respect to `getauxval(AT_PAGESZ)`
* @raise ENOMEM on Linux if addr/length overlaps unmapped regions
* @returnserrno * @returnserrno
*/ */
errno_t posix_madvise(void *addr, uint64_t len, int advice) { errno_t posix_madvise(void *addr, uint64_t len, int advice) {

View file

@ -16,8 +16,8 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/calls/struct/seccomp.internal.h"
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/struct/seccomp.internal.h"
#include "libc/calls/syscall-sysv.internal.h" #include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/errno.h" #include "libc/errno.h"
@ -62,6 +62,7 @@ int seccomp(unsigned operation, unsigned flags, void *args) {
rc = -1; rc = -1;
} }
#elif defined(__aarch64__) #elif defined(__aarch64__)
if (IsLinux()) {
register long r0 asm("x0") = (long)operation; register long r0 asm("x0") = (long)operation;
register long r1 asm("x1") = (long)flags; register long r1 asm("x1") = (long)flags;
register long r2 asm("x2") = (long)args; register long r2 asm("x2") = (long)args;
@ -72,6 +73,9 @@ int seccomp(unsigned operation, unsigned flags, void *args) {
: "i"(211), "r"(r0), "r"(r1), "r"(r2) : "i"(211), "r"(r0), "r"(r1), "r"(r2)
: "x8", "memory"); : "x8", "memory");
rc = _sysret(res_x0); rc = _sysret(res_x0);
} else {
rc = enosys();
}
#else #else
#error "arch unsupported" #error "arch unsupported"
#endif #endif

View file

@ -20,6 +20,7 @@
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/internal.h" #include "libc/calls/internal.h"
#include "libc/calls/state.internal.h" #include "libc/calls/state.internal.h"
#include "libc/calls/struct/aarch64.internal.h"
#include "libc/calls/struct/sigaction.h" #include "libc/calls/struct/sigaction.h"
#include "libc/calls/struct/siginfo-freebsd.internal.h" #include "libc/calls/struct/siginfo-freebsd.internal.h"
#include "libc/calls/struct/siginfo-meta.internal.h" #include "libc/calls/struct/siginfo-meta.internal.h"
@ -33,18 +34,18 @@
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/sysv/consts/sa.h" #include "libc/sysv/consts/sa.h"
#ifdef __x86_64__
privileged void __sigenter_freebsd(int sig, struct siginfo_freebsd *freebsdinfo, privileged void __sigenter_freebsd(int sig, struct siginfo_freebsd *freebsdinfo,
struct ucontext_freebsd *ctx) { struct ucontext_freebsd *ctx) {
#pragma GCC push_options #pragma GCC push_options
#pragma GCC diagnostic ignored "-Wframe-larger-than=" #pragma GCC diagnostic ignored "-Wframe-larger-than="
struct Goodies { struct {
ucontext_t uc; ucontext_t uc;
siginfo_t si; siginfo_t si;
} g; } g;
CheckLargeStackAllocation(&g, sizeof(g)); CheckLargeStackAllocation(&g, sizeof(g));
#pragma GCC pop_options #pragma GCC pop_options
int rva, flags; int rva, flags;
rva = __sighandrvas[sig]; rva = __sighandrvas[sig];
if (rva >= kSigactionMinRva) { if (rva >= kSigactionMinRva) {
@ -52,12 +53,20 @@ privileged void __sigenter_freebsd(int sig, struct siginfo_freebsd *freebsdinfo,
if (~flags & SA_SIGINFO) { if (~flags & SA_SIGINFO) {
((sigaction_f)(__executable_start + rva))(sig, 0, 0); ((sigaction_f)(__executable_start + rva))(sig, 0, 0);
} else { } else {
//
// TRANSLATE FREEBSD SIGNAL TO LINUX SIGNAL
//
__repstosb(&g, 0, sizeof(g)); __repstosb(&g, 0, sizeof(g));
g.uc.uc_mcontext.fpregs = &g.uc.__fpustate; __siginfo2cosmo(&g.si, (void *)freebsdinfo);
g.uc.uc_stack.ss_sp = ctx->uc_stack.ss_sp; g.uc.uc_stack.ss_sp = ctx->uc_stack.ss_sp;
g.uc.uc_stack.ss_size = ctx->uc_stack.ss_size; g.uc.uc_stack.ss_size = ctx->uc_stack.ss_size;
g.uc.uc_stack.ss_flags = ctx->uc_stack.ss_flags; g.uc.uc_stack.ss_flags = ctx->uc_stack.ss_flags;
g.uc.uc_sigmask = ctx->uc_sigmask[0] | (uint64_t)ctx->uc_sigmask[0] << 32; g.uc.uc_sigmask = ctx->uc_sigmask[0] | (uint64_t)ctx->uc_sigmask[0] << 32;
#ifdef __x86_64__
g.uc.uc_mcontext.fpregs = &g.uc.__fpustate;
g.uc.uc_mcontext.r8 = ctx->uc_mcontext.mc_r8; g.uc.uc_mcontext.r8 = ctx->uc_mcontext.mc_r8;
g.uc.uc_mcontext.r9 = ctx->uc_mcontext.mc_r9; g.uc.uc_mcontext.r9 = ctx->uc_mcontext.mc_r9;
g.uc.uc_mcontext.r10 = ctx->uc_mcontext.mc_r10; g.uc.uc_mcontext.r10 = ctx->uc_mcontext.mc_r10;
@ -81,14 +90,39 @@ privileged void __sigenter_freebsd(int sig, struct siginfo_freebsd *freebsdinfo,
g.uc.uc_mcontext.err = ctx->uc_mcontext.mc_err; g.uc.uc_mcontext.err = ctx->uc_mcontext.mc_err;
g.uc.uc_mcontext.trapno = ctx->uc_mcontext.mc_trapno; g.uc.uc_mcontext.trapno = ctx->uc_mcontext.mc_trapno;
__repmovsb(&g.uc.__fpustate, &ctx->uc_mcontext.mc_fpstate, 512); __repmovsb(&g.uc.__fpustate, &ctx->uc_mcontext.mc_fpstate, 512);
__siginfo2cosmo(&g.si, (void *)freebsdinfo); #endif /* __x86_64__ */
#ifdef __aarch64__
__memcpy(g.uc.uc_mcontext.regs, &ctx->uc_mcontext.mc_gpregs, 34 * 8);
if (ctx->uc_mcontext.mc_flags & _MC_FP_VALID) {
struct fpsimd_context *vc =
(struct fpsimd_context *)g.uc.uc_mcontext.__reserved;
vc->head.magic = FPSIMD_MAGIC;
vc->head.size = sizeof(*vc);
vc->fpsr = ctx->uc_mcontext.mc_fpregs.fp_sr;
vc->fpcr = ctx->uc_mcontext.mc_fpregs.fp_cr;
__memcpy(vc->vregs, ctx->uc_mcontext.mc_fpregs.fp_q, 32 * 16);
}
#endif /* __aarch64__ */
//
// INVOKE SIGNAL HANDLER
//
((sigaction_f)(__executable_start + rva))(sig, &g.si, &g.uc); ((sigaction_f)(__executable_start + rva))(sig, &g.si, &g.uc);
//
// TRANSLATE LINUX SIGNAL TO FREEBSD SIGNAL
//
ctx->uc_stack.ss_sp = g.uc.uc_stack.ss_sp; ctx->uc_stack.ss_sp = g.uc.uc_stack.ss_sp;
ctx->uc_stack.ss_size = g.uc.uc_stack.ss_size; ctx->uc_stack.ss_size = g.uc.uc_stack.ss_size;
ctx->uc_stack.ss_flags = g.uc.uc_stack.ss_flags; ctx->uc_stack.ss_flags = g.uc.uc_stack.ss_flags;
ctx->uc_flags = g.uc.uc_flags; ctx->uc_flags = g.uc.uc_flags;
ctx->uc_sigmask[0] = g.uc.uc_sigmask; ctx->uc_sigmask[0] = g.uc.uc_sigmask;
ctx->uc_sigmask[1] = g.uc.uc_sigmask >> 32; ctx->uc_sigmask[1] = g.uc.uc_sigmask >> 32;
#ifdef __x86_64__
ctx->uc_mcontext.mc_rdi = g.uc.uc_mcontext.rdi; ctx->uc_mcontext.mc_rdi = g.uc.uc_mcontext.rdi;
ctx->uc_mcontext.mc_rsi = g.uc.uc_mcontext.rsi; ctx->uc_mcontext.mc_rsi = g.uc.uc_mcontext.rsi;
ctx->uc_mcontext.mc_rdx = g.uc.uc_mcontext.rdx; ctx->uc_mcontext.mc_rdx = g.uc.uc_mcontext.rdx;
@ -112,13 +146,24 @@ privileged void __sigenter_freebsd(int sig, struct siginfo_freebsd *freebsdinfo,
ctx->uc_mcontext.mc_rip = g.uc.uc_mcontext.rip; ctx->uc_mcontext.mc_rip = g.uc.uc_mcontext.rip;
ctx->uc_mcontext.mc_rsp = g.uc.uc_mcontext.rsp; ctx->uc_mcontext.mc_rsp = g.uc.uc_mcontext.rsp;
__repmovsb(&ctx->uc_mcontext.mc_fpstate, &g.uc.__fpustate, 512); __repmovsb(&ctx->uc_mcontext.mc_fpstate, &g.uc.__fpustate, 512);
}
}
/*
* When the FreeBSD kernel invokes this signal handler it pushes a
* trampoline on the stack which does two things: 1) it calls this
* function, and 2) calls sys_sigreturn() once this returns.
*/
}
#endif /* __x86_64__ */ #endif /* __x86_64__ */
#ifdef __aarch64__
__memcpy(&ctx->uc_mcontext.mc_gpregs, g.uc.uc_mcontext.regs, 34 * 8);
struct fpsimd_context *vc =
(struct fpsimd_context *)g.uc.uc_mcontext.__reserved;
if (vc->head.magic == FPSIMD_MAGIC) {
ctx->uc_mcontext.mc_flags |= _MC_FP_VALID;
ctx->uc_mcontext.mc_fpregs.fp_sr = vc->fpsr;
ctx->uc_mcontext.mc_fpregs.fp_cr = vc->fpcr;
__memcpy(ctx->uc_mcontext.mc_fpregs.fp_q, vc->vregs, 32 * 16);
}
#endif /* __aarch64__ */
// done
}
}
// When the FreeBSD kernel invokes this signal handler it pushes a
// trampoline on the stack which does two things: 1) it calls this
// function, and 2) calls sys_sigreturn() once this returns.
}

View file

@ -2,6 +2,22 @@
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_UCONTEXT_FREEBSD_INTERNAL_H_ #define COSMOPOLITAN_LIBC_CALLS_STRUCT_UCONTEXT_FREEBSD_INTERNAL_H_
COSMOPOLITAN_C_START_ COSMOPOLITAN_C_START_
struct gpregs_freebsd_aarch64 {
int64_t gp_x[30];
int64_t gp_lr;
int64_t gp_sp;
int64_t gp_elr; /* pc */
uint64_t gp_spsr; /* pstate or cpsr */
};
struct fpregs_freebsd_aarch64 {
uint128_t fp_q[32];
uint32_t fp_sr;
uint32_t fp_cr;
int fp_flags;
int fp_pad;
};
struct stack_freebsd { struct stack_freebsd {
void *ss_sp; void *ss_sp;
uint64_t ss_size; uint64_t ss_size;
@ -9,6 +25,7 @@ struct stack_freebsd {
}; };
struct mcontext_freebsd { struct mcontext_freebsd {
#ifdef __x86_64__
int64_t mc_onstack; int64_t mc_onstack;
int64_t mc_rdi; int64_t mc_rdi;
int64_t mc_rsi; int64_t mc_rsi;
@ -47,6 +64,14 @@ struct mcontext_freebsd {
int64_t mc_xfpustate; int64_t mc_xfpustate;
int64_t mc_xfpustate_len; int64_t mc_xfpustate_len;
int64_t mc_spare[4]; int64_t mc_spare[4];
#elif defined(__aarch64__)
struct gpregs_freebsd_aarch64 mc_gpregs;
struct fpregs_freebsd_aarch64 mc_fpregs;
int mc_flags;
#define _MC_FP_VALID 0x1 /* Set when mc_fpregs has valid data */
int mc_pad; /* Padding */
uint64_t mc_spare[8]; /* Space for expansion, set to zero */
#endif
}; };
struct ucontext_freebsd { struct ucontext_freebsd {

View file

@ -0,0 +1,11 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_SYSDIR_H_
#define COSMOPOLITAN_LIBC_CALLS_SYSDIR_H_
COSMOPOLITAN_C_START_
const char *GetHostsTxtPath(char *, size_t);
const char *GetServicesTxtPath(char *, size_t);
const char *GetProtocolsTxtPath(char *, size_t);
char *GetSystemDirectoryPath(char *, const char *, size_t);
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_CALLS_SYSDIR_H_ */

View file

@ -125,6 +125,11 @@ _start:
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#elif defined(__aarch64__) #elif defined(__aarch64__)
#if SupportsFreebsd()
// save first arg
mov x3,x0
#endif
// save original stack pointer // save original stack pointer
// this is the first argument to cosmo() below // this is the first argument to cosmo() below
mov x0,sp mov x0,sp

View file

@ -13,7 +13,7 @@
*/ */
#define SUPPORT_VECTOR 255 #define SUPPORT_VECTOR 255
#else #else
#define SUPPORT_VECTOR (_HOSTLINUX | _HOSTXNU) #define SUPPORT_VECTOR (_HOSTLINUX | _HOSTXNU | _HOSTFREEBSD)
#endif #endif
#endif #endif
@ -62,8 +62,10 @@
#endif #endif
#ifdef __aarch64__ #ifdef __aarch64__
#define IsAarch64() 1
#define IsXnuSilicon() IsXnu() #define IsXnuSilicon() IsXnu()
#else #else
#define IsAarch64() 0
#define IsXnuSilicon() 0 #define IsXnuSilicon() 0
#endif #endif

View file

@ -1,59 +0,0 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#── vi: set noet ft=make ts=8 sw=8 fenc=utf-8 :vi ────────────────────┘
PKGS += LIBC_DNS
LIBC_DNS_ARTIFACTS += LIBC_DNS_A
LIBC_DNS = $(LIBC_DNS_A_DEPS) $(LIBC_DNS_A)
LIBC_DNS_A = o/$(MODE)/libc/dns/dns.a
LIBC_DNS_A_FILES := $(wildcard libc/dns/*)
LIBC_DNS_A_HDRS = $(filter %.h,$(LIBC_DNS_A_FILES))
LIBC_DNS_A_SRCS_C = $(filter %.c,$(LIBC_DNS_A_FILES))
LIBC_DNS_A_SRCS_S = $(filter %.S,$(LIBC_DNS_A_FILES))
LIBC_DNS_A_SRCS = \
$(LIBC_DNS_A_SRCS_S) \
$(LIBC_DNS_A_SRCS_C)
LIBC_DNS_A_OBJS = \
$(LIBC_DNS_A_SRCS_S:%.S=o/$(MODE)/%.o) \
$(LIBC_DNS_A_SRCS_C:%.c=o/$(MODE)/%.o)
LIBC_DNS_A_CHECKS = \
$(LIBC_DNS_A).pkg \
$(LIBC_DNS_A_HDRS:%=o/$(MODE)/%.ok)
LIBC_DNS_A_DIRECTDEPS = \
LIBC_CALLS \
LIBC_FMT \
LIBC_INTRIN \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_NT_ADVAPI32 \
LIBC_NT_KERNEL32 \
LIBC_RUNTIME \
LIBC_SOCK \
LIBC_STDIO \
LIBC_STR \
LIBC_SYSV
LIBC_DNS_A_DEPS := \
$(call uniq,$(foreach x,$(LIBC_DNS_A_DIRECTDEPS),$($(x))))
$(LIBC_DNS_A): libc/dns/ \
$(LIBC_DNS_A).pkg \
$(LIBC_DNS_A_OBJS)
$(LIBC_DNS_A).pkg: \
$(LIBC_DNS_A_OBJS) \
$(foreach x,$(LIBC_DNS_A_DIRECTDEPS),$($(x)_A).pkg)
LIBC_DNS_LIBS = $(foreach x,$(LIBC_DNS_ARTIFACTS),$($(x)))
LIBC_DNS_SRCS = $(foreach x,$(LIBC_DNS_ARTIFACTS),$($(x)_SRCS))
LIBC_DNS_HDRS = $(foreach x,$(LIBC_DNS_ARTIFACTS),$($(x)_HDRS))
LIBC_DNS_CHECKS = $(foreach x,$(LIBC_DNS_ARTIFACTS),$($(x)_CHECKS))
LIBC_DNS_OBJS = $(foreach x,$(LIBC_DNS_ARTIFACTS),$($(x)_OBJS))
$(LIBC_DNS_OBJS): $(BUILD_FILES) libc/dns/BUILD.mk
.PHONY: o/$(MODE)/libc/dns
o/$(MODE)/libc/dns: $(LIBC_DNS_CHECKS)

View file

@ -1,77 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dns/dns.h"
#include "libc/macros.internal.h"
#include "libc/str/str.h"
forceinline void FindDnsLabel(const char *A, size_t *i, size_t *n) {
while (*i) {
if (A[*i - 1] == '.') {
if (*i == *n) {
--(*n);
} else {
break;
}
}
--(*i);
}
}
/**
* Compares DNS hostnames in reverse lexicographical asciibetical order.
* @return <0, 0, or >0
* @see test/libc/dns/comparednsnames_test.c (the code that matters)
*/
int CompareDnsNames(const char *A, const char *B) {
int res;
bool first;
size_t n, m, i, j;
if (A == B) return 0;
n = strlen(A);
m = strlen(B);
if (!n || !m || ((A[n - 1] == '.') ^ (B[m - 1] == '.'))) {
if (n && m && A[n - 1] == '.' && strchr(B, '.')) {
--m;
} else if (n && m && B[m - 1] == '.' && strchr(A, '.')) {
--n;
} else {
return A[n ? n - 1 : 0] - B[m ? m - 1 : 0];
}
}
i = n;
j = m;
first = true;
for (;;) {
FindDnsLabel(A, &i, &n);
FindDnsLabel(B, &j, &m);
if (first) {
first = false;
if (!i && j) return 1;
if (!j && i) return -1;
}
if ((res = strncasecmp(&A[i], &B[j], MIN(n - i + 1, m - j + 1)))) {
return res;
}
if (!i || !j) {
return i - j;
}
n = i;
m = j;
}
}

View file

@ -1,19 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_DNS_CONSTS_H_
#define COSMOPOLITAN_LIBC_DNS_CONSTS_H_
#include "libc/sock/sock.h"
#define DNS_TYPE_A 1
#define DNS_TYPE_NS 2
#define DNS_TYPE_CNAME 5
#define DNS_TYPE_SOA 6
#define DNS_TYPE_PTR 12
#define DNS_TYPE_MX 15
#define DNS_TYPE_TXT 16
#define DNS_CLASS_IN 1
#define kMinSockaddr4Size \
(offsetof(struct sockaddr_in, sin_addr) + sizeof(struct in_addr))
#endif /* COSMOPOLITAN_LIBC_DNS_CONSTS_H_ */

View file

@ -1,79 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_DNS_DNS_H_
#define COSMOPOLITAN_LIBC_DNS_DNS_H_
#include "libc/dns/resolvconf.h"
#include "libc/sock/struct/sockaddr.h"
#define DNS_PORT 53
#define DNS_NAME_MAX 253
#define DNS_LABEL_MAX 63
#define EAI_SUCCESS 0
#define EAI_BADFLAGS -1
#define EAI_NONAME -2
#define EAI_AGAIN -3
#define EAI_FAIL -4
#define EAI_NODATA -5
#define EAI_FAMILY -6
#define EAI_SOCKTYPE -7
#define EAI_SERVICE -8
#define EAI_ADDRFAMILY -9
#define EAI_MEMORY -10
#define EAI_OVERFLOW -12
#define EAI_SYSTEM -11
#define EAI_ALLDONE -103
#define EAI_CANCELED -101
#define EAI_IDN_ENCODE -105
#define EAI_INPROGRESS -100
#define EAI_INTR -104
#define EAI_NOTCANCELED -102
/* AI_* conforms to NT ABI */
#define AI_PASSIVE 1
#define AI_CANONNAME 2
#define AI_NUMERICHOST 4
#define AI_NUMERICSERV 8
#define AI_ALL 0x0100
#define AI_ADDRCONFIG 0x0400
#define AI_V4MAPPED 0x0800
#define NI_NUMERICSCOPE 0
#define NI_NUMERICHOST 1
#define NI_NUMERICSERV 2
#define NI_NOFQDN 4
#define NI_NAMEREQD 8
#define NI_DGRAM 16
#define NI_MAXSERV 32
#define NI_MAXHOST 1025
COSMOPOLITAN_C_START_
struct addrinfo {
int32_t ai_flags; /* AI_XXX */
int32_t ai_family; /* AF_INET */
int32_t ai_socktype; /* SOCK_XXX */
int32_t ai_protocol; /* IPPROTO_XXX */
uint32_t ai_addrlen;
union {
struct sockaddr *ai_addr;
struct sockaddr_in *ai_addr4;
};
char *ai_canonname /*[DNS_NAME_MAX + 1]*/;
struct addrinfo *ai_next;
};
int getaddrinfo(const char *, const char *, const struct addrinfo *,
struct addrinfo **);
void freeaddrinfo(struct addrinfo *);
int getnameinfo(const struct sockaddr *, uint32_t, char *, uint32_t, char *,
uint32_t, int);
const char *gai_strerror(int);
int CompareDnsNames(const char *, const char *) paramsnonnull();
int PascalifyDnsName(uint8_t *, size_t, const char *) paramsnonnull();
int ResolveDns(const struct ResolvConf *, int, const char *, struct sockaddr *,
uint32_t) paramsnonnull();
int ResolveDnsReverse(const struct ResolvConf *, int, const char *, char *,
size_t) paramsnonnull();
struct addrinfo *newaddrinfo(uint16_t);
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_DNS_DNS_H_ */

View file

@ -1,57 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dns/dnsheader.h"
#include "libc/serialize.h"
#include "libc/sysv/errfuns.h"
/**
* Serializes DNS message h to wire.
*
* @return number of bytes written (always 12) or -1 w/ errno
* @see pascalifydnsname()
*/
void SerializeDnsHeader(uint8_t p[restrict 12], const struct DnsHeader *h) {
p[0x0] = h->id >> 8;
p[0x1] = h->id;
p[0x2] = h->bf1;
p[0x3] = h->bf2;
p[0x4] = h->qdcount >> 8;
p[0x5] = h->qdcount;
p[0x6] = h->ancount >> 8;
p[0x7] = h->ancount;
p[0x8] = h->nscount >> 8;
p[0x9] = h->nscount;
p[0xa] = h->arcount >> 8;
p[0xb] = h->arcount;
}
/**
* Serializes DNS message h to wire.
*
* @return number of bytes read (always 12) or -1 w/ errno
*/
void DeserializeDnsHeader(struct DnsHeader *h, const uint8_t p[restrict 12]) {
h->id = READ16BE(p);
h->bf1 = p[2];
h->bf2 = p[3];
h->qdcount = READ16BE(p + 4);
h->ancount = READ16BE(p + 6);
h->nscount = READ16BE(p + 8);
h->arcount = READ16BE(p + 10);
}

View file

@ -1,19 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_DNS_DNSHEADER_H_
#define COSMOPOLITAN_LIBC_DNS_DNSHEADER_H_
COSMOPOLITAN_C_START_
struct DnsHeader {
uint16_t id; /* transaction id */
uint8_t bf1; /* bit field 1 */
uint8_t bf2; /* bit field 2 */
uint16_t qdcount; /* question count */
uint16_t ancount; /* answer count */
uint16_t nscount; /* nameserver count */
uint16_t arcount; /* additional record count */
};
void SerializeDnsHeader(uint8_t[restrict 12], const struct DnsHeader *);
void DeserializeDnsHeader(struct DnsHeader *, const uint8_t[restrict 12]);
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_DNS_DNSHEADER_H_ */

View file

@ -1,14 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_DNS_DNSQUESTION_H_
#define COSMOPOLITAN_LIBC_DNS_DNSQUESTION_H_
COSMOPOLITAN_C_START_
struct DnsQuestion {
const char *qname;
uint16_t qtype;
uint16_t qclass;
};
int SerializeDnsQuestion(uint8_t *, size_t, const struct DnsQuestion *);
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_DNS_DNSQUESTION_H_ */

View file

@ -1,73 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_DNS_ENT_H_
#define COSMOPOLITAN_LIBC_DNS_ENT_H_
#include "libc/dns/dns.h"
#define HOST_NOT_FOUND 1
#define TRY_AGAIN 2
#define NO_RECOVERY 3
#define NO_DATA 4
#define NO_ADDRESS NO_DATA
COSMOPOLITAN_C_START_
struct netent {
char *n_name; /* official network name */
char **n_aliases; /* alias list */
int n_addrtype; /* net address type */
uint32_t n_net; /* network number */
};
struct protoent {
char *p_name; /* official protocol name */
char **p_aliases; /* alias list */
int p_proto; /* protocol number */
};
struct hostent {
char *h_name; /* official name of host */
char **h_aliases; /* alias list */
int h_addrtype; /* host address type */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses */
};
#define h_addr h_addr_list[0]
struct servent {
char *s_name; /* official service name */
char **s_aliases; /* alias list */
int s_port; /* port number (in network byte order) */
char *s_proto; /* protocol to use */
};
#define h_errno (*__h_errno_location())
errno_t *__h_errno_location(void) dontthrow pureconst;
void herror(const char *);
const char *hstrerror(int);
struct netent *getnetent(void);
struct netent *getnetbyname(const char *);
struct netent *getnetbyaddr(uint32_t, int);
void setnetent(int);
void endnetent(void);
struct protoent *getprotoent(void);
struct protoent *getprotobyname(const char *);
struct protoent *getprotobynumber(int);
void setprotoent(int);
void endprotoent(void);
struct hostent *gethostent(void);
struct hostent *gethostbyname(const char *);
struct hostent *gethostbyaddr(const void *, uint32_t, int);
void sethostent(int);
void endhostent(void);
struct servent *getservent(void);
struct servent *getservbyname(const char *, const char *);
struct servent *getservbyport(int, const char *);
void setservent(int);
void endservent(void);
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_DNS_ENT_H_ */

View file

@ -1,67 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dns/dns.h"
/**
* Turns getaddrinfo() return code into string.
*/
const char *gai_strerror(int code) {
switch (code) {
case EAI_ADDRFAMILY:
return "ADDRFAMILY";
case EAI_AGAIN:
return "AGAIN";
case EAI_ALLDONE:
return "ALLDONE";
case EAI_BADFLAGS:
return "BADFLAGS";
case EAI_CANCELED:
return "CANCELED";
case EAI_FAIL:
return "FAIL";
case EAI_FAMILY:
return "FAMILY";
case EAI_IDN_ENCODE:
return "ENCODE";
case EAI_INPROGRESS:
return "INPROGRESS";
case EAI_INTR:
return "INTR";
case EAI_MEMORY:
return "MEMORY";
case EAI_NODATA:
return "NODATA";
case EAI_NONAME:
return "NONAME";
case EAI_NOTCANCELED:
return "NOTCANCELED";
case EAI_OVERFLOW:
return "OVERFLOW";
case EAI_SERVICE:
return "SERVICE";
case EAI_SOCKTYPE:
return "SOCKTYPE";
case EAI_SUCCESS:
return "SUCCESS";
case EAI_SYSTEM:
return "SYSTEM";
default:
return "???";
}
}

View file

@ -1,116 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/dns/dns.h"
#include "libc/dns/hoststxt.h"
#include "libc/dns/resolvconf.h"
#include "libc/dns/servicestxt.h"
#include "libc/fmt/conv.h"
#include "libc/macros.internal.h"
#include "libc/mem/gc.h"
#include "libc/mem/mem.h"
#include "libc/sock/sock.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/af.h"
#include "libc/sysv/consts/inaddr.h"
#include "libc/sysv/consts/sock.h"
#include "libc/sysv/errfuns.h"
/**
* Resolves address for internet name.
*
* @param name is either an ip string or a utf-8 hostname
* @param service is the port number as a string
* @param hints may be passed to specialize behavior (optional)
* @param res receives a pointer that must be freed with freeaddrinfo(),
* and won't be modified if non-zero is returned
* @return 0 on success or EAI_xxx value
*/
int getaddrinfo(const char *name, const char *service,
const struct addrinfo *hints, struct addrinfo **res) {
char *eptr;
int rc, port;
char proto[32];
const char *canon;
struct addrinfo *ai;
port = 0;
if (!name && !service) {
return EAI_NONAME;
}
if (!name && hints && (hints->ai_flags & AI_CANONNAME)) {
return EAI_BADFLAGS;
}
if (service && ((port = strtol(service, &eptr, 10)), *eptr)) {
if (hints && hints->ai_socktype == SOCK_STREAM) {
strcpy(proto, "tcp");
} else if (hints && hints->ai_socktype == SOCK_DGRAM) {
strcpy(proto, "udp");
} else { // ai_socktype == 0
strcpy(proto, "");
}
if ((port = LookupServicesByName(service, proto, sizeof(proto), NULL, 0,
NULL)) == -1) {
return EAI_NONAME;
}
}
if (!(ai = newaddrinfo(port))) {
return EAI_MEMORY;
}
if (service) {
// if service isn't specified, port is left uninitialized
ai->ai_addr4->sin_port = htons(port);
}
if (hints) {
ai->ai_socktype = hints->ai_socktype;
ai->ai_protocol = hints->ai_protocol;
}
if (!name) {
ai->ai_addr4->sin_addr.s_addr =
(hints && (hints->ai_flags & AI_PASSIVE) == AI_PASSIVE)
? htonl(INADDR_ANY)
: htonl(INADDR_LOOPBACK);
*res = ai;
return 0;
}
if (inet_pton(AF_INET, name, &ai->ai_addr4->sin_addr.s_addr) == 1) {
*res = ai;
return 0;
} else if (hints && (hints->ai_flags & AI_NUMERICHOST) == AI_NUMERICHOST) {
freeaddrinfo(ai);
return EAI_NONAME;
} else if (ResolveHostsTxt(GetHostsTxt(), AF_INET, name, ai->ai_addr,
sizeof(ai->ai_addr4), &canon) > 0) {
strlcpy(ai->ai_canonname, canon, DNS_NAME_MAX + 1);
*res = ai;
return 0;
} else {
rc = ResolveDns(GetResolvConf(), AF_INET, name, ai->ai_addr,
sizeof(ai->ai_addr4));
if (rc > 0) {
*res = ai;
return 0;
}
freeaddrinfo(ai);
if (rc == 0) {
return EAI_NONAME;
} else {
return EAI_SYSTEM;
}
}
}

View file

@ -1,58 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/dns/ent.h"
#include "libc/mem/mem.h"
#include "libc/sysv/consts/af.h"
struct hostent *gethostbyaddr(const void *s_addr, uint32_t len, int type) {
static struct hostent *ptr1, he1;
static char h_name[DNS_NAME_MAX + 1];
static char *h_aliases[1];
static char *h_addr_list[2];
static char h_addr_list0[4];
struct sockaddr_in addr;
if (!ptr1) {
he1.h_name = h_name;
he1.h_aliases = h_aliases;
he1.h_aliases[0] = NULL;
he1.h_addrtype = AF_INET;
he1.h_length = 4;
he1.h_addr_list = h_addr_list;
he1.h_addr_list[0] = h_addr_list0;
he1.h_addr_list[1] = NULL;
ptr1 = &he1;
}
if (type != AF_INET || len != sizeof(uint32_t)) return NULL;
addr.sin_family = AF_INET;
addr.sin_port = 0;
addr.sin_addr.s_addr = *(uint32_t *)(s_addr);
if (getnameinfo((struct sockaddr *)&addr, sizeof(addr), ptr1->h_name,
DNS_NAME_MAX, NULL, 0, 0))
return NULL;
*((uint32_t *)ptr1->h_addr_list[0]) = (addr.sin_addr.s_addr);
return ptr1;
}

View file

@ -1,70 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/dns/ent.h"
#include "libc/mem/mem.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/af.h"
struct hostent *gethostbyname(const char *name) {
static struct hostent *ptr0, he0;
static char h_name[DNS_NAME_MAX + 1];
static char *h_aliases[1];
static char *h_addr_list[2];
static char h_addr_list0[4];
struct addrinfo *result = NULL;
if (!ptr0) {
he0.h_name = h_name;
he0.h_aliases = h_aliases;
he0.h_aliases[0] = NULL;
he0.h_addrtype = AF_INET;
he0.h_length = 4;
he0.h_addr_list = h_addr_list;
he0.h_addr_list[0] = h_addr_list0;
he0.h_addr_list[1] = NULL;
ptr0 = &he0;
}
if (getaddrinfo(name, NULL, NULL, &result) || result == NULL) {
return NULL;
}
/* if getaddrinfo is successful, result->ai_canonname is non-NULL,
* (see newaddrinfo) but the string can still be empty */
strlcpy(ptr0->h_name, *result->ai_canonname ? result->ai_canonname : name,
sizeof(h_name));
*((uint32_t *)ptr0->h_addr_list[0]) = result->ai_addr4->sin_addr.s_addr;
/* TODO: if result has ai_next, fit multiple entries for h_addr_list */
freeaddrinfo(result);
return ptr0;
}

View file

@ -1,94 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/cxxabi.h"
#include "libc/dce.h"
#include "libc/dns/hoststxt.h"
#include "libc/dns/servicestxt.h"
#include "libc/intrin/pushpop.internal.h"
#include "libc/intrin/safemacros.internal.h"
#include "libc/macros.internal.h"
#include "libc/mem/mem.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/thread/thread.h"
static struct HostsTxt *g_hoststxt;
static struct HostsTxtInitialStaticMemory {
struct HostsTxt ht;
pthread_mutex_t lock;
struct HostsTxtEntry entries[8];
char strings[64];
} g_hoststxt_init;
static const char *GetHostsTxtPath(char *path, size_t size) {
if (!IsWindows()) {
return "/etc/hosts";
} else {
return GetSystemDirectoryPath(path, size, "drivers\\etc\\hosts");
}
}
/**
* Returns hosts.txt map.
*
* @note yoinking realloc() ensures there's no size limits
*/
const struct HostsTxt *GetHostsTxt(void) {
FILE *f;
char pathbuf[256];
struct HostsTxtInitialStaticMemory *init;
init = &g_hoststxt_init;
pthread_mutex_lock(&init->lock);
if (!g_hoststxt) {
g_hoststxt = &init->ht;
init->ht.entries.n = pushpop(ARRAYLEN(init->entries));
init->ht.entries.p = init->entries;
init->ht.strings.n = pushpop(ARRAYLEN(init->strings));
init->ht.strings.p = init->strings;
__cxa_atexit((void *)FreeHostsTxt, &g_hoststxt, NULL);
if ((f = fopen(GetHostsTxtPath(pathbuf, sizeof(pathbuf)), "r"))) {
if (ParseHostsTxt(g_hoststxt, f) == -1) {
/* TODO(jart): Elevate robustness. */
}
fclose(f);
}
}
pthread_mutex_unlock(&init->lock);
return g_hoststxt;
}
/**
* Frees HOSTS.TXT data structure populated by ParseHostsTxt().
*/
void FreeHostsTxt(struct HostsTxt **ht) {
if (*ht) {
if ((*ht)->entries.p != g_hoststxt_init.entries) {
free((*ht)->entries.p);
}
if ((*ht)->strings.p != g_hoststxt_init.strings) {
free((*ht)->strings.p);
}
if (*ht != &g_hoststxt_init.ht) {
free(*ht);
}
*ht = 0;
}
}

View file

@ -1,115 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/dns/consts.h"
#include "libc/dns/dns.h"
#include "libc/dns/hoststxt.h"
#include "libc/dns/resolvconf.h"
#include "libc/dns/servicestxt.h"
#include "libc/fmt/conv.h"
#include "libc/fmt/itoa.h"
#include "libc/intrin/safemacros.internal.h"
#include "libc/mem/mem.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/af.h"
#include "libc/sysv/consts/inaddr.h"
#include "libc/sysv/errfuns.h"
/**
* Resolves name/service for socket address.
*
* @param addr
* @param addrlen
* @param name
* @param namelen
* @param service
* @param servicelen
* @param flags
*
* @return 0 on success or EAI_xxx value
*/
int getnameinfo(const struct sockaddr *addr, uint32_t addrlen, char *name,
uint32_t namelen, char *service, uint32_t servicelen,
int flags) {
char *p, rdomain[1 + sizeof "255.255.255.255.in-addr.arpa"];
char info[NI_MAXHOST + 1];
int port;
uint8_t *ip;
unsigned int valid_flags;
valid_flags =
(NI_NAMEREQD | NI_NUMERICHOST | NI_NUMERICSERV | NI_NOFQDN | NI_DGRAM);
if (flags & ~(valid_flags)) return EAI_BADFLAGS;
if (!name && !service) return EAI_NONAME;
if (addr->sa_family != AF_INET || addrlen < sizeof(struct sockaddr_in))
return EAI_FAMILY;
ip = (uint8_t *)&(((struct sockaddr_in *)addr)->sin_addr);
p = rdomain;
p = FormatUint32(p, ip[3]), *p++ = '.';
p = FormatUint32(p, ip[2]), *p++ = '.';
p = FormatUint32(p, ip[1]), *p++ = '.';
p = FormatUint32(p, ip[0]), stpcpy(p, ".in-addr.arpa");
info[0] = '\0';
if (name != NULL && namelen != 0) {
if ((flags & NI_NUMERICHOST) && (flags & NI_NAMEREQD)) return EAI_NONAME;
if ((flags & NI_NUMERICHOST) &&
inet_ntop(AF_INET, ip, info, sizeof(info)) == NULL)
return EAI_SYSTEM;
else if (!info[0] && ResolveHostsReverse(GetHostsTxt(), AF_INET, ip, info,
sizeof(info)) < 0)
return EAI_SYSTEM;
else if (!info[0] && ResolveDnsReverse(GetResolvConf(), AF_INET, rdomain,
info, sizeof(info)) < 0)
return EAI_SYSTEM;
else if (!info[0] && (flags & NI_NAMEREQD))
return EAI_NONAME;
else if (!info[0] && inet_ntop(AF_INET, ip, info, sizeof(info)) == NULL)
return EAI_SYSTEM;
if (strlen(info) + 1 > namelen) return EAI_OVERFLOW;
strcpy(name, info);
}
port = ntohs(((struct sockaddr_in *)addr)->sin_port);
info[0] = '\0';
if (service != NULL && servicelen != 0) {
if ((flags & NI_NUMERICSERV) ||
LookupServicesByPort(port, ((flags & NI_DGRAM) ? "udp" : "tcp"), 4,
info, sizeof(info), NULL) == -1) {
FormatInt32(info, port);
}
if (strlen(info) + 1 > servicelen) {
return EAI_OVERFLOW;
}
strcpy(service, info);
}
return 0;
}

View file

@ -1,93 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/dns/dns.h"
#include "libc/dns/resolvconf.h"
#include "libc/mem/arraylist.internal.h"
#include "libc/nt/enum/keyaccess.h"
#include "libc/nt/enum/reggetvalueflags.h"
#include "libc/nt/registry.h"
#include "libc/nt/runtime.h"
#include "libc/runtime/runtime.h"
#include "libc/sock/sock.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/af.h"
/**
* Extracts DNS nameserver IPs from Windows Registry.
*
* @param resolv points to a ResolvConf object, which should be zero
* initialized by the caller; or if it already contains items,
* this function will append
* @return number of nameservers appended, or -1 w/ errno
*/
textwindows int GetNtNameServers(struct ResolvConf *resolv) {
int rc;
char value8[128];
int64_t hkInterfaces;
char *state, *addr, *tmp;
struct sockaddr_in nameserver;
char16_t value[128], uuid[64];
uint32_t i, keycount, valuebytes, uuidlen;
keycount = 0;
hkInterfaces = kNtInvalidHandleValue;
if (!RegOpenKeyEx(
kNtHkeyLocalMachine,
u"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces",
0, kNtKeyRead, &hkInterfaces) &&
!RegQueryInfoKey(hkInterfaces, 0, 0, 0, &keycount, 0, 0, 0, 0, 0, 0, 0)) {
nameserver.sin_family = AF_INET;
nameserver.sin_port = htons(DNS_PORT);
rc = 0;
for (i = 0; i < keycount; ++i) {
uuidlen = sizeof(uuid);
if (!RegEnumKeyEx(hkInterfaces, i, uuid, &uuidlen, 0, 0, 0, 0) &&
((!RegGetValue(hkInterfaces, uuid, u"DhcpIpAddress",
kNtRrfRtRegSz | kNtRrfRtRegMultiSz, NULL, value,
((valuebytes = sizeof(value)), &valuebytes)) &&
valuebytes > 2 * sizeof(char16_t)) ||
(!RegGetValue(hkInterfaces, uuid, u"IpAddress",
kNtRrfRtRegSz | kNtRrfRtRegMultiSz, NULL, value,
((valuebytes = sizeof(value)), &valuebytes)) &&
valuebytes > 2 * sizeof(char16_t))) &&
((!RegGetValue(hkInterfaces, uuid, u"DhcpNameServer",
kNtRrfRtRegSz | kNtRrfRtRegMultiSz, NULL, value,
((valuebytes = sizeof(value)), &valuebytes)) &&
valuebytes > 2 * sizeof(char16_t)) ||
(!RegGetValue(hkInterfaces, uuid, u"NameServer",
kNtRrfRtRegSz | kNtRrfRtRegMultiSz, NULL, value,
((valuebytes = sizeof(value)), &valuebytes)) &&
valuebytes > 2 * sizeof(char16_t)))) {
tprecode16to8(value8, sizeof(value8), value);
tmp = value8;
while ((addr = strtok_r(tmp, ", ", &state))) {
if (inet_pton(AF_INET, addr, &nameserver.sin_addr.s_addr) == 1) {
if (append(&resolv->nameservers, &nameserver) != -1) ++rc;
}
tmp = NULL;
}
}
}
} else {
rc = __winerr();
}
RegCloseKey(hkInterfaces);
return rc;
}

View file

@ -1,37 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/dns/prototxt.h"
#include "libc/dns/servicestxt.h"
const char *GetProtocolsTxtPath(char *buf, size_t size) {
if (!IsWindows()) {
return "/etc/protocols";
} else {
return GetSystemDirectoryPath(buf, size, "drivers\\etc\\protocol");
}
}

View file

@ -1,36 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/dns/servicestxt.h"
const char *GetServicesTxtPath(char *path, size_t size) {
if (!IsWindows()) {
return "/etc/services";
} else {
return GetSystemDirectoryPath(path, size, "drivers\\etc\\services");
}
}

View file

@ -1,46 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/dns/ent.h"
#include "libc/dns/prototxt.h"
#include "libc/mem/mem.h"
struct protoent *getprotobyname(const char *name) {
static struct protoent *ptr0, pe0;
static char p_name[DNS_NAME_MAX + 1];
if (!ptr0) {
pe0.p_name = p_name;
if (!(pe0.p_aliases = calloc(1, sizeof(char *)))) return NULL;
pe0.p_proto = -1;
ptr0 = &pe0;
}
ptr0->p_proto = LookupProtoByName(name, ptr0->p_name, DNS_NAME_MAX, NULL);
if (ptr0->p_proto == -1) return NULL;
return ptr0;
}

View file

@ -1,47 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/dns/ent.h"
#include "libc/dns/prototxt.h"
#include "libc/mem/mem.h"
struct protoent *getprotobynumber(int proto) {
static struct protoent *ptr1, pe1;
static char p_name[DNS_NAME_MAX + 1];
if (!ptr1) {
pe1.p_name = p_name;
if (!(pe1.p_aliases = calloc(1, sizeof(char *)))) return NULL;
pe1.p_proto = -1;
ptr1 = &pe1;
}
if (LookupProtoByNumber(proto, ptr1->p_name, DNS_NAME_MAX, NULL) == -1)
return NULL;
ptr1->p_proto = proto;
return ptr1;
}

View file

@ -1,83 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/cxxabi.h"
#include "libc/dce.h"
#include "libc/dns/resolvconf.h"
#include "libc/intrin/pushpop.internal.h"
#include "libc/macros.internal.h"
#include "libc/mem/mem.h"
#include "libc/runtime/runtime.h"
#include "libc/sock/sock.h"
#include "libc/sock/struct/sockaddr.h"
#include "libc/stdio/stdio.h"
#include "libc/thread/thread.h"
static struct ResolvConf *g_resolvconf;
static struct ResolvConfInitialStaticMemory {
struct ResolvConf rv;
pthread_mutex_t lock;
struct sockaddr_in nameservers[3];
} g_resolvconf_init;
/**
* Returns singleton with DNS server address.
*/
const struct ResolvConf *GetResolvConf(void) {
int rc;
FILE *f;
struct ResolvConfInitialStaticMemory *init;
init = &g_resolvconf_init;
pthread_mutex_lock(&init->lock);
if (!g_resolvconf) {
g_resolvconf = &init->rv;
pushmov(&init->rv.nameservers.n, ARRAYLEN(init->nameservers));
init->rv.nameservers.p = init->nameservers;
__cxa_atexit((void *)FreeResolvConf, &g_resolvconf, NULL);
if (!IsWindows()) {
if ((f = fopen("/etc/resolv.conf", "r"))) {
rc = ParseResolvConf(g_resolvconf, f);
} else {
rc = -1;
}
fclose(f);
} else {
rc = GetNtNameServers(g_resolvconf);
}
if (rc == -1 && !IsTiny()) {
/* TODO(jart): Elevate robustness. */
}
}
pthread_mutex_unlock(&init->lock);
return g_resolvconf;
}
/**
* Frees resolv.conf data structure populated by ParseResolvConf().
*/
void FreeResolvConf(struct ResolvConf **rvp) {
if (*rvp) {
if ((*rvp)->nameservers.p != g_resolvconf_init.nameservers) {
free((*rvp)->nameservers.p);
}
if (*rvp != &g_resolvconf_init.rv) {
free(*rvp);
}
*rvp = 0;
}
}

View file

@ -1,55 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/dns/ent.h"
#include "libc/dns/servicestxt.h"
#include "libc/mem/mem.h"
#include "libc/sock/sock.h"
#include "libc/str/str.h"
struct servent *getservbyname(const char *name, const char *proto) {
static struct servent *ptr0, se0;
static char s_name[DNS_NAME_MAX + 1];
static char localproto[DNS_NAME_MAX + 1];
int p;
if (!ptr0) {
se0.s_name = s_name;
if (!(se0.s_aliases = calloc(1, sizeof(char *)))) return NULL;
se0.s_port = 0;
se0.s_proto = localproto;
ptr0 = &se0;
}
if (proto) {
strlcpy(localproto, proto, sizeof(localproto));
} else {
*localproto = 0;
}
p = LookupServicesByName(name, ptr0->s_proto, DNS_NAME_MAX, ptr0->s_name,
DNS_NAME_MAX, NULL);
if (p == -1) return NULL;
ptr0->s_port = htons(p);
return ptr0;
}

View file

@ -1,56 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/dns/ent.h"
#include "libc/dns/servicestxt.h"
#include "libc/mem/mem.h"
#include "libc/str/str.h"
struct servent *getservbyport(int port, const char *proto) {
static struct servent *ptr1, se1;
static char s_name[DNS_NAME_MAX + 1];
static char localproto[DNS_NAME_MAX + 1];
if (!ptr1) {
se1.s_name = s_name;
if (!(se1.s_aliases = calloc(1, sizeof(char *)))) return NULL;
se1.s_port = 0;
se1.s_proto = localproto;
ptr1 = &se1;
}
if (proto) {
if (!memccpy(localproto, proto, '\0', DNS_NAME_MAX)) {
return NULL;
}
} else {
*localproto = 0;
}
if (LookupServicesByPort(ntohs(port), ptr1->s_proto, DNS_NAME_MAX,
ptr1->s_name, DNS_NAME_MAX, NULL) == -1) {
return NULL;
}
ptr1->s_port = port;
return ptr1;
}

View file

@ -1,36 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/dns/ent.h"
#include "libc/stdio/stdio.h"
/**
* Prints `h_errno` description to stderr.
* @see perror()
*/
void herror(const char *s) {
fprintf(stderr, "%s%s%s\n", s ? s : "", s ? ": " : "", hstrerror(h_errno));
}

View file

@ -1,37 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/dns/ent.h"
struct hostent *gethostent(void) {
return NULL;
}
void sethostent(int stayopen) {
}
void endhostent(void) {
}

View file

@ -1,38 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_DNS_HOSTSTXT_H_
#define COSMOPOLITAN_LIBC_DNS_HOSTSTXT_H_
#include "libc/sock/struct/sockaddr.h"
#include "libc/stdio/stdio.h"
COSMOPOLITAN_C_START_
struct HostsTxtEntry {
uint8_t ip[4]; /* inet_ntop(AF_INET, he->ip, buf, size) */
uint32_t name; /* &ht->strings.p[he->name] */
uint32_t canon; /* &ht->strings.p[he->canon] */
};
struct HostsTxtEntries {
size_t i, n;
struct HostsTxtEntry *p;
};
struct HostsTxtStrings {
size_t i, n;
char *p;
};
struct HostsTxt {
struct HostsTxtEntries entries;
struct HostsTxtStrings strings;
};
const struct HostsTxt *GetHostsTxt(void) returnsnonnull;
void FreeHostsTxt(struct HostsTxt **) paramsnonnull();
int ParseHostsTxt(struct HostsTxt *, FILE *) paramsnonnull();
int ResolveHostsTxt(const struct HostsTxt *, int, const char *,
struct sockaddr *, uint32_t, const char **)
paramsnonnull((1, 3));
int ResolveHostsReverse(const struct HostsTxt *, int, const uint8_t *, char *,
size_t) paramsnonnull((1, 3));
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_DNS_HOSTSTXT_H_ */

View file

@ -1,101 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/dns/prototxt.h"
#include "libc/errno.h"
#include "libc/fmt/conv.h"
#include "libc/intrin/safemacros.internal.h"
#include "libc/macros.internal.h"
#include "libc/mem/mem.h"
#include "libc/str/str.h"
/**
* Opens and searches /etc/protocols to find number for a given name.
*
* @param protoname is a NULL-terminated string
* @param buf is a buffer to store the official name of the protocol
* @param bufsize is the size of buf
* @param filepath is the location of protocols file
* (if NULL, uses /etc/protocols)
* @return -1 on error, or
* positive protocol number
*
* @note aliases are read from file for comparison, but not returned.
* @see LookupProtoByNumber
*/
int LookupProtoByName(const char *protoname, char *buf, size_t bufsize,
const char *filepath) {
FILE *f;
char *line;
size_t linesize;
const char *path;
int found, result;
char pathbuf[256];
char *name, *number, *alias, *comment, *tok;
if (!(path = filepath)) {
path =
!IsWindows()
? "/etc/protocols"
: firstnonnull(GetProtocolsTxtPath(pathbuf, sizeof(pathbuf)), path);
}
if (bufsize == 0 || !(f = fopen(path, "r"))) {
return -1;
}
line = NULL;
linesize = 0;
found = 0;
result = -1;
while (found == 0 && getline(&line, &linesize, f) != -1) {
if ((comment = strchr(line, '#'))) *comment = '\0';
name = strtok_r(line, " \t\r\n\v", &tok);
number = strtok_r(NULL, "/ \t\r\n\v", &tok);
if (name && number) {
alias = name;
while (alias && strcasecmp(alias, protoname)) {
alias = strtok_r(NULL, " \t\r\n\v", &tok);
}
if (alias) { /* alias matched with protoname */
if (!memccpy(buf, name, '\0', bufsize)) {
if (bufsize) {
*buf = 0;
}
break;
}
result = atoi(number);
found = 1;
}
}
}
free(line);
if (ferror(f)) {
errno = ferror(f);
return -1;
}
fclose(f);
if (!found) return -1;
return result;
}

View file

@ -1,90 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/dns/prototxt.h"
#include "libc/errno.h"
#include "libc/fmt/conv.h"
#include "libc/macros.internal.h"
#include "libc/mem/mem.h"
#include "libc/str/str.h"
/**
* Opens and searches /etc/protocols to find name for a given number.
*
* The format of /etc/protocols is like this:
*
* # comment
* # NAME PROTOCOL ALIASES
* ip 0 IP
* icmp 1 ICMP
*
* @param protonum is the protocol number
* @param buf is a buffer to store the official name of the protocol
* @param bufsize is the size of buf
* @param path is the location of the protocols file, which may be NULL
* to use the system-wide default
* @return 0 on success, -1 on error
* @note aliases are not read from the file.
*/
int LookupProtoByNumber(const int protonum, char *buf, size_t bufsize,
const char *path) {
FILE *f;
int found;
char *line;
size_t linesize;
char pathbuf[256];
char *name, *number, *comment, *tok;
if (!bufsize ||
!(f = fopen(path ? path : GetProtocolsTxtPath(pathbuf, sizeof(pathbuf)),
"r"))) {
return -1;
}
line = NULL;
linesize = 0;
found = 0;
while (found == 0 && (getline(&line, &linesize, f)) != -1) {
if ((comment = strchr(line, '#'))) *comment = '\0';
name = strtok_r(line, " \t\r\n\v", &tok);
number = strtok_r(NULL, " \t\r\n\v", &tok);
if (name && number && protonum == atoi(number)) {
if (!memccpy(buf, name, '\0', bufsize)) {
strcpy(buf, "");
break;
}
found = 1;
}
}
free(line);
if (ferror(f)) {
errno = ferror(f);
fclose(f);
return -1;
}
fclose(f);
if (!found) return -1;
return 0;
}

View file

@ -1,107 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/dns/servicestxt.h"
#include "libc/errno.h"
#include "libc/fmt/conv.h"
#include "libc/intrin/safemacros.internal.h"
#include "libc/macros.internal.h"
#include "libc/mem/mem.h"
#include "libc/str/str.h"
/**
* Opens and searches /etc/services to find port for a given name.
*
* @param servname is a NULL-terminated string
* @param servproto is a NULL-terminated string (eg "tcp", "udp")
* (if servproto is an empty string,
* if is filled with the first matching
* protocol)
* @param servprotolen the size of servproto
* @param buf is a buffer to store the official name of the service
* (if NULL, the official name is not stored)
* @param bufsize is the size of buf
* @param path is the location of services file
* (if NULL, uses /etc/services)
* @return -1 on error, or positive port number
* @note aliases are read from file for comparison, but not returned.
* @see LookupServicesByPort
*/
int LookupServicesByName(const char *servname, char *servproto,
size_t servprotolen, char *buf, size_t bufsize,
const char *path) {
FILE *f;
char *line;
size_t linesize;
char pathbuf[256];
int found, result;
char *name, *port, *proto, *alias, *comment, *tok;
if (servprotolen == 0 ||
!(f = fopen(path ? path : GetServicesTxtPath(pathbuf, sizeof(pathbuf)),
"r"))) {
return -1;
}
line = NULL;
linesize = 0;
found = 0;
result = -1;
if (bufsize) strcpy(buf, "");
while (found == 0 && (getline(&line, &linesize, f)) != -1) {
if ((comment = strchr(line, '#'))) *comment = '\0';
name = strtok_r(line, " \t\r\n\v", &tok);
port = strtok_r(NULL, "/ \t\r\n\v", &tok);
proto = strtok_r(NULL, " \t\r\n\v", &tok);
if (name && port && proto) {
alias = name;
while (alias && strcasecmp(alias, servname) != 0)
alias = strtok_r(NULL, " \t\r\n\v", &tok);
if (alias) /* alias matched with servname */
{
if (!servproto[0] || strncasecmp(proto, servproto, servprotolen) == 0) {
if (!servproto[0] && !memccpy(servproto, proto, '\0', servprotolen)) {
strcpy(servproto, "");
break;
}
if (bufsize && !memccpy(buf, name, '\0', bufsize)) {
*buf = 0;
break;
}
result = atoi(port);
found = 1;
}
}
}
}
free(line);
if (ferror(f)) {
errno = ferror(f);
return -1;
}
fclose(f);
if (!found) return -1;
return result;
}

View file

@ -1,107 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/dns/servicestxt.h"
#include "libc/errno.h"
#include "libc/fmt/conv.h"
#include "libc/intrin/safemacros.internal.h"
#include "libc/macros.internal.h"
#include "libc/mem/mem.h"
#include "libc/str/str.h"
/**
* Opens and searches /etc/services to find name for a given port.
*
* The format of /etc/services is like this:
*
* # comment
* # NAME PORT/PROTOCOL ALIASES
* ftp 21/tcp
* fsp 21/udp fspd
* ssh 22/tcp
*
* @param servport is the port number
* @param servproto is a NULL-terminated string (eg "tcp", "udp")
* (if servproto is an empty string,
* if is filled with the first matching
* protocol)
* @param servprotolen the size of servproto
* @param buf is a buffer to store the official name of the service
* @param bufsize is the size of buf
* @param path is the location of the services file, which may be NULL
* to use the system-wide default
* @return 0 on success, -1 on error
* @note aliases are not read from the file.
*/
int LookupServicesByPort(const int servport, char *servproto,
size_t servprotolen, char *buf, size_t bufsize,
const char *path) {
FILE *f;
int found;
char *line;
size_t linesize;
char pathbuf[256];
char *name, *port, *proto, *comment, *tok;
if (!servprotolen ||
!(f = fopen(path ? path : GetServicesTxtPath(pathbuf, sizeof(pathbuf)),
"r"))) {
return -1;
}
found = 0;
line = NULL;
linesize = 0;
if (bufsize) *buf = 0;
while (!found && (getline(&line, &linesize, f)) != -1) {
if ((comment = strchr(line, '#'))) *comment = '\0';
name = strtok_r(line, " \t\r\n\v", &tok);
port = strtok_r(NULL, "/ \t\r\n\v", &tok);
proto = strtok_r(NULL, " \t\r\n\v", &tok);
if (name && port && proto && servport == atoi(port)) {
if (!servproto[0] || strncasecmp(proto, servproto, servprotolen) == 0) {
if (!servproto[0] && !memccpy(servproto, proto, '\0', servprotolen)) {
strcpy(servproto, "");
break;
}
if (!memccpy(buf, name, '\0', bufsize)) {
if (bufsize) {
*buf = 0;
}
break;
}
found = 1;
}
}
}
free(line);
if (ferror(f)) {
errno = ferror(f);
return -1;
}
fclose(f);
if (!found) return -1;
return 0;
}

View file

@ -1,45 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/dns/ent.h"
struct netent *getnetent(void) {
return NULL;
}
struct netent *getnetbyname(const char *name) {
return NULL;
}
struct netent *getnetbyaddr(uint32_t net, int type) {
return NULL;
}
void setnetent(int stayopen) {
}
void endnetent(void) {
}

View file

@ -1,39 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dns/dns.h"
#include "libc/macros.internal.h"
#include "libc/mem/mem.h"
#include "libc/sock/sock.h"
#include "libc/sysv/consts/af.h"
#define SIZE sizeof(struct addrinfo)
#define ADDRLEN sizeof(struct sockaddr_in)
struct addrinfo *newaddrinfo(uint16_t port) {
struct addrinfo *ai;
if ((ai = calloc(1, SIZE + ADDRLEN + DNS_NAME_MAX + 1))) {
ai->ai_family = AF_INET;
ai->ai_addrlen = ADDRLEN;
ai->ai_addr4 = (struct sockaddr_in *)((char *)ai + SIZE);
ai->ai_addr4->sin_family = AF_INET;
ai->ai_addr4->sin_port = htons(port);
ai->ai_canonname = (char *)ai + SIZE + ADDRLEN;
}
return ai;
}

View file

@ -1,72 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dns/dns.h"
#include "libc/dns/hoststxt.h"
#include "libc/errno.h"
#include "libc/mem/arraylist.internal.h"
#include "libc/mem/mem.h"
#include "libc/runtime/runtime.h"
#include "libc/sock/sock.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/af.h"
/**
* Parses HOSTS.TXT contents.
*
* Hostnames were invented by Peggy Karp; her format looks like this:
*
* # this is a comment
* # IP CANON [ALT...]
* 203.0.113.1 lol.example. lol
* 203.0.113.2 cat.example. cat
*
* @param htp points to a HostsTxt object, which should be zero
* initialized by the caller; or if it already contains items,
* this function will append
* @param f is the file content; see fopen() and fmemopen()
* @return 0 on success, or -1 w/ errno
* @see hoststxtsort() which is the logical next step
*/
int ParseHostsTxt(struct HostsTxt *ht, FILE *f) {
char *line;
size_t linesize;
struct HostsTxtEntry entry;
char *addr, *name, *tok, *comment;
line = NULL;
linesize = 0;
while ((getline(&line, &linesize, f)) != -1) {
if ((comment = strchr(line, '#'))) *comment = '\0';
if ((addr = strtok_r(line, " \t\r\n\v", &tok)) &&
inet_pton(AF_INET, addr, entry.ip) == 1) {
entry.canon = ht->strings.i;
while ((name = strtok_r(NULL, " \t\r\n\v", &tok))) {
entry.name = ht->strings.i;
concat(&ht->strings, name, strnlen(name, DNS_NAME_MAX) + 1);
append(&ht->entries, &entry);
}
}
}
free(line);
if (ferror(f)) {
errno = ferror(f);
return -1;
}
return 0;
}

View file

@ -1,68 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dns/dns.h"
#include "libc/dns/resolvconf.h"
#include "libc/mem/arraylist.internal.h"
#include "libc/mem/mem.h"
#include "libc/runtime/runtime.h"
#include "libc/sock/sock.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/af.h"
#include "libc/sysv/consts/inaddr.h"
/**
* Parses /etc/resolv.conf file.
*
* The content of the file usually looks like this:
*
* nameserver 8.8.8.8
* nameserver 8.8.4.4
*
* @param resolv points to a ResolvConf object, which should be zero
* initialized by the caller; or if it already contains items,
* this function will append
* @param f is an open stream with file content
* @return number of nameservers appended, or -1 w/ errno
*/
int ParseResolvConf(struct ResolvConf *resolv, struct FILE *f) {
/* TODO(jart): options ndots:5 */
int rc;
char *line;
size_t linesize;
struct sockaddr_in nameserver;
char *directive, *value, *tok, *comment;
rc = 0;
line = 0;
linesize = 0;
nameserver.sin_family = AF_INET;
nameserver.sin_port = htons(DNS_PORT);
while (getline(&line, &linesize, f) != -1) {
if ((comment = strchr(line, '#'))) *comment = '\0';
if ((directive = strtok_r(line, " \t\r\n\v", &tok)) &&
(value = strtok_r(NULL, " \t\r\n\v", &tok))) {
if ((strcmp(directive, "nameserver") == 0 &&
inet_pton(AF_INET, value, &nameserver.sin_addr.s_addr) == 1)) {
if (append(&resolv->nameservers, &nameserver) != -1) ++rc;
}
}
}
free(line);
return rc | ferror(f);
}

View file

@ -1,58 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dns/dns.h"
#include "libc/str/str.h"
#include "libc/sysv/errfuns.h"
/**
* Writes dotted hostname to DNS message wire.
*
* The wire format is basically a sequence of Pascal strings, for each
* label in the name. We only do enough validation to maintain protocol
* invariants.
*
* @param name is a dotted NUL-terminated hostname string
* @return bytes written (excluding NUL) or -1 w/ errno
*/
int PascalifyDnsName(uint8_t *buf, size_t size, const char *name) {
size_t i, j, k, namelen;
if ((namelen = strlen(name)) > DNS_NAME_MAX) return enametoolong();
i = 0;
if (size || namelen) {
if (namelen + 1 > size) return enospc();
buf[0] = '\0';
j = 0;
for (;;) {
for (k = 0; name[j + k] && name[j + k] != '.'; ++k) {
buf[i + k + 1] = name[j + k];
}
if (k) {
if (k > DNS_LABEL_MAX) return enametoolong();
buf[i] = k;
i += k + 1;
}
j += k + 1;
if (!name[j - 1]) {
break;
}
}
buf[i] = '\0';
}
return i;
}

View file

@ -1,37 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/dns/ent.h"
struct protoent *getprotoent(void) {
return NULL;
}
void setprotoent(int stayopen) {
}
void endprotoent(void) {
}

View file

@ -1,17 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_DNS_PROTOTXT_H_
#define COSMOPOLITAN_LIBC_DNS_PROTOTXT_H_
#include "libc/sock/sock.h"
#include "libc/stdio/stdio.h"
COSMOPOLITAN_C_START_
const char *GetProtocolsTxtPath(char *, size_t);
int LookupProtoByNumber(const int, char *, size_t, const char *)
paramsnonnull((2));
int LookupProtoByName(const char *, char *, size_t, const char *)
paramsnonnull((1, 2));
/* TODO: implement like struct HostsTxt? */
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_DNS_PROTOTXT_H_ */

View file

@ -1,22 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_DNS_RESOLVCONF_H_
#define COSMOPOLITAN_LIBC_DNS_RESOLVCONF_H_
#include "libc/sock/sock.h"
#include "libc/stdio/stdio.h"
COSMOPOLITAN_C_START_
struct Nameservers {
size_t i, n;
struct sockaddr_in *p;
};
struct ResolvConf {
struct Nameservers nameservers;
};
const struct ResolvConf *GetResolvConf(void) returnsnonnull;
int ParseResolvConf(struct ResolvConf *, struct FILE *) paramsnonnull();
void FreeResolvConf(struct ResolvConf **) paramsnonnull();
int GetNtNameServers(struct ResolvConf *) paramsnonnull();
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_DNS_RESOLVCONF_H_ */

View file

@ -1,113 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/dns/consts.h"
#include "libc/dns/dns.h"
#include "libc/dns/dnsheader.h"
#include "libc/dns/dnsquestion.h"
#include "libc/dns/resolvconf.h"
#include "libc/serialize.h"
#include "libc/mem/mem.h"
#include "libc/runtime/runtime.h"
#include "libc/sock/internal.h"
#include "libc/sock/sock.h"
#include "libc/sock/struct/sockaddr.h"
#include "libc/stdio/rand.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/af.h"
#include "libc/sysv/consts/ipproto.h"
#include "libc/sysv/consts/sock.h"
#include "libc/sysv/errfuns.h"
#define kMsgMax 512
/**
* Queries Domain Name System for address associated with name.
*
* @param resolvconf can be GetResolvConf()
* @param af can be AF_INET, AF_UNSPEC
* @param name can be a local or fully-qualified hostname
* @param addr should point to a struct sockaddr_in; if this function
* succeeds, its sin_family and sin_addr fields will be modified
* @param addrsize is the byte size of addr
* @return number of matches found, or -1 w/ errno
* @error EAFNOSUPPORT. ENETDOWN, ENAMETOOLONG, EBADMSG
*/
int ResolveDns(const struct ResolvConf *resolvconf, int af, const char *name,
struct sockaddr *addr, uint32_t addrsize) {
int rc, fd, n;
struct DnsQuestion q;
struct DnsHeader h, h2;
struct sockaddr_in *a4;
uint8_t *p, *pe, msg[512];
uint16_t rtype, rclass, rdlength;
if (addrsize < kMinSockaddr4Size) return einval();
if (af != AF_INET && af != AF_UNSPEC) return eafnosupport();
if (!resolvconf->nameservers.i) return 0;
bzero(&h, sizeof(h));
rc = ebadmsg();
h.id = _rand64();
h.bf1 = 1; /* recursion desired */
h.qdcount = 1;
q.qname = name;
q.qtype = DNS_TYPE_A;
q.qclass = DNS_CLASS_IN;
bzero(msg, sizeof(msg));
SerializeDnsHeader(msg, &h);
if ((n = SerializeDnsQuestion(msg + 12, 500, &q)) == -1) return -1;
if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) return -1;
if (sendto(fd, msg, 12 + n, 0, (struct sockaddr *)resolvconf->nameservers.p,
sizeof(*resolvconf->nameservers.p)) == 12 + n &&
(n = read(fd, msg, 512)) >= 12) {
DeserializeDnsHeader(&h2, msg);
if (h2.id == h.id) {
rc = 0;
p = msg + 12;
pe = msg + n;
while (p < pe && h2.qdcount--) {
p += strnlen((char *)p, pe - p) + 1 + 4;
}
while (p < pe && h2.ancount--) {
if ((p[0] & 0xc0) == 0xc0) { /* name pointer */
p += 2;
} else {
p += strnlen((char *)p, pe - p) + 1;
}
if (p + 10 <= pe) {
rtype = READ16BE(p);
rclass = READ16BE(p + 2);
// ttl = READ32BE(p + 4);
rdlength = READ16BE(p + 8);
if (p + 10 + rdlength <= pe && rdlength == 4 &&
rclass == DNS_CLASS_IN && rtype == DNS_TYPE_A) {
rc = 1;
a4 = (struct sockaddr_in *)addr;
a4->sin_family = AF_INET;
memcpy(&a4->sin_addr.s_addr, p + 10, 4);
break;
}
p += 10 + rdlength;
}
}
}
}
close(fd);
return rc;
}

View file

@ -1,128 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/dns/consts.h"
#include "libc/dns/dns.h"
#include "libc/dns/dnsheader.h"
#include "libc/dns/dnsquestion.h"
#include "libc/dns/resolvconf.h"
#include "libc/serialize.h"
#include "libc/mem/mem.h"
#include "libc/runtime/runtime.h"
#include "libc/sock/sock.h"
#include "libc/sock/struct/sockaddr.h"
#include "libc/stdio/rand.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/af.h"
#include "libc/sysv/consts/ipproto.h"
#include "libc/sysv/consts/sock.h"
#include "libc/sysv/errfuns.h"
#define kMsgMax 512
/**
* Performs reverse DNS lookup with IP address.
*
* @param resolvconf can be GetResolvConf()
* @param af can be AF_INET, AF_UNSPEC
* @param name is a reversed IP address string ending with .in-addr.arpa
* @param buf to store the obtained hostname if any
* @param bufsize is size of buf
* @return 0 on success, or -1 w/ errno
* @error EAFNOSUPPORT, ENETDOWN, ENAMETOOLONG, EBADMSG
*/
int ResolveDnsReverse(const struct ResolvConf *resolvconf, int af,
const char *name, char *buf, size_t bufsize) {
int rc, fd, n;
struct DnsQuestion q;
struct DnsHeader h, h2;
uint8_t *p, *pe, msg[512];
uint16_t rtype, rclass, rdlength;
if (af != AF_INET && af != AF_UNSPEC) return eafnosupport();
if (!resolvconf->nameservers.i) return 0;
bzero(&h, sizeof(h));
rc = ebadmsg();
h.id = _rand64();
h.bf1 = 1; /* recursion desired */
h.qdcount = 1;
q.qname = name;
q.qtype = DNS_TYPE_PTR;
q.qclass = DNS_CLASS_IN;
bzero(msg, sizeof(msg));
SerializeDnsHeader(msg, &h);
if ((n = SerializeDnsQuestion(msg + 12, 500, &q)) == -1) return -1;
if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) return -1;
if (sendto(fd, msg, 12 + n, 0, (struct sockaddr *)resolvconf->nameservers.p,
sizeof(*resolvconf->nameservers.p)) == 12 + n &&
(n = read(fd, msg, 512)) >= 12) {
DeserializeDnsHeader(&h2, msg);
if (h2.id == h.id) {
rc = 0;
if (h2.ancount) {
p = msg + 12;
pe = msg + n;
while (p < pe && h2.qdcount) {
p += strnlen((char *)p, pe - p) + 1 + 4;
h2.qdcount--;
}
if (p + 1 < pe) {
if ((p[0] & 0b11000000) == 0b11000000) { /* name pointer */
p += 2;
} else {
p += strnlen((char *)p, pe - p) + 1;
}
if (p + 2 + 2 + 4 + 2 < pe) {
rtype = READ16BE(p), p += 2;
rclass = READ16BE(p), p += 2;
/* ttl */ p += 4;
rdlength = READ16BE(p), p += 2;
if (p + rdlength <= pe && rtype == DNS_TYPE_PTR &&
rclass == DNS_CLASS_IN) {
if (strnlen((char *)p, pe - p) + 1 > bufsize)
rc = -1;
else {
/* domain name starts with a letter */
for (; !isalnum((char)(*p)) && p < pe; p++) rdlength--;
for (char *tmp = (char *)p; rdlength > 0 && *tmp != '\0';
tmp++) {
/* each label is alphanumeric or hyphen
* any other character is assumed separator */
if (!isalnum(*tmp) && *tmp != '-') *tmp = '.';
rdlength--;
}
strcpy(buf, (char *)p);
}
} else
rc = -1;
}
}
}
}
}
close(fd);
return rc;
}

View file

@ -1,52 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dns/consts.h"
#include "libc/dns/dns.h"
#include "libc/dns/hoststxt.h"
#include "libc/serialize.h"
#include "libc/mem/alg.h"
#include "libc/sock/sock.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/af.h"
#include "libc/sysv/errfuns.h"
/**
* Finds name associated with address in HOSTS.TXT table.
*
* @param ht can be GetHostsTxt()
* @param af can be AF_INET
* @param ip is IP address in binary (sin_addr)
* @param buf is buffer to store the name
* @param bufsize is length of buf
* @return 1 if found, 0 if not found, or -1 w/ errno
* @error EAFNOSUPPORT
*/
int ResolveHostsReverse(const struct HostsTxt *ht, int af, const uint8_t *ip,
char *buf, size_t bufsize) {
size_t i;
if (af != AF_INET && af != AF_UNSPEC) return eafnosupport();
for (i = 0; i < ht->entries.i; ++i) {
if (READ32LE(ip) == READ32LE(ht->entries.p[i].ip)) {
if (memccpy(buf, ht->strings.p + ht->entries.p[i].name, 0, bufsize)) {
return 1;
}
}
}
return 0;
}

View file

@ -1,62 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dns/consts.h"
#include "libc/dns/dns.h"
#include "libc/dns/hoststxt.h"
#include "libc/mem/alg.h"
#include "libc/sock/sock.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/af.h"
#include "libc/sysv/errfuns.h"
/**
* Finds address associated with name in HOSTS.TXT table.
*
* @param ht can be GetHostsTxt()
* @param af can be AF_INET, AF_UNSPEC
* @param name can be a local or fully-qualified hostname
* @param addr should point to a struct sockaddr_in; if this function
* succeeds, its sin_family and sin_addr fields will be modified
* @param addrsize is the byte size of addr
* @param canon be used to return a pointer to the canonical name
* @return number of matches found, or -1 w/ errno
* @error EAFNOSUPPORT
*/
int ResolveHostsTxt(const struct HostsTxt *ht, int af, const char *name,
struct sockaddr *addr, uint32_t addrsize,
const char **canon) {
size_t i;
struct sockaddr_in *addr4;
if (af != AF_INET && af != AF_UNSPEC) return eafnosupport();
for (i = 0; i < ht->entries.i; ++i) {
if (!CompareDnsNames(name, ht->strings.p + ht->entries.p[i].name)) {
if (addr) {
if (addrsize < kMinSockaddr4Size) return einval();
addr4 = (struct sockaddr_in *)addr;
addr4->sin_family = AF_INET;
memcpy(&addr4->sin_addr.s_addr, &ht->entries.p[i].ip[0], 4);
}
if (canon) {
*canon = ht->strings.p + ht->entries.p[i].canon;
}
return 1;
}
}
return 0;
}

View file

@ -1,59 +0,0 @@
NETWORK WORKING GROUP PEGGY KARP
REQUEST FOR COMMENTS #226 MITRE
NIC #7625 20 SEPT 71
CATEGORIES: D.3
UPDATES: NONE
OBSOLETES: NONE
STANDARDIZATION OF HOST MNEUMONICS
IN EACH TELNET IMPLEMENTATION, A LIST OF HOST NMEUMONICS IS PROVIDED
FOR THE USER TO INDICATE THE SERVING HOST DESIRED. CURRENTLY, EACH
SITE EMPLOYS THEIR OWN SPECIAL LIST. RATHER THAN REQUIRE THE USER TO
BE COGNIZANT OF THE IDIOSYNCRASIES OF EACH LIST, ESPECIALLY WHEN
CHAINED THROUGH SEVERAL HOSTS VIA TELNET, IT HAS BEEN RECOMMENDED THAT
STANDARD HOST DESIGNATORS BE ADOPTED.
THE FOLLOWING LIST OF SIX CHARACTER DESIGNATORS IS PROPOSED AS THE
STANDARD LIST. REGISTER ANY OBJECTIONS BY 3 OCTOBER TO P. KARP (703)
893-3500 X2391, X2318. AN OFFICIAL POLICY AND IMPLEMENTATION DATE WILL
BE SET ON 8 OCTOBER.
THE LIST:
HOST # DESIGNATOR
1 UCLA
65 UCLA36
2 SRIARC
66 SRIAI
3 UCSB
4 UTAH
6 MULTCS
70 MITDM
7 RAND
8 SDC
9 HARV
10 LNCTX2
74 LNC360
11 STAN
12 ILL
69 BBN
133 BBNB
144 AMES
145 MITRE
158 TIP
[ This RFC was put into machine readable form for entry ]
[ into the online RFC archives by BBN Corp. under the ]
[ direction of Alex McKenzie. 12/96 ]
[Page 1]

View file

@ -1,222 +0,0 @@
Network Working Group Peggy Karp
Request for Comments: #247 MITRE
NIC 7688 12 October 1971
Categories: Policy, Telnet
Related: #226, 236, 239, 233, 237
Obsoletes: #226
Proferred Set of Standard Host Names
In RFC #226, BBN's TENEX list of Host names was set up as a strawman
set of standard Host names. Comments received since then (an RFC
actually generated comments!!!) have influenced me to propose the
following general rules for forming Host names.
The Host names will be 8 characters in length. The general form is
<site> '-' <machine>
<site> will be at most 4 characters, formed as follows:
(a) Use the keyword in the site name, if not more than
four characters, e.g., NASA Ames, Case Western
Reserve. ---- ----
(b) Use the standard acronym, if not more than four
characters, e.g., UCLA, RADC, NBS.
(c) If a standard abbreviation exists, use it, e.g., Ill.
(d) If none of the above apply, use the first four letters
in the site name, e.g., Burr, Mitr, Harv.
(e) If none of the above is acceptable to the site, the
technical liaison should select the site mnemonic.
<machine> will be at most 4 characters of the form <mfg. #>
<designator>.
Examples of mfg. # are:
IBM 360 2 digit model number
IBM 370 3 digit model number
PDP 1 - 2 digit model number
Burroughs 4 digits
CDC 4 digits
etc.
[Page 1]
RFC #247
<designator> will be used when more than one machine of the same
type is located at a site (e.g., 2 PDP-10s at MIT, at SRI, and
at BBN).
Limiting <machine> to 4 characters does not permit distinctions
to be made between machines with 4 digit mfg. #s. I expect
the situation will be handled in an ad hoc manner by the NIC if
it arises.
TIPs are identified as 'TIP' rather than by '316'. If a Host
is not to be permanently addressable, the machine is identified
as 'TEST'.
A list of Host names, formed according to these rules, is
attached. Alternate Host names should be provided, as
suggested by Jon Postel (RFC #236). RFC's 206, 233, and
236 present lists with 4-character alternate names. The
Technical Liaison should select the alternate name for his
site and communicate the selection to the NIC.
The preceding rules and the attached list of Host names are
subject to the approval of the NWG. Hereafter, the list will
be generated and maintained by the NIC in cooperation with
the Technical Liaison at each site, as suggested in RFC #237.
Comments should be addressed to Dick Watson.
[ This RFC was put into machine readable form for entry ]
[ into the online RFC archives by BBN Corp. under the ]
[ direction of Alex McKenzie. 12/96 ]
[Page 2]
RFC #247
Attachment 1
NETWORK ADDRESS STANDARD NAME
--------------- -------------
1 UCLA-7
65 UCLA-91
2 SRI-10NI
66 SRI-10AI
3 UCSB-75
4 UTAH-10
5 BBN-516
69 BBN-10A
133 BBN-10B
6 MIT-645
70 MIT-10DM
134 MIT-10AI
7 RAND-65
71 RAND-10
8 SDC-75
9 HARV-10
73 HARV-1
137 HARV-11
10 LL-67
74 LL-TX2
138 LL-TSP
11 SAIL-10
12 ILL-11
76 ILL-6500
13 CASE-10
14 CMU-10
15 BURR-6500
79 BURR-TEST
16 AMES-67
144 AMES-TIP
145 MITR-TIP
18 RADC-645
146 RADC-TIP
19 NBS-11
147 NBS-TIP
148 ETAC-TIP
21 TINK-418
22 MCCL-418
23 USC-44
151 USC-TIP
152 GWC-TIP
25 NCAR-7600
153 NCAR-TIP
158 BBNX-TEST
[Page 3]
RFC #247
Attachment 2
An Implementation Scheme
If the standard Host names are formed according to the proposed
rules, the following implementation scheme, suggested by Steve
Crocker, can be used.
Map <site> into an 8-bit number, S and
map <machine> into an 8-bit number, M,
where
S + M = Network Address.
S and M can be selected such that specification of <site>
alone could cause a default to the "primary" Host at
the site. Note that this scheme depends on a unique
<site> designator for each IMP.
Some examples:
If the "primary" Host at UCLA is the 91, let
UCLA -> S = X'41'
7 -> M = X'40'
91 -> M = X'00'
then for
UCLA-7, S + M = X'01' = 1 base 10
UCLA-91,S + M = X'41' = 65 base 10
and
UCLA alone = X'41' = 65 base 10
If the primary Host at BBN is TENEX System A, let
BBN -> S = X'45'
516 -> M = X'40'
10A -> M = X'00'
10B -> M = X'C0'
then for
BBN-516, S + M = X'05' = 5 base 10
BBN-10A, S + M = X'45' = 69 base 10
BBN-10B, S + M = X'85' = 133 base 10
and
BBN alone = X'45' = 69 base 10
The primary Host for each IMP would be designated by the
site and such information disseminated by the NIC.
[Page 4]

File diff suppressed because it is too large Load diff

View file

@ -1,39 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dns/dns.h"
#include "libc/dns/dnsquestion.h"
#include "libc/sysv/errfuns.h"
/**
* Serializes DNS question record to wire.
*
* @return number of bytes written
* @see pascalifydnsname()
*/
int SerializeDnsQuestion(uint8_t *buf, size_t size,
const struct DnsQuestion *dq) {
int wrote;
if ((wrote = PascalifyDnsName(buf, size, dq->qname)) == -1) return -1;
if (wrote + 1 + 4 > size) return enospc();
buf[wrote + 1] = dq->qtype >> 8;
buf[wrote + 2] = dq->qtype;
buf[wrote + 3] = dq->qclass >> 8;
buf[wrote + 4] = dq->qclass;
return wrote + 5;
}

View file

@ -1,37 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/dns/ent.h"
struct servent *getservent(void) {
return NULL;
}
void setservent(int stayopen) {
}
void endservent(void) {
}

View file

@ -1,17 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_DNS_SERVICESTXT_H_
#define COSMOPOLITAN_LIBC_DNS_SERVICESTXT_H_
#include "libc/sock/sock.h"
#include "libc/stdio/stdio.h"
COSMOPOLITAN_C_START_
char *GetSystemDirectoryPath(char *, size_t, const char *);
int LookupServicesByPort(const int, char *, size_t, char *, size_t,
const char *) paramsnonnull((2, 4));
int LookupServicesByName(const char *, char *, size_t, char *, size_t,
const char *) paramsnonnull((1, 2));
const char *GetServicesTxtPath(char *, size_t);
/* TODO: implement like struct HostsTxt? */
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_DNS_SERVICESTXT_H_ */

View file

@ -59,12 +59,12 @@ wontreturn void _Exit(int exitcode) {
: "rcx", "r11", "memory"); : "rcx", "r11", "memory");
#elif defined(__aarch64__) #elif defined(__aarch64__)
register long x0 asm("x0") = exitcode; register long x0 asm("x0") = exitcode;
asm volatile("mov\tx8,%0\n\t" register long x8 asm("x8") = IsLinux() ? 94 : 1;
"mov\tx16,%1\n\t" asm volatile("mov\tx16,%1\n\t"
"svc\t0" "svc\t0"
: /* no outputs */ : /* no outputs */
: "i"(94), "i"(1), "r"(x0) : "r"(x8), "i"(1), "r"(x0)
: "x8", "x16", "memory"); : "x16", "memory");
#else #else
#error "unsupported architecture" #error "unsupported architecture"
#endif #endif
@ -77,12 +77,12 @@ wontreturn void _Exit(int exitcode) {
: "rcx", "r11", "memory"); : "rcx", "r11", "memory");
#else #else
register long r0 asm("x0") = exitcode; register long r0 asm("x0") = exitcode;
asm volatile("mov\tx8,%0\n\t" register long x8 asm("x8") = IsLinux() ? 93 : 431;
"mov\tx16,%1\n\t" asm volatile("mov\tx16,%1\n\t"
"svc\t0" "svc\t0"
: /* no outputs */ : /* no outputs */
: "i"(93), "i"(0x169), "r"(r0) : "r"(x8), "i"(0x169), "r"(r0)
: "x8", "memory"); : "memory");
#endif #endif
} else if (IsWindows()) { } else if (IsWindows()) {
uint32_t waitstatus; uint32_t waitstatus;

View file

@ -74,13 +74,27 @@ wontreturn void _Exit1(int rc) {
} }
notpossible; notpossible;
#elif defined(__aarch64__) #elif defined(__aarch64__)
if (IsLinux() || IsFreebsd()) {
register int x0 asm("x0") = rc;
register int x8 asm("x8");
if (IsLinux()) { if (IsLinux()) {
register long r0 asm("x0") = rc; x8 = 93; // exit
asm volatile("mov\tx8,%0\n\t" } else if (IsFreebsd()) {
x8 = 431; // thr_exit
} else {
__builtin_unreachable();
}
asm volatile("svc\t0" : "+r"(x0) : "r"(x8) : "memory");
if (SupportsFreebsd()) {
// On FreeBSD, thr_exit() fails if the current thread is orphaned.
// In that case we're really better off just calling plain _exit()
x0 = rc;
asm volatile("mov\tx8,#1\n\t"
"svc\t0" "svc\t0"
: /* no outputs */ : /* no outputs */
: "i"(93), "r"(r0) : "r"(x0)
: "x8", "memory"); : "memory");
}
} else if (IsXnu()) { } else if (IsXnu()) {
__syslib->__pthread_exit(0); __syslib->__pthread_exit(0);
} }

View file

@ -32,10 +32,19 @@ _futex:
neg %eax neg %eax
1: pop %rbp 1: pop %rbp
#elif defined(__aarch64__) #elif defined(__aarch64__)
mov x8,#0x062 ldr x7,=__hostos
svc #0 ldr w7,[x7]
tst x7,1 // IsLinux()
mov x7,98 // futex (Linux)
mov x8,454 // _umtx_op (FreeBSD)
csel x8,x7,x8,ne // choose syscall magnum
mov x7,0 // clear carry (for Linux)
adds x7,x7,0 // clear carry
svc #0 // call kernel
bcc 1f // jump if not carry
neg x0,x0 // linux style errno
#else #else
#error "unsupported architecture" #error "unsupported architecture"
#endif /* __x86_64__ */ #endif /* __x86_64__ */
ret 1: ret
.endfn _futex,globl,hidden .endfn _futex,globl,hidden

View file

@ -79,7 +79,7 @@ static textwindows void SetupWinStd(struct Fds *fds, int i, uint32_t x) {
textstartup void __init_fds(int argc, char **argv, char **envp) { textstartup void __init_fds(int argc, char **argv, char **envp) {
struct Fds *fds; struct Fds *fds;
fds = __veil("r", &g_fds); fds = &g_fds;
fds->n = 4; fds->n = 4;
atomic_store_explicit(&fds->f, 3, memory_order_relaxed); atomic_store_explicit(&fds->f, 3, memory_order_relaxed);
if (_weaken(_extend)) { if (_weaken(_extend)) {

View file

@ -18,6 +18,7 @@
*/ */
#include "libc/calls/syscall-sysv.internal.h" #include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/intrin/kprintf.h"
#include "libc/nt/thread.h" #include "libc/nt/thread.h"
#include "libc/nt/thunk/msabi.h" #include "libc/nt/thunk/msabi.h"
#include "libc/runtime/internal.h" #include "libc/runtime/internal.h"
@ -25,9 +26,9 @@
__msabi extern typeof(GetCurrentThreadId) *const __imp_GetCurrentThreadId; __msabi extern typeof(GetCurrentThreadId) *const __imp_GetCurrentThreadId;
int sys_gettid(void) { int sys_gettid(void) {
int64_t wut;
#ifdef __x86_64__ #ifdef __x86_64__
int tid; int tid;
int64_t wut;
if (IsWindows()) { if (IsWindows()) {
tid = __imp_GetCurrentThreadId(); tid = __imp_GetCurrentThreadId();
} else if (IsLinux()) { } else if (IsLinux()) {
@ -65,11 +66,23 @@ int sys_gettid(void) {
#elif defined(__aarch64__) #elif defined(__aarch64__)
// this can't be used on xnu // this can't be used on xnu
register long res asm("x0"); register long res asm("x0");
if (IsLinux()) {
asm volatile("mov\tx8,%1\n\t" asm volatile("mov\tx8,%1\n\t"
"svc\t0" "svc\t0"
: "=r"(res) : "=r"(res)
: "i"(178) : "i"(178)
: "x8", "memory"); : "x8", "memory");
} else if (IsFreebsd()) {
res = (long)&wut;
asm volatile("mov\tx8,%2\n\t"
"svc\t0"
: "+r"(res), "=m"(wut)
: "i"(432) // thr_self()
: "x8", "memory");
res = wut;
} else {
res = __pid;
}
return res; return res;
#else #else
#error "arch unsupported" #error "arch unsupported"

View file

@ -19,7 +19,6 @@
#include "libc/atomic.h" #include "libc/atomic.h"
#include "libc/sysv/consts/clock.h" #include "libc/sysv/consts/clock.h"
#include "libc/thread/freebsd.internal.h" #include "libc/thread/freebsd.internal.h"
#ifdef __x86_64__
int sys_umtx_timedwait_uint_cp(atomic_int *, int, int, size_t, int sys_umtx_timedwait_uint_cp(atomic_int *, int, int, size_t,
struct _umtx_time *) asm("sys_futex_cp"); struct _umtx_time *) asm("sys_futex_cp");
@ -46,5 +45,3 @@ int sys_umtx_timedwait_uint(atomic_int *p, int expect, bool pshare,
} }
return sys_umtx_timedwait_uint_cp(p, op, expect, size, tm_p); return sys_umtx_timedwait_uint_cp(p, op, expect, size, tm_p);
} }
#endif

View file

@ -1,8 +1,6 @@
#ifndef _NETDB_H #ifndef _NETDB_H
#define _NETDB_H #define _NETDB_H
#include "libc/calls/weirdtypes.h" #include "libc/calls/weirdtypes.h"
#include "libc/dns/dns.h"
#include "libc/dns/ent.h"
#include "libc/sock/sock.h" #include "libc/sock/sock.h"
#include "libc/sock/struct/in6_pktinfo.h" #include "libc/sock/struct/in6_pktinfo.h"
#include "libc/sock/struct/in_pktinfo.h" #include "libc/sock/struct/in_pktinfo.h"
@ -19,4 +17,5 @@
#include "libc/sysv/consts/mcast.h" #include "libc/sysv/consts/mcast.h"
#include "libc/sysv/consts/pf.h" #include "libc/sysv/consts/pf.h"
#include "libc/sysv/consts/sock.h" #include "libc/sysv/consts/sock.h"
#include "third_party/musl/netdb.h"
#endif /* _NETDB_H */ #endif /* _NETDB_H */

View file

@ -164,6 +164,7 @@ __funline void *__memset(void *a, int c, unsigned long n) {
char *d = a; char *d = a;
unsigned long i; unsigned long i;
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
__asm__ volatile("" ::: "memory");
d[i] = c; d[i] = c;
} }
return d; return d;
@ -174,6 +175,7 @@ __funline void *__memcpy(void *a, const void *b, unsigned long n) {
unsigned long i; unsigned long i;
const char *s = b; const char *s = b;
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
__asm__ volatile("" ::: "memory");
d[i] = s[i]; d[i] = s[i];
} }
return d; return d;
@ -185,10 +187,12 @@ __funline void *__memmove(void *a, const void *b, unsigned long n) {
const char *s = b; const char *s = b;
if (d > s) { if (d > s) {
for (i = n; i--;) { for (i = n; i--;) {
__asm__ volatile("" ::: "memory");
d[i] = s[i]; d[i] = s[i];
} }
} else { } else {
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
__asm__ volatile("" ::: "memory");
d[i] = s[i]; d[i] = s[i];
} }
} }

View file

@ -1,7 +1,7 @@
#ifndef COSMOPOLITAN_LIBC_LOG_LOG_H_ #ifndef COSMOPOLITAN_LIBC_LOG_LOG_H_
#define COSMOPOLITAN_LIBC_LOG_LOG_H_ #define COSMOPOLITAN_LIBC_LOG_LOG_H_
#ifdef _COSMO_SOURCE
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"
#ifdef _COSMO_SOURCE
#define kLogFatal 0 #define kLogFatal 0
#define kLogError 1 #define kLogError 1

View file

@ -221,7 +221,7 @@ static relegated void __oncrash_impl(int sig, struct siginfo *si,
Append(b, "%serror%s: Uncaught %G (%s) on %s pid %d tid %d\n", strong, reset, Append(b, "%serror%s: Uncaught %G (%s) on %s pid %d tid %d\n", strong, reset,
sig, kind, host, getpid(), gettid()); sig, kind, host, getpid(), gettid());
if (program_invocation_name) { if (program_invocation_name) {
Append(b, " %s\n", program_invocation_name); Append(b, " %s\n", __program_executable_name);
} }
if (errno) { if (errno) {
Append(b, " %s\n", strerror(errno)); Append(b, " %s\n", strerror(errno));

View file

@ -52,6 +52,7 @@ o/$(MODE)/libc/nexgen32e/ktolower.o \
o/$(MODE)/libc/nexgen32e/ktoupper.o \ o/$(MODE)/libc/nexgen32e/ktoupper.o \
o/$(MODE)/libc/nexgen32e/runlevel.o \ o/$(MODE)/libc/nexgen32e/runlevel.o \
o/$(MODE)/libc/nexgen32e/pid.o \ o/$(MODE)/libc/nexgen32e/pid.o \
o/$(MODE)/libc/nexgen32e/program_executable_name.o \
o/$(MODE)/libc/nexgen32e/program_invocation_name2.o \ o/$(MODE)/libc/nexgen32e/program_invocation_name2.o \
o/$(MODE)/libc/nexgen32e/threaded.o: private \ o/$(MODE)/libc/nexgen32e/threaded.o: private \
CFLAGS += \ CFLAGS += \

View file

@ -73,12 +73,6 @@ uint64_t VirtualQuery(const void *lpAddress,
void *VirtualAllocEx(int64_t hProcess, void *lpAddress, uint64_t dwSize, void *VirtualAllocEx(int64_t hProcess, void *lpAddress, uint64_t dwSize,
uint32_t flAllocationType, uint32_t flProtect); uint32_t flAllocationType, uint32_t flProtect);
bool32 PrefetchVirtualMemory(int64_t hProcess, const uint32_t *NumberOfEntries,
struct NtMemoryRangeEntry *VirtualAddresses,
uint32_t reserved_Flags);
bool32 OfferVirtualMemory(void *inout_VirtualAddress, size_t Size,
int Priority);
int64_t GetProcessHeap(void); int64_t GetProcessHeap(void);
void *HeapAlloc(int64_t hHeap, uint32_t dwFlags, size_t dwBytes) __wur; void *HeapAlloc(int64_t hHeap, uint32_t dwFlags, size_t dwBytes) __wur;
bool32 HeapFree(int64_t hHeap, uint32_t dwFlags, void *opt_lpMem); bool32 HeapFree(int64_t hHeap, uint32_t dwFlags, void *opt_lpMem);

View file

@ -60,7 +60,11 @@ int sys_fork(void) {
} else if (__syslib) { } else if (__syslib) {
return _sysret(__syslib->__fork()); return _sysret(__syslib->__fork());
} else { } else {
return enosys(); int ax;
axdx_t ad;
ad = __sys_fork();
ax = ad.ax;
return ax;
} }
#else #else

View file

@ -87,9 +87,9 @@ vfork:
#elif defined(__aarch64__) #elif defined(__aarch64__)
adrp x0,__hostos adrp x8,__hostos
ldr w0,[x0,#:lo12:__hostos] ldr w8,[x8,#:lo12:__hostos]
tbz x0,3,1f // bit 3 is xnu tbz x8,3,1f // bit 3 is xnu
b fork // which doesn't support vfork() b fork // which doesn't support vfork()
1: 1:
@ -102,10 +102,19 @@ vfork:
ldp x29,x30,[sp],16 ldp x29,x30,[sp],16
#endif #endif
mov x8,#220 // __NR_clone tbnz w8,5,1f // bit 5 is freebsd
mov x8,#220 // clone (linux)
mov x0,#0x4111 // SIGCHLD | CLONE_VM | CLONE_VFORK mov x0,#0x4111 // SIGCHLD | CLONE_VM | CLONE_VFORK
mov x1,#0 mov x1,#0
svc 0 svc 0
b 2f
1: mov x8,#66 // vfork (freebsd)
svc 0 // call kernel
bcc 2f // jump if not carry
neg x0,x0 // linux style errno
2:
// if (!rc) { // if (!rc) {
// __get_tls()->tib_flags |= TIB_FLAG_VFORKED; // __get_tls()->tib_flags |= TIB_FLAG_VFORKED;

View file

@ -231,60 +231,6 @@ static errno_t CloneXnu(int (*fn)(void *), char *stk, size_t stksz, int flags,
return sys_clone_xnu(fn, arg, wt, 0, PTHREAD_START_CUSTOM_XNU); return sys_clone_xnu(fn, arg, wt, 0, PTHREAD_START_CUSTOM_XNU);
} }
////////////////////////////////////////////////////////////////////////////////
// FREE BESIYATA DISHMAYA
static wontreturn void FreebsdThreadMain(void *p) {
struct CloneArgs *wt = p;
*wt->ctid = wt->tid;
wt->func(wt->arg, wt->tid);
// we no longer use the stack after this point
// void thr_exit(%rdi = long *state);
asm volatile("movl\t$0,%0\n\t" // *wt->ztid = 0
"syscall\n\t" // _umtx_op(wt->ztid, WAKE, INT_MAX)
"movl\t$431,%%eax\n\t" // thr_exit(long *nonzeroes_and_wake)
"xor\t%%edi,%%edi\n\t" // sad we can't use this free futex op
"syscall\n\t" // exit1() fails if thread is orphaned
"movl\t$1,%%eax\n\t" // exit()
"syscall" //
: "=m"(*wt->ztid)
: "a"(454), "D"(wt->ztid), "S"(UMTX_OP_WAKE), "d"(INT_MAX)
: "rcx", "r8", "r9", "r10", "r11", "memory");
__builtin_unreachable();
}
static errno_t CloneFreebsd(int (*func)(void *, int), char *stk, size_t stksz,
int flags, void *arg, void *tls, int *ptid,
int *ctid) {
int ax;
bool failed;
int64_t tid;
struct CloneArgs *wt;
wt = AllocateCloneArgs(stk, stksz);
wt->ctid = flags & CLONE_CHILD_SETTID ? ctid : &wt->tid;
wt->ztid = flags & CLONE_CHILD_CLEARTID ? ctid : &wt->tid;
wt->tls = tls;
wt->func = func;
wt->arg = arg;
struct thr_param params = {
.start_func = FreebsdThreadMain,
.arg = wt,
.stack_base = stk,
.stack_size = (uintptr_t)wt - (uintptr_t)stk,
.tls_base = flags & CLONE_SETTLS ? tls : 0,
.tls_size = 64,
.child_tid = &wt->tid64,
.parent_tid = &tid,
};
asm volatile(CFLAG_ASM("syscall")
: CFLAG_CONSTRAINT(failed), "=a"(ax)
: "1"(__NR_thr_new), "D"(&params), "S"(sizeof(params))
: "rcx", "rdx", "r8", "r9", "r10", "r11", "memory");
if (failed) return ax;
if (flags & CLONE_PARENT_SETTID) *ptid = tid;
return 0;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// OPEN BESIYATA DISHMAYA // OPEN BESIYATA DISHMAYA
@ -441,6 +387,95 @@ static int CloneNetbsd(int (*func)(void *, int), char *stk, size_t stksz,
#endif /* __x86_64__ */ #endif /* __x86_64__ */
////////////////////////////////////////////////////////////////////////////////
// FREE BESIYATA DISHMAYA
void bone(struct CloneArgs *wt) {
*wt->ztid = 0;
}
static wontreturn void FreebsdThreadMain(void *p) {
struct CloneArgs *wt = p;
#ifdef __aarch64__
asm volatile("mov\tx28,%0" : /* no outputs */ : "r"(wt->tls));
#endif
*wt->ctid = wt->tid;
wt->func(wt->arg, wt->tid);
// we no longer use the stack after this point
// void thr_exit(%rdi = long *state);
#ifdef __x86_64__
asm volatile("movl\t$0,%0\n\t" // *wt->ztid = 0
"syscall\n\t" // _umtx_op(wt->ztid, WAKE, INT_MAX)
"movl\t$431,%%eax\n\t" // thr_exit(long *nonzeroes_and_wake)
"xor\t%%edi,%%edi\n\t" // sad we can't use this free futex op
"syscall\n\t" // thr_exit() fails if thread is orphaned
"movl\t$1,%%eax\n\t" // _exit()
"syscall" //
: "=m"(*wt->ztid)
: "a"(454), "D"(wt->ztid), "S"(UMTX_OP_WAKE), "d"(INT_MAX)
: "rcx", "r8", "r9", "r10", "r11", "memory");
#elif defined(__aarch64__)
register long x0 asm("x0") = (long)wt->ztid;
register long x1 asm("x1") = UMTX_OP_WAKE;
register long x2 asm("x2") = INT_MAX;
register long x8 asm("x8") = 454; // _umtx_op
asm volatile("str\twzr,%0\n\t" // *wt->ztid = 0
"svc\t0\n\t" // _umtx_op(wt->ztid, WAKE, INT_MAX)
"mov\tx0,#0\n\t" // arg0 = 0
"mov\tx8,#431\n\t" // thr_exit
"svc\t0\n\t" // thr_exit(long *nonzeroes_and_wake = 0)
"mov\tx8,#1\n\t" // _exit
"svc\t0" // _exit(long *nonzeroes_and_wake = 0)
: "=m"(*wt->ztid)
: "r"(x0), "r"(x1), "r"(x2), "r"(x8));
#else
#error "unsupported architecture"
#endif
__builtin_unreachable();
}
static errno_t CloneFreebsd(int (*func)(void *, int), char *stk, size_t stksz,
int flags, void *arg, void *tls, int *ptid,
int *ctid) {
int64_t tid;
struct CloneArgs *wt;
wt = AllocateCloneArgs(stk, stksz);
wt->ctid = flags & CLONE_CHILD_SETTID ? ctid : &wt->tid;
wt->ztid = flags & CLONE_CHILD_CLEARTID ? ctid : &wt->tid;
wt->tls = tls;
wt->func = func;
wt->arg = arg;
struct thr_param params = {
.start_func = FreebsdThreadMain,
.arg = wt,
.stack_base = stk,
.stack_size = (uintptr_t)wt - (uintptr_t)stk,
.tls_base = flags & CLONE_SETTLS ? tls : 0,
.tls_size = 64,
.child_tid = &wt->tid64,
.parent_tid = &tid,
};
#ifdef __x86_64__
int ax;
bool failed;
asm volatile(CFLAG_ASM("syscall")
: CFLAG_CONSTRAINT(failed), "=a"(ax)
: "1"(__NR_thr_new), "D"(&params), "S"(sizeof(params))
: "rcx", "rdx", "r8", "r9", "r10", "r11", "memory");
if (failed) return ax;
#elif defined(__aarch64__)
register long x0 asm("x0") = (long)&params;
register long x1 asm("x1") = sizeof(params);
register int x8 asm("x8") = 0x1c7; // thr_new
asm volatile("svc\t0" : "+r"(x0) : "r"(x1), "r"(x8) : "memory");
if (x0) return x0;
#else
#error "unsupported architecture"
#endif
if (flags & CLONE_PARENT_SETTID) *ptid = tid;
return 0;
}
#ifdef __aarch64__ #ifdef __aarch64__
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -675,9 +710,9 @@ errno_t clone(void *func, void *stk, size_t stksz, int flags, void *arg,
#else #else
#error "unsupported architecture" #error "unsupported architecture"
#endif #endif
#ifdef __x86_64__
} else if (IsFreebsd()) { } else if (IsFreebsd()) {
rc = CloneFreebsd(func, stk, stksz, flags, arg, tls, ptid, ctid); rc = CloneFreebsd(func, stk, stksz, flags, arg, tls, ptid, ctid);
#ifdef __x86_64__
} else if (IsNetbsd()) { } else if (IsNetbsd()) {
rc = CloneNetbsd(func, stk, stksz, flags, arg, tls, ptid, ctid); rc = CloneNetbsd(func, stk, stksz, flags, arg, tls, ptid, ctid);
} else if (IsOpenbsd()) { } else if (IsOpenbsd()) {

View file

@ -78,7 +78,8 @@ static const char *DecodeMagnum(const char *p, long *r) {
return *r = x, p; return *r = x, p;
} }
wontreturn textstartup void cosmo(long *sp, struct Syslib *m1, char *exename) { wontreturn textstartup void cosmo(long *sp, struct Syslib *m1, char *exename,
long *is_freebsd) {
// get startup timestamp as early as possible // get startup timestamp as early as possible
// its used by --strace and also kprintf() %T // its used by --strace and also kprintf() %T
@ -95,6 +96,11 @@ wontreturn textstartup void cosmo(long *sp, struct Syslib *m1, char *exename) {
}; };
__set_tls(&tib); __set_tls(&tib);
// check for freebsd
if (is_freebsd) {
sp = is_freebsd;
}
// extracts arguments from old sysv stack abi // extracts arguments from old sysv stack abi
int argc = *sp; int argc = *sp;
char **argv = (char **)(sp + 1); char **argv = (char **)(sp + 1);
@ -114,7 +120,10 @@ wontreturn textstartup void cosmo(long *sp, struct Syslib *m1, char *exename) {
// detect apple m1 environment // detect apple m1 environment
const char *magnums; const char *magnums;
if (SupportsXnu() && (__syslib = m1)) { if (SupportsFreebsd() && is_freebsd) {
hostos = _HOSTFREEBSD;
magnums = syscon_freebsd;
} else if (SupportsXnu() && (__syslib = m1)) {
hostos = _HOSTXNU; hostos = _HOSTXNU;
magnums = syscon_xnu; magnums = syscon_xnu;
} else if (SupportsLinux()) { } else if (SupportsLinux()) {

View file

@ -39,7 +39,7 @@ int __zipos_close(int fd) {
if (!__vforked) { if (!__vforked) {
struct ZiposHandle *h; struct ZiposHandle *h;
h = (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle; h = (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle;
__zipos_free(h); __zipos_drop(h);
} }
return rc; return rc;
} }

View file

@ -88,18 +88,11 @@ struct ZiposHandle *__zipos_keep(struct ZiposHandle *h) {
return h; return h;
} }
static bool __zipos_drop(struct ZiposHandle *h) { void __zipos_drop(struct ZiposHandle *h) {
if (!atomic_fetch_sub_explicit(&h->refs, 1, memory_order_release)) { if (atomic_fetch_sub_explicit(&h->refs, 1, memory_order_release)) {
atomic_thread_fence(memory_order_acquire);
return true;
}
return false;
}
void __zipos_free(struct ZiposHandle *h) {
if (!__zipos_drop(h)) {
return; return;
} }
atomic_thread_fence(memory_order_acquire);
if (IsAsan()) { if (IsAsan()) {
__asan_poison((char *)h + sizeof(struct ZiposHandle), __asan_poison((char *)h + sizeof(struct ZiposHandle),
h->mapsize - sizeof(struct ZiposHandle), kAsanHeapFree); h->mapsize - sizeof(struct ZiposHandle), kAsanHeapFree);
@ -227,7 +220,7 @@ static int __zipos_load(struct Zipos *zipos, size_t cf, int flags,
} }
__fds_unlock(); __fds_unlock();
} }
__zipos_free(h); __zipos_drop(h);
return -1; return -1;
} }
@ -238,7 +231,7 @@ void __zipos_postdup(int oldfd, int newfd) {
BLOCK_SIGNALS; BLOCK_SIGNALS;
__fds_lock(); __fds_lock();
if (__isfdkind(newfd, kFdZip)) { if (__isfdkind(newfd, kFdZip)) {
__zipos_free((struct ZiposHandle *)(intptr_t)g_fds.p[newfd].handle); __zipos_drop((struct ZiposHandle *)(intptr_t)g_fds.p[newfd].handle);
if (!__isfdkind(oldfd, kFdZip)) { if (!__isfdkind(oldfd, kFdZip)) {
bzero(g_fds.p + newfd, sizeof(*g_fds.p)); bzero(g_fds.p + newfd, sizeof(*g_fds.p));
} }

View file

@ -38,17 +38,15 @@ static ssize_t __zipos_read_impl(struct ZiposHandle *h, const struct iovec *iov,
return eisdir(); return eisdir();
} }
if (opt_offset == -1) { if (opt_offset == -1) {
while (true) { Restart:
start_pos = atomic_load_explicit(&h->pos, memory_order_relaxed); start_pos = atomic_load_explicit(&h->pos, memory_order_relaxed);
do {
if (UNLIKELY(start_pos == SIZE_MAX)) { if (UNLIKELY(start_pos == SIZE_MAX)) {
continue; goto Restart;
} }
if (LIKELY(atomic_compare_exchange_weak_explicit( } while (!LIKELY(atomic_compare_exchange_weak_explicit(
&h->pos, &start_pos, SIZE_MAX, memory_order_acquire, &h->pos, &start_pos, SIZE_MAX, memory_order_acquire,
memory_order_relaxed))) { memory_order_relaxed)));
break;
}
}
x = y = start_pos; x = y = start_pos;
} else { } else {
x = y = opt_offset; x = y = opt_offset;

View file

@ -47,10 +47,11 @@ static int64_t Seek(int64_t pos, int64_t offset) {
*/ */
int64_t __zipos_seek(struct ZiposHandle *h, int64_t offset, unsigned whence) { int64_t __zipos_seek(struct ZiposHandle *h, int64_t offset, unsigned whence) {
int64_t pos, new_pos; int64_t pos, new_pos;
while (true) { Restart:
pos = atomic_load_explicit(&h->pos, memory_order_relaxed); pos = atomic_load_explicit(&h->pos, memory_order_relaxed);
do {
if (UNLIKELY(pos == SIZE_MAX)) { if (UNLIKELY(pos == SIZE_MAX)) {
continue; goto Restart;
} }
switch (whence) { switch (whence) {
case SEEK_SET: case SEEK_SET:
@ -65,11 +66,8 @@ int64_t __zipos_seek(struct ZiposHandle *h, int64_t offset, unsigned whence) {
default: default:
new_pos = einval(); new_pos = einval();
} }
if (LIKELY(atomic_compare_exchange_weak_explicit( } while (!LIKELY(atomic_compare_exchange_weak_explicit(
&h->pos, &pos, new_pos < 0 ? pos : new_pos, memory_order_release, &h->pos, &pos, new_pos < 0 ? pos : new_pos, memory_order_release,
memory_order_relaxed))) { memory_order_relaxed)));
break;
}
}
return new_pos; return new_pos;
} }

View file

@ -35,7 +35,7 @@
.yoink __zipos_mmap .yoink __zipos_mmap
.yoink __zipos_postdup .yoink __zipos_postdup
.yoink __zipos_keep .yoink __zipos_keep
.yoink __zipos_free .yoink __zipos_drop
// TODO(jart): why does corruption happen when zip has no assets? // TODO(jart): why does corruption happen when zip has no assets?
.yoink .cosmo .yoink .cosmo

View file

@ -38,7 +38,7 @@ struct Zipos {
}; };
int __zipos_close(int); int __zipos_close(int);
void __zipos_free(struct ZiposHandle *); void __zipos_drop(struct ZiposHandle *);
struct ZiposHandle *__zipos_keep(struct ZiposHandle *); struct ZiposHandle *__zipos_keep(struct ZiposHandle *);
struct Zipos *__zipos_get(void) pureconst; struct Zipos *__zipos_get(void) pureconst;
size_t __zipos_normpath(char *, const char *, size_t); size_t __zipos_normpath(char *, const char *, size_t);

Some files were not shown because too many files have changed in this diff Show more