]> git.stg.codes - stg.git/blob - doc/xslt/install.sh
Added local binding.
[stg.git] / doc / xslt / install.sh
1 #!/bin/bash
2 # $Id: install.sh 7942 2008-03-26 06:08:08Z xmldoc $
3 # $Source$ #
4
5 # install.sh - Set up user environment for a XML/XSLT distribution
6
7 # This is as an interactive installer for updating your
8 # environment to use an XML/XSLT distribution such as the DocBook
9 # XSL Stylesheets. Its main purpose is to configure your
10 # environment with XML catalog data and schema "locating rules"
11 # data provided in the XML/XSLT distribution.
12 #
13 # Although this installer was created for the DocBook project, it
14 # is a general-purpose tool that can be used with any XML/XSLT
15 # distribution that provides XML/SGML catalogs and locating rules.
16 #
17 # This script is mainly intended to make things easier for you if
18 # you want to install a particular XML/XSLT distribution that has
19 # not (yet) been packaged for your OS distro (Debian, Fedora,
20 # whatever), or to use "snapshot" or development releases 
21 #
22 # It works by updating your shell startup file (e.g., .bashrc and
23 # .cshrc) and .emacs file and by finding or creating a writable
24 # CatalogManager.properties file to update.
25 #
26 # It makes backup copies of any files it touches, and also
27 # generates a uninstall.sh script for reverting its changes.
28 #
29 # In the same directory where it is located, it expects to find
30 # the following four files:
31 #   - locatingrules.xml
32 #   - catalog.xml
33 #   - catalog
34 #   - .urilist
35 # And if it's unable to locate a CatalogManager.properties file in
36 # your environment, it expects to find an "example" one in the
37 # same directory as itself, which it copies over to your
38 # ~/.resolver directory.
39 #
40 # If the distribution contains any executables, change the value
41 # of the thisBinDir to a colon-separated list of the pathnames of
42 # the directories that contain those executables.
43
44 # mydir is the "canonical" absolute pathname for install.sh
45 mydir=$(cd -P $(dirname $0) && pwd -P) || exit 1
46
47 thisLocatingRules=$mydir/locatingrules.xml
48 thisXmlCatalog=$mydir/catalog.xml
49 thisSgmlCatalog=$mydir/catalog
50
51 # .urilist file contains a list of pairs of local pathnames and
52 # URIs to test for catalog resolution
53 thisUriList=$mydir/.urilist
54 exampleCatalogManager=$mydir/.CatalogManager.properties.example
55 thisCatalogManager=$HOME/.resolver/CatalogManager.properties
56
57 # thisBinDir directory is a colon-separated list of the pathnames
58 # to all directories that contain executables provided with the
59 # distribution (for example, the DocBook XSL Stylesheets
60 # distribution contains a "docbook-xsl-update" convenience script
61 # for rsync'ing up to the latest docbook-xsl snapshot). The
62 # install.sh script adds the value of thisBinDir to your PATH
63 # environment variable
64 thisBinDir=$mydir/tools/bin
65
66 emit_message() {
67   echo "$1" 1>&2
68 }
69
70 if [ ! "${*#--batch}" = "$*" ]; then
71   batchmode="Yes";
72 else
73   batchmode="No";
74   emit_message
75   if [ ! "$1" = "--test" ]; then 
76     emit_message "NOTE: For non-interactive installs/uninstalls, use --batch"
77     if [ ! "$1" = "--uninstall" ]; then
78       emit_message
79     fi
80   fi
81 fi
82
83 osName="Unidentified"
84 if uname -s | grep -qi "cygwin"; then
85   osName="Cygwin"
86 fi
87
88 classPathSeparator=":"
89 if [ "$osName" = "Cygwin" ]; then
90   thisJavaXmlCatalog=$(cygpath -m $thisXmlCatalog)
91   classPathSeparator=";"
92 else
93   thisJavaXmlCatalog=$thisXmlCatalog
94 fi
95
96 main() {
97   removeOldFiles
98   checkRoot
99   updateCatalogManager
100   checkForResolver
101   writeDotFiles
102   updateUserStartupFiles
103   updateUserDotEmacs
104   writeUninstallFile
105   writeTestFile
106   printExitMessage
107 }
108
109 removeOldFiles() {
110   rm -f $mydir/.profile.incl
111   rm -f $mydir/.cshrc.incl
112   rm -f $mydir/.emacs.el
113 }
114
115 checkRoot() {
116   if [ $(id -u)  == "0" ]; then
117     cat 1>&2 <<EOF
118
119 WARNING: This install script is meant to be run as a non-root
120          user, but you are running it as root.
121
122 EOF
123     read -s -n1 -p "Are you sure you want to continue? [No] "
124     emit_message "$REPLY"
125     case $REPLY in
126       [yY])
127       emit_message
128       ;;
129       *) emit_message "OK, exiting without making changes."
130       exit
131       ;;
132     esac
133   fi
134   return 0
135 }
136
137 updateCatalogManager() {
138
139   #  - finds or creates a writable CatalogManager.properties file
140   #
141   #  - adds the catalog.xml file for this distribution to the
142   #    CatalogManager.properties file found
143
144   if [ -z "$CLASSPATH" ]; then
145     cat 1>&2 <<EOF
146
147 NOTE: There is no CLASSPATH variable set in your environment.
148       No attempt was made to find a CatalogManager.properties
149       file.  Using $thisCatalogManager instead
150 EOF
151   else
152     # split CLASSPATH in a list of pathnames by replacing all separator
153     # characters with spaces
154     if [ "$osName" = "Cygwin" ]; then
155       pathnames=$(echo $CLASSPATH | tr ";" " ")
156     else
157       pathnames=$(echo $CLASSPATH | tr ":" " ")
158     fi
159     for path in $pathnames; do
160     if [ "$osName" = "Cygwin" ]; then
161       path=$(cygpath -u $path)
162     fi
163       # strip out trailing slash from pathname
164       path=$(echo $path | sed 's/\/$//')
165       # find CatalogManager.properties file
166       if [ -f $path/CatalogManager.properties ];
167       then
168         existingCatalogManager=$path/CatalogManager.properties
169         break
170       fi
171     done
172   fi
173   # end of CLASSPATH check
174
175   if [ -w "$existingCatalogManager" ]; then
176     # existing CatalogManager.properties was found and it is
177     # writable, so use it
178     myCatalogManager=$existingCatalogManager
179   else
180     if [ -f "$existingCatalogManager" ]; then
181       # a non-writable CatalogManager.properties exists, so emit a
182       # note saying that it won't be used
183       cat 1>&2 <<EOF
184 NOTE: $existingCatalogManager file found,
185       but you don't have permission to write to it.
186       Will instead use:
187       $thisCatalogManager
188 EOF
189     else
190       # CLASSPATH is set, but no CatalogManager.properties found
191       if [ -n "$CLASSPATH" ]; then
192         cat 1>&2 <<EOF
193 NOTE: No CatalogManager.properties found from CLASSPATH.
194       Will instead use:
195       $thisCatalogManager
196 EOF
197       fi
198     fi
199     if [ "$batchmode" = "Yes" ]; then
200       emit_message
201     fi
202     # end of check for existing writable CatalogManager.properties
203
204     if [ -f $thisCatalogManager ]; then
205       myCatalogManager=$thisCatalogManager
206     else
207       REPLY=""
208       if [ ! "$batchmode" = "Yes" ]; then
209         emit_message
210         read -s -n1 -p "Create $thisCatalogManager file? [Yes] "
211         emit_message "$REPLY"
212         emit_message
213       fi
214       case $REPLY in
215         [nNqQ])
216         emitNoChangeMsg
217         ;;
218         *)
219         if [ ! -d "${thisCatalogManager%/*}" ]; then
220           mkdir -p ${thisCatalogManager%/*}
221         fi
222         cp $mydir/.CatalogManager.properties.example $thisCatalogManager || exit 1
223         emit_message "NOTE: Created the following file:"
224         emit_message "      $thisCatalogManager"
225         myCatalogManager=$thisCatalogManager
226         ;;
227       esac
228       # end of creating "private" CatalogManager.properties
229     fi
230     # end of check for "private" CatalogManager.properties
231   fi
232   # end of check finding/creating writable CatalogManager.properties
233
234   if [ -n "$myCatalogManager" ]; then
235     etcXmlCatalog=
236     catalogsLine=$(grep "^catalogs=" $myCatalogManager)
237     if [ -f /etc/xml/catalog ] && [ "$osName" != "Cygwin" ] \
238       && [ "${catalogsLine#*/etc/xml/catalog*}" = "$catalogsLine" ]; then
239       cat 1>&2 <<EOF
240
241 WARNING: /etc/xml/catalog exists but was not found in:
242          $myCatalogManager
243          If /etc/xml/catalog file has content, you probably
244          should reference it in:
245          $myCatalogManager
246          This installer can automatically add it for you,
247          but BE WARNED that once it has been added, the
248          uninstaller for this distribution CANNOT REMOVE IT
249          automatically during uninstall. If you no longer want
250          it included, you will need to remove it manually.
251
252 EOF
253       REPLY=""
254       if [ ! "$batchmode" = "Yes" ]; then
255         read -s -n1 -p "Add /etc/xml/catalog to $myCatalogManager? [Yes] "
256         emit_message "$REPLY"
257       fi
258       case $REPLY in
259         [nNqQ])
260         emit_message
261         ;;
262         *)
263         etcXmlCatalog=/etc/xml/catalog
264         ;;
265       esac
266     fi
267
268     catalogBackup="$myCatalogManager.$$.bak"
269     if [ ! -w "${myCatalogManager%/*}" ]; then
270       emit_message
271       emit_message "WARNING: ${myCatalogManager%/*} directory is not writable."
272       emit_message
273       emitNoChangeMsg
274     else
275       REPLY=""
276       if [ ! "$batchmode" = "Yes" ]; then
277         emit_message
278         emit_message "Add $thisJavaXmlCatalog"
279         read -s -n1 -p "to $myCatalogManager file? [Yes] "
280         emit_message "$REPLY"
281         emit_message
282       fi
283       case $REPLY in
284         [nNqQ])
285         emitNoChangeMsg
286         ;;
287         *)
288         if [ "$catalogsLine" ] ; then
289           if [ "${catalogsLine#*$thisJavaXmlCatalog*}" != "$catalogsLine" ]; then
290             emit_message "NOTE: $thisJavaXmlCatalog"
291             emit_message "      already in:"
292             emit_message "      $myCatalogManager"
293           else
294             mv $myCatalogManager $catalogBackup || exit 1
295             sed "s#^catalogs=\(.*\)\$#catalogs=$thisJavaXmlCatalog;\1;$etcXmlCatalog#" $catalogBackup \
296             | sed 's/;\+/;/' | sed 's/;$//' > $myCatalogManager || exit 1
297             emit_message "NOTE: Successfully updated the following file:"
298             emit_message "      $myCatalogManager"
299             emit_message "      Backup written to:"
300             emit_message "      $catalogBackup"
301           fi
302         else
303           mv $myCatalogManager $catalogBackup || exit 1
304           cp $catalogBackup $myCatalogManager
305           echo "catalogs=$thisJavaXmlCatalog;$etcXmlCatalog" \
306           | sed 's/;\+/;/' | sed 's/;$//' >> $myCatalogManager || exit 1
307           emit_message "NOTE: \"catalogs=\" line added to $myCatalogManager."
308           emit_message "      Backup written to $catalogBackup"
309         fi
310         ;;
311       esac
312       # end of backing up and updating CatalogManager.properties
313     fi
314   fi
315   # end of CatalogManager.properties updates
316
317   if [ "$osName" = "Cygwin" ]; then
318     myCatalogManager=$(cygpath -m $myCatalogManager)
319   fi
320   return 0
321 }
322
323 writeDotFiles() {
324   while read; do
325     echo "$REPLY" >> $mydir/.profile.incl
326   done <<EOF
327 # $thisBinDir is not in PATH, so add it
328 if [ "\${PATH#*$thisBinDir*}" = "\$PATH" ]; then
329   PATH="$thisBinDir:\$PATH"
330   export PATH
331 fi
332 if [ -z "\$XML_CATALOG_FILES" ]; then
333   XML_CATALOG_FILES="$thisXmlCatalog"
334 else
335   # $thisXmlCatalog is not in XML_CATALOG_FILES, so add it
336   if [ "\${XML_CATALOG_FILES#*$thisXmlCatalog*}" = "\$XML_CATALOG_FILES" ]; then
337     XML_CATALOG_FILES="$thisXmlCatalog \$XML_CATALOG_FILES"
338   fi
339 fi
340 # /etc/xml/catalog exists but is not in XML_CATALOG_FILES, so add it
341 if [ -f /etc/xml/catalog ] && \
342   [ "\${XML_CATALOG_FILES#*/etc/xml/catalog*}" = "\$XML_CATALOG_FILES" ]; then
343   XML_CATALOG_FILES="\$XML_CATALOG_FILES /etc/xml/catalog"
344 fi
345 export XML_CATALOG_FILES
346
347 if [ -z "\$SGML_CATALOG_FILES" ]; then
348   SGML_CATALOG_FILES="$thisSgmlCatalog"
349 else
350   # $thisSgmlCatalog is not in SGML_CATALOG_FILES, so add it
351   if [ "\${SGML_CATALOG_FILES#*$thisSgmlCatalog}" = "\$SGML_CATALOG_FILES" ]; then
352     SGML_CATALOG_FILES="$thisSgmlCatalog:\$SGML_CATALOG_FILES"
353   fi
354 fi
355 # /etc/sgml/catalog exists but is not in SGML_CATALOG_FILES, so add it
356 if [ -f /etc/sgml/catalog ] && \
357   [ "\${SGML_CATALOG_FILES#*/etc/sgml/catalog*}" = "\$SGML_CATALOG_FILES" ]; then
358   SGML_CATALOG_FILES="\$SGML_CATALOG_FILES:/etc/sgml/catalog"
359 fi
360 export SGML_CATALOG_FILES
361 EOF
362
363 while read; do
364   echo "$REPLY" >> $mydir/.cshrc.incl
365 done <<EOF
366 # $thisBinDir is not in PATH, so add it
367 if ( "\\\`echo \$PATH | grep -v $thisBinDir\\\`" != "" ) then
368   setenv PATH "$thisBinDir:\$PATH"
369 endif
370 if ( ! $\?XML_CATALOG_FILES ) then
371   setenv XML_CATALOG_FILES "$thisXmlCatalog"
372 # $thisXmlCatalog is not in XML_CATALOG_FILES, so add it
373 else if ( "\\\`echo \$XML_CATALOG_FILES | grep -v $thisXmlCatalog\\\`" != "" ) then
374   setenv XML_CATALOG_FILES "$thisXmlCatalog \$XML_CATALOG_FILES"
375 endif
376 endif
377 # /etc/xml/catalog exists but is not in XML_CATALOG_FILES, so add it
378 if ( -f /etc/xml/catalog && "\\\`echo \$XML_CATALOG_FILES | grep -v /etc/xml/catalog\\\`" != "" ) then
379   setenv XML_CATALOG_FILES "\$XML_CATALOG_FILES /etc/xml/catalog"
380 endif
381
382 endif
383 if ( ! $\?SGML_CATALOG_FILES ) then
384   setenv SGML_CATALOG_FILES "$thisSgmlCatalog"
385 else if ( "\\\`echo \$SGML_CATALOG_FILES | grep -v $thisSgmlCatalog\\\`" != "" ) then
386   setenv SGML_CATALOG_FILES "$thisSgmlCatalog:\$SGML_CATALOG_FILES"
387 endif
388 endif
389 # /etc/SGML/catalog exists but is not in SGML_CATALOG_FILES, so add it
390 if ( -f /etc/sgml/catalog && "\\\`echo \$SGML_CATALOG_FILES | grep -v /etc/sgml/catalog\\\`" != "" ) then
391   setenv SGML_CATALOG_FILES {\$SGML_CATALOG_FILES}:/etc/sgml/catalog
392 endif
393 EOF
394
395 if [ -n "$myCatalogManager" ]; then
396   myCatalogManagerDir=${myCatalogManager%/*}
397   while read; do
398     echo "$REPLY" >> $mydir/.profile.incl
399   done <<EOF
400
401
402 if [ -z "\$CLASSPATH" ]; then
403   CLASSPATH="$myCatalogManagerDir"
404 else
405   # $myCatalogManagerDir is not in CLASSPATH, so add it
406   if [ "\${CLASSPATH#*$myCatalogManagerDir*}" = "\$CLASSPATH" ]; then
407     CLASSPATH="$myCatalogManagerDir$classPathSeparator\$CLASSPATH"
408   fi
409 fi
410 export CLASSPATH
411 EOF
412
413   while read; do
414     echo "$REPLY" >> $mydir/.cshrc.incl
415   done <<EOF
416
417
418 if ( ! $\?CLASSPATH ) then
419   setenv CLASSPATH "$myCatalogManagerDir"
420 # $myCatalogManagerDir is not in CLASSPATH, so add it
421 else if ( "\\\`echo \$CLASSPATH | grep -v $myCatalogManagerDir\\\`" != "" ) then
422   setenv CLASSPATH "$myCatalogManagerDir$classPathSeparator\$CLASSPATH"
423 endif
424 endif
425 EOF
426
427 fi
428
429 while read; do
430   echo "$REPLY" >> $mydir/.emacs.el
431 done <<EOF
432 (add-hook
433   'nxml-mode-hook
434   (lambda ()
435     (setq rng-schema-locating-files-default
436           (append '("$thisLocatingRules")
437                   rng-schema-locating-files-default ))))
438 EOF
439
440 return 0
441 }
442
443 updateUserStartupFiles() {
444   if [ ! "$batchmode" = "Yes" ]; then
445   cat 1>&2 <<EOF
446
447 NOTE: To source your environment correctly for using the catalog
448       files in this distribution, you need to update one or more
449       of your shell startup files. This installer can
450       automatically make the necessary changes. Or, if you prefer,
451       you can make the changes manually.
452
453 EOF
454   else
455     emit_message
456   fi
457
458   # if running csh or tcsh, target .cshrc and .tcshrc files for
459   # update; otherwise, target .bash_* and .profiles
460
461   parent=$(ps -p $PPID | grep "/")
462   if [ "${parent#*csh}" != "$parent" ] || [ "${parent#*tcsh}" != "$parent" ]; then
463     myStartupFiles=".cshrc .tcshrc"
464     appendLine="source $mydir/.cshrc.incl"
465   else
466     myStartupFiles=".bash_profile .bash_login .profile .bashrc"
467     appendLine=". $mydir/.profile.incl"
468   fi
469
470   for file in $myStartupFiles; do
471     if [ -f "$HOME/$file" ]; then
472       dotFileBackup=$HOME/$file.$$.bak
473       REPLY=""
474       if [ ! "$batchmode" = "Yes" ]; then
475         read -s -n1 -p "Update $HOME/$file? [Yes] "
476         emit_message "$REPLY"
477       fi
478       case $REPLY in
479         [nNqQ])
480         cat 1>&2 <<EOF
481
482 NOTE: No change made to $HOME/$file. You either need
483       to add the following line to it, or manually source
484       the shell environment for this distribution each
485       time you want use it.
486
487 $appendLine
488
489 EOF
490         ;;
491         *)
492         lineExists="$(grep "$appendLine" $HOME/$file )"
493         if [ ! "$lineExists" ]; then
494           mv $HOME/$file $dotFileBackup     || exit 1
495           cp $dotFileBackup $HOME/$file     || exit 1
496           echo "$appendLine" >> $HOME/$file || exit 1
497           cat 1>&2 <<EOF
498 NOTE: Successfully updated the following file:
499       $HOME/$file 
500       Backup written to:
501       $dotFileBackup
502
503 EOF
504         else
505           cat 1>&2 <<EOF
506 NOTE: The following file already contains information for this
507       distribution, so I did not update it.
508       $HOME/$file
509
510 EOF
511         fi
512         ;;
513       esac
514     fi
515   done
516   if [ -z "$dotFileBackup" ]; then
517     if [ ! "$batchmode" = "Yes" ]; then
518       emit_message
519     fi
520     cat 1>&2 <<EOF
521 NOTE: No shell startup files updated. You can source the
522       environment for this distribution manually, each time you
523       want to use it, by typing the following.
524
525 $appendLine
526
527 EOF
528   fi
529 }
530
531 updateUserDotEmacs() {
532   if [ -f $thisLocatingRules ]; then
533   cat 1>&2 <<EOF
534
535 NOTE: This distribution includes a "schema locating rules" file
536       for Emacs/nXML.  To use it, you should update either your
537       .emacs or .emacs.el file.  This installer can automatically
538       make the necessary changes. Or, if you prefer, you can make
539       the changes manually.
540
541 EOF
542
543   emacsAppendLine="(load-file \"$mydir/.emacs.el\")"
544   myEmacsFile=
545   for file in .emacs .emacs.el; do
546     if [ -f "$HOME/$file" ]; then
547       myEmacsFile=$HOME/$file
548       break
549     fi
550   done
551   if [ ! -f "$myEmacsFile" ]; then
552     REPLY=""
553     if [ ! "$batchmode" = "Yes" ]; then
554       read -s -n1 -p "No .emacs or .emacs.el file. Create one? [No] "
555       emit_message "$REPLY"
556       emit_message
557     fi
558     case $REPLY in
559       [yY])
560       myEmacsFile=$HOME/.emacs
561       touch $myEmacsFile
562       ;;
563       *)
564       cat 1>&2 <<EOF
565 NOTE: No Emacs changes made. To use this distribution with,
566       Emacs/nXML, you can create a .emacs file and manually add
567       the following line to it, or you can run it as a command
568       within Emacs.
569
570 $emacsAppendLine
571
572 EOF
573       ;;
574     esac
575   fi
576   if [ -n "$myEmacsFile" ]; then
577     REPLY=""
578     if [ ! "$batchmode" = "Yes" ]; then
579       read -s -n1 -p  "Update $myEmacsFile? [Yes] "
580       emit_message "$REPLY"
581       emit_message
582     fi
583     case $REPLY in
584       [nNqQ])
585       cat 1>&2 <<EOF
586
587 NOTE: No change made to $myEmacsFile. To use this distribution
588       with Emacs/nXML, you can manually add the following line
589       to your $myEmacsFile, or you can run it as a command
590       within Emacs.
591
592 $emacsAppendLine
593
594 EOF
595       ;;
596       *)
597       lineExists="$(grep "$emacsAppendLine" $myEmacsFile)"
598       if [ ! "$lineExists" ]; then
599         dotEmacsBackup=$myEmacsFile.$$.bak
600         mv $myEmacsFile $dotEmacsBackup    || exit 1
601         cp $dotEmacsBackup $myEmacsFile    || exit 1
602         echo "$emacsAppendLine" >> $myEmacsFile || exit 1
603         cat 1>&2 <<EOF
604 NOTE: Successfully updated the following file:
605       $myEmacsFile
606       Backup written to:
607       $dotEmacsBackup
608 EOF
609       else
610         cat 1>&2 <<EOF
611
612 NOTE: The following file already contains information for this
613       distribution, so I did not update it.
614       $myEmacsFile
615
616 EOF
617       fi
618       ;;
619     esac
620   fi
621 fi
622 }
623
624 uninstall() {
625   if [ ! "$batchmode" = "Yes" ]; then
626   cat 1>&2 <<EOF
627
628 NOTE: To "uninstall" this distribution, the changes made to your
629       CatalogManagers.properties, startup files, and/or .emacs
630       file need to be reverted. This uninstaller can automatically
631       revert them.  Or, if you prefer, you can revert them manually.
632
633 EOF
634   fi
635
636   if [ "$osName" = "Cygwin" ]; then
637     thisXmlCatalog=$thisJavaXmlCatalog
638   fi
639
640   # make "escaped" version of PWD to use with sed and grep
641   escapedPwd=$(echo $mydir | sed "s#/#\\\\\/#g")
642
643   # check to see if a non-empty value for catalogManager was fed
644   # to uninstaller.
645   if [ -n ${1#--catalogManager=} ]; then
646     myCatalogManager=${1#--catalogManager=}
647     catalogBackup="$myCatalogManager.$$.bak"
648     catalogsLine=$(grep "^catalogs=" $myCatalogManager)
649     if [ "$catalogsLine" ] ; then
650       if [ "${catalogsLine#*$thisXmlCatalog*}" != "$catalogsLine" ]; then
651         REPLY=""
652         if [ ! "$batchmode" = "Yes" ]; then
653           read -s -n1 -p "Revert $myCatalogManager? [Yes] "
654           emit_message "$REPLY"
655         fi
656         case $REPLY in
657           [nNqQ]*)
658           cat 1>&2 <<EOF
659
660 NOTE: No change made to $myCatalogManager. You need to manually
661       remove the following path from the "catalog=" line.
662
663           $thisXmlCatalog
664
665 EOF
666           ;;
667           *)
668           mv $myCatalogManager $catalogBackup || exit 1
669           sed "s#^catalogs=\(.*\)$thisXmlCatalog\(.*\)\$#catalogs=\1\2#" $catalogBackup \
670           | sed 's/;\+/;/' | sed 's/;$//' | sed 's/=;/=/' > $myCatalogManager || exit 1
671           cat 1>&2 <<EOF
672 NOTE: Successfully updated the following file:
673       $myCatalogManager
674       Backup written to:
675       $catalogBackup
676
677 EOF
678           ;;
679         esac
680       else
681         emit_message "NOTE: No data for this distribution found in:"
682         emit_message "       $myCatalogManager"
683         emit_message
684       fi
685     else
686       cat 1>&2 <<EOF
687 NOTE: No data for this distribution was found in the following
688       file, so I did not revert it.
689       $myCatalogManager
690 EOF
691     fi
692   fi
693
694   if [ -n "$myEmacsFile" ]; then 
695     # check to see if a non-empty value for --dotEmacs file was fed
696     # to uninstaller.
697     if [ -n ${2#--dotEmacs=} ]; then
698       myEmacsFile=${2#--dotEmacs=}
699       revertLine="(load-file \"$escapedPwd\/\.emacs\.el\")"
700       loadLine="$(grep "$revertLine" "$myEmacsFile")"
701       if [ -n "$loadLine" ]; then
702         emit_message
703         REPLY=""
704         if [ ! "$batchmode" = "Yes" ]; then
705           read -s -n1 -p "Revert $myEmacsFile? [Yes] "
706           emit_message "$REPLY"
707         fi
708         case $REPLY in
709           [nNqQ]*)
710           cat 1>&2 <<EOF
711
712 NOTE: No change made to $myEmacsFile. You need to manually
713 remove the following line.
714
715 (load-file \"$mydir/.emacs.el\")
716
717 EOF
718           ;;
719           *)
720           dotEmacsBackup=$myEmacsFile.$$.bak
721           sed -e "/$revertLine/d" -i".$$.bak" $myEmacsFile  || exit 1
722           cat 1>&2 <<EOF
723 NOTE: successfully reverted the following file:
724       $myEmacsFile
725       Backup written to:
726       $dotEmacsBackup
727
728 EOF
729           ;;
730         esac
731       else
732         emit_message "NOTE: No data for this distribution found in:"
733         emit_message "      $myEmacsFile"
734       fi
735     fi
736   fi
737
738   # check all startup files
739   myStartupFiles=".bash_profile .bash_login .profile .bashrc .cshrc .tcshrc"
740   for file in $myStartupFiles; do
741     if [ -e "$HOME/$file" ]; then
742       case $file in
743         .tcshrc|.cshrc)
744         revertLine="source $mydir/.cshrc.incl"
745         revertLineEsc="source $escapedPwd\/\.cshrc\.incl"
746         ;;
747         *)
748         revertLine=". $mydir/.profile.incl"
749         revertLineEsc="\. $escapedPwd\/\.profile\.incl"
750         ;;
751       esac
752       lineExists="$(grep "$revertLineEsc" $HOME/$file )"
753       if [ "$lineExists" ]; then
754         REPLY=""
755         if [ ! "$batchmode" = "Yes" ]; then
756           read -s -n1 -p "Update $HOME/$file? [Yes] "
757           emit_message "$REPLY"
758         fi
759         case $REPLY in
760           [nNqQ]*)
761           cat 1>&2 <<EOF
762
763 NOTE: No change made to $HOME/$file. You need to manually remove
764       the following line from it.
765
766  $revertLine
767
768 EOF
769           ;;
770           *)
771           dotFileBackup=$HOME/$file.$$.bak
772           sed -e "/$revertLineEsc/d" -i".$$.bak" $HOME/$file  || exit 1
773           cat 1>&2 <<EOF
774 NOTE: Successfully updated the following file:
775       $HOME/$file
776       Backup written to:
777       $dotFileBackup
778
779 EOF
780           ;;
781         esac
782       else
783         emit_message "NOTE: No data for this distribution found in:"
784         emit_message "      $HOME/$file"
785         emit_message
786       fi
787     fi
788   done
789   removeOldFiles
790   emit_message "Done. Deleted uninstall.sh file."
791   rm -f $mydir/test.sh      || exit 1
792   rm -f $mydir/uninstall.sh || exit 1
793 }
794
795 writeUninstallFile() {
796   uninstallFile=$mydir/uninstall.sh
797   echo '#!/bin/bash'                               > $uninstallFile || exit 1
798   echo 'mydir=$(cd -P $(dirname $0) && pwd -P)'   >> $uninstallFile || exit 1
799   echo "\$mydir/install.sh \\"                    >> $uninstallFile || exit 1
800   echo "  --uninstall \\"                         >> $uninstallFile || exit 1
801   echo "  --catalogManager=$myCatalogManager \\"  >> $uninstallFile || exit 1
802   echo "  --dotEmacs='$myEmacsFile' \\"           >> $uninstallFile || exit 1
803   echo '  $@'                                     >> $uninstallFile || exit 1
804   chmod 755 $uninstallFile || exit 1
805 }
806
807 writeTestFile() {
808   testFile=$mydir/test.sh
809   echo "#!/bin/bash"                                > $testFile || exit 1
810   echo 'mydir=$(cd -P $(dirname $0) && pwd -P)'    >> $testFile || exit 1
811   echo '$mydir/install.sh --test'                  >> $testFile || exit 1
812   chmod 755 $testFile || exit 1
813 }
814
815 printExitMessage() {
816   cat 1>&2 <<EOF
817 To source your shell environment for this distribution, type the
818 following:
819
820 $appendLine
821
822 EOF
823 }
824
825 checkForResolver() {
826   resolverResponse="$(java org.apache.xml.resolver.apps.resolver uri -u foo 2>/dev/null)"
827   if [ -z "$resolverResponse" ]; then
828     cat 1>&2 <<EOF
829
830 NOTE: Your environment does not seem to contain the Apache XML
831       Commons Resolver; without that, you can't use XML catalogs
832       with Java applications. For more information, see the "How
833       to use a catalog file" section in Bob Stayton's "DocBook
834       XSL: The Complete Guide"
835
836       http://sagehill.net/docbookxsl/UseCatalog.html
837
838 EOF
839   fi
840 }
841
842 emitNoChangeMsg() {
843   cat 1>&2 <<EOF
844
845 NOTE: No changes were made to CatalogManagers.properties. To
846       provide your Java tools with XML catalog information for
847       this distribution, you will need to make the appropriate
848       changes manually.
849
850 EOF
851 }
852
853 testCatalogs() {
854   if [ ! -f "$thisXmlCatalog" ]; then
855     cat 1>&2 <<EOF
856
857 FATAL: $thisXmlCatalog file needed but not found. Stopping.
858 EOF
859   exit
860   fi
861
862   if [ -z "$XML_CATALOG_FILES" ]; then
863     emit_message
864     emit_message "WARNING: XML_CATALOG_FILES not set. Not testing with xmlcatalog."
865   else
866     xmlCatalogResponse="$(xmlcatalog 2>/dev/null)"
867     if [ -z "$xmlCatalogResponse" ]; then
868     cat 1>&2 <<EOF
869
870 WARNING: Cannot locate the "xmlcatalog" command. Make sure that
871          you have libxml2 and its associated utilities installed.
872
873          http://xmlsoft.org/
874
875 EOF
876     else
877       emit_message "Testing with xmlcatalog..."
878       # read in pathname-uri pairs from .urilist file
879       while read pair; do
880         if [ ! "${pair%* *}" = "." ]; then
881           path=$mydir/${pair%* *}
882         else
883           path=$mydir/
884         fi
885         uri=${pair#* *}
886         emit_message
887         emit_message "  Tested: $uri"
888         for catalog in $XML_CATALOG_FILES; do
889           response="$(xmlcatalog $catalog $uri| grep -v "No entry")"
890           if [ -n "$response" ]; then
891             if [ "$response" = "$path" ]; then
892               emit_message "  Result: $path"
893               break
894             else
895               emit_message "  Result: FAILED"
896             fi
897           fi
898         done
899       done < $mydir/.urilist
900     fi
901   fi
902
903   if [ -z "$CLASSPATH" ]; then
904     emit_message
905     emit_message "NOTE: CLASSPATH not set. Not testing with Apache XML Commons Resolver."
906   else
907     if [ "$(checkForResolver)" ]; then
908       checkForResolver
909     else
910       emit_message
911       emit_message "Testing with Apache XML Commons Resolver..."
912       # read in pathname-uri pairs from .urilist file
913       while read pair; do
914         if [ ! "${pair%* *}" = "." ]; then
915           path=$mydir/${pair%* *}
916         else
917           path=$mydir/
918         fi
919         uri=${pair#* *}
920         emit_message
921         emit_message "  Tested: $uri"
922         if [ ${uri%.dtd} != $uri ]; then
923           response="$(java org.apache.xml.resolver.apps.resolver system -s $uri | grep "Result")"
924         else
925           response="$(java org.apache.xml.resolver.apps.resolver uri -u $uri | grep "Result")"
926         fi
927         if [ "$response" ]; then
928           if [ "${response#*$path}" != "$response" ]; then
929             emit_message "  Result: $path"
930           else
931             emit_message "  Result: FAILED"
932           fi
933           echo
934         fi
935       done < $mydir/.urilist
936     fi
937   fi
938 }
939
940 # get opts and execute appropriate function
941 case $1 in
942   *-uninstall)
943   uninstall $2 $3 $4
944   ;;
945   *-test)
946   testCatalogs
947   ;;
948   *)
949   main
950   ;;
951 esac
952
953 # Copyright
954 # ---------
955 # Copyright 2005-2007 Michael(tm) Smith <smith@sideshowbarker.net>
956
957 # Permission is hereby granted, free of charge, to any person
958 # obtaining a copy of this software and associated documentation
959 # files (the "Software"), to deal in the Software without
960 # restriction, including without limitation the rights to use, copy,
961 # modify, merge, publish, distribute, sublicense, and/or sell copies
962 # of the Software, and to permit persons to whom the Software is
963 # furnished to do so, subject to the following conditions:
964
965 # The above copyright notice and this permission notice shall be
966 # included in all copies or substantial portions of the Software.
967
968 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
969 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
970 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
971 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
972 # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
973 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
974 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
975 # DEALINGS IN THE SOFTWARE.
976
977 # vim: number