|
|
65cb35 |
/*******************************************************************/
|
|
|
eac61a |
/* slibtool: a strong libtool implementation, written in C */
|
|
|
49181b |
/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */
|
|
|
65cb35 |
/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */
|
|
|
65cb35 |
/*******************************************************************/
|
|
|
65cb35 |
|
|
|
65cb35 |
#include <fcntl.h>
|
|
|
65cb35 |
#include <stdio.h>
|
|
|
65cb35 |
#include <limits.h>
|
|
|
65cb35 |
#include <unistd.h>
|
|
|
65cb35 |
#include <string.h>
|
|
|
65cb35 |
#include <stdlib.h>
|
|
|
65cb35 |
#include <stdbool.h>
|
|
|
dd658d |
#include <inttypes.h>
|
|
|
dd658d |
#include <sys/stat.h>
|
|
|
65cb35 |
#include <sys/wait.h>
|
|
|
65cb35 |
|
|
|
65cb35 |
#include <slibtool/slibtool.h>
|
|
|
65cb35 |
#include "slibtool_driver_impl.h"
|
|
|
65cb35 |
#include "slibtool_spawn_impl.h"
|
|
|
65cb35 |
#include "slibtool_dprintf_impl.h"
|
|
|
65cb35 |
#include "slibtool_symlink_impl.h"
|
|
|
65cb35 |
#include "slibtool_readlink_impl.h"
|
|
|
5b993e |
#include "slibtool_realpath_impl.h"
|
|
|
19022e |
#include "slibtool_snprintf_impl.h"
|
|
|
65cb35 |
#include "slibtool_errinfo_impl.h"
|
|
|
65cb35 |
|
|
|
dd658d |
#define PPRIX64 "%"PRIx64
|
|
|
dd658d |
|
|
|
65cb35 |
static char * slbt_mri_argument(
|
|
|
65cb35 |
int fdat,
|
|
|
65cb35 |
char * arg,
|
|
|
65cb35 |
char * buf)
|
|
|
65cb35 |
{
|
|
|
65cb35 |
char * lnk;
|
|
|
65cb35 |
char * target;
|
|
|
65cb35 |
char mricwd[PATH_MAX];
|
|
|
65cb35 |
char dstbuf[PATH_MAX];
|
|
|
65cb35 |
|
|
|
65cb35 |
if ((!(strchr(arg,'+'))) && (!(strchr(arg,'-'))))
|
|
|
65cb35 |
return arg;
|
|
|
65cb35 |
|
|
|
ee9cbe |
if (arg[0] == '/') {
|
|
|
65cb35 |
target = arg;
|
|
|
ee9cbe |
} else {
|
|
|
d4b2a5 |
if (slbt_realpath(
|
|
|
ee9cbe |
fdat,".",O_DIRECTORY,
|
|
|
ee9cbe |
mricwd,sizeof(mricwd)) < 0)
|
|
|
65cb35 |
return 0;
|
|
|
65cb35 |
|
|
|
19022e |
if (slbt_snprintf(dstbuf,sizeof(dstbuf),
|
|
|
19022e |
"%s/%s",mricwd,arg) < 0)
|
|
|
65cb35 |
return 0;
|
|
|
65cb35 |
|
|
|
65cb35 |
target = dstbuf;
|
|
|
65cb35 |
}
|
|
|
65cb35 |
|
|
|
dd658d |
lnk = 0;
|
|
|
dd658d |
|
|
|
dd658d |
{
|
|
|
dd658d |
struct stat st;
|
|
|
dd658d |
|
|
|
dd658d |
if (fstatat(fdat,target,&st,0) < 0)
|
|
|
65cb35 |
return 0;
|
|
|
65cb35 |
|
|
|
dd658d |
sprintf(buf,
|
|
|
dd658d |
".mri.tmplnk"
|
|
|
dd658d |
".dev."PPRIX64
|
|
|
dd658d |
".inode."PPRIX64
|
|
|
dd658d |
".size."PPRIX64
|
|
|
dd658d |
".tmp",
|
|
|
dd658d |
st.st_dev,
|
|
|
dd658d |
st.st_ino,
|
|
|
dd658d |
st.st_size);
|
|
|
dd658d |
|
|
|
dd658d |
unlinkat(fdat,buf,0);
|
|
|
dd658d |
|
|
|
65cb35 |
if (!(symlinkat(target,fdat,buf)))
|
|
|
65cb35 |
lnk = buf;
|
|
|
65cb35 |
}
|
|
|
65cb35 |
|
|
|
65cb35 |
return lnk;
|
|
|
65cb35 |
}
|
|
|
65cb35 |
|
|
|
8dc63d |
static void slbt_util_import_archive_child(
|
|
|
65cb35 |
char * program,
|
|
|
65cb35 |
int fd[2])
|
|
|
65cb35 |
{
|
|
|
65cb35 |
char * argv[3];
|
|
|
65cb35 |
|
|
|
65cb35 |
argv[0] = program;
|
|
|
65cb35 |
argv[1] = "-M";
|
|
|
65cb35 |
argv[2] = 0;
|
|
|
65cb35 |
|
|
|
65cb35 |
close(fd[1]);
|
|
|
65cb35 |
|
|
|
65cb35 |
if (dup2(fd[0],0) == 0)
|
|
|
65cb35 |
execvp(program,argv);
|
|
|
65cb35 |
|
|
|
65cb35 |
_exit(EXIT_FAILURE);
|
|
|
65cb35 |
}
|
|
|
65cb35 |
|
|
|
8dc63d |
int slbt_util_import_archive_mri(
|
|
|
5b993e |
struct slbt_exec_ctx * ectx,
|
|
|
5b993e |
char * dstarchive,
|
|
|
5b993e |
char * srcarchive)
|
|
|
65cb35 |
{
|
|
|
65cb35 |
int fdcwd;
|
|
|
65cb35 |
pid_t pid;
|
|
|
65cb35 |
pid_t rpid;
|
|
|
65cb35 |
int fd[2];
|
|
|
65cb35 |
char * dst;
|
|
|
65cb35 |
char * src;
|
|
|
65cb35 |
char * fmt;
|
|
|
dd658d |
char mridst [96];
|
|
|
dd658d |
char mrisrc [96];
|
|
|
65cb35 |
char program[PATH_MAX];
|
|
|
65cb35 |
|
|
|
5b993e |
const struct slbt_driver_ctx * dctx;
|
|
|
5b993e |
|
|
|
5b993e |
/* driver context */
|
|
|
5b993e |
dctx = (slbt_get_exec_ictx(ectx))->dctx;
|
|
|
5b993e |
|
|
|
65cb35 |
/* fdcwd */
|
|
|
65cb35 |
fdcwd = slbt_driver_fdcwd(dctx);
|
|
|
65cb35 |
|
|
|
65cb35 |
/* not needed? */
|
|
|
65cb35 |
if (slbt_symlink_is_a_placeholder(fdcwd,srcarchive))
|
|
|
65cb35 |
return 0;
|
|
|
65cb35 |
|
|
|
65cb35 |
/* program */
|
|
|
19022e |
if (slbt_snprintf(program,sizeof(program),
|
|
|
19022e |
"%s",dctx->cctx->host.ar) < 0)
|
|
|
65cb35 |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
65cb35 |
|
|
|
65cb35 |
/* fork */
|
|
|
65cb35 |
if (pipe(fd))
|
|
|
65cb35 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
65cb35 |
|
|
|
65cb35 |
if ((pid = fork()) < 0) {
|
|
|
65cb35 |
close(fd[0]);
|
|
|
65cb35 |
close(fd[1]);
|
|
|
65cb35 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
65cb35 |
}
|
|
|
65cb35 |
|
|
|
65cb35 |
/* child */
|
|
|
65cb35 |
if (pid == 0)
|
|
|
8dc63d |
slbt_util_import_archive_child(
|
|
|
65cb35 |
program,
|
|
|
65cb35 |
fd);
|
|
|
65cb35 |
|
|
|
65cb35 |
/* parent */
|
|
|
65cb35 |
close(fd[0]);
|
|
|
65cb35 |
|
|
|
65cb35 |
ectx->pid = pid;
|
|
|
65cb35 |
|
|
|
65cb35 |
dst = slbt_mri_argument(fdcwd,dstarchive,mridst);
|
|
|
65cb35 |
src = slbt_mri_argument(fdcwd,srcarchive,mrisrc);
|
|
|
65cb35 |
|
|
|
a8ca7c |
if (!dst || !src) {
|
|
|
a8ca7c |
close(fd[1]);
|
|
|
65cb35 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
a8ca7c |
}
|
|
|
65cb35 |
|
|
|
65cb35 |
fmt = "OPEN %s\n"
|
|
|
65cb35 |
"ADDLIB %s\n"
|
|
|
65cb35 |
"SAVE\n"
|
|
|
65cb35 |
"END\n";
|
|
|
65cb35 |
|
|
|
65cb35 |
if (slbt_dprintf(fd[1],fmt,dst,src) < 0) {
|
|
|
65cb35 |
close(fd[1]);
|
|
|
65cb35 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
65cb35 |
}
|
|
|
65cb35 |
|
|
|
65cb35 |
close(fd[1]);
|
|
|
65cb35 |
|
|
|
65cb35 |
rpid = waitpid(
|
|
|
65cb35 |
pid,
|
|
|
65cb35 |
&ectx->exitcode,
|
|
|
65cb35 |
0);
|
|
|
65cb35 |
|
|
|
65cb35 |
if (dst == mridst)
|
|
|
65cb35 |
unlinkat(fdcwd,dst,0);
|
|
|
65cb35 |
|
|
|
65cb35 |
if (src == mrisrc)
|
|
|
65cb35 |
unlinkat(fdcwd,src,0);
|
|
|
65cb35 |
|
|
|
65cb35 |
return (rpid == pid) && (ectx->exitcode == 0)
|
|
|
65cb35 |
? 0 : SLBT_CUSTOM_ERROR(dctx,SLBT_ERR_ARCHIVE_IMPORT);
|
|
|
65cb35 |
}
|