|
|
258073 |
/*******************************************************************/
|
|
|
258073 |
/* slibtool: a skinny libtool implementation, written in C */
|
|
|
6803d8 |
/* Copyright (C) 2016--2018 Z. Gilboa */
|
|
|
258073 |
/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */
|
|
|
258073 |
/*******************************************************************/
|
|
|
258073 |
|
|
|
50fd60 |
#include <fcntl.h>
|
|
|
258073 |
#include <stdio.h>
|
|
|
258073 |
#include <string.h>
|
|
|
258073 |
#include <stdbool.h>
|
|
|
258073 |
#include <fcntl.h>
|
|
|
258073 |
#include <errno.h>
|
|
|
258073 |
#include <sys/stat.h>
|
|
|
258073 |
|
|
|
258073 |
#define ARGV_DRIVER
|
|
|
258073 |
|
|
|
258073 |
#include <slibtool/slibtool.h>
|
|
|
d58d2f |
#include "slibtool_driver_impl.h"
|
|
|
258073 |
#include "slibtool_install_impl.h"
|
|
|
50fd60 |
#include "slibtool_mapfile_impl.h"
|
|
|
e8159c |
#include "slibtool_readlink_impl.h"
|
|
|
258073 |
#include "slibtool_spawn_impl.h"
|
|
|
258073 |
#include "slibtool_symlink_impl.h"
|
|
|
8a1cbd |
#include "slibtool_errinfo_impl.h"
|
|
|
258073 |
#include "argv/argv.h"
|
|
|
258073 |
|
|
|
258073 |
static int slbt_install_usage(
|
|
|
a82cc2 |
int fdout,
|
|
|
258073 |
const char * program,
|
|
|
258073 |
const char * arg,
|
|
|
d58d2f |
const struct argv_option ** optv,
|
|
|
258073 |
struct argv_meta * meta)
|
|
|
258073 |
{
|
|
|
258073 |
char header[512];
|
|
|
258073 |
|
|
|
258073 |
snprintf(header,sizeof(header),
|
|
|
258073 |
"Usage: %s --mode=install <install> [options] [SOURCE]... DEST\n"
|
|
|
258073 |
"Options:\n",
|
|
|
258073 |
program);
|
|
|
258073 |
|
|
|
a82cc2 |
argv_usage(fdout,header,optv,arg);
|
|
|
258073 |
argv_free(meta);
|
|
|
258073 |
|
|
|
258073 |
return SLBT_USAGE;
|
|
|
258073 |
}
|
|
|
258073 |
|
|
|
258073 |
static int slbt_exec_install_fail(
|
|
|
258073 |
struct slbt_exec_ctx * actx,
|
|
|
8a1cbd |
struct argv_meta * meta,
|
|
|
8a1cbd |
int ret)
|
|
|
258073 |
{
|
|
|
258073 |
argv_free(meta);
|
|
|
258073 |
slbt_free_exec_ctx(actx);
|
|
|
8a1cbd |
return ret;
|
|
|
258073 |
}
|
|
|
258073 |
|
|
|
258073 |
static int slbt_exec_install_init_dstdir(
|
|
|
8a1cbd |
const struct slbt_driver_ctx * dctx,
|
|
|
258073 |
struct argv_entry * dest,
|
|
|
258073 |
struct argv_entry * last,
|
|
|
258073 |
char * dstdir)
|
|
|
258073 |
{
|
|
|
061d4a |
struct stat st;
|
|
|
258073 |
char * slash;
|
|
|
258073 |
size_t len;
|
|
|
258073 |
|
|
|
8a1cbd |
(void)dctx;
|
|
|
8a1cbd |
|
|
|
258073 |
if (dest)
|
|
|
258073 |
last = dest;
|
|
|
258073 |
|
|
|
258073 |
/* dstdir: initial string */
|
|
|
258073 |
if ((size_t)snprintf(dstdir,PATH_MAX,"%s",
|
|
|
258073 |
last->arg) >= PATH_MAX)
|
|
|
8a1cbd |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
258073 |
|
|
|
258073 |
/* dstdir might end with a slash */
|
|
|
258073 |
len = strlen(dstdir);
|
|
|
258073 |
|
|
|
258073 |
if (dstdir[--len] == '/')
|
|
|
239674 |
dstdir[len] = 0;
|
|
|
258073 |
|
|
|
061d4a |
/* -t DSTDIR? */
|
|
|
061d4a |
if (dest)
|
|
|
061d4a |
return 0;
|
|
|
061d4a |
|
|
|
061d4a |
/* is DEST a directory? */
|
|
|
061d4a |
if (!(stat(dstdir,&st)))
|
|
|
061d4a |
if (S_ISDIR(st.st_mode))
|
|
|
061d4a |
return 0;
|
|
|
061d4a |
|
|
|
258073 |
/* remove last path component */
|
|
|
061d4a |
if ((slash = strrchr(dstdir,'/')))
|
|
|
239674 |
*slash = 0;
|
|
|
258073 |
|
|
|
258073 |
return 0;
|
|
|
258073 |
}
|
|
|
258073 |
|
|
|
c6e3d1 |
static int slbt_exec_install_import_libraries(
|
|
|
c6e3d1 |
const struct slbt_driver_ctx * dctx,
|
|
|
c6e3d1 |
struct slbt_exec_ctx * ectx,
|
|
|
c6e3d1 |
char * srcdso,
|
|
|
c6e3d1 |
char * dstdir)
|
|
|
c6e3d1 |
{
|
|
|
c6e3d1 |
char * host;
|
|
|
c6e3d1 |
char * slash;
|
|
|
c6e3d1 |
char * dot;
|
|
|
c6e3d1 |
char * mark;
|
|
|
c6e3d1 |
char srcbuf [PATH_MAX];
|
|
|
c6e3d1 |
char implib [PATH_MAX];
|
|
|
c6e3d1 |
char hosttag[PATH_MAX];
|
|
|
c6e3d1 |
char hostlnk[PATH_MAX];
|
|
|
c6e3d1 |
char major [128];
|
|
|
c6e3d1 |
char minor [128];
|
|
|
c6e3d1 |
char rev [128];
|
|
|
c6e3d1 |
|
|
|
c6e3d1 |
/* .libs/libfoo.so.x.y.z */
|
|
|
c6e3d1 |
if ((size_t)snprintf(srcbuf,sizeof(srcbuf),"%s",
|
|
|
c6e3d1 |
srcdso) >= sizeof(srcbuf))
|
|
|
8a1cbd |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
c6e3d1 |
|
|
|
c6e3d1 |
/* (dso is under .libs) */
|
|
|
c6e3d1 |
if (!(slash = strrchr(srcbuf,'/')))
|
|
Kylie McClain |
7ce25c |
return SLBT_CUSTOM_ERROR(dctx,SLBT_ERR_INSTALL_FLOW);
|
|
|
c6e3d1 |
|
|
|
c6e3d1 |
/* libfoo.so.x.y.z */
|
|
|
c6e3d1 |
if ((size_t)snprintf(implib,sizeof(implib),"%s",
|
|
|
c6e3d1 |
++slash) >= sizeof(implib)
|
|
|
c6e3d1 |
- strlen(dctx->cctx->settings.impsuffix))
|
|
|
8a1cbd |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
c6e3d1 |
|
|
Kylie McClain |
7ce25c |
/* guard against an infinitely long version */
|
|
|
c6e3d1 |
mark = srcbuf + strlen(srcbuf);
|
|
|
c6e3d1 |
|
|
|
c6e3d1 |
/* rev */
|
|
|
c6e3d1 |
if (!(dot = strrchr(srcbuf,'.')))
|
|
Kylie McClain |
7ce25c |
return SLBT_CUSTOM_ERROR(dctx,SLBT_ERR_INSTALL_FLOW);
|
|
|
c6e3d1 |
else if ((size_t)(mark - dot) > sizeof(rev))
|
|
Kylie McClain |
7ce25c |
return SLBT_CUSTOM_ERROR(dctx,SLBT_ERR_INSTALL_REV);
|
|
|
c6e3d1 |
else {
|
|
|
c6e3d1 |
strcpy(rev,dot);
|
|
|
239674 |
*dot = 0;
|
|
|
c6e3d1 |
}
|
|
|
c6e3d1 |
|
|
|
c6e3d1 |
/* minor */
|
|
|
c6e3d1 |
if (!(dot = strrchr(srcbuf,'.')))
|
|
Kylie McClain |
7ce25c |
return SLBT_CUSTOM_ERROR(dctx,SLBT_ERR_INSTALL_FLOW);
|
|
|
c6e3d1 |
else if ((size_t)(mark - dot) > sizeof(minor))
|
|
Kylie McClain |
7ce25c |
return SLBT_CUSTOM_ERROR(dctx,SLBT_ERR_INSTALL_REV);
|
|
|
c6e3d1 |
else {
|
|
|
c6e3d1 |
strcpy(minor,dot);
|
|
|
239674 |
*dot = 0;
|
|
|
c6e3d1 |
}
|
|
|
c6e3d1 |
|
|
|
c6e3d1 |
/* major */
|
|
|
c6e3d1 |
if (!(dot = strrchr(srcbuf,'.')))
|
|
Kylie McClain |
7ce25c |
return SLBT_CUSTOM_ERROR(dctx,SLBT_ERR_INSTALL_FLOW);
|
|
|
c6e3d1 |
else if ((size_t)(mark - dot) > sizeof(major))
|
|
Kylie McClain |
7ce25c |
return SLBT_CUSTOM_ERROR(dctx,SLBT_ERR_INSTALL_REV);
|
|
|
c6e3d1 |
else {
|
|
|
c6e3d1 |
strcpy(major,dot);
|
|
|
239674 |
*dot = 0;
|
|
|
c6e3d1 |
}
|
|
|
c6e3d1 |
|
|
|
c6e3d1 |
if (!(dot = strrchr(srcbuf,'.')))
|
|
Kylie McClain |
7ce25c |
return SLBT_CUSTOM_ERROR(dctx,SLBT_ERR_INSTALL_FLOW);
|
|
|
c6e3d1 |
|
|
|
c6e3d1 |
/* .libs/libfoo.so.def.host */
|
|
|
c6e3d1 |
if ((size_t)snprintf(hostlnk,sizeof(hostlnk),"%s.def.host",
|
|
|
c6e3d1 |
srcbuf) >= sizeof(hostlnk))
|
|
|
8a1cbd |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
c6e3d1 |
|
|
|
c6e3d1 |
/* libfoo.so.def.{flavor} */
|
|
|
c6e3d1 |
if (slbt_readlink(hostlnk,hosttag,sizeof(hosttag)))
|
|
|
6beda1 |
return SLBT_SYSTEM_ERROR(dctx,hostlnk);
|
|
|
c6e3d1 |
|
|
|
c6e3d1 |
/* host/flabor */
|
|
|
c6e3d1 |
if (!(host = strrchr(hosttag,'.')))
|
|
Kylie McClain |
7ce25c |
return SLBT_CUSTOM_ERROR(dctx,SLBT_ERR_INSTALL_FLOW);
|
|
|
c6e3d1 |
else
|
|
|
c6e3d1 |
host++;
|
|
|
c6e3d1 |
|
|
|
c6e3d1 |
/* symlink-based alternate host */
|
|
|
c6e3d1 |
if (slbt_set_alternate_host(dctx,host,host))
|
|
|
8a1cbd |
return SLBT_NESTED_ERROR(dctx);
|
|
|
c6e3d1 |
|
|
|
c6e3d1 |
/* .libs/libfoo.x.y.z.lib.a */
|
|
|
c6e3d1 |
sprintf(dot,"%s%s%s%s",
|
|
|
c6e3d1 |
major,minor,rev,
|
|
|
c6e3d1 |
dctx->cctx->asettings.impsuffix);
|
|
|
c6e3d1 |
|
|
|
c6e3d1 |
/* copy: .libs/libfoo.x.y.z.lib.a --> dstdir */
|
|
|
c6e3d1 |
if (slbt_copy_file(dctx,ectx,srcbuf,dstdir))
|
|
|
8a1cbd |
return SLBT_NESTED_ERROR(dctx);
|
|
|
c6e3d1 |
|
|
|
c6e3d1 |
/* .libs/libfoo.x.lib.a */
|
|
|
c6e3d1 |
sprintf(dot,"%s%s",
|
|
|
c6e3d1 |
major,
|
|
|
c6e3d1 |
dctx->cctx->asettings.impsuffix);
|
|
|
c6e3d1 |
|
|
|
c6e3d1 |
/* copy: .libs/libfoo.x.lib.a --> dstdir */
|
|
|
c6e3d1 |
if (slbt_copy_file(dctx,ectx,srcbuf,dstdir))
|
|
|
8a1cbd |
return SLBT_NESTED_ERROR(dctx);
|
|
|
c6e3d1 |
|
|
|
c6e3d1 |
/* /dstdir/libfoo.lib.a */
|
|
|
c6e3d1 |
strcpy(implib,slash);
|
|
|
c6e3d1 |
strcpy(dot,dctx->cctx->asettings.impsuffix);
|
|
|
c6e3d1 |
|
|
|
c6e3d1 |
if ((size_t)snprintf(hostlnk,sizeof(hostlnk),"%s/%s",
|
|
|
c6e3d1 |
dstdir,slash) >= sizeof(hostlnk))
|
|
|
8a1cbd |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
c6e3d1 |
|
|
|
c6e3d1 |
if (slbt_create_symlink(
|
|
|
c6e3d1 |
dctx,ectx,
|
|
|
c6e3d1 |
implib,
|
|
|
c6e3d1 |
hostlnk,
|
|
|
c6e3d1 |
false))
|
|
|
8a1cbd |
return SLBT_NESTED_ERROR(dctx);
|
|
|
c6e3d1 |
|
|
|
c6e3d1 |
return 0;
|
|
|
c6e3d1 |
}
|
|
|
c6e3d1 |
|
|
|
5b5408 |
static int slbt_exec_install_library_wrapper(
|
|
|
5b5408 |
const struct slbt_driver_ctx * dctx,
|
|
|
5b5408 |
struct slbt_exec_ctx * ectx,
|
|
|
5b5408 |
struct argv_entry * entry,
|
|
|
5b5408 |
char * dstdir)
|
|
|
5b5408 |
{
|
|
|
5fac6c |
int fdcwd;
|
|
|
50fd60 |
int fddst;
|
|
|
50fd60 |
size_t buflen;
|
|
|
50fd60 |
const char * base;
|
|
|
50fd60 |
char * srcline;
|
|
|
50fd60 |
char * dstline;
|
|
|
50fd60 |
char clainame[PATH_MAX];
|
|
|
50fd60 |
char instname[PATH_MAX];
|
|
|
50fd60 |
char cfgbuf [PATH_MAX];
|
|
|
50fd60 |
struct slbt_map_info * mapinfo;
|
|
|
5b5408 |
|
|
|
5b5408 |
/* base libfoo.la */
|
|
|
5b5408 |
if ((base = strrchr(entry->arg,'/')))
|
|
|
5b5408 |
base++;
|
|
|
5b5408 |
else
|
|
|
5b5408 |
base = entry->arg;
|
|
|
5b5408 |
|
|
|
5b5408 |
/* /dstdir/libfoo.la */
|
|
|
5b5408 |
if ((size_t)snprintf(instname,sizeof(instname),"%s/%s",
|
|
|
5b5408 |
dstdir,base) >= sizeof(instname))
|
|
|
8a1cbd |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
5b5408 |
|
|
|
5b5408 |
/* libfoo.la.slibtool.install */
|
|
|
5b5408 |
if ((size_t)snprintf(clainame,sizeof(clainame),"%s.slibtool.install",
|
|
|
5b5408 |
entry->arg) >= sizeof(clainame))
|
|
|
8a1cbd |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
5b5408 |
|
|
|
5fac6c |
/* fdcwd */
|
|
|
5fac6c |
fdcwd = slbt_driver_fdcwd(dctx);
|
|
|
5fac6c |
|
|
|
50fd60 |
/* fddst (libfoo.la.slibtool.install, build directory) */
|
|
|
5fac6c |
if ((fddst = openat(fdcwd,clainame,O_RDWR|O_CREAT|O_TRUNC,0644)) < 0)
|
|
|
6beda1 |
return SLBT_SYSTEM_ERROR(dctx,clainame);
|
|
|
5b5408 |
|
|
|
50fd60 |
/* mapinfo (libfoo.la, build directory) */
|
|
|
5fac6c |
if (!(mapinfo = slbt_map_file(fdcwd,entry->arg,SLBT_MAP_INPUT))) {
|
|
|
50fd60 |
close(fddst);
|
|
|
6beda1 |
return SLBT_SYSTEM_ERROR(dctx,entry->arg);
|
|
|
5b5408 |
}
|
|
|
5b5408 |
|
|
|
50fd60 |
/* srcline */
|
|
|
50fd60 |
if (mapinfo->size < sizeof(cfgbuf)) {
|
|
|
50fd60 |
buflen = sizeof(cfgbuf);
|
|
|
50fd60 |
srcline = cfgbuf;
|
|
|
50fd60 |
} else {
|
|
|
50fd60 |
buflen = mapinfo->size;
|
|
|
50fd60 |
srcline = malloc(++buflen);
|
|
|
5b5408 |
}
|
|
|
5b5408 |
|
|
|
50fd60 |
if (!srcline) {
|
|
|
50fd60 |
close(fddst);
|
|
|
50fd60 |
slbt_unmap_file(mapinfo);
|
|
|
6beda1 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
5b5408 |
}
|
|
|
5b5408 |
|
|
|
50fd60 |
/* copy config, installed=no --> installed=yes */
|
|
|
50fd60 |
while (mapinfo->mark < mapinfo->cap) {
|
|
|
50fd60 |
if (slbt_mapped_readline(dctx,mapinfo,srcline,buflen) < 0) {
|
|
|
50fd60 |
close(fddst);
|
|
|
50fd60 |
slbt_unmap_file(mapinfo);
|
|
|
50fd60 |
return SLBT_NESTED_ERROR(dctx);
|
|
|
50fd60 |
}
|
|
|
50fd60 |
|
|
|
50fd60 |
dstline = strcmp(srcline,"installed=no\n")
|
|
|
50fd60 |
? srcline
|
|
|
50fd60 |
: "installed=yes\n";
|
|
|
50fd60 |
|
|
|
50fd60 |
if (slbt_dprintf(fddst,"%s",dstline) < 0) {
|
|
|
50fd60 |
close(fddst);
|
|
|
50fd60 |
slbt_unmap_file(mapinfo);
|
|
|
6beda1 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
50fd60 |
}
|
|
|
5b5408 |
}
|
|
|
5b5408 |
|
|
|
5b5408 |
if (srcline != cfgbuf)
|
|
|
5b5408 |
free(srcline);
|
|
|
5b5408 |
|
|
|
50fd60 |
/* close, unmap */
|
|
|
50fd60 |
close(fddst);
|
|
|
50fd60 |
slbt_unmap_file(mapinfo);
|
|
|
5b5408 |
|
|
|
5b5408 |
/* cp libfoo.la.slibtool.instal /dstdir/libfoo.la */
|
|
|
5b5408 |
if (slbt_copy_file(dctx,ectx,clainame,instname))
|
|
|
8a1cbd |
return SLBT_NESTED_ERROR(dctx);
|
|
|
5b5408 |
|
|
|
5b5408 |
return 0;
|
|
|
5b5408 |
}
|
|
|
5b5408 |
|
|
|
258073 |
static int slbt_exec_install_entry(
|
|
|
258073 |
const struct slbt_driver_ctx * dctx,
|
|
|
258073 |
struct slbt_exec_ctx * ectx,
|
|
|
258073 |
struct argv_entry * entry,
|
|
|
258073 |
struct argv_entry * last,
|
|
|
258073 |
struct argv_entry * dest,
|
|
|
258073 |
char * dstdir,
|
|
|
258073 |
char ** src,
|
|
|
258073 |
char ** dst)
|
|
|
258073 |
{
|
|
|
258073 |
int ret;
|
|
|
258073 |
char * dot;
|
|
|
258073 |
char * base;
|
|
|
258073 |
char * slash;
|
|
|
ca36f5 |
char * suffix;
|
|
|
258073 |
char target [PATH_MAX];
|
|
|
258073 |
char srcfile [PATH_MAX];
|
|
|
258073 |
char dstfile [PATH_MAX];
|
|
|
258073 |
char slnkname[PATH_MAX];
|
|
|
258073 |
char dlnkname[PATH_MAX];
|
|
|
aa8ca6 |
char lasource[PATH_MAX - 8];
|
|
|
5e5804 |
bool fexe = false;
|
|
|
1c05ca |
bool fpe;
|
|
|
112a2b |
bool frelease;
|
|
|
5e5804 |
struct stat st;
|
|
|
5e5804 |
|
|
|
5e5804 |
/* executable wrapper? */
|
|
|
5e5804 |
if ((size_t)snprintf(slnkname,sizeof(slnkname),"%s.exe.wrapper",
|
|
|
5e5804 |
entry->arg) >= sizeof(slnkname))
|
|
|
8a1cbd |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
5e5804 |
|
|
|
5e5804 |
fexe = stat(slnkname,&st)
|
|
|
5e5804 |
? false
|
|
|
5e5804 |
: true;
|
|
|
258073 |
|
|
|
af8d17 |
dot = strrchr(entry->arg,'.');
|
|
|
af8d17 |
|
|
|
af8d17 |
/* .lai --> .la */
|
|
|
af8d17 |
if (!fexe && dot && !strcmp(dot,".lai"))
|
|
|
af8d17 |
dot[3] = 0;
|
|
|
af8d17 |
|
|
|
258073 |
/* srcfile */
|
|
|
258073 |
if (strlen(entry->arg) + strlen(".libs/") >= (PATH_MAX-1))
|
|
|
8a1cbd |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
258073 |
|
|
|
258073 |
strcpy(lasource,entry->arg);
|
|
|
258073 |
|
|
|
258073 |
if ((slash = strrchr(lasource,'/'))) {
|
|
|
239674 |
*slash++ = 0;
|
|
|
258073 |
sprintf(srcfile,"%s/.libs/%s",lasource,slash);
|
|
|
258073 |
} else
|
|
|
258073 |
sprintf(srcfile,".libs/%s",lasource);
|
|
|
258073 |
|
|
|
e13a5c |
/* executable? ordinary file? */
|
|
|
e13a5c |
if (fexe || !dot || strcmp(dot,".la")) {
|
|
|
e13a5c |
*src = fexe ? srcfile : (char *)entry->arg;
|
|
|
e13a5c |
*dst = dest ? 0 : (char *)last->arg;
|
|
|
5e5804 |
|
|
|
5e5804 |
if (!(dctx->cctx->drvflags & SLBT_DRIVER_SILENT))
|
|
|
5e5804 |
if (slbt_output_install(dctx,ectx))
|
|
|
8a1cbd |
return SLBT_NESTED_ERROR(dctx);
|
|
|
5e5804 |
|
|
|
5e5804 |
return (((ret = slbt_spawn(ectx,true)) < 0) || ectx->exitcode)
|
|
|
8a1cbd |
? SLBT_SPAWN_ERROR(dctx) : 0;
|
|
|
5e5804 |
}
|
|
|
258073 |
|
|
|
e13a5c |
/* legabits? */
|
|
|
e13a5c |
if (dctx->cctx->drvflags & SLBT_DRIVER_LEGABITS)
|
|
|
e13a5c |
if (slbt_exec_install_library_wrapper(dctx,ectx,entry,dstdir))
|
|
|
8a1cbd |
return SLBT_NESTED_ERROR(dctx);
|
|
|
e13a5c |
|
|
|
e13a5c |
/* *dst: consider: cp libfoo.la /dest/dir/libfoo.la */
|
|
|
e13a5c |
if ((*dst = dest ? 0 : (char *)last->arg))
|
|
|
e13a5c |
if ((dot = strrchr(last->arg,'.')))
|
|
|
e13a5c |
if (!(strcmp(dot,".la")))
|
|
|
e13a5c |
*dst = dstdir;
|
|
|
e13a5c |
|
|
|
f38ea1 |
/* libfoo.a */
|
|
|
f38ea1 |
dot = strrchr(srcfile,'.');
|
|
|
f38ea1 |
strcpy(dot,dctx->cctx->settings.arsuffix);
|
|
|
f38ea1 |
|
|
|
252629 |
if (!(dctx->cctx->drvflags & SLBT_DRIVER_DISABLE_STATIC))
|
|
|
252629 |
if (slbt_copy_file(dctx,ectx,
|
|
|
252629 |
srcfile,
|
|
|
252629 |
dest ? (char *)dest->arg : *dst))
|
|
|
252629 |
return SLBT_NESTED_ERROR(dctx);
|
|
|
f38ea1 |
|
|
|
112a2b |
/* dot/suffix */
|
|
|
5e5804 |
strcpy(slnkname,srcfile);
|
|
|
258073 |
dot = strrchr(slnkname,'.');
|
|
|
112a2b |
|
|
|
112a2b |
/* libfoo.a --> libfoo.so.release */
|
|
|
112a2b |
sprintf(dot,"%s.release",dctx->cctx->settings.dsosuffix);
|
|
|
112a2b |
frelease = stat(slnkname,&st) ? false : true;
|
|
|
112a2b |
|
|
|
112a2b |
/* libfoo.a --> libfoo.so */
|
|
|
b3c21a |
strcpy(dot,dctx->cctx->settings.dsosuffix);
|
|
|
258073 |
|
|
|
1c05ca |
/* PE support: does .libs/libfoo.so.def exist? */
|
|
|
1c05ca |
if ((size_t)snprintf(dstfile,sizeof(dstfile),"%s.def",
|
|
|
1c05ca |
slnkname) >= sizeof(dstfile))
|
|
|
8a1cbd |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
1c05ca |
|
|
|
1c05ca |
fpe = stat(dstfile,&st) ? false : true;
|
|
|
1c05ca |
|
|
|
258073 |
/* basename */
|
|
|
258073 |
if ((base = strrchr(slnkname,'/')))
|
|
|
258073 |
base++;
|
|
|
258073 |
else
|
|
|
258073 |
base = slnkname;
|
|
|
258073 |
|
|
|
258073 |
/* source (build) symlink target */
|
|
|
e8159c |
if (slbt_readlink(slnkname,target,sizeof(target)) < 0) {
|
|
|
2baf1c |
/* -all-static? */
|
|
|
2baf1c |
if (slbt_symlink_is_a_placeholder(slnkname))
|
|
|
2baf1c |
return 0;
|
|
|
2baf1c |
|
|
|
b107e2 |
/* -avoid-version? */
|
|
|
b107e2 |
if (stat(slnkname,&st))
|
|
|
6beda1 |
return SLBT_SYSTEM_ERROR(dctx,slnkname);
|
|
|
b107e2 |
|
|
|
b107e2 |
/* dstfile */
|
|
|
b107e2 |
if ((size_t)snprintf(dstfile,sizeof(dstfile),"%s/%s",
|
|
|
b107e2 |
dstdir,base) >= sizeof(dstfile))
|
|
|
8a1cbd |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
b107e2 |
|
|
|
b107e2 |
/* single spawn, no symlinks */
|
|
|
b107e2 |
*src = slnkname;
|
|
|
b107e2 |
*dst = dest ? 0 : dstfile;
|
|
|
b107e2 |
|
|
|
b107e2 |
if (!(dctx->cctx->drvflags & SLBT_DRIVER_SILENT))
|
|
|
b107e2 |
if (slbt_output_install(dctx,ectx))
|
|
|
8a1cbd |
return SLBT_NESTED_ERROR(dctx);
|
|
|
b107e2 |
|
|
|
b107e2 |
if (((ret = slbt_spawn(ectx,true)) < 0) || ectx->exitcode)
|
|
|
8a1cbd |
return SLBT_SPAWN_ERROR(dctx);
|
|
|
b107e2 |
|
|
|
b107e2 |
return 0;
|
|
|
b107e2 |
}
|
|
|
258073 |
|
|
|
258073 |
/* srcfile: .libs/libfoo.so.x.y.z */
|
|
|
258073 |
slash = strrchr(srcfile,'/');
|
|
|
258073 |
strcpy(++slash,target);
|
|
|
258073 |
|
|
|
258073 |
/* dstfile */
|
|
|
258073 |
if (!dest)
|
|
|
258073 |
if ((size_t)snprintf(dstfile,sizeof(dstfile),"%s/%s",
|
|
|
258073 |
dstdir,target) >= sizeof(dstfile))
|
|
|
8a1cbd |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
258073 |
|
|
|
258073 |
/* spawn */
|
|
|
258073 |
*src = srcfile;
|
|
|
258073 |
*dst = dest ? 0 : dstfile;
|
|
|
258073 |
|
|
|
258073 |
if (!(dctx->cctx->drvflags & SLBT_DRIVER_SILENT))
|
|
|
258073 |
if (slbt_output_install(dctx,ectx))
|
|
|
8a1cbd |
return SLBT_NESTED_ERROR(dctx);
|
|
|
258073 |
|
|
|
258073 |
if (((ret = slbt_spawn(ectx,true)) < 0) || ectx->exitcode)
|
|
|
8a1cbd |
return SLBT_SPAWN_ERROR(dctx);
|
|
|
258073 |
|
|
|
258073 |
/* destination symlink: dstdir/libfoo.so */
|
|
|
258073 |
if ((size_t)snprintf(dlnkname,sizeof(dlnkname),"%s/%s",
|
|
|
258073 |
dstdir,base) >= sizeof(dlnkname))
|
|
|
8a1cbd |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
258073 |
|
|
|
258073 |
/* create symlink: libfoo.so --> libfoo.so.x.y.z */
|
|
|
258073 |
if (slbt_create_symlink(
|
|
|
258073 |
dctx,ectx,
|
|
|
258073 |
target,dlnkname,
|
|
|
258073 |
false))
|
|
|
8a1cbd |
return SLBT_NESTED_ERROR(dctx);
|
|
|
258073 |
|
|
|
112a2b |
if (frelease)
|
|
|
112a2b |
return 0;
|
|
|
112a2b |
|
|
|
ca36f5 |
/* libfoo.so.x --> libfoo.so.x.y.z */
|
|
|
258073 |
strcpy(slnkname,target);
|
|
|
258073 |
|
|
|
ca36f5 |
if ((suffix = strrchr(slnkname,'.')))
|
|
|
ca36f5 |
*suffix++ = 0;
|
|
|
258073 |
else
|
|
Kylie McClain |
7ce25c |
return SLBT_CUSTOM_ERROR(dctx,SLBT_ERR_INSTALL_FLOW);
|
|
|
258073 |
|
|
|
258073 |
if ((dot = strrchr(slnkname,'.')))
|
|
|
ca36f5 |
*dot++ = 0;
|
|
|
258073 |
else
|
|
Kylie McClain |
7ce25c |
return SLBT_CUSTOM_ERROR(dctx,SLBT_ERR_INSTALL_FLOW);
|
|
|
258073 |
|
|
|
ca36f5 |
if ((*dot < '0') || (*dot > '9'))
|
|
|
ca36f5 |
return SLBT_CUSTOM_ERROR(dctx,SLBT_ERR_INSTALL_FLOW);
|
|
|
ca36f5 |
|
|
|
ca36f5 |
/* libfoo.x.y.z.so? */
|
|
|
ca36f5 |
if ((suffix[0] < '0') || (suffix[0] > '9')) {
|
|
|
ca36f5 |
if ((dot = strrchr(slnkname,'.')))
|
|
|
ca36f5 |
dot++;
|
|
|
ca36f5 |
else
|
|
|
ca36f5 |
return SLBT_CUSTOM_ERROR(dctx,SLBT_ERR_INSTALL_FLOW);
|
|
|
ca36f5 |
|
|
|
ca36f5 |
if ((*dot < '0') || (*dot > '9'))
|
|
|
ca36f5 |
return SLBT_CUSTOM_ERROR(dctx,SLBT_ERR_INSTALL_FLOW);
|
|
|
ca36f5 |
|
|
|
ca36f5 |
for (; *suffix; )
|
|
|
ca36f5 |
*dot++ = *suffix++;
|
|
|
ca36f5 |
|
|
|
ca36f5 |
*dot++ = 0;
|
|
|
ca36f5 |
}
|
|
|
ca36f5 |
|
|
|
258073 |
/* destination symlink: dstdir/libfoo.so.x */
|
|
|
258073 |
if ((size_t)snprintf(dlnkname,sizeof(dlnkname),"%s/%s",
|
|
|
258073 |
dstdir,slnkname) >= sizeof(dlnkname))
|
|
|
8a1cbd |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
258073 |
|
|
|
1c05ca |
if (fpe) {
|
|
|
1c05ca |
/* copy: .libs/libfoo.so.x.y.z --> libfoo.so.x */
|
|
|
1c05ca |
if (slbt_copy_file(
|
|
|
1c05ca |
dctx,ectx,
|
|
|
1c05ca |
srcfile,
|
|
|
1c05ca |
dlnkname))
|
|
|
8a1cbd |
return SLBT_NESTED_ERROR(dctx);
|
|
|
c6e3d1 |
|
|
|
c6e3d1 |
/* import libraries */
|
|
|
c6e3d1 |
if (slbt_exec_install_import_libraries(
|
|
|
c6e3d1 |
dctx,ectx,
|
|
|
c6e3d1 |
srcfile,
|
|
|
c6e3d1 |
dstdir))
|
|
|
8a1cbd |
return SLBT_NESTED_ERROR(dctx);
|
|
|
1c05ca |
} else {
|
|
|
1c05ca |
/* create symlink: libfoo.so.x --> libfoo.so.x.y.z */
|
|
|
1c05ca |
if (slbt_create_symlink(
|
|
|
1c05ca |
dctx,ectx,
|
|
|
1c05ca |
target,dlnkname,
|
|
|
1c05ca |
false))
|
|
|
8a1cbd |
return SLBT_NESTED_ERROR(dctx);
|
|
|
1c05ca |
}
|
|
|
258073 |
|
|
|
258073 |
return 0;
|
|
|
258073 |
}
|
|
|
258073 |
|
|
|
258073 |
int slbt_exec_install(
|
|
|
258073 |
const struct slbt_driver_ctx * dctx,
|
|
|
258073 |
struct slbt_exec_ctx * ectx)
|
|
|
258073 |
{
|
|
|
258073 |
int ret;
|
|
|
a82cc2 |
int fdout;
|
|
|
258073 |
char ** argv;
|
|
|
668906 |
char ** iargv;
|
|
|
258073 |
char ** src;
|
|
|
258073 |
char ** dst;
|
|
|
430840 |
char * slash;
|
|
|
430840 |
char * optsh;
|
|
|
430840 |
char * script;
|
|
|
258073 |
struct slbt_exec_ctx * actx;
|
|
|
258073 |
struct argv_meta * meta;
|
|
|
258073 |
struct argv_entry * entry;
|
|
|
258073 |
struct argv_entry * copy;
|
|
|
258073 |
struct argv_entry * dest;
|
|
|
258073 |
struct argv_entry * last;
|
|
|
d58d2f |
const struct argv_option * optv[SLBT_OPTV_ELEMENTS];
|
|
|
258073 |
char dstdir[PATH_MAX];
|
|
|
258073 |
|
|
|
c4a389 |
/* dry run */
|
|
|
c4a389 |
if (dctx->cctx->drvflags & SLBT_DRIVER_DRY_RUN)
|
|
|
c4a389 |
return 0;
|
|
|
c4a389 |
|
|
|
258073 |
/* context */
|
|
|
258073 |
if (ectx)
|
|
|
258073 |
actx = 0;
|
|
|
258073 |
else if ((ret = slbt_get_exec_ctx(dctx,&ectx)))
|
|
|
258073 |
return ret;
|
|
|
258073 |
else
|
|
|
258073 |
actx = ectx;
|
|
|
258073 |
|
|
|
258073 |
/* initial state, install mode skin */
|
|
|
258073 |
slbt_reset_arguments(ectx);
|
|
|
258073 |
slbt_disable_placeholders(ectx);
|
|
|
668906 |
iargv = ectx->cargv;
|
|
|
a82cc2 |
fdout = slbt_driver_fdout(dctx);
|
|
|
430840 |
optsh = 0;
|
|
|
430840 |
script = 0;
|
|
|
668906 |
|
|
|
668906 |
/* work around non-conforming uses of --mode=install */
|
|
|
430840 |
if (iargv[1] && (slash = strrchr(iargv[1],'/'))) {
|
|
|
430840 |
if (!strcmp(++slash,"install-sh")) {
|
|
|
430840 |
optsh = *iargv++;
|
|
|
430840 |
script = *iargv;
|
|
|
430840 |
}
|
|
|
430840 |
}
|
|
|
258073 |
|
|
|
258073 |
/* missing arguments? */
|
|
|
d58d2f |
argv_optv_init(slbt_install_options,optv);
|
|
|
d58d2f |
|
|
|
668906 |
if (!iargv[1] && (dctx->cctx->drvflags & SLBT_DRIVER_VERBOSITY_USAGE))
|
|
|
a82cc2 |
return slbt_install_usage(
|
|
|
a82cc2 |
fdout,
|
|
|
a82cc2 |
dctx->program,
|
|
|
a82cc2 |
0,optv,0);
|
|
|
258073 |
|
|
|
258073 |
/* <install> argv meta */
|
|
|
258073 |
if (!(meta = argv_get(
|
|
|
a82cc2 |
iargv,optv,
|
|
|
258073 |
dctx->cctx->drvflags & SLBT_DRIVER_VERBOSITY_ERRORS
|
|
|
258073 |
? ARGV_VERBOSITY_ERRORS
|
|
|
93f9e4 |
: ARGV_VERBOSITY_NONE,
|
|
|
a82cc2 |
fdout)))
|
|
|
8a1cbd |
return slbt_exec_install_fail(
|
|
|
8a1cbd |
actx,meta,
|
|
Kylie McClain |
7ce25c |
SLBT_CUSTOM_ERROR(dctx,SLBT_ERR_INSTALL_FAIL));
|
|
|
258073 |
|
|
|
258073 |
/* dest, alternate argument vector options */
|
|
|
258073 |
argv = ectx->altv;
|
|
|
258073 |
copy = meta->entries;
|
|
|
258073 |
dest = 0;
|
|
|
258073 |
last = 0;
|
|
|
258073 |
|
|
|
430840 |
if (optsh)
|
|
|
430840 |
*argv++ = script;
|
|
|
430840 |
|
|
|
668906 |
*argv++ = iargv[0];
|
|
|
258073 |
|
|
|
258073 |
for (entry=meta->entries; entry->fopt || entry->arg; entry++) {
|
|
|
258073 |
if (entry->fopt) {
|
|
|
258073 |
switch (entry->tag) {
|
|
|
258073 |
case TAG_INSTALL_COPY:
|
|
|
258073 |
*argv++ = "-c";
|
|
|
258073 |
copy = entry;
|
|
|
258073 |
break;
|
|
|
258073 |
|
|
|
f8ac22 |
case TAG_INSTALL_FORCE:
|
|
|
f8ac22 |
*argv++ = "-f";
|
|
|
f8ac22 |
break;
|
|
|
f8ac22 |
|
|
|
258073 |
case TAG_INSTALL_MKDIR:
|
|
|
258073 |
*argv++ = "-d";
|
|
|
258073 |
copy = 0;
|
|
|
258073 |
break;
|
|
|
258073 |
|
|
|
258073 |
case TAG_INSTALL_TARGET_MKDIR:
|
|
|
258073 |
*argv++ = "-D";
|
|
|
258073 |
copy = 0;
|
|
|
258073 |
break;
|
|
|
258073 |
|
|
|
258073 |
case TAG_INSTALL_STRIP:
|
|
|
258073 |
*argv++ = "-s";
|
|
|
258073 |
break;
|
|
|
258073 |
|
|
|
258073 |
case TAG_INSTALL_PRESERVE:
|
|
|
258073 |
*argv++ = "-p";
|
|
|
258073 |
break;
|
|
|
258073 |
|
|
|
258073 |
case TAG_INSTALL_USER:
|
|
|
258073 |
*argv++ = "-o";
|
|
|
258073 |
break;
|
|
|
258073 |
|
|
|
258073 |
case TAG_INSTALL_GROUP:
|
|
|
258073 |
*argv++ = "-g";
|
|
|
258073 |
break;
|
|
|
258073 |
|
|
|
258073 |
case TAG_INSTALL_MODE:
|
|
|
258073 |
*argv++ = "-m";
|
|
|
258073 |
break;
|
|
|
258073 |
|
|
|
258073 |
case TAG_INSTALL_DSTDIR:
|
|
|
258073 |
*argv++ = "-t";
|
|
|
258073 |
dest = entry;
|
|
|
258073 |
break;
|
|
|
258073 |
}
|
|
|
258073 |
|
|
|
258073 |
if (entry->fval)
|
|
|
258073 |
*argv++ = (char *)entry->arg;
|
|
|
258073 |
} else
|
|
|
258073 |
last = entry;
|
|
|
258073 |
}
|
|
|
258073 |
|
|
|
258073 |
/* install */
|
|
|
258073 |
if (copy) {
|
|
|
258073 |
/* using alternate argument vector */
|
|
|
430840 |
if (optsh)
|
|
|
430840 |
ectx->altv[0] = optsh;
|
|
|
430840 |
|
|
|
258073 |
ectx->argv = ectx->altv;
|
|
|
258073 |
ectx->program = ectx->altv[0];
|
|
|
258073 |
|
|
|
258073 |
/* marks */
|
|
|
258073 |
src = argv++;
|
|
|
258073 |
dst = argv++;
|
|
|
258073 |
|
|
|
258073 |
/* dstdir */
|
|
|
8a1cbd |
if (slbt_exec_install_init_dstdir(dctx,dest,last,dstdir))
|
|
|
8a1cbd |
return slbt_exec_install_fail(
|
|
|
8a1cbd |
actx,meta,
|
|
|
8a1cbd |
SLBT_NESTED_ERROR(dctx));
|
|
|
258073 |
|
|
|
258073 |
/* install entries one at a time */
|
|
|
258073 |
for (entry=meta->entries; entry->fopt || entry->arg; entry++)
|
|
|
258073 |
if (!entry->fopt && (dest || (entry != last)))
|
|
|
258073 |
if (slbt_exec_install_entry(
|
|
|
258073 |
dctx,ectx,
|
|
|
258073 |
entry,last,
|
|
|
258073 |
dest,dstdir,
|
|
|
258073 |
src,dst))
|
|
|
8a1cbd |
return slbt_exec_install_fail(
|
|
|
8a1cbd |
actx,meta,
|
|
|
8a1cbd |
SLBT_NESTED_ERROR(dctx));
|
|
|
258073 |
} else {
|
|
|
258073 |
/* using original argument vector */
|
|
|
258073 |
ectx->argv = ectx->cargv;
|
|
|
258073 |
ectx->program = ectx->cargv[0];
|
|
|
258073 |
|
|
|
258073 |
/* spawn */
|
|
|
258073 |
if (!(dctx->cctx->drvflags & SLBT_DRIVER_SILENT))
|
|
|
258073 |
if (slbt_output_install(dctx,ectx))
|
|
|
8a1cbd |
return SLBT_NESTED_ERROR(dctx);
|
|
|
258073 |
|
|
|
258073 |
if (((ret = slbt_spawn(ectx,true)) < 0) || ectx->exitcode)
|
|
|
8a1cbd |
return slbt_exec_install_fail(
|
|
|
8a1cbd |
actx,meta,
|
|
|
8a1cbd |
SLBT_SPAWN_ERROR(dctx));
|
|
|
258073 |
}
|
|
|
258073 |
|
|
|
258073 |
argv_free(meta);
|
|
|
258073 |
slbt_free_exec_ctx(actx);
|
|
|
258073 |
|
|
|
258073 |
return 0;
|
|
|
258073 |
}
|