|
|
83bcd3 |
/*******************************************************************/
|
|
|
83bcd3 |
/* slibtool: a strong libtool implementation, written in C */
|
|
|
83bcd3 |
/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */
|
|
|
83bcd3 |
/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */
|
|
|
83bcd3 |
/*******************************************************************/
|
|
|
83bcd3 |
|
|
|
83bcd3 |
#include <ctype.h>
|
|
|
83bcd3 |
#include <fcntl.h>
|
|
|
83bcd3 |
#include <errno.h>
|
|
|
83bcd3 |
#include <stdint.h>
|
|
|
83bcd3 |
#include <stddef.h>
|
|
|
83bcd3 |
#include <stdlib.h>
|
|
|
83bcd3 |
#include <string.h>
|
|
|
83bcd3 |
#include <sys/stat.h>
|
|
|
83bcd3 |
|
|
|
83bcd3 |
#include <slibtool/slibtool.h>
|
|
|
83bcd3 |
#include "slibtool_driver_impl.h"
|
|
|
83bcd3 |
#include "slibtool_errinfo_impl.h"
|
|
|
83bcd3 |
#include "slibtool_realpath_impl.h"
|
|
|
83bcd3 |
#include "slibtool_stoolie_impl.h"
|
|
|
83bcd3 |
#include "slibtool_txtline_impl.h"
|
|
|
83bcd3 |
#include "slibtool_m4fake_impl.h"
|
|
|
83bcd3 |
|
|
|
be21a3 |
static const char slbt_this_dir[2] = {'.',0};
|
|
|
be21a3 |
|
|
|
83bcd3 |
static int slbt_st_free_stoolie_ctx_impl(
|
|
|
83bcd3 |
struct slbt_stoolie_ctx_impl * ctx,
|
|
|
83bcd3 |
int fdsrc,
|
|
|
83bcd3 |
int ret)
|
|
|
83bcd3 |
{
|
|
|
83bcd3 |
char ** parg;
|
|
|
83bcd3 |
|
|
|
83bcd3 |
if (ctx) {
|
|
|
83bcd3 |
if (fdsrc >= 0)
|
|
|
83bcd3 |
close(fdsrc);
|
|
|
83bcd3 |
|
|
|
83bcd3 |
if (ctx->fdtgt >= 0)
|
|
|
83bcd3 |
close(ctx->fdtgt);
|
|
|
83bcd3 |
|
|
|
83bcd3 |
if (ctx->fdaux >= 0)
|
|
|
83bcd3 |
close(ctx->fdaux);
|
|
|
83bcd3 |
|
|
|
83bcd3 |
if (ctx->fdm4 >= 0)
|
|
|
83bcd3 |
close(ctx->fdm4);
|
|
|
83bcd3 |
|
|
|
83bcd3 |
for (parg=ctx->m4argv; parg && *parg; parg++)
|
|
|
83bcd3 |
free(*parg);
|
|
|
83bcd3 |
|
|
|
83bcd3 |
free(ctx->m4buf);
|
|
|
83bcd3 |
free(ctx->m4argv);
|
|
|
83bcd3 |
free(ctx->auxbuf);
|
|
|
83bcd3 |
free(ctx->pathbuf);
|
|
|
83bcd3 |
|
|
|
83bcd3 |
slbt_lib_free_txtfile_ctx(ctx->acinc);
|
|
|
83bcd3 |
slbt_lib_free_txtfile_ctx(ctx->cfgac);
|
|
|
83bcd3 |
slbt_lib_free_txtfile_ctx(ctx->makam);
|
|
|
83bcd3 |
|
|
|
83bcd3 |
free(ctx);
|
|
|
83bcd3 |
}
|
|
|
83bcd3 |
|
|
|
83bcd3 |
return ret;
|
|
|
83bcd3 |
}
|
|
|
83bcd3 |
|
|
|
83bcd3 |
int slbt_st_get_stoolie_ctx(
|
|
|
83bcd3 |
const struct slbt_driver_ctx * dctx,
|
|
|
83bcd3 |
const char * path,
|
|
|
83bcd3 |
struct slbt_stoolie_ctx ** pctx)
|
|
|
83bcd3 |
{
|
|
|
83bcd3 |
struct slbt_stoolie_ctx_impl * ctx;
|
|
|
83bcd3 |
int cint;
|
|
|
83bcd3 |
int fdcwd;
|
|
|
83bcd3 |
int fdtgt;
|
|
|
83bcd3 |
int fdsrc;
|
|
|
83bcd3 |
const char ** pline;
|
|
|
83bcd3 |
char ** margv;
|
|
|
83bcd3 |
const char * mark;
|
|
|
be21a3 |
const char * dpath;
|
|
|
83bcd3 |
char pathbuf[PATH_MAX];
|
|
|
83bcd3 |
|
|
|
83bcd3 |
/* target directory: fd and real path*/
|
|
|
83bcd3 |
fdcwd = slbt_driver_fdcwd(dctx);
|
|
|
83bcd3 |
|
|
|
83bcd3 |
if ((fdtgt = openat(fdcwd,path,O_DIRECTORY|O_CLOEXEC,0)) < 0)
|
|
|
83bcd3 |
return SLBT_SYSTEM_ERROR(dctx,path);
|
|
|
83bcd3 |
|
|
|
83bcd3 |
if (slbt_realpath(fdtgt,".",0,pathbuf,sizeof(pathbuf)) < 0) {
|
|
|
83bcd3 |
close(fdtgt);
|
|
|
83bcd3 |
return SLBT_SYSTEM_ERROR(dctx,path);
|
|
|
83bcd3 |
}
|
|
|
83bcd3 |
|
|
|
83bcd3 |
/* context alloc and init */
|
|
|
83bcd3 |
if (!(ctx = calloc(1,sizeof(*ctx)))) {
|
|
|
83bcd3 |
close(fdtgt);
|
|
|
83bcd3 |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
83bcd3 |
}
|
|
|
83bcd3 |
|
|
|
83bcd3 |
ctx->fdtgt = fdtgt;
|
|
|
83bcd3 |
ctx->fdaux = (-1);
|
|
|
83bcd3 |
ctx->fdm4 = (-1);
|
|
|
83bcd3 |
|
|
|
83bcd3 |
/* target directory real path */
|
|
|
83bcd3 |
if (!(ctx->pathbuf = strdup(pathbuf)))
|
|
|
83bcd3 |
return slbt_st_free_stoolie_ctx_impl(ctx,(-1),
|
|
|
83bcd3 |
SLBT_NESTED_ERROR(dctx));
|
|
|
83bcd3 |
|
|
|
83bcd3 |
/* acinclude.m4, configure.ac, Makefile.am */
|
|
|
83bcd3 |
if ((fdsrc = openat(fdtgt,"acinlcude.m4",O_RDONLY,0)) < 0) {
|
|
|
83bcd3 |
if (errno != ENOENT)
|
|
|
83bcd3 |
return slbt_st_free_stoolie_ctx_impl(ctx,fdsrc,
|
|
|
83bcd3 |
SLBT_SYSTEM_ERROR(dctx,"acinlcude.m4"));
|
|
|
83bcd3 |
} else {
|
|
|
83bcd3 |
if (slbt_impl_get_txtfile_ctx(dctx,"acinclude.m4",fdsrc,&ctx->acinc) < 0)
|
|
|
83bcd3 |
return slbt_st_free_stoolie_ctx_impl(ctx,fdsrc,
|
|
|
83bcd3 |
SLBT_NESTED_ERROR(dctx));
|
|
|
83bcd3 |
|
|
|
83bcd3 |
close(fdsrc);
|
|
|
83bcd3 |
}
|
|
|
83bcd3 |
|
|
|
83bcd3 |
if ((fdsrc = openat(fdtgt,"configure.ac",O_RDONLY,0)) < 0) {
|
|
|
83bcd3 |
if (errno != ENOENT)
|
|
|
83bcd3 |
return slbt_st_free_stoolie_ctx_impl(ctx,fdsrc,
|
|
|
83bcd3 |
SLBT_SYSTEM_ERROR(dctx,"configure.ac"));
|
|
|
83bcd3 |
} else {
|
|
|
83bcd3 |
if (slbt_impl_get_txtfile_ctx(dctx,"configure.ac",fdsrc,&ctx->cfgac) < 0)
|
|
|
83bcd3 |
return slbt_st_free_stoolie_ctx_impl(ctx,fdsrc,
|
|
|
83bcd3 |
SLBT_NESTED_ERROR(dctx));
|
|
|
83bcd3 |
|
|
|
83bcd3 |
close(fdsrc);
|
|
|
83bcd3 |
}
|
|
|
83bcd3 |
|
|
|
83bcd3 |
if ((fdsrc = openat(fdtgt,"Makefile.am",O_RDONLY,0)) < 0) {
|
|
|
83bcd3 |
if (errno != ENOENT)
|
|
|
83bcd3 |
return slbt_st_free_stoolie_ctx_impl(ctx,fdsrc,
|
|
|
83bcd3 |
SLBT_SYSTEM_ERROR(dctx,"Makefile.am"));
|
|
|
83bcd3 |
} else {
|
|
|
83bcd3 |
if (slbt_impl_get_txtfile_ctx(dctx,"Makefile.am",fdsrc,&ctx->makam) < 0)
|
|
|
83bcd3 |
return slbt_st_free_stoolie_ctx_impl(ctx,fdsrc,
|
|
|
83bcd3 |
SLBT_NESTED_ERROR(dctx));
|
|
|
83bcd3 |
|
|
|
83bcd3 |
close(fdsrc);
|
|
|
83bcd3 |
}
|
|
|
83bcd3 |
|
|
|
83bcd3 |
/* aux dir */
|
|
|
83bcd3 |
if (ctx->acinc) {
|
|
|
83bcd3 |
if (slbt_m4fake_expand_cmdarg(
|
|
|
83bcd3 |
dctx,ctx->acinc,
|
|
|
83bcd3 |
"AC_CONFIG_AUX_DIR",
|
|
|
83bcd3 |
&pathbuf) < 0)
|
|
|
83bcd3 |
return slbt_st_free_stoolie_ctx_impl(
|
|
|
83bcd3 |
ctx,(-1),
|
|
|
83bcd3 |
SLBT_NESTED_ERROR(dctx));
|
|
|
83bcd3 |
|
|
|
83bcd3 |
if (pathbuf[0])
|
|
|
83bcd3 |
if (!(ctx->auxbuf = strdup(pathbuf)))
|
|
|
83bcd3 |
return slbt_st_free_stoolie_ctx_impl(
|
|
|
83bcd3 |
ctx,(-1),
|
|
|
83bcd3 |
SLBT_NESTED_ERROR(dctx));
|
|
|
83bcd3 |
}
|
|
|
83bcd3 |
|
|
|
83bcd3 |
if (!ctx->auxbuf && ctx->cfgac) {
|
|
|
83bcd3 |
if (slbt_m4fake_expand_cmdarg(
|
|
|
83bcd3 |
dctx,ctx->cfgac,
|
|
|
83bcd3 |
"AC_CONFIG_AUX_DIR",
|
|
|
83bcd3 |
&pathbuf) < 0)
|
|
|
83bcd3 |
return slbt_st_free_stoolie_ctx_impl(
|
|
|
83bcd3 |
ctx,(-1),
|
|
|
83bcd3 |
SLBT_NESTED_ERROR(dctx));
|
|
|
83bcd3 |
|
|
|
83bcd3 |
if (pathbuf[0])
|
|
|
83bcd3 |
if (!(ctx->auxbuf = strdup(pathbuf)))
|
|
|
83bcd3 |
return slbt_st_free_stoolie_ctx_impl(
|
|
|
83bcd3 |
ctx,(-1),
|
|
|
83bcd3 |
SLBT_NESTED_ERROR(dctx));
|
|
|
83bcd3 |
}
|
|
|
83bcd3 |
|
|
|
83bcd3 |
/* m4 dir */
|
|
|
a98361 |
if (ctx->acinc) {
|
|
|
a98361 |
if (slbt_m4fake_expand_cmdarg(
|
|
|
a98361 |
dctx,ctx->acinc,
|
|
|
a98361 |
"AC_CONFIG_MACRO_DIR",
|
|
|
a98361 |
&pathbuf) < 0)
|
|
|
a98361 |
return slbt_st_free_stoolie_ctx_impl(
|
|
|
a98361 |
ctx,(-1),
|
|
|
a98361 |
SLBT_NESTED_ERROR(dctx));
|
|
|
a98361 |
|
|
|
a98361 |
if (pathbuf[0])
|
|
|
a98361 |
if (!(ctx->m4buf = strdup(pathbuf)))
|
|
|
a98361 |
return slbt_st_free_stoolie_ctx_impl(
|
|
|
a98361 |
ctx,(-1),
|
|
|
a98361 |
SLBT_NESTED_ERROR(dctx));
|
|
|
a98361 |
}
|
|
|
a98361 |
|
|
|
a98361 |
if (!ctx->m4buf && ctx->cfgac) {
|
|
|
a98361 |
if (slbt_m4fake_expand_cmdarg(
|
|
|
a98361 |
dctx,ctx->cfgac,
|
|
|
a98361 |
"AC_CONFIG_MACRO_DIR",
|
|
|
a98361 |
&pathbuf) < 0)
|
|
|
a98361 |
return slbt_st_free_stoolie_ctx_impl(
|
|
|
a98361 |
ctx,(-1),
|
|
|
a98361 |
SLBT_NESTED_ERROR(dctx));
|
|
|
a98361 |
|
|
|
a98361 |
if (pathbuf[0])
|
|
|
a98361 |
if (!(ctx->m4buf = strdup(pathbuf)))
|
|
|
a98361 |
return slbt_st_free_stoolie_ctx_impl(
|
|
|
a98361 |
ctx,(-1),
|
|
|
a98361 |
SLBT_NESTED_ERROR(dctx));
|
|
|
a98361 |
}
|
|
|
a98361 |
if (!ctx->m4buf && ctx->makam) {
|
|
|
83bcd3 |
for (pline=ctx->makam->txtlinev; !ctx->m4argv && *pline; pline++) {
|
|
|
83bcd3 |
if (!strncmp(*pline,"ACLOCAL_AMFLAGS",15)) {
|
|
|
83bcd3 |
if (isspace((*pline)[15]) || ((*pline)[15] == '=')) {
|
|
|
83bcd3 |
mark = &(*pline)[15];
|
|
|
83bcd3 |
|
|
|
83bcd3 |
for (; isspace(cint = *mark); )
|
|
|
83bcd3 |
mark++;
|
|
|
83bcd3 |
|
|
|
83bcd3 |
if (mark[0] != '=')
|
|
|
83bcd3 |
return slbt_st_free_stoolie_ctx_impl(
|
|
|
83bcd3 |
ctx,(-1),
|
|
|
83bcd3 |
SLBT_CUSTOM_ERROR(
|
|
|
83bcd3 |
dctx,
|
|
|
83bcd3 |
SLBT_ERR_FLOW_ERROR));
|
|
|
83bcd3 |
|
|
|
83bcd3 |
if (slbt_txtline_to_string_vector(++mark,&margv) < 0)
|
|
|
83bcd3 |
return slbt_st_free_stoolie_ctx_impl(
|
|
|
83bcd3 |
ctx,(-1),
|
|
|
83bcd3 |
SLBT_CUSTOM_ERROR(
|
|
|
83bcd3 |
dctx,
|
|
|
83bcd3 |
SLBT_ERR_FLOW_ERROR));
|
|
|
83bcd3 |
|
|
|
83bcd3 |
ctx->m4argv = margv;
|
|
|
83bcd3 |
|
|
|
83bcd3 |
if (!strcmp((mark = margv[0]),"-I")) {
|
|
|
83bcd3 |
ctx->m4buf = strdup(margv[1]);
|
|
|
83bcd3 |
|
|
|
83bcd3 |
} else if (!strncmp(mark,"-I",2)) {
|
|
|
83bcd3 |
ctx->m4buf = strdup(&mark[2]);
|
|
|
83bcd3 |
}
|
|
|
83bcd3 |
|
|
|
83bcd3 |
if (!ctx->m4buf)
|
|
|
83bcd3 |
return slbt_st_free_stoolie_ctx_impl(
|
|
|
83bcd3 |
ctx,(-1),
|
|
|
83bcd3 |
SLBT_CUSTOM_ERROR(
|
|
|
83bcd3 |
dctx,
|
|
|
83bcd3 |
SLBT_ERR_FLOW_ERROR));
|
|
|
83bcd3 |
}
|
|
|
83bcd3 |
}
|
|
|
83bcd3 |
}
|
|
|
83bcd3 |
}
|
|
|
83bcd3 |
|
|
|
83bcd3 |
/* build-aux directory */
|
|
|
be21a3 |
if (!(dpath = ctx->auxbuf))
|
|
|
be21a3 |
dpath = slbt_this_dir;
|
|
|
be21a3 |
|
|
|
be21a3 |
if ((ctx->fdaux = openat(fdtgt,dpath,O_DIRECTORY,0)) < 0)
|
|
|
83bcd3 |
if (errno == ENOENT)
|
|
|
be21a3 |
if (!mkdirat(fdtgt,dpath,0755))
|
|
|
be21a3 |
ctx->fdaux = openat(fdtgt,dpath,O_DIRECTORY,0);
|
|
|
83bcd3 |
|
|
|
83bcd3 |
if (ctx->fdaux < 0)
|
|
|
83bcd3 |
return slbt_st_free_stoolie_ctx_impl(
|
|
|
83bcd3 |
ctx,(-1),
|
|
|
be21a3 |
SLBT_SYSTEM_ERROR(dctx,dpath));
|
|
|
83bcd3 |
|
|
|
83bcd3 |
/* m4 directory */
|
|
|
be21a3 |
if (!(dpath = ctx->m4buf))
|
|
|
be21a3 |
dpath = slbt_this_dir;
|
|
|
be21a3 |
|
|
|
be21a3 |
if ((ctx->fdm4 = openat(fdtgt,dpath,O_DIRECTORY,0)) < 0)
|
|
|
83bcd3 |
if (errno == ENOENT)
|
|
|
be21a3 |
if (!mkdirat(fdtgt,dpath,0755))
|
|
|
be21a3 |
ctx->fdm4 = openat(fdtgt,dpath,O_DIRECTORY,0);
|
|
|
83bcd3 |
|
|
|
83bcd3 |
if (ctx->fdm4 < 0)
|
|
|
83bcd3 |
return slbt_st_free_stoolie_ctx_impl(
|
|
|
83bcd3 |
ctx,(-1),
|
|
|
be21a3 |
SLBT_SYSTEM_ERROR(dctx,dpath));
|
|
|
83bcd3 |
|
|
|
83bcd3 |
/* all done */
|
|
|
83bcd3 |
ctx->path = ctx->pathbuf;
|
|
|
83bcd3 |
ctx->auxarg = ctx->auxbuf;
|
|
|
83bcd3 |
ctx->m4arg = ctx->m4buf;
|
|
|
83bcd3 |
|
|
|
83bcd3 |
ctx->zctx.path = &ctx->path;
|
|
|
83bcd3 |
ctx->zctx.acinc = ctx->acinc;
|
|
|
83bcd3 |
ctx->zctx.cfgac = ctx->cfgac;
|
|
|
83bcd3 |
ctx->zctx.makam = ctx->makam;
|
|
|
83bcd3 |
ctx->zctx.auxarg = &ctx->auxarg;
|
|
|
83bcd3 |
ctx->zctx.m4arg = &ctx->m4arg;
|
|
|
83bcd3 |
|
|
|
83bcd3 |
*pctx = &ctx->zctx;
|
|
|
83bcd3 |
return 0;
|
|
|
83bcd3 |
}
|
|
|
83bcd3 |
|
|
|
83bcd3 |
void slbt_st_free_stoolie_ctx(struct slbt_stoolie_ctx * ctx)
|
|
|
83bcd3 |
{
|
|
|
83bcd3 |
struct slbt_stoolie_ctx_impl * ictx;
|
|
|
83bcd3 |
uintptr_t addr;
|
|
|
83bcd3 |
|
|
|
83bcd3 |
if (ctx) {
|
|
|
83bcd3 |
addr = (uintptr_t)ctx - offsetof(struct slbt_stoolie_ctx_impl,zctx);
|
|
|
83bcd3 |
ictx = (struct slbt_stoolie_ctx_impl *)addr;
|
|
|
83bcd3 |
slbt_st_free_stoolie_ctx_impl(ictx,(-1),0);
|
|
|
83bcd3 |
}
|
|
|
83bcd3 |
}
|