Package: gs-eps Version: 7.07.1-9 Priority: normal Tags: security patch While doing a source code audit I've noticed a number of unsafe usage of /tmp in some of gs-eps's scripts and C files. Some of they are used in distibution or building of the package, a few (ps2epsi and some filters) seems targeted at users. I believe none is included in the Debian binary package which is built from these sources.
However, I'm worried about the bug found in src/gpdevgna.c (a test driver for transparency). Is this code used at all? As for ps2epsi, this was recently fixed in gs-common (see #278282 and CAN-2004-0967), and I've also reported this in gs-gspl. I believe this /tmp usage should be removed from the package altogether since the code might introduces security vulnerabilities in developer's build systems. Attached is a proposed (untested) patch which tries to fix these issues. For the Tcl/tk code I've used the sample code available at http://wiki.tcl.tk/772, it seems that tcl does not provide a mktemp() implementation. Consider this patch as a sample, to be improved upon. Hope this is useful, please forward it upstream. Regards Javier
diff -Nru gs-esp-7.07.1.old/lib/pj-gs.sh gs-esp-7.07.1/lib/pj-gs.sh --- gs-esp-7.07.1.old/lib/pj-gs.sh 2002-04-23 13:58:36.000000000 +0200 +++ gs-esp-7.07.1/lib/pj-gs.sh 2005-01-20 21:08:58.000000000 +0100 @@ -242,6 +242,9 @@ /usr/lib/lprcat $Nofilter $Nolabel $file PCL1 $user $dev else type=`file $file | sed 's/^[^:]*..//'` + errfile=`mktemp -t sherr.XXXXXX` || { echo "$0: Cannot create temporary file" >&2 ; exit 1 ; } + outfile=`mktemp -t pj.XXXXXX` || { echo "$0: Cannot create temporary file" >&2 ; exit 1 ; } + trap "rm -f -- \"$errfile\" \"$outfile\" ;" 0 1 2 3 13 15 case "$type" in postscript*) # @@ -249,24 +252,21 @@ # image in memory for (possibly) several minutes. Better to use and # intermediate file, since cat is "lightweight"... # -# gs -q -sDEVICE=paintjet -r180 -sOutputFile=- -dDISKFONTS -dNOPAUSE - < $file 2>/tmp/sh$$ +# gs -q -sDEVICE=paintjet -r180 -sOutputFile=- -dDISKFONTS -dNOPAUSE - < $file 2>$errfile - gs -q -sDEVICE=paintjet -r180 -sOutputFile=/tmp/pj$$ -dDISKFONTS -dNOPAUSE - < $file 1>2 - cat /tmp/pj$$ - rm /tmp/pj$$ + gs -q -sDEVICE=paintjet -r180 -sOutputFile=$outfile -dDISKFONTS -dNOPAUSE - < $file 1>&2 2>$errfile + cat $outfile needff= ;; - *) cat "$file" 2>/tmp/sh$$ + *) cat "$file" 2>$errfile needff=1 ;; esac - if [ -s /tmp/sh$$ ] + if [ -s "$errfile" ] then -# cat /tmp/sh$$ # output any errors - cat /tmp/sh$$ 1>2 # output any errors +# cat $errfile 1>&2 # output any errors fi - rm -f /tmp/sh$$ if [ $needff ]; then echo "\014\r\c"; fi fi diff -Nru gs-esp-7.07.1.old/lib/ps2epsi gs-esp-7.07.1/lib/ps2epsi --- gs-esp-7.07.1.old/lib/ps2epsi 2003-09-02 20:01:31.000000000 +0200 +++ gs-esp-7.07.1/lib/ps2epsi 2005-01-20 21:10:18.000000000 +0100 @@ -1,12 +1,7 @@ #!/bin/sh # $Id: ps2epsi,v 1.7 2003/09/02 18:01:31 easysw Exp $ -tmpfile=/tmp/ps2epsi$$ -rm -f $tmpfile -if test -e $tmpfile; then - echo "$0: Our temporary file $tmpfile already exists." 1>&2 - exit 1 -fi +tmpfile=`mktemp -t ps2epsi.XXXXXX` || { echo "$0: Error creating temporary file " 1>&2 ; exit 1 ; } trap "rm -rf $tmpfile" 0 1 2 3 7 13 15 export outfile diff -Nru gs-esp-7.07.1.old/lib/sysvlp.sh gs-esp-7.07.1/lib/sysvlp.sh --- gs-esp-7.07.1.old/lib/sysvlp.sh 2002-04-23 13:58:37.000000000 +0200 +++ gs-esp-7.07.1/lib/sysvlp.sh 2005-01-20 21:42:08.000000000 +0100 @@ -28,18 +28,21 @@ # echo "\033\015H\c" i=1 +tempfile=`mktemp -t psp` || { echo "$0: Cannot create temporary file" >&2; exit 1; } +logfile=`mktemp -t log` || { echo "$0: Cannot create temporary file" >&2; exit 1; } +trap "rm -f $tempfile $logfile" 0 1 2 3 13 15 while [ $i -le $copies ] do for file in $files do + > $tempfile $GSHOME/gs \ - -sOUTPUTFILE=/tmp/psp$$.%02d \ + -sOUTPUTFILE=$tempfile \ -sDEVICE=$DEVICE \ $EHANDLER $file \ - < /dev/null >> /usr/tmp/ps_log 2>&1 + < /dev/null >> $logfile 2>&1 - cat /tmp/psp$$.* 2>> /usr/tmp/ps_log - rm -f /tmp/psp$$.* + cat $tempfile 2>> $logfile done i=`expr $i + 1` done diff -Nru gs-esp-7.07.1.old/pcl3/lib/cups-pcl3 gs-esp-7.07.1/pcl3/lib/cups-pcl3 --- gs-esp-7.07.1.old/pcl3/lib/cups-pcl3 2002-07-12 18:11:43.000000000 +0200 +++ gs-esp-7.07.1/pcl3/lib/cups-pcl3 2005-01-20 21:22:59.000000000 +0100 @@ -259,19 +259,17 @@ rc=$? else # Call ghostscript with an intermediate file. See also comments above. - tmp="${TMPDIR:-/tmp}/$$.tmp" - rm -f "$tmp" + tmp=`mktemp -t cups.XXXXXX` || { echo "$0: Cannot create temporary file" >&2; exit 1; } + trap "rm -f $tmp" 0 1 2 3 7 13 15 $gs_command $gs_options -dCUPSMessages $accounting -q -dNOPAUSE -dBATCH \ -dSAFER -sOutputFile="$tmp" $cfgfile - >&2 rc=$? # Copy the file to stdout on success test 0 -ne $rc -o ! -f "$tmp" || cat "$tmp" || { - rm -f "$tmp" printf 'ERROR: %s: cat to stdout failed for %s.\n' "$name" "$tmp" >&2 exit 1 } - rm -f "$tmp" fi if [ 0 -ne $rc ]; then diff -Nru gs-esp-7.07.1.old/pcl3/lib/if-pcl3 gs-esp-7.07.1/pcl3/lib/if-pcl3 --- gs-esp-7.07.1.old/pcl3/lib/if-pcl3 2002-07-12 18:11:45.000000000 +0200 +++ gs-esp-7.07.1/pcl3/lib/if-pcl3 2005-01-20 21:23:37.000000000 +0100 @@ -151,8 +151,9 @@ # standard error into a temporary file and mail it to the user if it is # non-empty when the filter terminates. -errlog="${TMPDIR:-/tmp}/$$-1.tmp" -rm -f "$errlog" +errlog=`mktemp -t err.XXXXXX` || { echo "$0: Cannot create temporary file" >&2; exit 1; } +tmp=`mktemp -t tmp.XXXXXX` || { echo "$0: Cannot create temporary file" >&2; exit 1; } +trap "rm -f $errlog $tmp" 0 1 2 3 7 13 15 notify_user=root # This will be overwritten after we've checked the notify_host=`uname -n` # arguments in the call. @@ -360,8 +361,6 @@ printf '\n? %s: %s returned an exit code of %s.\n' "$name" "$GS" "$rc" >&2 else # Two-step process with an intermediate file - tmp="${TMPDIR:-/tmp}/$$-2.tmp" - rm -f "$tmp" # Call ghostscript, redirecting stdout to stderr. Note that permissible # output (e.g., from "=") will be redirected to stderr as well, hence @@ -385,7 +384,6 @@ '? %s: Error copying the generated file to stdout.\n' "$name" >&2 fi - rm -f "$tmp" fi fi diff -Nru gs-esp-7.07.1.old/pcl3/ppd/catppd gs-esp-7.07.1/pcl3/ppd/catppd --- gs-esp-7.07.1.old/pcl3/ppd/catppd 2002-07-12 18:11:46.000000000 +0200 +++ gs-esp-7.07.1/pcl3/ppd/catppd 2005-01-20 21:24:41.000000000 +0100 @@ -43,8 +43,9 @@ fi # Create awk script -tmp="${TMPDIR:-/tmp}/$$.tmp" -rm -f "$tmp" +tmp=`mktemp -t tmp.XXXXXX` || { echo "$0: Cannot create temporary file" >&2; exit 1; } +# Clean up +trap "rm -f $tmp" 0 1 2 3 7 13 15 : ${AWK:=awk} cat << '---' | sed -e "s,@AWK@,$AWK," -e "s,@TMP@,$tmp," > "$tmp" || exit 1 NR == 1 && first == "" && $1 ~ /^\*PPD-Adobe:/ {next} @@ -62,10 +63,7 @@ --- # Create output file -$AWK -f "$tmp" -v first=yes "$infile" > "$outfile" || \ - { rm -f "$tmp" "$outfile"; exit 1; } +$AWK -f "$tmp" -v first=yes "$infile" > "$outfile" || exit 1 -# Clean up -rm -f "$tmp" exit 0 diff -Nru gs-esp-7.07.1.old/src/gdevhpij.c gs-esp-7.07.1/src/gdevhpij.c --- gs-esp-7.07.1.old/src/gdevhpij.c 2002-09-03 04:23:05.000000000 +0200 +++ gs-esp-7.07.1/src/gdevhpij.c 2005-01-20 21:37:03.000000000 +0100 @@ -261,10 +261,11 @@ /* } */ /* Assign fifo names for environment space, names must be const char. */ + /* TODO: This code is insecure and can lead to symlink attacks */ sprintf(s2c, "SRV_TO_CLIENT=/tmp/hpijs_s2c_%d", getpid()); sprintf(c2s, "CLIENT_TO_SRV=/tmp/hpijs_c2s_%d", getpid()); - /* Put fifo names in envirmoment space for child process. */ + /* Put fifo names in environment space for child process. */ putenv(s2c); putenv(c2s); diff -Nru gs-esp-7.07.1.old/src/gdevpnga.c gs-esp-7.07.1/src/gdevpnga.c --- gs-esp-7.07.1.old/src/gdevpnga.c 2002-04-23 14:43:43.000000000 +0200 +++ gs-esp-7.07.1/src/gdevpnga.c 2005-01-20 21:35:16.000000000 +0100 @@ -629,6 +629,7 @@ int width = dev->width; int height = dev->height; int rowbytes = width << 2; + int tmpfd; /* PNG structures */ byte *row = gs_alloc_bytes(mem, rowbytes, "png raster buffer"); @@ -648,7 +649,18 @@ int planestride = buf->planestride; byte *buf_ptr = buf->data; - file = fopen ("/tmp/tmp.png", "wb"); /* todo: suck from OutputFile */ + tmpfd = mkstemp ("pngXXXXXX"); + if (tmpfd = -1 ) { + /* Problem creating the temporary file */ + code = gs_note_error(gs_error_VMerror); + goto done; + } + file = fdopen (tmpfd, "wb"); /* todo: suck from OutputFile */ + if (!file) { + /* Problem opening the temporary file */ + code = gs_note_error(gs_error_VMerror); + goto done; + } if_debug0('v', "[v]pnga_output_page\n"); diff -Nru gs-esp-7.07.1.old/toolbin/3way.tcl gs-esp-7.07.1/toolbin/3way.tcl --- gs-esp-7.07.1.old/toolbin/3way.tcl 2002-04-23 13:58:49.000000000 +0200 +++ gs-esp-7.07.1/toolbin/3way.tcl 2005-01-20 21:38:17.000000000 +0100 @@ -25,7 +25,29 @@ # produces a report for merging the olddir/branchdir changes into maindir. proc filesame {f1 f2} { - set t /tmp/t + # There is no Tcl builtin for temporary files + # This is taken from http://wiki.tcl.tk/772 + switch $tcl_platform(platform) { + unix { + set tmpdir /tmp # or even $::env(TMPDIR), at times. + } macintosh { + set tmpdir $::env(TRASH_FOLDER) ;# a better place? + } default { + set tmpdir [pwd] + catch {set tmpdir $::env(TMP)} + catch {set tmpdir $::env(TEMP)} + } + } + set t [file join $tmpdir [pid]] + set access [list RDWR CREAT EXCL TRUNC] + set perm 0600 + if {[catch {open $t $access $perm} fid ]} { + # something went wrong + error "Could not open tempfile." + } + if {[catch {close $t} err]} { + error "Failed closing temporary file: $err" + } if {![catch {exec diff $f1 $f2 > $t}]} { return 1 } @@ -50,6 +72,9 @@ break } close $in + if {![catch {exec rm $t}]} { + error "Failed removing temporary file" + } return $same } diff -Nru gs-esp-7.07.1.old/toolbin/gsindent gs-esp-7.07.1/toolbin/gsindent --- gs-esp-7.07.1.old/toolbin/gsindent 2002-04-23 13:58:49.000000000 +0200 +++ gs-esp-7.07.1/toolbin/gsindent 2005-01-20 21:38:17.000000000 +0100 @@ -21,12 +21,13 @@ # The perl invocations work around a bug in GNU indent. if [ $# -ne 0 ]; then + tempfile=`mktemp -t || tempfile` || { echo "$0: Cannot create temporary file" >&2; exit 1; } for f in $* do - $0 < $f > /tmp/$$ + $0 < $f > $tempfile cp -p $f $f.bak if ( test ! -e $f~ ) then cp -p $f $f~; fi - mv /tmp/$$ $f + mv $tempfile $f done exit fi diff -Nru gs-esp-7.07.1.old/toolbin/makeset.tcl gs-esp-7.07.1/toolbin/makeset.tcl --- gs-esp-7.07.1.old/toolbin/makeset.tcl 2002-04-23 13:58:49.000000000 +0200 +++ gs-esp-7.07.1/toolbin/makeset.tcl 2005-01-20 21:38:22.000000000 +0100 @@ -157,7 +157,23 @@ set ogfonts $cwd/gnu-gs-fonts-other-$Dot.tar.gz file delete $afonts $ofonts $agfonts $ogfonts - set tmp /tmp/[pid].tmp + switch $tcl_platform(platform) { + unix { + set tmpdir /tmp # or even $::env(TMPDIR), at times. + } macintosh { + set tmpdir $::env(TRASH_FOLDER) ;# a better place? + } default { + set tmpdir [pwd] + catch {set tmpdir $::env(TMP)} + catch {set tmpdir $::env(TEMP)} + } + } + set tmp [file join $tmpdir [pid]] + exec umask 077 + if {[catch {exec mkdir $tmp}]} { + # something went wrong + error "Could not create temporary dir." + } licensefonts $tmp annotURWAladdin -u sh -c "\ @@ -344,7 +360,15 @@ proc makehist {} { global Dot - set tmpname /tmp/[pid].htm + set tmpname [file join $tmpdir [pid] htm] + set access [list RDWR CREAT EXCL TRUNC] + set perm 0600 + if {[catch {open $tmpname $access $perm} fid ]} { + error "Could not open tempfile." + } + if {[catch {close $tmpname} err]} { + error "Failed closing temporary file: $err" + } set news [open doc/News.htm] set changes [open doc/Changes.htm] set inum [expr int($Dot)] @@ -377,7 +401,15 @@ set cwd [pwd] set atmp $cwd/gs${Num3}.zip set asetup gs${Num3}.bat - set tmp /tmp/[pid].tmp + set tmp [file join $tmpdir [pid] tmp] + set access [list RDWR CREAT EXCL TRUNC] + set perm 0600 + if {[catch {open $tmp $access $perm} fid ]} { + error "Could not open tempfile." + } + if {[catch {close $tmp} err]} { + error "Failed closing temporary file: $err" + } file delete $atmp $asetup $Dir ln-s . $Dir diff -Nru gs-esp-7.07.1.old/toolbin/makeset.tcl.orig gs-esp-7.07.1/toolbin/makeset.tcl.orig --- gs-esp-7.07.1.old/toolbin/makeset.tcl.orig 1970-01-01 01:00:00.000000000 +0100 +++ gs-esp-7.07.1/toolbin/makeset.tcl.orig 2002-04-23 13:58:49.000000000 +0200 @@ -0,0 +1,433 @@ +#!/usr/bin/tclsh + +# Copyright (C) 1999, 2000 Aladdin Enterprises. All rights reserved. +# +# This software is provided AS-IS with no warranty, either express or +# implied. +# +# This software is distributed under license and may not be copied, +# modified or distributed except as expressly authorized under the terms +# of the license contained in the file LICENSE in this distribution. +# +# For more information about licensing, please refer to +# http://www.ghostscript.com/licensing/. For information on +# commercial licensing, go to http://www.artifex.com/licensing/ or +# contact Artifex Software, Inc., 101 Lucas Valley Road #110, +# San Rafael, CA 94903, U.S.A., +1(415)492-9861. + +# $Id: makeset.tcl,v 1.4 2002/04/23 11:58:49 easysw Exp $ + +# Make various Ghostscript filesets. Assumes the current directory is gs. +# maketars +# ghostscript-#.#[#].tar.gz +# ({doc,examples,lib,man,src,toolbin}/* => gs#.#[#]/*/*) +# ghostscript-#.#[#].tar.bz2 +# (--same--) +# ghostscript-#.#[#]gnu.tar.gz +# (gnu/*/* => gs#.#[#]/) +# makefonts [#.#[#]] +# ghostscript-fonts-std-#.#[#].tar.gz +# (fonts/?0*l.*, fonts/metrics/?0*l.* => fonts/) +# gnu-gs-fonts-std-#.#[#].tar.gz +# (--same--) +# ghostscript-fonts-other-#.#[#].tar.gz +# (...other fonts...) +# gnu-gs-fonts-other-#.#[#].tar.gz +# (--same--) +# makehist +# (merges doc/News.htm and doc/Changes.htm into doc/History#.htm) +# makewin +# gs###.zip +# ({man,src,doc,examples,lib,toolbin}/* => gs#.#[#]/*/*, +# fonts/*.*, fonts/metrics/*.* => fonts/, +# {jpeg,libpng,zlib}/* => ibid., +# gs###.bat) +# makemaster +# (moves the maketars & makefonts files to master/###/) + +# Acquire the Ghostscript version numbers. +proc setnum {num3} { + global Num3 Dot Dir + + set Num3 $num3 + + set Dot [expr ${Num3} / 100].[format %02d [expr ${Num3} % 100]] + +# Set other, derived globals. + set Dir gs$Dot +} +setnum [exec egrep {^[0-9]+$} lib/gs_init.ps] +set Work {c:\work} + +# Execute a shell command with *- and ?-expansion. +proc sh {args} { + if {[lindex $args 0] == "-c"} { + set cmd [concat sh $args] + } elseif {[regexp {[*?]} $args]} { + set cmd [list sh -c [join $args]] + } else { + set cmd $args + } + puts stdout $cmd + puts stdout [eval exec -- $cmd 2>@ stderr] +} + +# Move all or none of a list of files to a directory. +proc movelist {name files todir} { + set ex {} + set nex {} + foreach f $files { + if {[file exists $f]} {lappend ex $f} else {lappend nex $f} + } + if {$ex == ""} { + puts stderr "$name archives do not exist." + return + } + if {$nex != ""} { + puts stderr "Missing files: $nex" + exit 1 + } + if {![file isdirectory $todir]} { + puts "Creating $todir"; flush stdout + sh mkdir -p $todir + } + foreach f $files { + if {[regexp {^/c} $f]} { + sh cp $f $todir + } else { + sh mv $f $todir + } + } + sh ls -l $todir/* +} + +# Create a symbolic link from name to path. +proc ln-s {path name} {sh ln -s $path $name} + +# Make the tarballs for the code and documentation. +proc maketars {} { + global Dir Dot + + set agz ghostscript-$Dot.tar.gz + set abz2 ghostscript-$Dot.tar.bz2 + set agnu ghostscript-${Dot}gnu.tar.gz + + file delete $agz $abz2 $Dir + ln-s . $Dir + sh tar -chf ghostscript-$Dot.tar --exclude=\\*CVS\\* --exclude=\\*.mak.tcl $Dir/configure $Dir/autogen.sh $Dir/Makefile.in $Dir/src $Dir/icclib $Dir/ijs $Dir/doc $Dir/lib $Dir/man $Dir/examples $Dir/toolbin + file delete $Dir + sh time bzip2 -c4 ghostscript-$Dot.tar > $abz2 + sh time gzip ghostscript-$Dot.tar + #ln-s ./gnu $Dir + #sh tar -czhf $agnu --exclude=\\*CVS\\* $Dir/* + file delete $Dir + sh ls -l ghostscript-$Dot*.tar.* +} + +# Assemble the fonts and metrics with a given license in $tmp/fonts. +proc licensefonts {tmp annot eol} { + set ftmp $tmp/fonts + + sh rm -rf $ftmp + sh mkdir -p $ftmp + sh cp -p /gs/fonts/*.*f* /gs/fonts/fonts.* $ftmp + sh cp -p /gs/fonts/metrics/*.?f? $ftmp + sh chmod 644 $ftmp/* + sh -c "\ + cd $tmp/fonts;\ + /gs/gs -I/gs/lib -dNODISPLAY /gs/aladdin/anntfont.ps -c $annot quit;\ + ctf $eol *.afm *.pfa *.gsf" +} + +# Make the tarballs for the fonts. +proc makefonts {{dot ""}} { + global Dot + + if {$dot != ""} { + if {![regexp {^[0-9]+\.(0|[0-9][0-9])$} $dot]} { + puts stderr "Version numbers must be #.0 or #.##." + exit 1 + } + setnum [expr "int($dot * 100)"] + } + set cwd [pwd] + set afonts $cwd/ghostscript-fonts-std-$Dot.tar.gz + set ofonts $cwd/ghostscript-fonts-other-$Dot.tar.gz + set agfonts $cwd/gnu-gs-fonts-std-$Dot.tar.gz + set ogfonts $cwd/gnu-gs-fonts-other-$Dot.tar.gz + + file delete $afonts $ofonts $agfonts $ogfonts + set tmp /tmp/[pid].tmp + + licensefonts $tmp annotURWAladdin -u + sh -c "\ + cd $tmp;\ + tar -czf $afonts fonts/?0*l.pfb fonts/?0*l.afm fonts/?0*l.pfm fonts/fonts.*;\ + rm -f fonts/?0*l.?f?;\ + tar -czf $ofonts fonts/*.pf\[ab\] fonts/*.gsf fonts/*.afm fonts/*.pfm" + + licensefonts $tmp annotURWGPL -u + sh -c "\ + cd $tmp;\ + tar -czf $agfonts fonts/?0*l.pfb fonts/?0*l.afm fonts/?0*l.pfm fonts/fonts.*;\ + rm -f fonts/?0*l.?f?;\ + tar -czf $ogfonts fonts/*.pf\[ab\] fonts/*.gsf fonts/*.afm fonts/*.pfm" + + sh rm -rf $tmp + sh ls -l $afonts $ofonts $agfonts $ogfonts +} + +# Merge News and Changes into History#. +proc mergehist {news changes hist tmp} { + # Merge News, Changes, and the existing History# to tmp. + # Return 0 if OK, non-0 or an error if not. + + # Define the pattern for the version/date line. + set vdpattern {Version ([0-9.]+) \((([0-9]+)-0*([1-9][0-9]*)-0*([1-9][0-9]*))\)} + + # Scan the News file to find the header line. + while {![regexp {^<h[1-3]><a name="Version} [set l [gets $news]]]} { + if {[eof $news]} { + puts stderr "EOF scanning News for header line" + return 1 + } + } + if {![regexp $vdpattern $l skip nver ndate nyear nmonth nday]} { + puts stderr "Can't parse header line in News: $l" + return 1 + } + puts $l + # Change the header tag to h1 for compatiability with existing files. + regsub -all {h[1-3]>} $l h1> l + set monthnames [list\ + January February March April May June\ + July August September October November December] + set nmonthname [lindex $monthnames [expr $nmonth - 1]] + + # Read the rest of the News file to determine whether there are any + # Incompatible Changes, which we need to know for the TOC entry. + set nlines [list $l] + set have_changes 0 + while {[string first </pre> [set l [gets $news]]] != 0} { + if {[eof $news]} { + puts stderr "EOF scanning News for Incompatible changes" + return 1 + } + if {[string first "Incompatible changes</h" $l] >= 0} { + set have_changes 1 + } + lappend nlines $l + } + + # Copy the prefix of the existing History file. + while {[string first <li> [set l [gets $hist]]] != 0} { + if {[eof $hist]} { + puts stderr "EOF copying History up to <li>" + return 1 + } + puts $tmp $l + } + + # If there is already a History TOC for this version, delete it. + if {![regexp $vdpattern $l skip hver hdate]} { + puts stderr "Can't parse header line in History: $l" + return 1 + } + if {$hver > $nver} { + puts stderr "First History version = $hver > first News version = $nver" + return 1 + } + if {$hver == $nver} { + # Skip over the TOC section. + while {[gets $hist] != "</ul>"} { + if {[eof $hist]} { + puts stderr "EOF skipping History TOC" + return 1 + } + } + set l [gets $hist] + } + set hline $l + + # Advance the Changes file to the TOC. + while {[string first <ul> [set l [gets $changes]]] != 0} { + if {[eof $changes]} { + puts stderr "EOF seeking Changes TOC" + return 1 + } + } + + # Create the new TOC entry. + puts $tmp "<li><a href=\"#Version$nver\">Version $nver ($ndate)</a>" + puts $tmp "<ul>" + if {$have_changes} { + puts $tmp "<li><a href=\"#${nver}_Incompatible_changes\">Incompatible changes</a>," + set l [gets $changes] + if {[string first <li> $l] == 0} { + puts $tmp " [string range $l 4 end]" + } else { + # Changes TOC must be empty. + puts $tmp $l + } + } + while {[set l [gets $changes]] != "</ul>"} { + if {[eof $changes]} { + puts stderr "EOF copying Changes TOC" + return 1 + } + puts $tmp $l + } + puts $tmp $l + + # Copy the rest of the TOC and preamble. + puts $tmp $hline + while {[string first <h1> [set l [gets $hist]]] != 0} { + if {[eof $hist]} { + puts stderr "EOF copying History TOC and preamble" + return 1 + } + puts $tmp $l + } + + # If there is a History section for this version, delete it. + if {![regexp $vdpattern $l skip hver hdate]} { + puts stderr "Can't parse header line in History: $l" + return 1 + } + if {$hver == $nver} { + # Skip over the history section. + while {[set l [gets $hist]] != "<hr>"} { + if {[eof $hist]} { + puts stderr "EOF skipping old History section" + return 1 + } + } + # Skip the following blank line, too. + gets $hist + set l [gets $hist] + } + set hline $l + + # Copy the comment and "incompatible changes" sections from News. + foreach l $nlines { + puts $tmp $l + } + + # Copy the rest of Changes. + while {[string first </pre></body> [set l [gets $changes]]] != 0} { + if {[eof $changes]} { + puts stderr "EOF copying rest of Changes" + return 1 + } + puts $tmp $l + } + + # Copy the rest of the History file, changing the date at the end. + puts $tmp <hr> + puts $tmp "" + puts $tmp $hline + while {[string first "<small>Ghostscript version " [set l [gets $hist]]] != 0} { + if {[eof $hist]} { + puts stderr "EOF seeking History Ghostscript version" + return 1 + } + puts $tmp $l + } + + puts $tmp "<small>Ghostscript version $nver, $nday $nmonthname $nyear" + while {[gets $hist l] >= 0} { + puts $tmp $l + } + + return 0 +} +proc makehist {} { + global Dot + + set tmpname /tmp/[pid].htm + set news [open doc/News.htm] + set changes [open doc/Changes.htm] + set inum [expr int($Dot)] + if {$inum > 9} { + set histname doc/Hist$inum.htm + } else { + set histname doc/History$inum.htm + } + set hist [open $histname] + set tmp [open $tmpname w] + set ecode [catch {set code [mergehist $news $changes $hist $tmp]} errMsg] + close $tmp + close $hist + close $changes + close $news + if {$ecode == 0 && $code == 0} { + file rename -force $tmpname $histname + } else { + file delete $tmpname + if {$ecode != 0} { + error $errMsg + } + } +} + +# Make the zip file for building on Windows. +proc makewin {} { + global Dir Num3 Work + + set cwd [pwd] + set atmp $cwd/gs${Num3}.zip + set asetup gs${Num3}.bat + set tmp /tmp/[pid].tmp + + file delete $atmp $asetup $Dir + ln-s . $Dir + + set out [open $asetup w] + # The dir\NUL test is per Microsoft.... + puts $out "if not exist $Work\\$Dir\\bin\\NUL mkdir $Work\\$Dir\\bin" + puts $out "if not exist $Work\\$Dir\\obj\\NUL mkdir $Work\\$Dir\\obj" + puts $out "set GS_LIB=$Work\\$Dir\\lib;$Work\\fonts" + puts $out "set MOREPATH=%MOREPATH%$Work\\$Dir\\bin;$Work\\$Dir\\lib;" + puts $out "call \\postboot.bat" + puts $out "cd $Dir" + close $out + + sh zip -q -l $atmp $asetup $Dir/src/* $Dir/icclib $Dir/man/* -x $Dir/\\*/CVS/ $Dir/\\*.mak.tcl + sh zip -q -l -g $atmp $Dir/lib/* $Dir/doc/* $Dir/examples/* $Dir/toolbin/* -x $Dir/\\*/CVS/ + sh zip -q -l -r -g $atmp $Dir/jpeg $Dir/libpng $Dir/zlib + + licensefonts $tmp annotURWAladdin -d + sh -c "\ + cd $tmp;\ + zip -q -g $atmp fonts/*.pfa fonts/*.pfb fonts/*.gsf fonts/*.afm fonts/*.pfm fonts/fonts.*" + + file delete $asetup $Dir + sh ls -l $atmp +} + +# Move the tar archives to the 'master' directory. +proc makemaster {} { + global Dot Num3 + + set todir master/$Num3 + + set agz ghostscript-$Dot.tar.gz + set abz2 ghostscript-$Dot.tar.bz2 + set agnu ghostscript-${Dot}gnu.tar.gz + movelist Code [list $agz $abz2 $agnu] $todir + + set afonts ghostscript-fonts-std-$Dot.tar.gz + set ofonts ghostscript-fonts-other-$Dot.tar.gz + set agfonts gnu-gs-fonts-std-$Dot.tar.gz + set ogfonts gnu-gs-fonts-other-$Dot.tar.gz + movelist Font [list $afonts $ofonts $agfonts $ogfonts] $todir +} + +# Call the procedure selected by the link name. +switch [file tail $argv0] { + maketars {eval maketars $argv} + makefonts {eval makefonts $argv} + makehist {eval makehist $argv} + makewin {eval makewin $argv} + makemaster {eval makemaster $argv} +} diff -Nru gs-esp-7.07.1.old/toolbin/pre gs-esp-7.07.1/toolbin/pre --- gs-esp-7.07.1.old/toolbin/pre 2002-04-23 13:58:49.000000000 +0200 +++ gs-esp-7.07.1/toolbin/pre 2005-01-20 21:38:28.000000000 +0100 @@ -183,12 +183,31 @@ lappend doclist $d } } +switch $tcl_platform(platform) { + unix { + set tmpdir /tmp # or even $::env(TMPDIR), at times. + } macintosh { + set tmpdir $::env(TRASH_FOLDER) ;# a better place? + } default { + set tmpdir [pwd] + catch {set tmpdir $::env(TMP)} + catch {set tmpdir $::env(TEMP)} + } +} if {$argv == {update}} { # Update dates in .htm and .1 files. proc updoc {doc before after} { - set tmpfile /tmp/[pid] - catch {file delete $tmpfile} + set tmpfile [file join $tmpdir [pid]] + set access [list RDWR CREAT EXCL TRUNC] + set perm 0600 + if {[catch {open $tempfile $access $perm} fid ]} { + # something went wrong + error "Could not open tempfile." + } + if {[catch {close $t} err]} { + error "Failed closing temporary file: $err" + } exec perl -pwe "s{$before}{$after}" < $doc > $tmpfile file rename -force $tmpfile $doc }
signature.asc
Description: Digital signature