1#! /bin/sh
2#
3# Copyright (C) 2002-2006 Free Software Foundation, Inc.
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2, or (at your option)
8# any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software Foundation,
17# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18#
19
20# This file is meant for authors, maintainers, co-maintainers or installers
21# of packages which are internationalized with the help of GNU gettext.  For
22# further information how to use it consult the GNU gettext manual.
23
24progname=$0
25package=@PACKAGE@
26version=@VERSION@
27
28# Set variables
29# - gettext_dir     directory where the sources are stored.
30prefix="@prefix@"
31datarootdir="@datarootdir@"
32gettext_dir="@datadir@/gettext"
33
34# func_tmpdir
35# creates a temporary directory.
36# Sets variable
37# - tmp             pathname of freshly created temporary directory
38func_tmpdir ()
39{
40  # Use the environment variable TMPDIR, falling back to /tmp. This allows
41  # users to specify a different temporary directory, for example, if their
42  # /tmp is filled up or too small.
43  : ${TMPDIR=/tmp}
44  {
45    # Use the mktemp program if available. If not available, hide the error
46    # message.
47    tmp=`(umask 077 && mktemp -d "$TMPDIR/gtXXXXXX") 2>/dev/null` &&
48    test -n "$tmp" && test -d "$tmp"
49  } ||
50  {
51    # Use a simple mkdir command. It is guaranteed to fail if the directory
52    # already exists.  $RANDOM is bash specific and expands to empty in shells
53    # other than bash, ksh and zsh.  Its use does not increase security;
54    # rather, it minimizes the probability of failure in a very cluttered /tmp
55    # directory.
56    tmp=$TMPDIR/gt$$-$RANDOM
57    (umask 077 && mkdir "$tmp")
58  } ||
59  {
60    echo "$0: cannot create a temporary directory in $TMPDIR" >&2
61    { (exit 1); exit 1; }
62  }
63}
64
65# Support for relocatability.
66func_find_curr_installdir ()
67{
68  # Determine curr_installdir, even taking into account symlinks.
69  curr_executable="$0"
70  case "$curr_executable" in
71    */* | *\\*) ;;
72    *) # Need to look in the PATH.
73      if test "${PATH_SEPARATOR+set}" != set; then
74        func_tmpdir
75        { echo "#! /bin/sh"; echo "exit 0"; } > "$tmp"/conf.sh
76        chmod +x "$tmp"/conf.sh
77        if (PATH="/nonexistent;$tmp"; conf.sh) >/dev/null 2>&1; then
78          PATH_SEPARATOR=';'
79        else
80          PATH_SEPARATOR=:
81        fi
82        rm -rf "$tmp"
83      fi
84      save_IFS="$IFS"; IFS="$PATH_SEPARATOR"
85      for dir in $PATH; do
86        IFS="$save_IFS"
87        test -z "$dir" && dir=.
88        for exec_ext in ''; do
89          if test -f "$dir/$curr_executable$exec_ext"; then
90            curr_executable="$dir/$curr_executable$exec_ext"
91            break 2
92          fi
93        done
94      done
95      IFS="$save_IFS"
96      ;;
97  esac
98  # Make absolute.
99  case "$curr_executable" in
100    /* | ?:/* | ?:\\*) ;;
101    *) curr_executable=`pwd`/"$curr_executable" ;;
102  esac
103  # Resolve symlinks.
104  sed_dirname='s,/[^/]*$,,'
105  sed_linkdest='s,^.* -> \(.*\),\1,p'
106  while : ; do
107    lsline=`LC_ALL=C ls -l "$curr_executable"`
108    case "$lsline" in
109      *" -> "*)
110        linkdest=`echo "$lsline" | sed -n -e "$sed_linkdest"`
111        case "$linkdest" in
112          /* | ?:/* | ?:\\*) curr_executable="$linkdest" ;;
113          *) curr_executable=`echo "$curr_executable" | sed -e "$sed_dirname"`/"$linkdest" ;;
114        esac ;;
115      *) break ;;
116    esac
117  done
118  curr_installdir=`echo "$curr_executable" | sed -e 's,/[^/]*$,,'`
119  # Canonicalize.
120  curr_installdir=`cd "$curr_installdir" && pwd`
121}
122func_find_prefixes ()
123{
124  # Compute the original/current installation prefixes by stripping the
125  # trailing directories off the original/current installation directories.
126  orig_installprefix="$orig_installdir"
127  curr_installprefix="$curr_installdir"
128  while true; do
129    orig_last=`echo "$orig_installprefix" | sed -n -e 's,^.*/\([^/]*\)$,\1,p'`
130    curr_last=`echo "$curr_installprefix" | sed -n -e 's,^.*/\([^/]*\)$,\1,p'`
131    if test -z "$orig_last" || test -z "$curr_last"; then
132      break
133    fi
134    if test "$orig_last" != "$curr_last"; then
135      break
136    fi
137    orig_installprefix=`echo "$orig_installprefix" | sed -e 's,/[^/]*$,,'`
138    curr_installprefix=`echo "$curr_installprefix" | sed -e 's,/[^/]*$,,'`
139  done
140}
141if test "@RELOCATABLE@" = yes; then
142  exec_prefix="@exec_prefix@"
143  bindir="@bindir@"
144  orig_installdir="$bindir" # see Makefile.am's *_SCRIPTS variables
145  func_find_curr_installdir # determine curr_installdir
146  func_find_prefixes
147  # Relocate the directory variables that we use.
148  gettext_dir=`echo "$gettext_dir/" | sed -e "s%^${orig_installprefix}/%${curr_installprefix}/%" | sed -e 's,/$,,'`
149fi
150
151# func_usage
152# outputs to stdout the --help usage message.
153func_usage ()
154{
155  echo "\
156Usage: autopoint [OPTION]...
157
158Copies standard gettext infrastructure files into a source package.
159
160Options:
161      --help           print this help and exit
162      --version        print version information and exit
163  -f, --force          force overwriting of files that already exist
164  -n, --dry-run        print modifications but don't perform them"
165#  echo "\
166#  -V version           copy the infrastructure of the specified gettext version
167#                         (dangerous)"
168  echo "
169Report bugs to <bug-gnu-gettext@gnu.org>."
170}
171
172# func_version
173# outputs to stdout the --version message.
174func_version ()
175{
176  echo "$progname (GNU $package) $version"
177  echo "Copyright (C) 2002-2006 Free Software Foundation, Inc.
178This is free software; see the source for copying conditions.  There is NO
179warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
180  echo "Written by" "Bruno Haible"
181}
182
183# func_fatal_error message
184# outputs to stderr a fatal error message, and terminates the program.
185func_fatal_error ()
186{
187  echo "autopoint: *** $1" 1>&2
188  echo "autopoint: *** Stop." 1>&2
189  exit 1
190}
191
192# Command-line option processing.
193# Removes the OPTIONS from the arguments. Sets the variables:
194# - force           yes if --force was given, empty otherwise
195# - ver             gettext version if -V was given, empty otherwise
196# - doit            false if --dry-run was given, : otherwise
197{
198  force=
199  ver=
200  doit=:
201
202  while test $# -gt 0; do
203    case "$1" in
204      -n | --dry-run | --dry-ru | --dry-r | --dry- | --dry | --dr | --d )
205        shift
206        doit=false ;;
207      -f | --force | --forc | --for | --fo | --f )
208        shift
209        force=yes ;;
210      --help | --hel | --he | --h )
211        func_usage; exit 0 ;;
212#      -V ) # Some people put a space between -V and the version number.
213#        shift
214#        if test $# = 0; then
215#          func_usage 1>&2
216#          exit 1
217#        fi
218#        ver=$1;
219#        shift ;;
220#      -V*) # Some people omit the space between -V and the version number.
221#        ver=`echo "X$1" | sed -e 's/^X-V//'`
222#        shift ;;
223      --version | --versio | --versi | --vers | --ver | --ve | --v )
224        func_version
225        exit 0 ;;
226      -- ) # Stop option prcessing
227        shift; break ;;
228      -* )
229        echo "autopoint: unknown option $1" 1>&2
230        echo "Try 'autopoint --help' for more information." 1>&2
231        exit 1 ;;
232      * )
233        break ;;
234    esac
235  done
236}
237
238# Command-line argument processing.
239# Analyzes the remaining arguments.
240{
241  if test $# -gt 0; then
242    func_usage 1>&2
243    exit 1
244  fi
245}
246
247srcdir=`pwd`
248# The current directory is now $srcdir.
249
250# Check integrity of package: A configure.in/ac must be present. Sets variable
251# - configure_in    name of configure.in/ac file.
252if test -f configure.in; then
253  configure_in=configure.in
254else
255  if test -f configure.ac; then
256    configure_in=configure.ac
257  else
258    # KDE specific convention: configure.in.in
259    if test -f configure.in.in; then
260      configure_in=configure.in.in
261    else
262      func_fatal_error "Missing configure.in or configure.ac, please cd to your package first."
263    fi
264  fi
265fi
266
267# Check whether the -V option and the version number in configure.in match.
268# At least one of the two must be given. If both are given, they must agree.
269xver=`cat "$configure_in" | grep '^AM_GNU_GETTEXT_VERSION(' | sed -e 's/^AM_GNU_GETTEXT_VERSION(\([^()]*\))/\1/p' | sed -e 's/^\[\(.*\)\]$/\1/' | sed -e 1q`
270if test -z "$xver" && test -f intl/VERSION; then
271  xver=`cat intl/VERSION | LC_ALL=C sed -n -e 's/^.*gettext-\([-+_.0-9A-Za-z]*\).*$/\1/p'`
272fi
273if test -n "$xver"; then
274  if test -n "$ver"; then
275    if test "X$ver" != "X$xver"; then
276      func_fatal_error "Version mismatch: specified -V $ver but the package uses gettext version $xver"
277    fi
278  else
279    ver="$xver"
280  fi
281else
282  if test -z "$ver"; then
283    func_fatal_error "Missing version: please specify in $configure_in through a line 'AM_GNU_GETTEXT_VERSION(x.yy.zz)' the gettext version the package is using"
284  fi
285fi
286
287# Check whether the version number is supported.
288case "$ver" in
289  0.10.35 | 0.10.36 | 0.10.37 | 0.10.38 | 0.10.39 | 0.10.40 | \
290  0.11 | 0.11.1 | 0.11.2 | 0.11.3 | 0.11.4 | 0.11.5 | \
291  0.12 | 0.12.1 | \
292  0.13 | 0.13.1 | \
293  0.14 | 0.14.1 | 0.14.2 | 0.14.3 | 0.14.4 | 0.14.5 | 0.14.6 | \
294  0.15 | \
295  0.16 | 0.16.1 )
296    ;;
297  *)
298    func_fatal_error "The AM_GNU_GETTEXT_VERSION declaration in your $configure_in\
299               file requires the infrastructure from gettext-$ver but this version\
300               is older. Please upgrade to gettext-$ver or newer."
301    ;;
302esac
303
304# We distribute the many different versions of the files in a CVS repository.
305# This guarantees a good compression rate:
306#
307#   Including version    size in KB of
308#                       "du autopoint-files/archive"
309#      0.10.35                  240
310#      0.10.36                  428
311#      0.10.37                  436
312#      0.10.38                  488
313#      0.10.39                  500
314#      0.10.40                  528
315#      0.11                     720
316#      0.11.1                   740
317#      0.11.2                   748
318#      0.11.3                   804
319#      0.11.4                   864
320#      0.11.5                   880
321#      0.12                    1032
322#      0.12.1                  1032
323#      0.13                    1220
324#      0.13.1                  1236
325#      0.14                    1296
326#      0.14.1                  1300
327#      0.14.2                  1420
328#      0.14.3                  1428
329#      0.14.4                  1464
330#      0.14.5                  1508
331#      0.14.6                  1580
332#      0.15                    1760
333#      0.16                    1808
334#      0.16.1                  1812
335#
336# The requirement that the user must have the CVS program available is not
337# a severe restrictions, because most of the people who use autopoint are
338# users of CVS.
339#
340# Check availability of the CVS program.
341(cvs -v) >/dev/null 2>/dev/null || func_fatal_error "cvs program not found"
342
343# Check in which directory config.rpath, mkinstalldirs etc. belong.
344auxdir=`cat "$configure_in" | grep '^AC_CONFIG_AUX_DIR' | sed -n -e 's/AC_CONFIG_AUX_DIR(\([^()]*\))/\1/p' | sed -e 's/^\[\(.*\)\]$/\1/' | sed -e 1q`
345if test -n "$auxdir"; then
346  auxdir="$auxdir/"
347fi
348
349# Check in which directory the *.m4 macros belong.
350m4dir=m4
351if test -f Makefile.am; then
352  # A package using automake.
353  # Extract the macro directory name from Makefile.am.
354  aclocal_amflags=`grep '^ACLOCAL_AMFLAGS[ 	]*=' Makefile.am | sed -e 's/^ACLOCAL_AMFLAGS[ 	]*=\(.*\)$/\1/'`
355  m4dir_is_next=
356  for arg in $aclocal_amflags; do
357    if test -n "$m4dir_is_next"; then
358      m4dir="$arg"
359      break
360    else
361      if test "X$arg" = "X-I"; then
362        m4dir_is_next=yes
363      else
364        m4dir_is_next=
365      fi
366    fi
367  done
368fi
369
370# Check whether to omit the intl/ directory.
371omitintl=`cat "$configure_in" | grep '^AM_GNU_GETTEXT' | sed -n -e 's/^AM_GNU_GETTEXT(\([^(),]*\).*$/\1/p' | sed -e 's/^\[\(.*\)\]$/\1/' | sed -e 1q`
372omitintl=`if test 'external' = "$omitintl"; then echo yes; fi`
373
374# Set up a temporary CVS repository and a temporary checkout directory.
375# We need the temporary CVS repository because any checkout needs write
376# access to the CVSROOT/history file, so it cannot be under $gettext_dir.
377# We need the temporary checkout directory because when --force was not
378# given, we need to compare the existing files with the checked out ones.
379# Set variables
380# - cvs_dir         directory containing the temporary repository
381# - work_dir        directory containing the temporary checkout
382cvs_dir=tmpcvs$$
383work_dir=tmpwrk$$
384# Use an umask of 077, to avoid attacks that work by overwriting files in the
385# "$CVSROOT"/CVSROOT directory.
386(umask 077 && mkdir "$cvs_dir") || {
387  if test -d "$cvs_dir"; then
388    func_fatal_error "directory $cvs_dir already exists"
389  else
390    func_fatal_error "cannot create directory $cvs_dir"
391  fi
392}
393mkdir "$work_dir" || {
394  if test -d "$work_dir"; then
395    func_fatal_error "directory $work_dir already exists"
396  else
397    func_fatal_error "cannot create directory $work_dir"
398  fi
399}
400CVSROOT="$srcdir/$cvs_dir"
401export CVSROOT
402unset CVS_CLIENT_LOG
403unset CVS_CLIENT_PORT
404unset CVS_IGNORE_REMOTE_ROOT
405unset CVS_PASSFILE
406unset CVS_PASSWORD
407unset CVS_RCMD_PORT
408unset CVS_RSH
409unset CVS_SERVER
410unset CVS_SERVER_SLEEP
411unset CVSIGNORE
412unset CVSREAD
413unset CVSUMASK
414unset CVSWRAPPERS
415
416# Need to pass -d "$CVSROOT", because there may be a CVS directory in the
417# current directory.
418cvs -d "$CVSROOT" init
419gzip -d -c < "$gettext_dir/archive.tar.gz" | (cd "$cvs_dir" && tar xf -)
420
421cd "$work_dir"
422cvsver=gettext-`echo "$ver" | sed -e 's/\./_/g'`
423(cvs checkout -r"$cvsver" archive > /dev/null) 2>&1 | grep -v '^cvs checkout: Updating'
424find archive -name CVS -type d -print | xargs rm -rf
425if test `find archive -type f -print | wc -l` = 0; then
426  cd ..
427  rm -rf "$cvs_dir" "$work_dir"
428  func_fatal_error "infrastructure files for version $ver not found; this is autopoint from GNU $package $version"
429fi
430cd ..
431
432# func_destfile file
433# determines the destination file, relative to the package's top level
434# directory, for a given file name, relative to archive.
435# Sets variables
436# - destfile        relative destination file name, or
437#                   empty if the file shall be omitted
438# - sharedowner     yes if the file is not only owned by GNU gettext but may
439#                   be installed by automake or other tools, otherwise empty
440func_destfile ()
441{
442  # There are five categories of files:
443  # ABOUT_NLS -> top level directory
444  # config.rpath mkinstalldirs -> $auxdir
445  # m4/* -> $m4dir/
446  # intl/* -> intl/
447  # po/* -> po/
448  sharedowner=
449  case `echo "$1" | sed -e 's,[^/]*$,,'` in
450    "" )
451      case "$1" in
452        config.rpath ) destfile="$auxdir$1" ;;
453        mkinstalldirs ) destfile="$auxdir$1" sharedowner=yes ;;
454        * ) destfile="$1" ;;
455      esac
456      ;;
457    m4/ ) destfile=`echo "$1" | sed -e "s,^m4/,$m4dir/,"` ;;
458    intl/ ) if test -n "$omitintl"; then destfile=""; else destfile="$1"; fi ;;
459    * ) destfile="$1" ;;
460  esac
461}
462
463# If some files have been locally modified and we have not been requested
464# to overwrite them, then bail out. This is better than leaving a source
465# package around where half of the files are locally modified and half are
466# original - too great risk of version mismatch.
467if test -z "$force"; then
468  mismatch=
469  func_tmpdir
470  mismatchfile="$tmp"/autopoint.diff
471  for file in `find "$work_dir/archive" -type f -print | sed -e "s,^$work_dir/archive/,," | LC_ALL=C sort`; do
472    func_destfile "$file"
473    if test -n "$destfile"; then
474      if test -f "$destfile"; then
475        if cmp -s "$work_dir/archive/$file" "$destfile"; then
476          :
477        else
478          if test -n "$sharedowner"; then
479            echo "autopoint: warning: File $destfile has been locally modified." 1>&2
480          else
481            echo "autopoint: File $destfile has been locally modified." 1>&2
482            mismatch=yes
483            diff -c "$work_dir/archive/$file" "$destfile" | sed -e "1s,$work_dir/archive/,," >> "$mismatchfile"
484          fi
485        fi
486      fi
487    fi
488  done
489  if test -n "$mismatch"; then
490    rm -rf "$cvs_dir" "$work_dir"
491    func_fatal_error "Some files have been locally modified. Not overwriting them because --force has not been specified. For your convenience, you find the local modifications in the file '$mismatchfile'."
492  fi
493  rm -rf "$tmp"
494fi
495
496# func_mkdir_for to
497# ensures the directory that would the given file exists.
498# 'to' is a relative pathname, relative to the current directory.
499func_mkdir_for ()
500{
501  base=`echo "$1" | sed -e 's,/[^/]*$,,'`
502  if test "X$base" != "X$1" && test -n "$base"; then
503    func_mkdir_for "$base"
504    # Recompute base. It was clobbered by the recursive call.
505    base=`echo "$1" | sed -e 's,/[^/]*$,,'`
506    test -d "$base" || { echo "Creating directory $base"; mkdir "$base"; }
507  fi
508}
509
510# func_copy from to
511# copies a file.
512# 'from' is a relative pathname, relative to the current directory.
513# 'to' is a relative pathname, relative to the current directory.
514func_copy ()
515{
516  if $doit; then
517    func_mkdir_for "$2"
518    rm -f "$2"
519    echo "Copying file $2"
520    cp "$1" "$2"
521  else
522    echo "Copy file $2"
523  fi
524}
525
526# func_backup to
527# makes a backup of a file that is about to be overwritten or replaced.
528# 'to' is a relative pathname, relative to the current directory.
529func_backup ()
530{
531  if $doit; then
532    if test -f "$1"; then
533      rm -f "$1~"
534      cp -p "$1" "$1~"
535    fi
536  fi
537}
538
539# Now copy the files.
540for file in `find "$work_dir/archive" -type f -print | sed -e "s,^$work_dir/archive/,," | LC_ALL=C sort`; do
541  func_destfile "$file"
542  mustcopy=
543  if test -n "$destfile"; then
544    if test -f "$destfile"; then
545      if cmp -s "$work_dir/archive/$file" "$destfile"; then
546        :
547      else
548        if test -n "$force"; then
549          # Overwrite locally modified file.
550          mustcopy=yes
551        fi
552        # If --force is not specified, don't overwrite locally modified files
553        # for which GNU gettext is a shared owner.
554      fi
555    else
556      mustcopy=yes
557    fi
558  fi
559  if test -n "$mustcopy"; then
560    func_backup "$destfile"
561    func_copy "$work_dir/archive/$file" "$destfile"
562  fi
563done
564
565# That's it.
566rm -rf "$cvs_dir" "$work_dir"
567exit 0
568