/*******************************************************************/ /* slibtool: a skinny libtool implementation, written in C */ /* Copyright (C) 2016 Z. Gilboa */ /* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ /*******************************************************************/ #include #include #include #include #include "slibtool_symlink_impl.h" int slbt_create_symlink( const struct slbt_driver_ctx * dctx, struct slbt_exec_ctx * ectx, const char * target, char * lnkname, bool flawrapper) { const char * slash; char * ln[5]; char * dotdot; char tmplnk [PATH_MAX]; char atarget[PATH_MAX]; /* atarget */ if ((slash = strrchr(target,'/'))) slash++; else slash = target; dotdot = flawrapper ? "../" : ""; if ((size_t)snprintf(atarget,sizeof(atarget),"%s%s", dotdot,slash) >= sizeof(atarget)) return -1; /* tmplnk */ if ((size_t)snprintf(tmplnk,sizeof(tmplnk),"%s.symlink.tmp", lnkname) >= sizeof(tmplnk)) return -1; /* ln argv (fake) */ ln[0] = "ln"; ln[1] = "-s"; ln[2] = atarget; ln[3] = lnkname; ln[4] = 0; ectx->argv = ln; /* step output */ if (!(dctx->cctx->drvflags & SLBT_DRIVER_SILENT)) { if ((dctx->cctx->mode == SLBT_MODE_LINK) && slbt_output_link(dctx,ectx)) return -1; else if (slbt_output_install(dctx,ectx)) return -1; } /* create symlink */ if (symlink(atarget,tmplnk)) return -1; return rename(tmplnk,lnkname); }