mkcatalog 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. #!@l_prefix@/bin/bash
  2. ##
  3. ## mkcatalog - script for managing SGML catalog file
  4. ## Created: 20001015 Shigeyuki Fukushima <shige@FreeBSD.org>.
  5. ## Modified: 20001019 Hiroki Sato <hrs@FreeBSD.org>.
  6. ##
  7. sh_basename () {
  8. l_value=$1
  9. IFS_old=${IFS}; IFS=" /"; set -- ${l_value}; IFS=${IFS_old}
  10. case $# in
  11. 0) ;;
  12. *) echo `eval echo \\$$#` ;;
  13. esac
  14. }
  15. sh_dirname () {
  16. l_value=$1
  17. IFS_old=${IFS}; IFS=" /"; set -- ${l_value}; IFS=${IFS_old}
  18. l_dirname=$1
  19. shift
  20. while
  21. case $# in
  22. 0) break ;;
  23. 1) echo ${l_dirname}; break ;;
  24. *) ;;
  25. esac
  26. do
  27. l_dirname="${l_dirname}/$1";
  28. shift;
  29. done
  30. }
  31. norm_dir () {
  32. [ -d "$1" ] && echo `exec 2>/dev/null; cd $1; echo ${PWD}`
  33. }
  34. verbose_msg () {
  35. case ${F_VERBOSE} in
  36. 1) echo " ===> $*" ;;
  37. *) ;;
  38. esac
  39. }
  40. PREFIX=@l_prefix@
  41. TMPDIR=/tmp
  42. ARGV0=`sh_basename $0`
  43. CAT_DIR=${PREFIX}/share/sgml
  44. CAT_FILE=catalog
  45. F_PRESERVE_OLD=""
  46. F_VERBOSE=""
  47. args=`getopt pqvc: $*` ; set -- $args
  48. for i
  49. do
  50. case "$i" in
  51. -c) CAT_DIR=`sh_dirname $2`; CAT_FILE=`sh_basename $2`; shift; shift ;;
  52. -p) F_PRESERVE_OLD=1; shift ;;
  53. -q) exec 1>/dev/null 2>&1; shift ;;
  54. -v) F_VERBOSE=1; shift ;;
  55. --) shift; break ;;
  56. esac
  57. done
  58. dtd_act=$1
  59. dtd_dir=$2
  60. dtd_catalog=`sh_basename "$3"`
  61. # option check and normalize ${dtd_dir}
  62. case "${dtd_act}" in
  63. add|install|delete|deinstall|enable|disable)
  64. if [ ! -d "${CAT_DIR}" ]; then
  65. echo "${ARGV0}: top-level catalog dir \"${CAT_DIR}\" not found."
  66. exit 1
  67. elif [ ! -n "${dtd_dir}" ]; then
  68. echo "${ARGV0}: DTD directory is not specified."
  69. exit 1
  70. elif [ ! -d "${CAT_DIR}/${dtd_dir}"\
  71. -a ! -d "${dtd_dir}" ]; then
  72. echo "${ARGV0}: DTD directory \"${dtd_dir}\" not found."
  73. exit 1
  74. elif [ ! -f "${CAT_DIR}/${dtd_dir}/${dtd_catalog:-catalog}"\
  75. -a ! -f "${dtd_dir}/${dtd_catalog:-catalog}" ]; then
  76. echo "${ARGV0}: DTD catalog \"${dtd_dir}/${dtd_catalog:-catalog}\" not found."
  77. exit 1
  78. fi
  79. verbose_msg "top-level catalog dir (specified): ${CAT_DIR}"
  80. CAT_DIR=`norm_dir ${CAT_DIR}`
  81. verbose_msg "top-level catalog dir (normalized): ${CAT_DIR}"
  82. verbose_msg "target catalog dir (specified): ${dtd_dir}"
  83. dtd_dir=`norm_dir ${CAT_DIR}/${dtd_dir} || norm_dir ${dtd_dir}`
  84. verbose_msg "target catalog dir (normalized): ${dtd_dir}"
  85. case "${dtd_dir}" in
  86. ${CAT_DIR}/*) ;;
  87. *) echo "${ARGV0}: DTD directory \"${dtd_dir}\" is invalid."
  88. exit 1 ;;
  89. esac
  90. # keep dtd_dir relative
  91. dtd_dir=${dtd_dir#"${CAT_DIR}/"}
  92. ;;
  93. *)
  94. echo "${ARGV0}: missing options."
  95. cat <<EOF
  96. Usage: ${ARGV0} [-c toplv-catalog-filename] [-pqv]
  97. [install|add|deinstall|delete|enable|disable]
  98. dtd-directory-name [catalog-filename]
  99. -c filename specifies top-level catalog file
  100. (default: ${PREFIX}/share/sgml/catalog)
  101. -p preserve old catalog file (as .old)
  102. -q quiet mode
  103. -v verbose mode (for debug)
  104. ex.) mkcatalog install html/4.0
  105. mkcatalog -c /home/foo/sgml/catalog install html/4.0/my_ext html_catalog
  106. EOF
  107. exit 1
  108. ;;
  109. esac
  110. echo "* top-level catalog: ${CAT_DIR}/${CAT_FILE}"
  111. verbose_msg "action: ${dtd_act}"
  112. verbose_msg "target catalog dir: ${dtd_dir}"
  113. verbose_msg "target catalog file: ${dtd_catalog:-catalog}"
  114. echo "* attempt to ${dtd_act} catalog in ${dtd_dir}"
  115. TMPCAT=/tmp/catalog.$$
  116. proc_catalog () {
  117. l_bottom_p=$1 # allow to delete upper catalog?
  118. l_upper=$2 # dirname of upper catalog
  119. l_lower=$3 # dirname of lower catalog
  120. case ${first_p} in
  121. [Yy][Ee][Ss]) catalog=${dtd_catalog:-"catalog"} ;;
  122. *) catalog=${CAT_FILE} ;;
  123. esac
  124. # l_upper_cat -> relative path from ${CAT_DIR}
  125. # l_lower_cat -> relative path from l_upper
  126. l_upper_cat="${l_upper}/${CAT_FILE}"
  127. l_lower_cat="`sh_basename ${l_lower}`/${catalog}"
  128. # l_*_abs_* -> absolute path respectively
  129. l_upper_abs="${CAT_DIR}/${l_upper}"
  130. l_lower_abs="${CAT_DIR}/${l_lower}"
  131. l_upper_abs_cat="${CAT_DIR}/${l_upper}/${CAT_FILE}"
  132. l_lower_abs_cat="${CAT_DIR}/${l_lower}/${catalog}"
  133. l_cat_line="CATALOG \"${l_lower_cat}\""
  134. l_abs_path_head=`cd ${l_upper_abs}; echo ${PWD}`
  135. # first, create temporary catalog from l_upper_cat
  136. # not including CATALOG line of l_lower_cat (if no catalog,
  137. # create empty one).
  138. #
  139. # NOTE: file manipulations require absolute path, but
  140. # CATALOG line do relative from upper's one.
  141. #
  142. touch ${l_upper_abs_cat} || exit 1
  143. grep -v "\( *-- *\)\?CATALOG *\"\(${l_abs_path_head}/\)\?${l_lower_cat}\"\( *-- *\)\?" \
  144. ${l_upper_abs_cat} >${TMPCAT}
  145. # preserve old catalog as necessary
  146. if [ "x${F_PRESERVE_OLD}" != "x" ]; then
  147. cp ${l_upper_abs_cat} ${l_upper_abs_cat}.old || exit 1
  148. fi
  149. case "${dtd_act}" in
  150. add|install|enable)
  151. # if "install or add or enable",
  152. # create "the temporary catalog + l_cat_line" and install it.
  153. echo " - ${dtd_act} ${l_cat_line} line in ${l_upper_cat}"
  154. echo "${l_cat_line}" >>${TMPCAT}
  155. cp ${TMPCAT} ${l_upper_abs_cat} || exit 1
  156. ;;
  157. disable)
  158. # if "disable", install the same above but l_cat_line is
  159. # commented out.
  160. case ${first_p} in
  161. [Yy][Ee][Ss])
  162. echo " - ${dtd_act} ${l_cat_line} line in ${l_upper_cat}"
  163. echo "-- ${l_cat_line} --" >>${TMPCAT}
  164. cp ${TMPCAT} ${l_upper_abs_cat} || exit 1
  165. ;;
  166. *) rm -f ${TMPCAT}
  167. exit 0
  168. ;;
  169. esac
  170. ;;
  171. delete|deinstall)
  172. # if "deinstall or delete" install the temporary catalog
  173. # ${l_bottom_p}=YES means that
  174. # ${l_upper_cat} can be deleted safely, otherwise not.
  175. case ${l_bottom_p} in
  176. [Yy][Ee][Ss])
  177. echo " - ${dtd_act} ${l_cat_line} line from ${l_upper_cat}"
  178. cp ${TMPCAT} ${l_upper_abs_cat} || exit 1
  179. ;;
  180. *) rm -f ${TMPCAT}
  181. exit 0
  182. ;;
  183. esac
  184. ;;
  185. esac
  186. # when flag "preserve old" is specified but
  187. # there is no difference between new file and old one,
  188. # preservation is silently denied.
  189. if [ "x${F_PRESERVE_OLD}" != "x" ] && \
  190. cmp -s ${l_upper_abs_cat}.old ${l_upper_abs_cat}; then
  191. rm -f ${l_upper_abs_cat}.old
  192. fi
  193. rm -f ${TMPCAT}
  194. }
  195. compose_dir_list () {
  196. l_dir=$1
  197. # Creates dirlist such as the following.
  198. # input: docbook/4.1/my_extension
  199. # return: docbook/4.1/my_extension docbook/4.1 docbook
  200. IFS_old=${IFS}; IFS=" /"; set -- ${l_dir}
  201. l_dir_top=$1
  202. shift
  203. l_dir_rest="$*"
  204. IFS=${IFS_old}
  205. l_dir_item=${l_dir_top}
  206. l_dir_list=${l_dir_top}
  207. for i in ${l_dir_rest}; do
  208. l_dir_item="${l_dir_item}/${i}"
  209. l_dir_list="${l_dir_item} ${l_dir_list}"
  210. done
  211. echo ${l_dir_list}
  212. }
  213. bottom_p=YES
  214. first_p=YES
  215. set -- `compose_dir_list ${dtd_dir}` .
  216. verbose_msg "process catalog (relative to top one): $*"
  217. while
  218. case $# in
  219. 1) break ;;
  220. *) ;;
  221. esac
  222. do
  223. lower=$1
  224. upper=$2
  225. proc_catalog "${bottom_p}" "${upper}" "${lower}"
  226. first_p=NO
  227. if [ -f ${CAT_DIR}/${upper}/${CAT_FILE} ]; then
  228. bottom_p=NO
  229. fi
  230. shift
  231. done
  232. exit 0