2026-10-12 07:43:34 +03:00
|
|
|
#include <stdio.h>
|
|
|
|
|
#include "hygate.h"
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <errno.h>
|
2026-10-14 00:00:02 +03:00
|
|
|
#include <stdint.h>
|
2026-10-12 07:43:34 +03:00
|
|
|
|
|
|
|
|
/* ----------------------------- strbuf ------------------------------ */
|
|
|
|
|
|
|
|
|
|
void sb_init(strbuf *s) {
|
|
|
|
|
s->cap = 64;
|
|
|
|
|
s->buf = (char *)malloc(s->cap);
|
|
|
|
|
if (!s->buf) { s->cap = 0; s->len = 0; return; }
|
|
|
|
|
s->len = 0;
|
|
|
|
|
s->buf[0] = '\0';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void sb_free(strbuf *s) {
|
|
|
|
|
free(s->buf);
|
|
|
|
|
s->buf = NULL;
|
|
|
|
|
s->len = s->cap = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int sb_append(strbuf *s, const char *data, size_t n) {
|
|
|
|
|
if (n == 0) return 0;
|
2026-10-14 00:00:02 +03:00
|
|
|
if (!data) return -1;
|
|
|
|
|
if (n > SIZE_MAX - s->len - 1) return -1;
|
|
|
|
|
size_t need = s->len + n + 1;
|
|
|
|
|
if (need > s->cap) {
|
|
|
|
|
size_t ncap = s->cap ? s->cap : 64;
|
|
|
|
|
while (ncap < need) {
|
|
|
|
|
if (ncap > SIZE_MAX / 2) { ncap = need; break; }
|
|
|
|
|
ncap *= 2;
|
|
|
|
|
}
|
2026-10-12 07:43:34 +03:00
|
|
|
char *nb = (char *)realloc(s->buf, ncap);
|
|
|
|
|
if (!nb) return -1;
|
|
|
|
|
s->buf = nb;
|
|
|
|
|
s->cap = ncap;
|
|
|
|
|
}
|
|
|
|
|
memcpy(s->buf + s->len, data, n);
|
|
|
|
|
s->len += n;
|
|
|
|
|
s->buf[s->len] = '\0';
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int sb_append_str(strbuf *s, const char *str) {
|
2026-10-14 00:00:02 +03:00
|
|
|
if (!str) return 0;
|
2026-10-12 07:43:34 +03:00
|
|
|
return sb_append(s, str, strlen(str));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void sb_reset(strbuf *s) {
|
|
|
|
|
s->len = 0;
|
|
|
|
|
if (s->buf) s->buf[0] = '\0';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* --------------------------- utilities ---------------------------- */
|
|
|
|
|
|
|
|
|
|
void generate_uuid(char out[37]) {
|
|
|
|
|
unsigned char b[16];
|
|
|
|
|
size_t i;
|
|
|
|
|
FILE *f = fopen("/dev/urandom", "rb");
|
|
|
|
|
if (f) {
|
|
|
|
|
size_t got = fread(b, 1, 16, f);
|
|
|
|
|
fclose(f);
|
|
|
|
|
if (got != 16) {
|
|
|
|
|
for (i = 0; i < 16; i++) b[i] = (unsigned char)(rand() & 0xff);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
for (i = 0; i < 16; i++) b[i] = (unsigned char)(rand() & 0xff);
|
|
|
|
|
}
|
|
|
|
|
b[6] = (unsigned char)((b[6] & 0x0f) | 0x40);
|
|
|
|
|
b[8] = (unsigned char)((b[8] & 0x3f) | 0x80);
|
|
|
|
|
snprintf(out, 37,
|
|
|
|
|
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
|
|
|
|
b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7],
|
|
|
|
|
b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
long fib_delay(int attempt) {
|
|
|
|
|
if (attempt <= 0) return 1;
|
|
|
|
|
long a = 1, b = 1;
|
|
|
|
|
for (int i = 1; i < attempt; i++) {
|
|
|
|
|
long t = a + b;
|
|
|
|
|
a = b;
|
|
|
|
|
b = t;
|
|
|
|
|
}
|
|
|
|
|
return a;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int write_all(int fd, const char *buf, size_t n) {
|
|
|
|
|
size_t off = 0;
|
|
|
|
|
while (off < n) {
|
|
|
|
|
ssize_t w = write(fd, buf + off, n - off);
|
|
|
|
|
if (w < 0) {
|
|
|
|
|
if (errno == EINTR) continue;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if (w == 0) break;
|
|
|
|
|
off += (size_t)w;
|
|
|
|
|
}
|
|
|
|
|
return (off == n) ? 0 : -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int iequals(const char *a, const char *b) {
|
|
|
|
|
while (*a && *b) {
|
|
|
|
|
char ca = *a, cb = *b;
|
|
|
|
|
if (ca >= 'A' && ca <= 'Z') ca += 32;
|
|
|
|
|
if (cb >= 'A' && cb <= 'Z') cb += 32;
|
|
|
|
|
if (ca != cb) return 0;
|
|
|
|
|
a++;
|
|
|
|
|
b++;
|
|
|
|
|
}
|
|
|
|
|
return *a == *b;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void free_toolcalls(tool_call_t *tc, int n) {
|
|
|
|
|
if (!tc) return;
|
|
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
|
|
free(tc[i].id);
|
|
|
|
|
free(tc[i].type);
|
|
|
|
|
free(tc[i].name);
|
|
|
|
|
free(tc[i].arguments);
|
|
|
|
|
}
|
|
|
|
|
free(tc);
|
|
|
|
|
}
|