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
     }

Attachment: signature.asc
Description: Digital signature

Reply via email to