Blame src/internal/slibtool_symlink_impl.c

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
6529aa
#include "slibtool_symlink_impl.h"
6529aa
6529aa
int slbt_create_symlink(
6529aa
	const struct slbt_driver_ctx *	dctx,
6529aa
	struct slbt_exec_ctx *		ectx,
6529aa
	const char *			target,
6529aa
	char *				lnkname,
6529aa
	bool				flawrapper)
6529aa
{
6529aa
	const char *	slash;
6529aa
	char *		ln[5];
6529aa
	char *		dotdot;
6529aa
	char		tmplnk [PATH_MAX];
6529aa
	char		atarget[PATH_MAX];
6529aa
6529aa
	/* atarget */
6529aa
	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))
6529aa
		return -1;
6529aa
6529aa
	/* tmplnk */
6529aa
	if ((size_t)snprintf(tmplnk,sizeof(tmplnk),"%s.symlink.tmp",
6529aa
			lnkname) >= sizeof(tmplnk))
6529aa
		return -1;
6529aa
6529aa
	/* ln argv (fake) */
6529aa
	ln[0] = "ln";
6529aa
	ln[1] = "-s";
6529aa
	ln[2] = atarget;
6529aa
	ln[3] = lnkname;
6529aa
	ln[4] = 0;
6529aa
	ectx->argv = ln;
6529aa
6529aa
	/* step output */
6529aa
	if (!(dctx->cctx->drvflags & SLBT_DRIVER_SILENT))
6529aa
		if (slbt_output_link(dctx,ectx))
6529aa
			return -1;
6529aa
6529aa
	/* create symlink */
6529aa
	if (symlink(atarget,tmplnk))
6529aa
		return -1;
6529aa
6529aa
	return rename(tmplnk,lnkname);
6529aa
}