mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-06 18:00:28 +00:00
Merge branch 'master' into setugid-check
This commit is contained in:
commit
a2d6ae9b83
637 changed files with 5187 additions and 9140 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/dlopen/BUILD.mk # │ You can now use processes
|
||||
include libc/thread/BUILD.mk # │ You can finally call malloc()
|
||||
include tool/hello/BUILD.mk # │
|
||||
include third_party/zlib/BUILD.mk # │
|
||||
include libc/stdio/BUILD.mk # │
|
||||
include tool/hello/BUILD.mk # │
|
||||
include libc/time/BUILD.mk # │
|
||||
include net/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 libc/BUILD.mk #─┘
|
||||
include libc/sock/BUILD.mk #─┐
|
||||
include libc/dns/BUILD.mk # ├──ONLINE RUNTIME
|
||||
include net/http/BUILD.mk # │ You can communicate with the network
|
||||
include third_party/musl/BUILD.mk # │
|
||||
include net/http/BUILD.mk # ├──ONLINE RUNTIME
|
||||
include third_party/musl/BUILD.mk # │ You can communicate with the network
|
||||
include libc/x/BUILD.mk # │
|
||||
include dsp/scale/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/xed/BUILD.mk
|
||||
include test/libc/fmt/BUILD.mk
|
||||
include test/libc/dns/BUILD.mk
|
||||
include test/libc/time/BUILD.mk
|
||||
include test/libc/proc/BUILD.mk
|
||||
include test/libc/stdio/BUILD.mk
|
||||
|
@ -373,7 +371,6 @@ loc: o/$(MODE)/tool/build/summy.com
|
|||
COSMOPOLITAN_OBJECTS = \
|
||||
TOOL_ARGS \
|
||||
NET_HTTP \
|
||||
LIBC_DNS \
|
||||
LIBC_SOCK \
|
||||
LIBC_NT_WS2_32 \
|
||||
LIBC_NT_IPHLPAPI \
|
||||
|
@ -424,7 +421,6 @@ COSMOPOLITAN_H_PKGS = \
|
|||
APE \
|
||||
LIBC \
|
||||
LIBC_CALLS \
|
||||
LIBC_DNS \
|
||||
LIBC_ELF \
|
||||
LIBC_FMT \
|
||||
LIBC_DLOPEN \
|
||||
|
|
|
@ -78,7 +78,8 @@ APE_LOADER_FLAGS = \
|
|||
$<
|
||||
|
||||
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/start.o \
|
||||
|
@ -88,7 +89,7 @@ o/$(MODE)/ape/ape.elf.dbg: \
|
|||
@$(COMPILE) -ALINK.elf $(LD) $(APE_LOADER_LDFLAGS) -o $@ $(patsubst %.lds,-T %.lds,$^)
|
||||
|
||||
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
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/ape/launch.o: ape/launch.S
|
||||
|
|
|
@ -87,7 +87,7 @@
|
|||
#define MIN(X, Y) ((Y) > (X) ? (X) : (Y))
|
||||
#define MAX(X, Y) ((Y) < (X) ? (X) : (Y))
|
||||
|
||||
#define PATH_MAX 1024 /* XXX verify */
|
||||
#define PATH_MAX 1024 /* XXX verify */
|
||||
|
||||
#define SupportsLinux() (SUPPORT_VECTOR & LINUX)
|
||||
#define SupportsXnu() (SUPPORT_VECTOR & XNU)
|
||||
|
@ -224,8 +224,8 @@ struct ApeLoader {
|
|||
};
|
||||
|
||||
EXTERN_C long SystemCall(long, long, long, long, long, long, long, int);
|
||||
EXTERN_C void
|
||||
Launch(void *, long, void *, void *, int) __attribute__((__noreturn__));
|
||||
EXTERN_C void Launch(void *, long, void *, void *, int)
|
||||
__attribute__((__noreturn__));
|
||||
|
||||
extern char __executable_start[];
|
||||
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)),)
|
||||
ARCH = aarch64
|
||||
HOSTS ?= pi silicon
|
||||
HOSTS ?= pi studio freebsdarm
|
||||
else
|
||||
ARCH = x86_64
|
||||
HOSTS ?= freebsd rhel7 xnu win10 openbsd netbsd
|
||||
|
|
|
@ -9,8 +9,9 @@ int mulaw(int);
|
|||
int unmulaw(int);
|
||||
void *double2byte(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 *dctjpeg(float[8][8]);
|
||||
void *dct(float[restrict hasatleast 8][8], unsigned,
|
||||
float, float, float, float, float);
|
||||
void *dctjpeg(float[restrict hasatleast 8][8], unsigned);
|
||||
double det3(const double[3][3]) nosideeffect;
|
||||
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]);
|
||||
|
|
|
@ -18,40 +18,40 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/core/core.h"
|
||||
|
||||
#define DCT(A, B, C, D, E, F, G, H, T, C0, C1, C2, C3, C4) \
|
||||
do { \
|
||||
T z1, z2, z3, z4, z5, z11, z13; \
|
||||
T t0, t1, t2, t3, t4, t5, t6, t7, t10, t11, t12, t13; \
|
||||
t0 = A + H; \
|
||||
t7 = A - H; \
|
||||
t1 = B + G; \
|
||||
t6 = B - G; \
|
||||
t2 = C + F; \
|
||||
t5 = C - F; \
|
||||
t3 = D + E; \
|
||||
t4 = D - E; \
|
||||
t10 = t0 + t3; \
|
||||
t13 = t0 - t3; \
|
||||
t11 = t1 + t2; \
|
||||
t12 = t1 - t2; \
|
||||
A = t10 + t11; \
|
||||
E = t10 - t11; \
|
||||
z1 = (t12 + t13) * C0; \
|
||||
C = t13 + z1; \
|
||||
G = t13 - z1; \
|
||||
t10 = t4 + t5; \
|
||||
t11 = t5 + t6; \
|
||||
t12 = t6 + t7; \
|
||||
z5 = (t10 - t12) * C1; \
|
||||
z2 = t10 * C2 + z5; \
|
||||
z4 = t12 * C3 + z5; \
|
||||
z3 = t11 * C4; \
|
||||
z11 = t7 + z3; \
|
||||
z13 = t7 - z3; \
|
||||
F = z13 + z2; \
|
||||
D = z13 - z2; \
|
||||
B = z11 + z4; \
|
||||
H = z11 - z4; \
|
||||
#define DCT(A, B, C, D, E, F, G, H, T, C0, C1, C2, C3, C4) \
|
||||
do { \
|
||||
T z1, z2, z3, z4, z5, z11, z13; \
|
||||
T t0, t1, t2, t3, t4, t5, t6, t7, t10, t11, t12, t13; \
|
||||
t0 = A + H; \
|
||||
t7 = A - H; \
|
||||
t1 = B + G; \
|
||||
t6 = B - G; \
|
||||
t2 = C + F; \
|
||||
t5 = C - F; \
|
||||
t3 = D + E; \
|
||||
t4 = D - E; \
|
||||
t10 = t0 + t3; \
|
||||
t13 = t0 - t3; \
|
||||
t11 = t1 + t2; \
|
||||
t12 = t1 - t2; \
|
||||
A = t10 + t11; \
|
||||
E = t10 - t11; \
|
||||
z1 = (t12 + t13) * C0; \
|
||||
C = t13 + z1; \
|
||||
G = t13 - z1; \
|
||||
t10 = t4 + t5; \
|
||||
t11 = t5 + t6; \
|
||||
t12 = t6 + t7; \
|
||||
z5 = (t10 - t12) * C1; \
|
||||
z2 = t10 * C2 + z5; \
|
||||
z4 = t12 * C3 + z5; \
|
||||
z3 = t11 * C4; \
|
||||
z11 = t7 + z3; \
|
||||
z13 = t7 - z3; \
|
||||
F = z13 + z2; \
|
||||
D = z13 - z2; \
|
||||
B = z11 + z4; \
|
||||
H = z11 - z4; \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
|
@ -65,20 +65,21 @@
|
|||
*
|
||||
* @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;
|
||||
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],
|
||||
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],
|
||||
float, c0, c1, c2, c3, c4);
|
||||
}
|
||||
return M;
|
||||
}
|
||||
|
||||
void *dctjpeg(float M[8][8]) {
|
||||
return dct(M, .707106781f, .382683433f, .541196100f, 1.306562965f,
|
||||
void *dctjpeg(float M[restrict hasatleast 8][8], unsigned stride) {
|
||||
return dct(M, stride, .707106781f, .382683433f, .541196100f, 1.306562965f,
|
||||
.707106781f);
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
#include "dsp/mpeg/mpeg.h"
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct FILE;
|
||||
|
||||
enum plm_buffer_mode {
|
||||
PLM_BUFFER_MODE_FILE,
|
||||
PLM_BUFFER_MODE_FIXED_MEM,
|
||||
|
@ -17,7 +15,7 @@ typedef struct plm_buffer_t {
|
|||
unsigned length;
|
||||
int free_when_done;
|
||||
int close_when_done;
|
||||
struct FILE *fh;
|
||||
FILE *fh;
|
||||
plm_buffer_load_callback load_callback;
|
||||
void *load_callback_user_data;
|
||||
unsigned char *bytes;
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
#ifndef COSMOPOLITAN_DSP_MPEG_MPEG_H_
|
||||
#define COSMOPOLITAN_DSP_MPEG_MPEG_H_
|
||||
#include "libc/stdio/stdio.h"
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct FILE;
|
||||
|
||||
typedef struct plm_t plm_t;
|
||||
typedef struct plm_buffer_t plm_buffer_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
|
||||
* 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
|
||||
|
@ -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
|
||||
* 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
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct FILE;
|
||||
struct termios;
|
||||
|
||||
struct TtyIdent {
|
||||
|
|
|
@ -44,7 +44,6 @@ EXAMPLES_DIRECTDEPS = \
|
|||
DSP_TTY \
|
||||
LIBC_CALLS \
|
||||
LIBC_DLOPEN \
|
||||
LIBC_DNS \
|
||||
LIBC_FMT \
|
||||
LIBC_INTRIN \
|
||||
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
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
@ -26,6 +25,7 @@
|
|||
#include "libc/sysv/consts/sock.h"
|
||||
#include "libc/sysv/consts/sol.h"
|
||||
#include "third_party/getopt/getopt.internal.h"
|
||||
#include "third_party/musl/netdb.h"
|
||||
|
||||
/**
|
||||
* @fileoverview netcat clone
|
||||
|
@ -60,9 +60,7 @@ int main(int argc, char *argv[]) {
|
|||
halfclose = false;
|
||||
break;
|
||||
case 'h':
|
||||
fputs("Usage: ", stdout);
|
||||
fputs(argv[0], stdout);
|
||||
fputs(" [-hH] IP PORT\n", stdout);
|
||||
tinyprint(1, "Usage: ", argv[0], " [-hH] IP PORT\n", NULL);
|
||||
exit(0);
|
||||
default:
|
||||
fprintf(stderr, "bad option %d\n", opt);
|
||||
|
@ -76,17 +74,9 @@ int main(int argc, char *argv[]) {
|
|||
host = argv[optind + 0];
|
||||
port = argv[optind + 1];
|
||||
|
||||
switch ((rc = getaddrinfo(host, port, &hint, &ai))) {
|
||||
case EAI_SUCCESS:
|
||||
break;
|
||||
case EAI_SYSTEM:
|
||||
perror("getaddrinfo");
|
||||
exit(1);
|
||||
default:
|
||||
fputs("EAI_", stderr);
|
||||
fputs(gai_strerror(rc), stderr);
|
||||
fputs("\n", stderr);
|
||||
exit(1);
|
||||
if ((rc = getaddrinfo(host, port, &hint, &ai))) {
|
||||
tinyprint(2, host, ": ", gai_strerror(rc), "\n", NULL);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) == -1) {
|
||||
|
@ -95,12 +85,12 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)) == -1) {
|
||||
perror("setsockopt(SO_LINGER)");
|
||||
perror("SO_LINGER");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
|
||||
perror("connect");
|
||||
perror(host);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,12 +30,13 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/weirdtypes.h"
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/log/bsd.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/sock/struct/pollfd.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
#include "libc/sysv/consts/ex.h"
|
||||
|
@ -44,6 +45,7 @@
|
|||
#include "libc/sysv/consts/poll.h"
|
||||
#include "libc/sysv/consts/sock.h"
|
||||
#include "third_party/getopt/getopt.internal.h"
|
||||
#include "third_party/musl/netdb.h"
|
||||
// clang-format off
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
|
|
|
@ -276,7 +276,6 @@ LIBC_FILES := $(wildcard libc/*)
|
|||
o/$(MODE)/libc: o/$(MODE)/libc/calls \
|
||||
o/$(MODE)/libc/crt \
|
||||
o/$(MODE)/libc/dlopen \
|
||||
o/$(MODE)/libc/dns \
|
||||
o/$(MODE)/libc/elf \
|
||||
o/$(MODE)/libc/fmt \
|
||||
o/$(MODE)/libc/intrin \
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*-*- 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 2022 Justine Alexandra Roberts Tunney │
|
||||
│ Copyright 2023 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 │
|
||||
|
@ -16,11 +16,13 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ 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.
|
||||
static _Thread_local int __h_errno;
|
||||
|
||||
errno_t *__h_errno_location(void) {
|
||||
return &__h_errno;
|
||||
const char *GetHostsTxtPath(char *path, size_t size) {
|
||||
if (!IsWindows()) {
|
||||
return "/etc/hosts";
|
||||
} else {
|
||||
return GetSystemDirectoryPath(path, "drivers\\etc\\hosts", size);
|
||||
}
|
||||
}
|
|
@ -64,8 +64,8 @@ static inline int AllNumDot(const char *s) {
|
|||
case 0: return 1;
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9': case '.':
|
||||
/* continue */
|
||||
}
|
||||
; /* continue */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,6 +104,7 @@ static int TryPath(const char *q, int com) {
|
|||
}
|
||||
*p = 0;
|
||||
if (!sys_faccessat(AT_FDCWD, g_prog.u.buf, F_OK, 0)) return 1;
|
||||
if (!com) return 0;
|
||||
p = WRITE32LE(p, READ32LE(".com"));
|
||||
*p = 0;
|
||||
if (!sys_faccessat(AT_FDCWD, g_prog.u.buf, F_OK, 0)) return 1;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*-*- 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 │
|
||||
│ Copyright 2023 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 │
|
||||
|
@ -16,18 +16,13 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/calls/sysdir.internal.h"
|
||||
#include "libc/dce.h"
|
||||
|
||||
/**
|
||||
* Frees addresses returned by getaddrinfo().
|
||||
*/
|
||||
void freeaddrinfo(struct addrinfo *ai) {
|
||||
struct addrinfo *next;
|
||||
while (ai) {
|
||||
/* we assume ai_addr and ai_canonname are shoehorned */
|
||||
next = ai->ai_next;
|
||||
free(ai);
|
||||
ai = next;
|
||||
const char *GetProtocolsTxtPath(char *buf, size_t size) {
|
||||
if (!IsWindows()) {
|
||||
return "/etc/protocols";
|
||||
} else {
|
||||
return GetSystemDirectoryPath(buf, "drivers\\etc\\protocol", size);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*-*- 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 2022 Justine Alexandra Roberts Tunney │
|
||||
│ Copyright 2023 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 │
|
||||
|
@ -16,22 +16,13 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/ent.h"
|
||||
#include "libc/calls/sysdir.internal.h"
|
||||
#include "libc/dce.h"
|
||||
|
||||
/**
|
||||
* Turns `h_errno` value into string.
|
||||
*/
|
||||
const char *hstrerror(int err) {
|
||||
switch (err) {
|
||||
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";
|
||||
const char *GetServicesTxtPath(char *path, size_t size) {
|
||||
if (!IsWindows()) {
|
||||
return "/etc/services";
|
||||
} else {
|
||||
return GetSystemDirectoryPath(path, "drivers\\etc\\services", size);
|
||||
}
|
||||
}
|
|
@ -16,19 +16,16 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/nt/systeminfo.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
// e.g. GetSystemDirectoryPath(buf, size, "FOO") → "C:\WINDOWS\SYSTEM32\FOO"
|
||||
textwindows char *GetSystemDirectoryPath(char *buf, size_t size,
|
||||
const char *path) {
|
||||
// e.g. GetSystemDirectoryPath(buf, "FOO", size) → "C:\WINDOWS\SYSTEM32\FOO"
|
||||
textwindows char *GetSystemDirectoryPath(char *buf, const char *path,
|
||||
size_t size) {
|
||||
uint32_t syslen = GetSystemDirectoryA(buf, size);
|
||||
size_t pathlen = strlen(path);
|
||||
if (syslen && syslen + pathlen + 1 < size) {
|
||||
if (buf[syslen] == '\\') {
|
||||
--syslen;
|
||||
}
|
||||
if (buf[syslen] == '\\') --syslen;
|
||||
memcpy(buf + syslen, path, pathlen + 1);
|
||||
return buf;
|
||||
} else {
|
|
@ -17,46 +17,43 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/enum/offerpriority.h"
|
||||
#include "libc/nt/memory.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/memoryrangeentry.h"
|
||||
#include "libc/sysv/consts/madv.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
forceinline typeof(PrefetchVirtualMemory) *GetPrefetchVirtualMemory(void) {
|
||||
static bool once;
|
||||
static typeof(PrefetchVirtualMemory) *PrefetchVirtualMemory_;
|
||||
if (!once) {
|
||||
typedef bool32 (*__msabi PrefetchVirtualMemoryPtr)(
|
||||
int64_t hProcess, uintptr_t NumberOfEntries,
|
||||
struct NtMemoryRangeEntry *VirtualAddresses, uint32_t reserved_Flags);
|
||||
|
||||
textwindows static PrefetchVirtualMemoryPtr GetPrefetchVirtualMemory(void) {
|
||||
static PrefetchVirtualMemoryPtr PrefetchVirtualMemory_;
|
||||
if (!PrefetchVirtualMemory_) {
|
||||
PrefetchVirtualMemory_ = /* win8.1+ */
|
||||
GetProcAddressModule("Kernel32.dll", "PrefetchVirtualMemory");
|
||||
once = true;
|
||||
}
|
||||
return PrefetchVirtualMemory_;
|
||||
}
|
||||
|
||||
forceinline typeof(OfferVirtualMemory) *GetOfferVirtualMemory(void) {
|
||||
static bool once;
|
||||
static typeof(OfferVirtualMemory) *OfferVirtualMemory_;
|
||||
if (!once) {
|
||||
typedef bool32 (*__msabi OfferVirtualMemoryPtr)(void *inout_VirtualAddress,
|
||||
size_t Size, int Priority);
|
||||
|
||||
textwindows static OfferVirtualMemoryPtr GetOfferVirtualMemory(void) {
|
||||
static OfferVirtualMemoryPtr OfferVirtualMemory_;
|
||||
if (!OfferVirtualMemory_) {
|
||||
OfferVirtualMemory_ = /* win8.1+ */
|
||||
GetProcAddressModule("Kernel32.dll", "OfferVirtualMemory");
|
||||
once = true;
|
||||
}
|
||||
return OfferVirtualMemory_;
|
||||
}
|
||||
|
||||
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) {
|
||||
typeof(PrefetchVirtualMemory) *fn = GetPrefetchVirtualMemory();
|
||||
PrefetchVirtualMemoryPtr fn = GetPrefetchVirtualMemory();
|
||||
if (fn) {
|
||||
ranges[0].VirtualAddress = addr;
|
||||
ranges[0].NumberOfBytes = length;
|
||||
rangecount = ARRAYLEN(ranges);
|
||||
if (fn(GetCurrentProcess(), &rangecount, ranges, 0)) {
|
||||
if (fn(GetCurrentProcess(), 1, &(struct NtMemoryRangeEntry){addr, length},
|
||||
0)) {
|
||||
return 0;
|
||||
} else {
|
||||
return __winerr();
|
||||
|
@ -65,7 +62,7 @@ textwindows int sys_madvise_nt(void *addr, size_t length, int advice) {
|
|||
return enosys();
|
||||
}
|
||||
} else if (advice == MADV_FREE) {
|
||||
typeof(OfferVirtualMemory) *fn = GetOfferVirtualMemory();
|
||||
OfferVirtualMemoryPtr fn = GetOfferVirtualMemory();
|
||||
if (fn) {
|
||||
if (fn(addr, length, kNtVmOfferPriorityNormal)) {
|
||||
return 0;
|
||||
|
|
|
@ -29,21 +29,21 @@
|
|||
*
|
||||
* @param advice can be MADV_WILLNEED, MADV_SEQUENTIAL, MADV_FREE, etc.
|
||||
* @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 fadvise()
|
||||
*/
|
||||
int madvise(void *addr, size_t length, int advice) {
|
||||
int rc;
|
||||
if (advice != 127 /* see consts.sh */) {
|
||||
if (IsAsan() && !__asan_is_valid(addr, length)) {
|
||||
rc = efault();
|
||||
} else if (!IsWindows()) {
|
||||
rc = sys_madvise(addr, length, advice);
|
||||
} else {
|
||||
rc = sys_madvise_nt(addr, length, advice);
|
||||
}
|
||||
if (IsAsan() && !__asan_is_valid(addr, length)) {
|
||||
rc = efault();
|
||||
} else if (!IsWindows()) {
|
||||
rc = sys_madvise(addr, length, advice);
|
||||
} else {
|
||||
rc = einval();
|
||||
rc = sys_madvise_nt(addr, length, advice);
|
||||
}
|
||||
STRACE("madvise(%p, %'zu, %d) → %d% m", addr, length, advice, rc);
|
||||
return rc;
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
* Advises kernel about memory intentions, the POSIX way.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
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 │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/seccomp.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/seccomp.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
|
@ -62,16 +62,20 @@ int seccomp(unsigned operation, unsigned flags, void *args) {
|
|||
rc = -1;
|
||||
}
|
||||
#elif defined(__aarch64__)
|
||||
register long r0 asm("x0") = (long)operation;
|
||||
register long r1 asm("x1") = (long)flags;
|
||||
register long r2 asm("x2") = (long)args;
|
||||
register long res_x0 asm("x0");
|
||||
asm volatile("mov\tx8,%1\n\t"
|
||||
"svc\t0"
|
||||
: "=r"(res_x0)
|
||||
: "i"(211), "r"(r0), "r"(r1), "r"(r2)
|
||||
: "x8", "memory");
|
||||
rc = _sysret(res_x0);
|
||||
if (IsLinux()) {
|
||||
register long r0 asm("x0") = (long)operation;
|
||||
register long r1 asm("x1") = (long)flags;
|
||||
register long r2 asm("x2") = (long)args;
|
||||
register long res_x0 asm("x0");
|
||||
asm volatile("mov\tx8,%1\n\t"
|
||||
"svc\t0"
|
||||
: "=r"(res_x0)
|
||||
: "i"(211), "r"(r0), "r"(r1), "r"(r2)
|
||||
: "x8", "memory");
|
||||
rc = _sysret(res_x0);
|
||||
} else {
|
||||
rc = enosys();
|
||||
}
|
||||
#else
|
||||
#error "arch unsupported"
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/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/siginfo-freebsd.internal.h"
|
||||
#include "libc/calls/struct/siginfo-meta.internal.h"
|
||||
|
@ -33,18 +34,18 @@
|
|||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sa.h"
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
privileged void __sigenter_freebsd(int sig, struct siginfo_freebsd *freebsdinfo,
|
||||
struct ucontext_freebsd *ctx) {
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC diagnostic ignored "-Wframe-larger-than="
|
||||
struct Goodies {
|
||||
struct {
|
||||
ucontext_t uc;
|
||||
siginfo_t si;
|
||||
} g;
|
||||
CheckLargeStackAllocation(&g, sizeof(g));
|
||||
#pragma GCC pop_options
|
||||
|
||||
int rva, flags;
|
||||
rva = __sighandrvas[sig];
|
||||
if (rva >= kSigactionMinRva) {
|
||||
|
@ -52,12 +53,20 @@ privileged void __sigenter_freebsd(int sig, struct siginfo_freebsd *freebsdinfo,
|
|||
if (~flags & SA_SIGINFO) {
|
||||
((sigaction_f)(__executable_start + rva))(sig, 0, 0);
|
||||
} else {
|
||||
|
||||
//
|
||||
// TRANSLATE FREEBSD SIGNAL TO LINUX SIGNAL
|
||||
//
|
||||
|
||||
__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_size = ctx->uc_stack.ss_size;
|
||||
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;
|
||||
|
||||
#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.r9 = ctx->uc_mcontext.mc_r9;
|
||||
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.trapno = ctx->uc_mcontext.mc_trapno;
|
||||
__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);
|
||||
|
||||
//
|
||||
// TRANSLATE LINUX SIGNAL TO FREEBSD SIGNAL
|
||||
//
|
||||
|
||||
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_flags = g.uc.uc_stack.ss_flags;
|
||||
ctx->uc_flags = g.uc.uc_flags;
|
||||
ctx->uc_sigmask[0] = g.uc.uc_sigmask;
|
||||
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_rsi = g.uc.uc_mcontext.rsi;
|
||||
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_rsp = g.uc.uc_mcontext.rsp;
|
||||
__repmovsb(&ctx->uc_mcontext.mc_fpstate, &g.uc.__fpustate, 512);
|
||||
#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.
|
||||
*/
|
||||
// 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__ */
|
||||
|
|
|
@ -2,6 +2,22 @@
|
|||
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_UCONTEXT_FREEBSD_INTERNAL_H_
|
||||
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 {
|
||||
void *ss_sp;
|
||||
uint64_t ss_size;
|
||||
|
@ -9,6 +25,7 @@ struct stack_freebsd {
|
|||
};
|
||||
|
||||
struct mcontext_freebsd {
|
||||
#ifdef __x86_64__
|
||||
int64_t mc_onstack;
|
||||
int64_t mc_rdi;
|
||||
int64_t mc_rsi;
|
||||
|
@ -47,6 +64,14 @@ struct mcontext_freebsd {
|
|||
int64_t mc_xfpustate;
|
||||
int64_t mc_xfpustate_len;
|
||||
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 {
|
||||
|
|
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__)
|
||||
|
||||
#if SupportsFreebsd()
|
||||
// save first arg
|
||||
mov x3,x0
|
||||
#endif
|
||||
|
||||
// save original stack pointer
|
||||
// this is the first argument to cosmo() below
|
||||
mov x0,sp
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
*/
|
||||
#define SUPPORT_VECTOR 255
|
||||
#else
|
||||
#define SUPPORT_VECTOR (_HOSTLINUX | _HOSTXNU)
|
||||
#define SUPPORT_VECTOR (_HOSTLINUX | _HOSTXNU | _HOSTFREEBSD)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -62,8 +62,10 @@
|
|||
#endif
|
||||
|
||||
#ifdef __aarch64__
|
||||
#define IsAarch64() 1
|
||||
#define IsXnuSilicon() IsXnu()
|
||||
#else
|
||||
#define IsAarch64() 0
|
||||
#define IsXnuSilicon() 0
|
||||
#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");
|
||||
#elif defined(__aarch64__)
|
||||
register long x0 asm("x0") = exitcode;
|
||||
asm volatile("mov\tx8,%0\n\t"
|
||||
"mov\tx16,%1\n\t"
|
||||
register long x8 asm("x8") = IsLinux() ? 94 : 1;
|
||||
asm volatile("mov\tx16,%1\n\t"
|
||||
"svc\t0"
|
||||
: /* no outputs */
|
||||
: "i"(94), "i"(1), "r"(x0)
|
||||
: "x8", "x16", "memory");
|
||||
: "r"(x8), "i"(1), "r"(x0)
|
||||
: "x16", "memory");
|
||||
#else
|
||||
#error "unsupported architecture"
|
||||
#endif
|
||||
|
@ -77,12 +77,12 @@ wontreturn void _Exit(int exitcode) {
|
|||
: "rcx", "r11", "memory");
|
||||
#else
|
||||
register long r0 asm("x0") = exitcode;
|
||||
asm volatile("mov\tx8,%0\n\t"
|
||||
"mov\tx16,%1\n\t"
|
||||
register long x8 asm("x8") = IsLinux() ? 93 : 431;
|
||||
asm volatile("mov\tx16,%1\n\t"
|
||||
"svc\t0"
|
||||
: /* no outputs */
|
||||
: "i"(93), "i"(0x169), "r"(r0)
|
||||
: "x8", "memory");
|
||||
: "r"(x8), "i"(0x169), "r"(r0)
|
||||
: "memory");
|
||||
#endif
|
||||
} else if (IsWindows()) {
|
||||
uint32_t waitstatus;
|
||||
|
|
|
@ -74,13 +74,27 @@ wontreturn void _Exit1(int rc) {
|
|||
}
|
||||
notpossible;
|
||||
#elif defined(__aarch64__)
|
||||
if (IsLinux()) {
|
||||
register long r0 asm("x0") = rc;
|
||||
asm volatile("mov\tx8,%0\n\t"
|
||||
"svc\t0"
|
||||
: /* no outputs */
|
||||
: "i"(93), "r"(r0)
|
||||
: "x8", "memory");
|
||||
if (IsLinux() || IsFreebsd()) {
|
||||
register int x0 asm("x0") = rc;
|
||||
register int x8 asm("x8");
|
||||
if (IsLinux()) {
|
||||
x8 = 93; // exit
|
||||
} 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"
|
||||
: /* no outputs */
|
||||
: "r"(x0)
|
||||
: "memory");
|
||||
}
|
||||
} else if (IsXnu()) {
|
||||
__syslib->__pthread_exit(0);
|
||||
}
|
||||
|
|
|
@ -32,10 +32,19 @@ _futex:
|
|||
neg %eax
|
||||
1: pop %rbp
|
||||
#elif defined(__aarch64__)
|
||||
mov x8,#0x062
|
||||
svc #0
|
||||
ldr x7,=__hostos
|
||||
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
|
||||
#error "unsupported architecture"
|
||||
#endif /* __x86_64__ */
|
||||
ret
|
||||
1: ret
|
||||
.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) {
|
||||
struct Fds *fds;
|
||||
fds = __veil("r", &g_fds);
|
||||
fds = &g_fds;
|
||||
fds->n = 4;
|
||||
atomic_store_explicit(&fds->f, 3, memory_order_relaxed);
|
||||
if (_weaken(_extend)) {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/nt/thread.h"
|
||||
#include "libc/nt/thunk/msabi.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
|
@ -25,9 +26,9 @@
|
|||
__msabi extern typeof(GetCurrentThreadId) *const __imp_GetCurrentThreadId;
|
||||
|
||||
int sys_gettid(void) {
|
||||
int64_t wut;
|
||||
#ifdef __x86_64__
|
||||
int tid;
|
||||
int64_t wut;
|
||||
if (IsWindows()) {
|
||||
tid = __imp_GetCurrentThreadId();
|
||||
} else if (IsLinux()) {
|
||||
|
@ -65,11 +66,23 @@ int sys_gettid(void) {
|
|||
#elif defined(__aarch64__)
|
||||
// this can't be used on xnu
|
||||
register long res asm("x0");
|
||||
asm volatile("mov\tx8,%1\n\t"
|
||||
"svc\t0"
|
||||
: "=r"(res)
|
||||
: "i"(178)
|
||||
: "x8", "memory");
|
||||
if (IsLinux()) {
|
||||
asm volatile("mov\tx8,%1\n\t"
|
||||
"svc\t0"
|
||||
: "=r"(res)
|
||||
: "i"(178)
|
||||
: "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;
|
||||
#else
|
||||
#error "arch unsupported"
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include "libc/atomic.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/thread/freebsd.internal.h"
|
||||
#ifdef __x86_64__
|
||||
|
||||
int sys_umtx_timedwait_uint_cp(atomic_int *, int, int, size_t,
|
||||
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);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#ifndef _NETDB_H
|
||||
#define _NETDB_H
|
||||
#include "libc/calls/weirdtypes.h"
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/dns/ent.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/sock/struct/in6_pktinfo.h"
|
||||
#include "libc/sock/struct/in_pktinfo.h"
|
||||
|
@ -19,4 +17,5 @@
|
|||
#include "libc/sysv/consts/mcast.h"
|
||||
#include "libc/sysv/consts/pf.h"
|
||||
#include "libc/sysv/consts/sock.h"
|
||||
#include "third_party/musl/netdb.h"
|
||||
#endif /* _NETDB_H */
|
||||
|
|
|
@ -164,6 +164,7 @@ __funline void *__memset(void *a, int c, unsigned long n) {
|
|||
char *d = a;
|
||||
unsigned long i;
|
||||
for (i = 0; i < n; ++i) {
|
||||
__asm__ volatile("" ::: "memory");
|
||||
d[i] = c;
|
||||
}
|
||||
return d;
|
||||
|
@ -174,6 +175,7 @@ __funline void *__memcpy(void *a, const void *b, unsigned long n) {
|
|||
unsigned long i;
|
||||
const char *s = b;
|
||||
for (i = 0; i < n; ++i) {
|
||||
__asm__ volatile("" ::: "memory");
|
||||
d[i] = s[i];
|
||||
}
|
||||
return d;
|
||||
|
@ -185,10 +187,12 @@ __funline void *__memmove(void *a, const void *b, unsigned long n) {
|
|||
const char *s = b;
|
||||
if (d > s) {
|
||||
for (i = n; i--;) {
|
||||
__asm__ volatile("" ::: "memory");
|
||||
d[i] = s[i];
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < n; ++i) {
|
||||
__asm__ volatile("" ::: "memory");
|
||||
d[i] = s[i];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_LOG_LOG_H_
|
||||
#define COSMOPOLITAN_LIBC_LOG_LOG_H_
|
||||
#ifdef _COSMO_SOURCE
|
||||
#include "libc/stdio/stdio.h"
|
||||
#ifdef _COSMO_SOURCE
|
||||
|
||||
#define kLogFatal 0
|
||||
#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,
|
||||
sig, kind, host, getpid(), gettid());
|
||||
if (program_invocation_name) {
|
||||
Append(b, " %s\n", program_invocation_name);
|
||||
Append(b, " %s\n", __program_executable_name);
|
||||
}
|
||||
if (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/runlevel.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/threaded.o: private \
|
||||
CFLAGS += \
|
||||
|
|
|
@ -73,12 +73,6 @@ uint64_t VirtualQuery(const void *lpAddress,
|
|||
void *VirtualAllocEx(int64_t hProcess, void *lpAddress, uint64_t dwSize,
|
||||
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);
|
||||
void *HeapAlloc(int64_t hHeap, uint32_t dwFlags, size_t dwBytes) __wur;
|
||||
bool32 HeapFree(int64_t hHeap, uint32_t dwFlags, void *opt_lpMem);
|
||||
|
|
|
@ -60,7 +60,11 @@ int sys_fork(void) {
|
|||
} else if (__syslib) {
|
||||
return _sysret(__syslib->__fork());
|
||||
} else {
|
||||
return enosys();
|
||||
int ax;
|
||||
axdx_t ad;
|
||||
ad = __sys_fork();
|
||||
ax = ad.ax;
|
||||
return ax;
|
||||
}
|
||||
|
||||
#else
|
||||
|
|
|
@ -87,9 +87,9 @@ vfork:
|
|||
|
||||
#elif defined(__aarch64__)
|
||||
|
||||
adrp x0,__hostos
|
||||
ldr w0,[x0,#:lo12:__hostos]
|
||||
tbz x0,3,1f // bit 3 is xnu
|
||||
adrp x8,__hostos
|
||||
ldr w8,[x8,#:lo12:__hostos]
|
||||
tbz x8,3,1f // bit 3 is xnu
|
||||
b fork // which doesn't support vfork()
|
||||
1:
|
||||
|
||||
|
@ -102,10 +102,19 @@ vfork:
|
|||
ldp x29,x30,[sp],16
|
||||
#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 x1,#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) {
|
||||
// __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);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
|
||||
|
@ -441,6 +387,95 @@ static int CloneNetbsd(int (*func)(void *, int), char *stk, size_t stksz,
|
|||
|
||||
#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__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -675,9 +710,9 @@ errno_t clone(void *func, void *stk, size_t stksz, int flags, void *arg,
|
|||
#else
|
||||
#error "unsupported architecture"
|
||||
#endif
|
||||
#ifdef __x86_64__
|
||||
} else if (IsFreebsd()) {
|
||||
rc = CloneFreebsd(func, stk, stksz, flags, arg, tls, ptid, ctid);
|
||||
#ifdef __x86_64__
|
||||
} else if (IsNetbsd()) {
|
||||
rc = CloneNetbsd(func, stk, stksz, flags, arg, tls, ptid, ctid);
|
||||
} else if (IsOpenbsd()) {
|
||||
|
|
|
@ -78,7 +78,8 @@ static const char *DecodeMagnum(const char *p, long *r) {
|
|||
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
|
||||
// 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);
|
||||
|
||||
// check for freebsd
|
||||
if (is_freebsd) {
|
||||
sp = is_freebsd;
|
||||
}
|
||||
|
||||
// extracts arguments from old sysv stack abi
|
||||
int argc = *sp;
|
||||
char **argv = (char **)(sp + 1);
|
||||
|
@ -114,7 +120,10 @@ wontreturn textstartup void cosmo(long *sp, struct Syslib *m1, char *exename) {
|
|||
|
||||
// detect apple m1 environment
|
||||
const char *magnums;
|
||||
if (SupportsXnu() && (__syslib = m1)) {
|
||||
if (SupportsFreebsd() && is_freebsd) {
|
||||
hostos = _HOSTFREEBSD;
|
||||
magnums = syscon_freebsd;
|
||||
} else if (SupportsXnu() && (__syslib = m1)) {
|
||||
hostos = _HOSTXNU;
|
||||
magnums = syscon_xnu;
|
||||
} else if (SupportsLinux()) {
|
||||
|
|
|
@ -39,7 +39,7 @@ int __zipos_close(int fd) {
|
|||
if (!__vforked) {
|
||||
struct ZiposHandle *h;
|
||||
h = (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle;
|
||||
__zipos_free(h);
|
||||
__zipos_drop(h);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -88,18 +88,11 @@ struct ZiposHandle *__zipos_keep(struct ZiposHandle *h) {
|
|||
return h;
|
||||
}
|
||||
|
||||
static bool __zipos_drop(struct ZiposHandle *h) {
|
||||
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)) {
|
||||
void __zipos_drop(struct ZiposHandle *h) {
|
||||
if (atomic_fetch_sub_explicit(&h->refs, 1, memory_order_release)) {
|
||||
return;
|
||||
}
|
||||
atomic_thread_fence(memory_order_acquire);
|
||||
if (IsAsan()) {
|
||||
__asan_poison((char *)h + sizeof(struct ZiposHandle),
|
||||
h->mapsize - sizeof(struct ZiposHandle), kAsanHeapFree);
|
||||
|
@ -227,7 +220,7 @@ static int __zipos_load(struct Zipos *zipos, size_t cf, int flags,
|
|||
}
|
||||
__fds_unlock();
|
||||
}
|
||||
__zipos_free(h);
|
||||
__zipos_drop(h);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -238,7 +231,7 @@ void __zipos_postdup(int oldfd, int newfd) {
|
|||
BLOCK_SIGNALS;
|
||||
__fds_lock();
|
||||
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)) {
|
||||
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();
|
||||
}
|
||||
if (opt_offset == -1) {
|
||||
while (true) {
|
||||
start_pos = atomic_load_explicit(&h->pos, memory_order_relaxed);
|
||||
Restart:
|
||||
start_pos = atomic_load_explicit(&h->pos, memory_order_relaxed);
|
||||
do {
|
||||
if (UNLIKELY(start_pos == SIZE_MAX)) {
|
||||
continue;
|
||||
goto Restart;
|
||||
}
|
||||
if (LIKELY(atomic_compare_exchange_weak_explicit(
|
||||
&h->pos, &start_pos, SIZE_MAX, memory_order_acquire,
|
||||
memory_order_relaxed))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (!LIKELY(atomic_compare_exchange_weak_explicit(
|
||||
&h->pos, &start_pos, SIZE_MAX, memory_order_acquire,
|
||||
memory_order_relaxed)));
|
||||
x = y = start_pos;
|
||||
} else {
|
||||
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 pos, new_pos;
|
||||
while (true) {
|
||||
pos = atomic_load_explicit(&h->pos, memory_order_relaxed);
|
||||
Restart:
|
||||
pos = atomic_load_explicit(&h->pos, memory_order_relaxed);
|
||||
do {
|
||||
if (UNLIKELY(pos == SIZE_MAX)) {
|
||||
continue;
|
||||
goto Restart;
|
||||
}
|
||||
switch (whence) {
|
||||
case SEEK_SET:
|
||||
|
@ -65,11 +66,8 @@ int64_t __zipos_seek(struct ZiposHandle *h, int64_t offset, unsigned whence) {
|
|||
default:
|
||||
new_pos = einval();
|
||||
}
|
||||
if (LIKELY(atomic_compare_exchange_weak_explicit(
|
||||
&h->pos, &pos, new_pos < 0 ? pos : new_pos, memory_order_release,
|
||||
memory_order_relaxed))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (!LIKELY(atomic_compare_exchange_weak_explicit(
|
||||
&h->pos, &pos, new_pos < 0 ? pos : new_pos, memory_order_release,
|
||||
memory_order_relaxed)));
|
||||
return new_pos;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
.yoink __zipos_mmap
|
||||
.yoink __zipos_postdup
|
||||
.yoink __zipos_keep
|
||||
.yoink __zipos_free
|
||||
.yoink __zipos_drop
|
||||
|
||||
// TODO(jart): why does corruption happen when zip has no assets?
|
||||
.yoink .cosmo
|
||||
|
|
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