|
|
4c3fb7 |
/*******************************************************************/
|
|
|
4c3fb7 |
/* slibtool: a strong libtool implementation, written in C */
|
|
|
4c3fb7 |
/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */
|
|
|
4c3fb7 |
/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */
|
|
|
4c3fb7 |
/*******************************************************************/
|
|
|
4c3fb7 |
|
|
|
967a11 |
#include <sys/stat.h>
|
|
|
4c3fb7 |
#include <slibtool/slibtool.h>
|
|
|
4c3fb7 |
#include <slibtool/slibtool_output.h>
|
|
|
4c3fb7 |
#include "slibtool_driver_impl.h"
|
|
|
4c3fb7 |
#include "slibtool_stoolie_impl.h"
|
|
|
4c3fb7 |
#include "slibtool_errinfo_impl.h"
|
|
|
0dcc39 |
#include "slibtool_realpath_impl.h"
|
|
|
0dcc39 |
#include "slibtool_snprintf_impl.h"
|
|
|
0dcc39 |
#include "slibtool_symlink_impl.h"
|
|
|
4c3fb7 |
#include "argv/argv.h"
|
|
|
4c3fb7 |
|
|
|
967a11 |
static const char slbt_this_dir[2] = {'.',0};
|
|
|
967a11 |
|
|
|
4c3fb7 |
static int slbt_stoolie_usage(
|
|
|
4c3fb7 |
int fdout,
|
|
|
4c3fb7 |
const char * program,
|
|
|
4c3fb7 |
const char * arg,
|
|
|
4c3fb7 |
const struct argv_option ** optv,
|
|
|
4c3fb7 |
struct argv_meta * meta,
|
|
|
4c3fb7 |
struct slbt_exec_ctx * ectx,
|
|
|
4c3fb7 |
int noclr)
|
|
|
4c3fb7 |
{
|
|
|
4c3fb7 |
char header[512];
|
|
|
4c3fb7 |
bool stooliemode;
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
stooliemode = !strcmp(program,"slibtoolize");
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
snprintf(header,sizeof(header),
|
|
|
4c3fb7 |
"Usage: %s%s [options] ...\n"
|
|
|
4c3fb7 |
"Options:\n",
|
|
|
4c3fb7 |
program,
|
|
|
4c3fb7 |
stooliemode ? "" : " --mode=slibtoolize");
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
switch (noclr) {
|
|
|
4c3fb7 |
case 0:
|
|
|
4c3fb7 |
slbt_argv_usage(fdout,header,optv,arg);
|
|
|
4c3fb7 |
break;
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
default:
|
|
|
4c3fb7 |
slbt_argv_usage_plain(fdout,header,optv,arg);
|
|
|
4c3fb7 |
break;
|
|
|
4c3fb7 |
}
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
if (ectx)
|
|
|
4c3fb7 |
slbt_ectx_free_exec_ctx(ectx);
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
slbt_argv_free(meta);
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
return SLBT_USAGE;
|
|
|
4c3fb7 |
}
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
static int slbt_exec_stoolie_fail(
|
|
|
4c3fb7 |
struct slbt_exec_ctx * ectx,
|
|
|
4c3fb7 |
struct argv_meta * meta,
|
|
|
4c3fb7 |
int ret)
|
|
|
4c3fb7 |
{
|
|
|
4c3fb7 |
slbt_argv_free(meta);
|
|
|
4c3fb7 |
slbt_ectx_free_exec_ctx(ectx);
|
|
|
4c3fb7 |
return ret;
|
|
|
4c3fb7 |
}
|
|
|
4c3fb7 |
|
|
|
0dcc39 |
static int slbt_exec_stoolie_remove_file(
|
|
|
0dcc39 |
const struct slbt_driver_ctx * dctx,
|
|
|
0dcc39 |
int fddst,
|
|
|
0dcc39 |
const char * target)
|
|
|
0dcc39 |
{
|
|
|
0dcc39 |
/* remove target (if any) */
|
|
|
0dcc39 |
if (!unlinkat(fddst,target,0) || (errno == ENOENT))
|
|
|
0dcc39 |
return 0;
|
|
|
0dcc39 |
|
|
|
0dcc39 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
0dcc39 |
}
|
|
|
0dcc39 |
|
|
|
4c3fb7 |
static int slbt_exec_stoolie_perform_actions(
|
|
|
0dcc39 |
const struct slbt_driver_ctx * dctx,
|
|
|
0dcc39 |
struct slbt_exec_ctx * ectx,
|
|
|
0dcc39 |
struct slbt_stoolie_ctx * stctx)
|
|
|
4c3fb7 |
{
|
|
|
0dcc39 |
struct slbt_stoolie_ctx_impl * ictx;
|
|
|
0dcc39 |
struct stat st;
|
|
|
0dcc39 |
char m4dir [PATH_MAX];
|
|
|
0dcc39 |
char auxdir[PATH_MAX];
|
|
|
0dcc39 |
char slibm4[PATH_MAX];
|
|
|
0dcc39 |
char ltmain[PATH_MAX];
|
|
|
0dcc39 |
bool fslibm4;
|
|
|
0dcc39 |
bool fltmain;
|
|
|
0dcc39 |
|
|
|
0dcc39 |
ictx = slbt_get_stoolie_ictx(stctx);
|
|
|
0dcc39 |
|
|
|
0dcc39 |
/* source files */
|
|
|
0dcc39 |
if (slbt_snprintf(
|
|
|
0dcc39 |
slibm4,sizeof(slibm4),"%s/%s",
|
|
|
0dcc39 |
SLBT_PACKAGE_DATADIR,
|
|
|
0dcc39 |
"slibtool.m4") < 0)
|
|
|
0dcc39 |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
0dcc39 |
|
|
|
0dcc39 |
if (slbt_snprintf(
|
|
|
0dcc39 |
ltmain,sizeof(slibm4),"%s/%s",
|
|
|
0dcc39 |
SLBT_PACKAGE_DATADIR,
|
|
|
0dcc39 |
"ltmain.sh") < 0)
|
|
|
0dcc39 |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
0dcc39 |
|
|
|
0dcc39 |
/* --force? */
|
|
|
0dcc39 |
if (dctx->cctx->drvflags & SLBT_DRIVER_STOOLIE_FORCE) {
|
|
|
0dcc39 |
if (slbt_exec_stoolie_remove_file(dctx,ictx->fdm4,"slibtool.m4") < 0)
|
|
|
0dcc39 |
return SLBT_NESTED_ERROR(dctx);
|
|
|
0dcc39 |
|
|
|
0dcc39 |
if (slbt_exec_stoolie_remove_file(dctx,ictx->fdaux,"ltmain.sh") < 0)
|
|
|
0dcc39 |
return SLBT_NESTED_ERROR(dctx);
|
|
|
0dcc39 |
|
|
|
0dcc39 |
fslibm4 = true;
|
|
|
0dcc39 |
fltmain = true;
|
|
|
0dcc39 |
} else {
|
|
|
0dcc39 |
if (fstatat(ictx->fdm4,"slibtool.m4",&st,AT_SYMLINK_NOFOLLOW) == 0) {
|
|
|
0dcc39 |
fslibm4 = false;
|
|
|
0dcc39 |
|
|
|
0dcc39 |
} else if (errno == ENOENT) {
|
|
|
0dcc39 |
fslibm4 = true;
|
|
|
0dcc39 |
|
|
|
0dcc39 |
} else {
|
|
|
0dcc39 |
return SLBT_SYSTEM_ERROR(dctx,"slibtool.m4");
|
|
|
0dcc39 |
}
|
|
|
0dcc39 |
|
|
|
0dcc39 |
if (fstatat(ictx->fdaux,"ltmain.sh",&st,AT_SYMLINK_NOFOLLOW) == 0) {
|
|
|
0dcc39 |
fltmain = false;
|
|
|
0dcc39 |
|
|
|
0dcc39 |
} else if (errno == ENOENT) {
|
|
|
0dcc39 |
fltmain = true;
|
|
|
0dcc39 |
|
|
|
0dcc39 |
} else {
|
|
|
0dcc39 |
return SLBT_SYSTEM_ERROR(dctx,"ltmain.sh");
|
|
|
0dcc39 |
}
|
|
|
0dcc39 |
}
|
|
|
0dcc39 |
|
|
|
0dcc39 |
/* --copy? */
|
|
|
0dcc39 |
if (dctx->cctx->drvflags & SLBT_DRIVER_STOOLIE_COPY) {
|
|
|
0dcc39 |
if (fslibm4) {
|
|
|
0dcc39 |
if (slbt_realpath(ictx->fdm4,".",0,m4dir,sizeof(m4dir)) < 0)
|
|
|
0dcc39 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
0dcc39 |
|
|
|
0dcc39 |
if (slbt_util_copy_file(ectx,slibm4,m4dir) < 0)
|
|
|
0dcc39 |
return SLBT_NESTED_ERROR(dctx);
|
|
|
0dcc39 |
}
|
|
|
0dcc39 |
|
|
|
0dcc39 |
if (fltmain) {
|
|
|
0dcc39 |
if (slbt_realpath(ictx->fdaux,".",0,auxdir,sizeof(auxdir)) < 0)
|
|
|
0dcc39 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
0dcc39 |
|
|
|
0dcc39 |
if (slbt_util_copy_file(ectx,ltmain,auxdir) < 0)
|
|
|
0dcc39 |
return SLBT_NESTED_ERROR(dctx);
|
|
|
0dcc39 |
}
|
|
|
0dcc39 |
} else {
|
|
|
0dcc39 |
/* default to symlinks */
|
|
|
0dcc39 |
if (fslibm4)
|
|
|
0dcc39 |
if (slbt_create_symlink_ex(
|
|
|
0dcc39 |
dctx,ectx,
|
|
|
0dcc39 |
ictx->fdm4,
|
|
|
0dcc39 |
slibm4,
|
|
|
0dcc39 |
"slibtool.m4",
|
|
|
0dcc39 |
SLBT_SYMLINK_LITERAL) < 0)
|
|
|
0dcc39 |
return SLBT_NESTED_ERROR(dctx);
|
|
|
0dcc39 |
|
|
|
0dcc39 |
if (fltmain)
|
|
|
0dcc39 |
if (slbt_create_symlink_ex(
|
|
|
0dcc39 |
dctx,ectx,
|
|
|
0dcc39 |
ictx->fdaux,
|
|
|
0dcc39 |
ltmain,
|
|
|
0dcc39 |
"ltmain.sh",
|
|
|
0dcc39 |
SLBT_SYMLINK_LITERAL) < 0)
|
|
|
0dcc39 |
return SLBT_NESTED_ERROR(dctx);
|
|
|
0dcc39 |
}
|
|
|
0dcc39 |
|
|
|
4c3fb7 |
return 0;
|
|
|
4c3fb7 |
}
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
int slbt_exec_stoolie(const struct slbt_driver_ctx * dctx)
|
|
|
4c3fb7 |
{
|
|
|
4c3fb7 |
int ret;
|
|
|
4c3fb7 |
int fdout;
|
|
|
4c3fb7 |
int fderr;
|
|
|
4c3fb7 |
char ** argv;
|
|
|
4c3fb7 |
char ** iargv;
|
|
|
4c3fb7 |
struct slbt_exec_ctx * ectx;
|
|
|
4c3fb7 |
struct slbt_driver_ctx_impl * ictx;
|
|
|
4c3fb7 |
const struct slbt_common_ctx * cctx;
|
|
|
4c3fb7 |
struct argv_meta * meta;
|
|
|
4c3fb7 |
struct argv_entry * entry;
|
|
|
4c3fb7 |
size_t nunits;
|
|
|
967a11 |
size_t cunits;
|
|
|
967a11 |
const char ** unitv;
|
|
|
967a11 |
const char ** unitp;
|
|
|
967a11 |
struct slbt_stoolie_ctx ** stctxv;
|
|
|
967a11 |
struct slbt_stoolie_ctx ** stctxp;
|
|
|
4c3fb7 |
const struct argv_option * optv[SLBT_OPTV_ELEMENTS];
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
/* context */
|
|
|
4c3fb7 |
if (slbt_ectx_get_exec_ctx(dctx,&ectx) < 0)
|
|
|
4c3fb7 |
return SLBT_NESTED_ERROR(dctx);
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
/* initial state, slibtoolize (stoolie) mode skin */
|
|
|
4c3fb7 |
slbt_ectx_reset_arguments(ectx);
|
|
|
4c3fb7 |
slbt_disable_placeholders(ectx);
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
ictx = slbt_get_driver_ictx(dctx);
|
|
|
4c3fb7 |
cctx = dctx->cctx;
|
|
|
4c3fb7 |
iargv = ectx->cargv;
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
fdout = slbt_driver_fdout(dctx);
|
|
|
4c3fb7 |
fderr = slbt_driver_fderr(dctx);
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
(void)fderr;
|
|
|
4c3fb7 |
|
|
|
967a11 |
/* <stoolie> argv meta */
|
|
|
4c3fb7 |
slbt_optv_init(slbt_stoolie_options,optv);
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
if (!(meta = slbt_argv_get(
|
|
|
4c3fb7 |
iargv,optv,
|
|
|
4c3fb7 |
dctx->cctx->drvflags & SLBT_DRIVER_VERBOSITY_ERRORS
|
|
|
4c3fb7 |
? ARGV_VERBOSITY_ERRORS
|
|
|
4c3fb7 |
: ARGV_VERBOSITY_NONE,
|
|
|
4c3fb7 |
fdout)))
|
|
|
4c3fb7 |
return slbt_exec_stoolie_fail(
|
|
|
4c3fb7 |
ectx,meta,
|
|
|
4c3fb7 |
SLBT_CUSTOM_ERROR(dctx,SLBT_ERR_AR_FAIL));
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
/* dest, alternate argument vector options */
|
|
|
4c3fb7 |
argv = ectx->altv;
|
|
|
4c3fb7 |
*argv++ = iargv[0];
|
|
|
4c3fb7 |
nunits = 0;
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
for (entry=meta->entries; entry->fopt || entry->arg; entry++) {
|
|
|
4c3fb7 |
if (entry->fopt) {
|
|
|
4c3fb7 |
switch (entry->tag) {
|
|
|
4c3fb7 |
case TAG_STLE_HELP:
|
|
|
4c3fb7 |
slbt_stoolie_usage(
|
|
|
4c3fb7 |
fdout,
|
|
|
4c3fb7 |
dctx->program,
|
|
|
4c3fb7 |
0,optv,0,ectx,
|
|
|
4c3fb7 |
dctx->cctx->drvflags
|
|
|
4c3fb7 |
& SLBT_DRIVER_ANNOTATE_NEVER);
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
ictx->cctx.drvflags |= SLBT_DRIVER_VERSION;
|
|
|
4c3fb7 |
ictx->cctx.drvflags ^= SLBT_DRIVER_VERSION;
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
slbt_argv_free(meta);
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
return SLBT_OK;
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
case TAG_STLE_VERSION:
|
|
|
4c3fb7 |
ictx->cctx.drvflags |= SLBT_DRIVER_VERSION;
|
|
|
4c3fb7 |
break;
|
|
|
af48d3 |
|
|
|
af48d3 |
case TAG_STLE_COPY:
|
|
|
af48d3 |
ictx->cctx.drvflags |= SLBT_DRIVER_STOOLIE_COPY;
|
|
|
af48d3 |
break;
|
|
|
af48d3 |
|
|
|
af48d3 |
case TAG_STLE_FORCE:
|
|
|
af48d3 |
ictx->cctx.drvflags |= SLBT_DRIVER_STOOLIE_FORCE;
|
|
|
af48d3 |
break;
|
|
|
af48d3 |
|
|
|
af48d3 |
case TAG_STLE_INSTALL:
|
|
|
af48d3 |
ictx->cctx.drvflags |= SLBT_DRIVER_STOOLIE_INSTALL;
|
|
|
af48d3 |
break;
|
|
|
e6c34e |
|
|
|
e6c34e |
case TAG_STLE_DEBUG:
|
|
|
e6c34e |
ictx->cctx.drvflags |= SLBT_DRIVER_DEBUG;
|
|
|
e6c34e |
break;
|
|
|
e6c34e |
|
|
|
e6c34e |
case TAG_STLE_DRY_RUN:
|
|
|
e6c34e |
ictx->cctx.drvflags |= SLBT_DRIVER_DRY_RUN;
|
|
|
e6c34e |
break;
|
|
|
8fb92c |
|
|
|
8fb92c |
case TAG_STLE_SILENT:
|
|
|
8fb92c |
ictx->cctx.drvflags &= ~(uint64_t)SLBT_DRIVER_VERBOSE;
|
|
|
8fb92c |
ictx->cctx.drvflags |= SLBT_DRIVER_SILENT;
|
|
|
8fb92c |
break;
|
|
|
8fb92c |
|
|
|
8fb92c |
case TAG_STLE_VERBOSE:
|
|
|
8fb92c |
ictx->cctx.drvflags &= ~(uint64_t)SLBT_DRIVER_SILENT;
|
|
|
8fb92c |
ictx->cctx.drvflags |= SLBT_DRIVER_VERBOSE;
|
|
|
8fb92c |
break;
|
|
|
4c3fb7 |
}
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
if (entry->fval) {
|
|
|
4c3fb7 |
*argv++ = (char *)entry->arg;
|
|
|
4c3fb7 |
}
|
|
|
4c3fb7 |
} else {
|
|
|
4c3fb7 |
nunits++;
|
|
|
4c3fb7 |
};
|
|
|
4c3fb7 |
}
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
/* defer --version printing to slbt_main() as needed */
|
|
|
4c3fb7 |
if (cctx->drvflags & SLBT_DRIVER_VERSION) {
|
|
|
4c3fb7 |
slbt_argv_free(meta);
|
|
|
4c3fb7 |
slbt_ectx_free_exec_ctx(ectx);
|
|
|
4c3fb7 |
return SLBT_OK;
|
|
|
4c3fb7 |
}
|
|
|
4c3fb7 |
|
|
|
967a11 |
/* default to this-dir as needed */
|
|
|
967a11 |
if (!(cunits = nunits))
|
|
|
967a11 |
nunits++;
|
|
|
967a11 |
|
|
|
967a11 |
/* slibtoolize target directory vector allocation */
|
|
|
967a11 |
if (!(stctxv = calloc(nunits+1,sizeof(struct slbt_stoolie_ctx *))))
|
|
|
967a11 |
return slbt_exec_stoolie_fail(
|
|
|
967a11 |
ectx,meta,
|
|
|
967a11 |
SLBT_SYSTEM_ERROR(dctx,0));
|
|
|
967a11 |
|
|
|
967a11 |
/* unit vector allocation */
|
|
|
967a11 |
if (!(unitv = calloc(nunits+1,sizeof(const char *)))) {
|
|
|
967a11 |
free (stctxv);
|
|
|
967a11 |
|
|
|
967a11 |
return slbt_exec_stoolie_fail(
|
|
|
967a11 |
ectx,meta,
|
|
|
967a11 |
SLBT_SYSTEM_ERROR(dctx,0));
|
|
|
967a11 |
}
|
|
|
967a11 |
|
|
|
967a11 |
/* unit vector initialization */
|
|
|
967a11 |
for (entry=meta->entries,unitp=unitv; entry->fopt || entry->arg; entry++)
|
|
|
967a11 |
if (!entry->fopt)
|
|
|
967a11 |
*unitp++ = entry->arg;
|
|
|
967a11 |
|
|
|
967a11 |
if (!cunits)
|
|
|
967a11 |
unitp[0] = slbt_this_dir;
|
|
|
967a11 |
|
|
|
967a11 |
/* slibtoolize target directory vector initialization */
|
|
|
967a11 |
for (unitp=unitv,stctxp=stctxv; *unitp; unitp++,stctxp++) {
|
|
|
967a11 |
if (slbt_st_get_stoolie_ctx(dctx,*unitp,stctxp) < 0) {
|
|
|
967a11 |
for (stctxp=stctxv; *stctxp; stctxp++)
|
|
|
967a11 |
slbt_st_free_stoolie_ctx(*stctxp);
|
|
|
967a11 |
|
|
|
967a11 |
free(unitv);
|
|
|
967a11 |
free(stctxv);
|
|
|
967a11 |
|
|
|
967a11 |
return slbt_exec_stoolie_fail(
|
|
|
967a11 |
ectx,meta,
|
|
|
967a11 |
SLBT_NESTED_ERROR(dctx));
|
|
|
967a11 |
}
|
|
|
967a11 |
}
|
|
|
967a11 |
|
|
|
4c3fb7 |
/* slibtoolize operations */
|
|
|
0dcc39 |
for (ret=0,stctxp=stctxv; !ret && *stctxp; stctxp++)
|
|
|
0dcc39 |
ret = slbt_exec_stoolie_perform_actions(dctx,ectx,*stctxp);
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
/* all done */
|
|
|
967a11 |
for (stctxp=stctxv; *stctxp; stctxp++)
|
|
|
967a11 |
slbt_st_free_stoolie_ctx(*stctxp);
|
|
|
967a11 |
|
|
|
967a11 |
free(unitv);
|
|
|
967a11 |
free(stctxv);
|
|
|
967a11 |
|
|
|
4c3fb7 |
slbt_argv_free(meta);
|
|
|
4c3fb7 |
slbt_ectx_free_exec_ctx(ectx);
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
return ret;
|
|
|
4c3fb7 |
}
|
|
|
4c3fb7 |
|
|
|
4c3fb7 |
int slbt_exec_slibtoolize(const struct slbt_driver_ctx * dctx)
|
|
|
4c3fb7 |
{
|
|
|
4c3fb7 |
return slbt_exec_stoolie(dctx);
|
|
|
4c3fb7 |
}
|