summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2024-03-25 03:04:51 +0000
committermidipix <writeonce@midipix.org>2024-03-25 03:04:51 +0000
commit83bcd3a56a9be8ef0f19c5682793697569b1724f (patch)
tree2343007211be5d804730d759b605fcfcd3ebf977
parentd4a2be8699ad197a213cbbc989dd206731bfb34a (diff)
downloadslibtool-83bcd3a56a9be8ef0f19c5682793697569b1724f.tar.bz2
slibtool-83bcd3a56a9be8ef0f19c5682793697569b1724f.tar.xz
slibtoolize: slbt_st_get_stoolie_ctx(): initial implementation.
-rw-r--r--include/slibtool/slibtool.h15
-rw-r--r--project/common.mk1
-rw-r--r--project/tree.mk1
-rw-r--r--src/internal/slibtool_driver_impl.h17
-rw-r--r--src/stoolie/slbt_stoolie_ctx.c266
5 files changed, 300 insertions, 0 deletions
diff --git a/include/slibtool/slibtool.h b/include/slibtool/slibtool.h
index cd3b3c4..d428e54 100644
--- a/include/slibtool/slibtool.h
+++ b/include/slibtool/slibtool.h
@@ -391,6 +391,15 @@ struct slbt_txtfile_ctx {
const char ** txtlinev;
};
+struct slbt_stoolie_ctx {
+ const char * const * path;
+ const struct slbt_txtfile_ctx * acinc;
+ const struct slbt_txtfile_ctx * cfgac;
+ const struct slbt_txtfile_ctx * makam;
+ const char * const * auxarg;
+ const char * const * m4arg;
+};
+
/* raw input api */
slbt_api int slbt_fs_map_input (const struct slbt_driver_ctx *,
int, const char *, int,
@@ -490,6 +499,12 @@ slbt_api int slbt_ar_create_symfile (const struct slbt_archive_meta *, const
slbt_api int slbt_ar_create_dlsyms (struct slbt_archive_ctx **, const char *, const char *, mode_t);
+/* slibtoolize api */
+slbt_api int slbt_st_get_stoolie_ctx (const struct slbt_driver_ctx *, const char * path,
+ struct slbt_stoolie_ctx **);
+
+slbt_api void slbt_st_free_stoolie_ctx (struct slbt_stoolie_ctx *);
+
/* utility api */
slbt_api int slbt_main (char **, char **,
const struct slbt_fd_ctx *);
diff --git a/project/common.mk b/project/common.mk
index 1e2ae5e..ace734f 100644
--- a/project/common.mk
+++ b/project/common.mk
@@ -61,6 +61,7 @@ API_SRCS = \
src/skin/slbt_skin_install.c \
src/skin/slbt_skin_stoolie.c \
src/skin/slbt_skin_uninstall.c \
+ src/stoolie/slbt_stoolie_ctx.c \
FALLBACK_SRCS = \
src/fallback/slbt_archive_import_mri.c \
diff --git a/project/tree.mk b/project/tree.mk
index 1edd9b9..f855e82 100644
--- a/project/tree.mk
+++ b/project/tree.mk
@@ -9,6 +9,7 @@ tree.tag:
mkdir -p src/logic
mkdir -p src/output
mkdir -p src/skin
+ mkdir -p src/stoolie
mkdir -p src/arbits/output
mkdir -p src/logic/linkcmd
touch tree.tag
diff --git a/src/internal/slibtool_driver_impl.h b/src/internal/slibtool_driver_impl.h
index b35f375..43ac576 100644
--- a/src/internal/slibtool_driver_impl.h
+++ b/src/internal/slibtool_driver_impl.h
@@ -232,6 +232,23 @@ struct slbt_txtfile_ctx_impl {
struct slbt_txtfile_ctx tctx;
};
+struct slbt_stoolie_ctx_impl {
+ const struct slbt_driver_ctx * dctx;
+ const char * path;
+ char * pathbuf;
+ int fdtgt;
+ int fdaux;
+ int fdm4;
+ const char * auxarg;
+ char * auxbuf;
+ const char * m4arg;
+ char * m4buf;
+ char ** m4argv;
+ struct slbt_txtfile_ctx * acinc;
+ struct slbt_txtfile_ctx * cfgac;
+ struct slbt_txtfile_ctx * makam;
+ struct slbt_stoolie_ctx zctx;
+};
const char * slbt_program_name(const char *);
diff --git a/src/stoolie/slbt_stoolie_ctx.c b/src/stoolie/slbt_stoolie_ctx.c
new file mode 100644
index 0000000..f562cf9
--- /dev/null
+++ b/src/stoolie/slbt_stoolie_ctx.c
@@ -0,0 +1,266 @@
+/*******************************************************************/
+/* slibtool: a strong libtool implementation, written in C */
+/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */
+/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */
+/*******************************************************************/
+
+#include <ctype.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include <slibtool/slibtool.h>
+#include "slibtool_driver_impl.h"
+#include "slibtool_errinfo_impl.h"
+#include "slibtool_realpath_impl.h"
+#include "slibtool_stoolie_impl.h"
+#include "slibtool_txtline_impl.h"
+#include "slibtool_m4fake_impl.h"
+
+static int slbt_st_free_stoolie_ctx_impl(
+ struct slbt_stoolie_ctx_impl * ctx,
+ int fdsrc,
+ int ret)
+{
+ char ** parg;
+
+ if (ctx) {
+ if (fdsrc >= 0)
+ close(fdsrc);
+
+ if (ctx->fdtgt >= 0)
+ close(ctx->fdtgt);
+
+ if (ctx->fdaux >= 0)
+ close(ctx->fdaux);
+
+ if (ctx->fdm4 >= 0)
+ close(ctx->fdm4);
+
+ for (parg=ctx->m4argv; parg && *parg; parg++)
+ free(*parg);
+
+ free(ctx->m4buf);
+ free(ctx->m4argv);
+ free(ctx->auxbuf);
+ free(ctx->pathbuf);
+
+ slbt_lib_free_txtfile_ctx(ctx->acinc);
+ slbt_lib_free_txtfile_ctx(ctx->cfgac);
+ slbt_lib_free_txtfile_ctx(ctx->makam);
+
+ free(ctx);
+ }
+
+ return ret;
+}
+
+int slbt_st_get_stoolie_ctx(
+ const struct slbt_driver_ctx * dctx,
+ const char * path,
+ struct slbt_stoolie_ctx ** pctx)
+{
+ struct slbt_stoolie_ctx_impl * ctx;
+ int cint;
+ int fdcwd;
+ int fdtgt;
+ int fdsrc;
+ const char ** pline;
+ char ** margv;
+ const char * mark;
+ char pathbuf[PATH_MAX];
+
+ /* target directory: fd and real path*/
+ fdcwd = slbt_driver_fdcwd(dctx);
+
+ if ((fdtgt = openat(fdcwd,path,O_DIRECTORY|O_CLOEXEC,0)) < 0)
+ return SLBT_SYSTEM_ERROR(dctx,path);
+
+ if (slbt_realpath(fdtgt,".",0,pathbuf,sizeof(pathbuf)) < 0) {
+ close(fdtgt);
+ return SLBT_SYSTEM_ERROR(dctx,path);
+ }
+
+ /* context alloc and init */
+ if (!(ctx = calloc(1,sizeof(*ctx)))) {
+ close(fdtgt);
+ return SLBT_BUFFER_ERROR(dctx);
+ }
+
+ ctx->fdtgt = fdtgt;
+ ctx->fdaux = (-1);
+ ctx->fdm4 = (-1);
+
+ /* target directory real path */
+ if (!(ctx->pathbuf = strdup(pathbuf)))
+ return slbt_st_free_stoolie_ctx_impl(ctx,(-1),
+ SLBT_NESTED_ERROR(dctx));
+
+ /* acinclude.m4, configure.ac, Makefile.am */
+ if ((fdsrc = openat(fdtgt,"acinlcude.m4",O_RDONLY,0)) < 0) {
+ if (errno != ENOENT)
+ return slbt_st_free_stoolie_ctx_impl(ctx,fdsrc,
+ SLBT_SYSTEM_ERROR(dctx,"acinlcude.m4"));
+ } else {
+ if (slbt_impl_get_txtfile_ctx(dctx,"acinclude.m4",fdsrc,&ctx->acinc) < 0)
+ return slbt_st_free_stoolie_ctx_impl(ctx,fdsrc,
+ SLBT_NESTED_ERROR(dctx));
+
+ close(fdsrc);
+ }
+
+ if ((fdsrc = openat(fdtgt,"configure.ac",O_RDONLY,0)) < 0) {
+ if (errno != ENOENT)
+ return slbt_st_free_stoolie_ctx_impl(ctx,fdsrc,
+ SLBT_SYSTEM_ERROR(dctx,"configure.ac"));
+ } else {
+ if (slbt_impl_get_txtfile_ctx(dctx,"configure.ac",fdsrc,&ctx->cfgac) < 0)
+ return slbt_st_free_stoolie_ctx_impl(ctx,fdsrc,
+ SLBT_NESTED_ERROR(dctx));
+
+ close(fdsrc);
+ }
+
+ if ((fdsrc = openat(fdtgt,"Makefile.am",O_RDONLY,0)) < 0) {
+ if (errno != ENOENT)
+ return slbt_st_free_stoolie_ctx_impl(ctx,fdsrc,
+ SLBT_SYSTEM_ERROR(dctx,"Makefile.am"));
+ } else {
+ if (slbt_impl_get_txtfile_ctx(dctx,"Makefile.am",fdsrc,&ctx->makam) < 0)
+ return slbt_st_free_stoolie_ctx_impl(ctx,fdsrc,
+ SLBT_NESTED_ERROR(dctx));
+
+ close(fdsrc);
+ }
+
+ /* aux dir */
+ if (ctx->acinc) {
+ if (slbt_m4fake_expand_cmdarg(
+ dctx,ctx->acinc,
+ "AC_CONFIG_AUX_DIR",
+ &pathbuf) < 0)
+ return slbt_st_free_stoolie_ctx_impl(
+ ctx,(-1),
+ SLBT_NESTED_ERROR(dctx));
+
+ if (pathbuf[0])
+ if (!(ctx->auxbuf = strdup(pathbuf)))
+ return slbt_st_free_stoolie_ctx_impl(
+ ctx,(-1),
+ SLBT_NESTED_ERROR(dctx));
+ }
+
+ /* aux dir */
+ if (!ctx->auxbuf && ctx->cfgac) {
+ if (slbt_m4fake_expand_cmdarg(
+ dctx,ctx->cfgac,
+ "AC_CONFIG_AUX_DIR",
+ &pathbuf) < 0)
+ return slbt_st_free_stoolie_ctx_impl(
+ ctx,(-1),
+ SLBT_NESTED_ERROR(dctx));
+
+ if (pathbuf[0])
+ if (!(ctx->auxbuf = strdup(pathbuf)))
+ return slbt_st_free_stoolie_ctx_impl(
+ ctx,(-1),
+ SLBT_NESTED_ERROR(dctx));
+ }
+
+ /* m4 dir */
+ if (ctx->makam) {
+ for (pline=ctx->makam->txtlinev; !ctx->m4argv && *pline; pline++) {
+ if (!strncmp(*pline,"ACLOCAL_AMFLAGS",15)) {
+ if (isspace((*pline)[15]) || ((*pline)[15] == '=')) {
+ mark = &(*pline)[15];
+
+ for (; isspace(cint = *mark); )
+ mark++;
+
+ if (mark[0] != '=')
+ return slbt_st_free_stoolie_ctx_impl(
+ ctx,(-1),
+ SLBT_CUSTOM_ERROR(
+ dctx,
+ SLBT_ERR_FLOW_ERROR));
+
+ if (slbt_txtline_to_string_vector(++mark,&margv) < 0)
+ return slbt_st_free_stoolie_ctx_impl(
+ ctx,(-1),
+ SLBT_CUSTOM_ERROR(
+ dctx,
+ SLBT_ERR_FLOW_ERROR));
+
+ ctx->m4argv = margv;
+
+ if (!strcmp((mark = margv[0]),"-I")) {
+ ctx->m4buf = strdup(margv[1]);
+
+ } else if (!strncmp(mark,"-I",2)) {
+ ctx->m4buf = strdup(&mark[2]);
+ }
+
+ if (!ctx->m4buf)
+ return slbt_st_free_stoolie_ctx_impl(
+ ctx,(-1),
+ SLBT_CUSTOM_ERROR(
+ dctx,
+ SLBT_ERR_FLOW_ERROR));
+ }
+ }
+ }
+ }
+
+ /* build-aux directory */
+ if ((ctx->fdaux = openat(fdtgt,ctx->auxbuf,O_DIRECTORY,0)) < 0)
+ if (errno == ENOENT)
+ if (!mkdirat(fdtgt,ctx->auxbuf,0755))
+ ctx->fdaux = openat(fdtgt,ctx->auxbuf,O_DIRECTORY,0);
+
+ if (ctx->fdaux < 0)
+ return slbt_st_free_stoolie_ctx_impl(
+ ctx,(-1),
+ SLBT_SYSTEM_ERROR(dctx,ctx->auxbuf));
+
+ /* m4 directory */
+ if ((ctx->fdm4 = openat(fdtgt,ctx->m4buf,O_DIRECTORY,0)) < 0)
+ if (errno == ENOENT)
+ if (!mkdirat(fdtgt,ctx->m4buf,0755))
+ ctx->fdm4 = openat(fdtgt,ctx->m4buf,O_DIRECTORY,0);
+
+ if (ctx->fdm4 < 0)
+ return slbt_st_free_stoolie_ctx_impl(
+ ctx,(-1),
+ SLBT_SYSTEM_ERROR(dctx,ctx->m4buf));
+
+ /* all done */
+ ctx->path = ctx->pathbuf;
+ ctx->auxarg = ctx->auxbuf;
+ ctx->m4arg = ctx->m4buf;
+
+ ctx->zctx.path = &ctx->path;
+ ctx->zctx.acinc = ctx->acinc;
+ ctx->zctx.cfgac = ctx->cfgac;
+ ctx->zctx.makam = ctx->makam;
+ ctx->zctx.auxarg = &ctx->auxarg;
+ ctx->zctx.m4arg = &ctx->m4arg;
+
+ *pctx = &ctx->zctx;
+ return 0;
+}
+
+void slbt_st_free_stoolie_ctx(struct slbt_stoolie_ctx * ctx)
+{
+ struct slbt_stoolie_ctx_impl * ictx;
+ uintptr_t addr;
+
+ if (ctx) {
+ addr = (uintptr_t)ctx - offsetof(struct slbt_stoolie_ctx_impl,zctx);
+ ictx = (struct slbt_stoolie_ctx_impl *)addr;
+ slbt_st_free_stoolie_ctx_impl(ictx,(-1),0);
+ }
+}