DF-2249 / dfarm.c
/* * dfarm.c -- DF harness charset-pair armer. Registers crafted charset * pairs through the REAL kern.iconv.add sysctl path (same wire format * as lib/libkiconv), for the kernel-compiled libiconv framework * (options LIBICONV). * * usage: * dfarm ucs <to> <from> (UCS pair, datalen 0) * dfarm xlat <to> <from> <datalen> <fillhex> [idx:val ...] * registers an "xlat" pair whose table is <datalen> bytes, filled * with <fillhex>, then patched at the given indices (idx:valhex). */ #include <sys/types.h> #include <sys/iconv.h> #include <sys/sysctl.h> #include <err.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> static void add_pair(const char *conv, const char *to, const char *from, const void *data, size_t datalen) { struct iconv_add_in din; struct iconv_add_out dout; size_t olen = sizeof(dout); memset(&din, 0, sizeof(din)); din.ia_version = ICONV_ADD_VER; strlcpy(din.ia_converter, conv, sizeof(din.ia_converter)); strlcpy(din.ia_to, to, sizeof(din.ia_to)); strlcpy(din.ia_from, from, sizeof(din.ia_from)); din.ia_data = data; din.ia_datalen = (int)datalen; if (sysctlbyname("kern.iconv.add", &dout, &olen, &din, sizeof(din)) == -1) { if (errno == EEXIST) { printf("already registered %s <- %s (%s)\n", to, from, conv); return; } err(1, "sysctl kern.iconv.add %s <- %s", to, from); } printf("registered %s <- %s conv=%s csid=%d datalen=%zu\n", to, from, conv, dout.ia_csid, datalen); } int main(int argc, char **argv) { unsigned char *tbl; unsigned long fill; size_t len, i; char *spec, *col; if (argc == 4 && strcmp(argv[1], "ucs") == 0) { /* the UCS converter registers under ENCODING_UNICODE */ add_pair("UTF-16BE", argv[2], argv[3], NULL, 0); return (0); } if (argc >= 6 && strcmp(argv[1], "xlat") == 0) { len = strtoul(argv[4], NULL, 0); fill = strtoul(argv[5], NULL, 16); tbl = malloc(len ? len : 1); if (tbl == NULL) err(1, "malloc"); memset(tbl, fill & 0xff, len ? len : 1); for (i = 6; i < (size_t)argc; i++) { unsigned long idx, val; idx = strtoul(argv[i], &col, 16); if (col == NULL || *col != ':' || idx >= len) errx(2, "bad spec %s", argv[i]); val = strtoul(col + 1, NULL, 16); tbl[idx] = val & 0xff; } add_pair("xlat", argv[2], argv[3], tbl, len); free(tbl); return (0); } errx(2, "usage: dfarm ucs <to> <from> | " "dfarm xlat <to> <from> <datalen> <fillhex> [idx:val ...]"); } |