beta-0.89.2
[luatex.git] / source / texk / texlive / tl_scripts / texlinks.sh
blob91540eac147cd9018c806e2f36a9751e9e7c8008
1 #!/bin/sh
2 # $Id: texlinks.sh 36938 2015-04-19 21:15:06Z karl $
4 # Thomas Esser, 1999, 2002, 2003. public domain.
6 # texlinks: script to maintain symlinks from format to engine. Interprets
7 # the lines given in fmtutil.cnf.
9 # History:
10 # (Further changes in ChangeLog.)
11 # Tue Oct 9 14:23:01 BST 2007
12 # Added unlink option (-u) to aid OpenBSD package uninstall
13 # Edd Barrett <vext01@gmail.com>
14 # Sun Aug 28 21:41:06 CEST 2005
15 # remove special cases for csplain,cslatex,pdfcslatex,pdfcsplain
16 # Fr Apr 8 19:15:05 CEST 2005
17 # cleanup now has an argument for the return code
18 # So Mar 27 18:52:06 CEST 2005
19 # honor $TMPDIR, $TEMP and $TMP, not just $TMP
20 # Mon May 10 20:52:48 CEST 2004
21 # kpseaccess instead of access
22 # Thu Dec 25 22:11:53 CET 2003, te:
23 # add version string
24 # Tue Apr 9 22:46:34 CEST 2002, te:
25 # do not create symlinks for cont-??, metafun and mptopdf
27 test -f /bin/sh5 && test -z "$RUNNING_SH5" \
28 && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
29 && { RUNNING_SH5=true; export RUNNING_SH5; exec /bin/sh5 $0 ${1+"$@"}; }
30 unset RUNNING_SH5
32 test -f /bin/bsh && test -z "$RUNNING_BSH" \
33 && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \
34 && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; }
35 unset RUNNING_BSH
37 export PATH
39 # hack around a bug in zsh:
40 test -n "${ZSH_VERSION+set}" && alias -g '${1+"$@"}'='"$@"'
42 version='$Id: texlinks.sh 36938 2015-04-19 21:15:06Z karl $'
43 progname=texlinks
44 cnf=fmtutil.cnf # name of the config file
46 usage='Usage: texlinks [OPTION]... [DIRECTORY]...
48 Create symbolic links format -> engine according to fmtutil setup.
50 Mandatory arguments to long options are mandatory for short options too.
51 -e, --exeext EXT append EXT to symlink targets (default: none)
52 -f, --cnffile FILE use FILE as config file (default: fmtutil.cnf)
53 -m, --multiplatform operate in all platform specific directories
54 (default: operate only in directory for this platform)
55 -q, --quiet silently skip existing scripts / binaries
56 (default: issue warning)
57 -s, --silent same as -q
58 -u, --unlink remove symlinks created by texlinks
59 -v, --verbose enable verbose messages (default: off)
60 -h, --help show this help text
61 --version show version string
63 The DIRECTORY arguments are an optional list of directories in which to
64 operate. If no directories are specified and --multiplatform is
65 likewise not specified, the directory of this script itself is used.
66 With --multiplatform, all child dirs of an upper-level bin/ dir are used.
68 Report bugs to: tex-k@tug.org
69 TeX Live home page: <http://tug.org/texlive/>
72 # print `errmsg' to stderr and exit with error code 1:
73 abort() { errmsg "texlinks: $1."; cleanup 1; }
75 # error message to stderr:
76 errmsg() { echo "$@" >&2; }
78 # give message to stderr only if "verbose" mode is on:
79 verbose_echo() { $verbose && errmsg "$@"; }
81 # in verbose mode: show command that is executed:
82 verbose_do() { verbose_echo "$@"; "$@"; }
84 # clean up the temp area and exit with proper exit status:
85 cleanup()
87 rc=$1
88 $needsCleanup && test -n "$tmpdir" && test -d "$tmpdir" \
89 && { rm -f "$tmpdir"/*; cd /; rmdir "$tmpdir"; }
90 exit $rc
93 ###############################################################################
94 # setupTmpDir()
95 # set up a temp directory and a trap to remove it
96 ###############################################################################
97 setupTmpDir()
99 $needsCleanup && return
101 trap 'cleanup 1' 1 2 3 7 13 15
102 needsCleanup=true
103 (umask 077; mkdir "$tmpdir") \
104 || abort "could not create directory \`$tmpdir'"
108 # search a binary along $PATH:
109 check_for_binary()
111 testbin=$1
112 set x `echo "$PATH" | sed 's/^:/.:/; s/:$/:./; s/::/:.:/g; s/:/ /g'`; shift
113 for i
115 if [ -x "$i/$testbin" ]; then
116 echo "$i/$testbin"
117 return 0
119 done
120 return 1
124 ###############################################################################
125 # install_link(dest src)
126 # create a symlink like ln -s dest src, but make sure that src is not
127 # an existing binary, possibly adding the executable extension if
128 # passed on the command.
129 ###############################################################################
130 install_link()
132 # make symlink src -> dest
133 dest=$1; src=$2
135 case $src in
136 */mf)
137 if test "$dest" = mf-nowin; then
138 if test -f $selfautoloc/mfw; then
139 dest=mfw # name for windows-enabled mf, once upon a time
140 verbose_echo "both mfw and mf-nowin exists, $src linked to $dest"
142 if test -f $selfautoloc/mf && test -f $selfautoloc/mf-nowin; then
143 # have both mf and mf-nowin binaries. no link.
144 verbose_echo "skipped metafont symlink $src -> $dest (special case)"
145 return
149 esac
151 # append .exe if supplied (for cygwin).
152 test -n "$exeext" && dest="$dest$exeext"
154 case $src in
155 */cont-??|*/mptopdf)
156 # context includes wrapper scripts that create/run these.
157 verbose_echo "skipped ConTeXtish symlink $src -> $dest (special case)"
160 test "x$src" != "x`(ls -ld $src | awk '{print $NF}') 2>/dev/null`" &&
161 rm -f "$src"
163 if test -f "$src"; then
164 if $silent; then :; else
165 # i.e., the rm failed.
166 errmsg "install_link $src -> $dest failed: file already exists."
168 else
169 if echo "$src" | grep '/pdfcsplain$' >/dev/null; then
170 # at p.olsak insistence: we have three pdfcsplain entries in
171 # fmtutil.cnf with different engines, but the executable link
172 # must point to pdftex.
173 verbose_echo "forcing pdfcsplain destination to be pdftex"
174 dest=pdftex$exeext
176 verbose_do ln -s "$dest" "$src"
179 esac
182 ###############################################################################
183 # search_symlinkdir()
184 # look if $PATH has only symlinks to the real binaries and find that
185 # directory. Also check if this directory is writable.
186 ###############################################################################
187 search_symlinkdir()
189 kpsewhich=`check_for_binary kpsewhich`
190 test -z "$kpsewhich" && return 1
191 symlinkdir=`echo $kpsewhich | sed 's@/*kpsewhich$@@'`
192 kpseaccess -w "$symlinkdir" || return 1
193 touch "$symlinkdir/tl$$"
194 if test -f "$selfautoloc/tl$$"; then
195 rm -f "$symlinkdir/tl$$"
196 return 1
197 else
198 rm -f "$symlinkdir/tl$$"
199 return 0
203 ###############################################################################
204 # upd_symlinkdir()
205 # if $PATH has only symlinks to the real binaries, update that directory
206 # that holds the symlinks
207 ###############################################################################
208 upd_symlinkdir()
210 search_symlinkdir || return 0
211 for i in `sed 's@ .*@@' cnf_file_ln.$$`; do
212 install_link "$selfautoloc/$i" "$symlinkdir/$i"
213 done
216 ###############################################################################
217 # rm_link()
218 # Delete a previously installed link
219 ###############################################################################
220 rm_link()
222 link=$1;
223 if test -e $link; then
224 if test -h $link; then
225 verbose_do rm -Rf $link
226 else
227 verbose_echo "kept $link, since not a symlink"
229 else
230 verbose_echo "skipped $link, non-existent"
234 ###############################################################################
235 # main()
236 # parse commandline arguments, initialize variables,
237 # switch into temp. direcrory, execute desired command
238 ###############################################################################
239 main()
241 cnf_file= # global variable: full name of the config file
242 dirs=
243 needsCleanup=false
245 exeext=
246 multiplatform=false
247 verbose=false
248 unlink=false
249 silent=false
250 thisdir=`pwd`
251 : ${KPSE_DOT=$thisdir}; export KPSE_DOT
252 selfautoloc=`kpsewhich --expand-var='$SELFAUTOLOC'`
253 while
254 case $1 in
255 --h*|-h)
256 echo "$usage"; exit 0;;
257 --version)
258 echo "$progname version $version"; exit 0;;
259 --cnffile|-f)
260 shift; cnf_file=$1;;
261 --e*|-e) shift; exeext=$1;;
262 --m*|-m) multiplatform=true;;
263 --s*|-s|--q*|-q) silent=true;;
264 --u*|-u) unlink=true;;
265 --v*|-v) verbose=true;;
266 -*) errmsg "fmtutil: unknown option \`$1' ignored.";;
267 *) break;;
268 esac
269 do test $# -gt 0 && shift; done
270 dirs="$*"
272 # if no cnf_file from command-line, look it up with kpsewhich:
273 test -z "$cnf_file" && cnf_file=`kpsewhich --format='web2c files' $cnf`
274 test -f "$cnf_file" || abort "config file \`$cnf' not found"
277 tmpdir=${TMPDIR-${TEMP-${TMP-/tmp}}}/texlinks.$$
278 setupTmpDir
279 cd "$tmpdir" || cleanup 1
281 sed '/^[ ]*#/d; /^[ ]*$/d' $cnf_file \
282 | awk '{print $1, $2}' > cnf_file_ln.$$
284 if test -z "$dirs"; then
285 if test $multiplatform = true; then
286 case $selfautoloc in
287 */bin) dirs=$selfautoloc;;
288 *) parent=`kpsewhich --expand-var='$SELFAUTODIR'`
289 dirs=`find $parent -type f -name kpsewhich -print \
290 | sed 's@/kpsewhich$@@'`;;
291 esac
292 else
293 dirs=$selfautoloc
297 for d in $dirs; do
298 kpseaccess -w $d \
299 || { errmsg "$d: no write permissions. Skipping..."; continue; }
300 # cnf_file_ln.$$ has lines with "format engine" pairs
301 set x `cat cnf_file_ln.$$`; shift
302 while test $# != 0; do
303 fmt=$1; engine=$2; shift; shift
305 # Some broken shells destroy the positional arguments when calling a
306 # shellfunction. Therefore, we save and restore them "by hand" in the
307 # main_args_while variable.
308 main_args_while="$@"
310 test "x$fmt" = "x$engine" && continue
311 if test -f "$d/$engine$exeext"; then
312 case $unlink in
313 true)
314 rm_link "$d/$fmt";;
316 install_link "$engine" "$d/$fmt";;
317 esac
318 else
319 verbose_echo "skipped $d/$engine, engine does not exist"
322 # restore positional arguments:
323 set x $main_args_while; shift
325 done
326 done
327 upd_symlinkdir
330 main ${1+"$@"}
332 # set successful return code
333 cleanup 0