mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-07 10:20:29 +00:00
Merge branch 'master' into pass-os
This commit is contained in:
commit
fc8bcd5cd5
637 changed files with 5166 additions and 9120 deletions
10
Makefile
10
Makefile
|
@ -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 \
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
@ -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
|
||||||
|
|
|
@ -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]);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
struct FILE;
|
|
||||||
struct termios;
|
struct termios;
|
||||||
|
|
||||||
struct TtyIdent {
|
struct TtyIdent {
|
||||||
|
|
|
@ -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
23
examples/crashreport2.cc
Normal 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);
|
||||||
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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\
|
||||||
|
|
|
@ -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 \
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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 {
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
11
libc/calls/sysdir.internal.h
Normal file
11
libc/calls/sysdir.internal.h
Normal 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_ */
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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_ */
|
|
|
@ -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_ */
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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_ */
|
|
|
@ -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_ */
|
|
|
@ -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_ */
|
|
|
@ -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 "???";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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));
|
|
||||||
}
|
|
|
@ -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) {
|
|
||||||
}
|
|
|
@ -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_ */
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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) {
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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) {
|
|
||||||
}
|
|
|
@ -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_ */
|
|
|
@ -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_ */
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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]
|
|
||||||
|
|
|
@ -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]
|
|
||||||
|
|
3077
libc/dns/rfc1035.txt
3077
libc/dns/rfc1035.txt
File diff suppressed because it is too large
Load diff
|
@ -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;
|
|
||||||
}
|
|
|
@ -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) {
|
|
||||||
}
|
|
|
@ -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_ */
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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 += \
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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"(¶ms), "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"(¶ms), "S"(sizeof(params))
|
||||||
|
: "rcx", "rdx", "r8", "r9", "r10", "r11", "memory");
|
||||||
|
if (failed) return ax;
|
||||||
|
#elif defined(__aarch64__)
|
||||||
|
register long x0 asm("x0") = (long)¶ms;
|
||||||
|
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()) {
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue