|
|
6529aa |
/*******************************************************************/
|
|
|
6529aa |
/* slibtool: a skinny libtool implementation, written in C */
|
|
|
6529aa |
/* Copyright (C) 2016 Z. Gilboa */
|
|
|
6529aa |
/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */
|
|
|
6529aa |
/*******************************************************************/
|
|
|
6529aa |
|
|
|
6529aa |
#include <stdio.h>
|
|
|
6529aa |
#include <string.h>
|
|
|
6529aa |
#include <stdbool.h>
|
|
|
6529aa |
#include <unistd.h>
|
|
|
6529aa |
|
|
|
d56ead |
#include "slibtool_errinfo_impl.h"
|
|
|
6529aa |
#include "slibtool_symlink_impl.h"
|
|
|
6529aa |
|
|
|
d1e257 |
#define SLBT_DEV_NULL_FLAGS (SLBT_DRIVER_ALL_STATIC \
|
|
|
d1e257 |
| SLBT_DRIVER_DISABLE_SHARED)
|
|
|
d1e257 |
|
|
|
6529aa |
int slbt_create_symlink(
|
|
|
6529aa |
const struct slbt_driver_ctx * dctx,
|
|
|
6529aa |
struct slbt_exec_ctx * ectx,
|
|
|
6529aa |
const char * target,
|
|
|
e0a045 |
const char * lnkname,
|
|
|
6529aa |
bool flawrapper)
|
|
|
6529aa |
{
|
|
|
660491 |
char ** oargv;
|
|
|
6529aa |
const char * slash;
|
|
|
6529aa |
char * ln[5];
|
|
|
6529aa |
char * dotdot;
|
|
|
6529aa |
char tmplnk [PATH_MAX];
|
|
|
e0a045 |
char lnkarg [PATH_MAX];
|
|
|
6529aa |
char atarget[PATH_MAX];
|
|
|
6529aa |
|
|
|
6529aa |
/* atarget */
|
|
|
d1e257 |
if ((dctx->cctx->drvflags & SLBT_DEV_NULL_FLAGS)
|
|
|
372423 |
&& !strcmp(target,"/dev/null"))
|
|
|
372423 |
slash = target;
|
|
|
372423 |
else if ((slash = strrchr(target,'/')))
|
|
|
6529aa |
slash++;
|
|
|
6529aa |
else
|
|
|
6529aa |
slash = target;
|
|
|
6529aa |
|
|
|
6529aa |
dotdot = flawrapper ? "../" : "";
|
|
|
6529aa |
|
|
|
6529aa |
if ((size_t)snprintf(atarget,sizeof(atarget),"%s%s",
|
|
|
6529aa |
dotdot,slash) >= sizeof(atarget))
|
|
|
d56ead |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
6529aa |
|
|
|
6529aa |
/* tmplnk */
|
|
|
6529aa |
if ((size_t)snprintf(tmplnk,sizeof(tmplnk),"%s.symlink.tmp",
|
|
|
6529aa |
lnkname) >= sizeof(tmplnk))
|
|
|
d56ead |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
6529aa |
|
|
|
e0a045 |
/* lnkarg */
|
|
|
e0a045 |
strcpy(lnkarg,lnkname);
|
|
|
e0a045 |
|
|
|
6529aa |
/* ln argv (fake) */
|
|
|
6529aa |
ln[0] = "ln";
|
|
|
6529aa |
ln[1] = "-s";
|
|
|
6529aa |
ln[2] = atarget;
|
|
|
e0a045 |
ln[3] = lnkarg;
|
|
|
6529aa |
ln[4] = 0;
|
|
|
660491 |
|
|
|
660491 |
oargv = ectx->argv;
|
|
|
6529aa |
ectx->argv = ln;
|
|
|
6529aa |
|
|
|
6529aa |
/* step output */
|
|
|
dc77cb |
if (!(dctx->cctx->drvflags & SLBT_DRIVER_SILENT)) {
|
|
|
5e1c21 |
if (dctx->cctx->mode == SLBT_MODE_LINK) {
|
|
|
660491 |
if (slbt_output_link(dctx,ectx)) {
|
|
|
660491 |
ectx->argv = oargv;
|
|
|
d56ead |
return SLBT_NESTED_ERROR(dctx);
|
|
|
660491 |
}
|
|
|
5e1c21 |
} else {
|
|
|
660491 |
if (slbt_output_install(dctx,ectx)) {
|
|
|
660491 |
ectx->argv = oargv;
|
|
|
d56ead |
return SLBT_NESTED_ERROR(dctx);
|
|
|
660491 |
}
|
|
|
5e1c21 |
}
|
|
|
dc77cb |
}
|
|
|
dc77cb |
|
|
|
660491 |
/* restore execution context */
|
|
|
660491 |
ectx->argv = oargv;
|
|
|
660491 |
|
|
|
6529aa |
/* create symlink */
|
|
|
6529aa |
if (symlink(atarget,tmplnk))
|
|
|
d56ead |
return SLBT_SYSTEM_ERROR(dctx);
|
|
|
6529aa |
|
|
|
d56ead |
return rename(tmplnk,lnkname)
|
|
|
d56ead |
? SLBT_SYSTEM_ERROR(dctx)
|
|
|
d56ead |
: 0;
|
|
|
6529aa |
}
|