1#!/bin/sh 2# This is a Tcl/Tk script to be interpreted by tclsh (>=8.3): \ 3exec tclsh "$0" "$@" 4 5# instupdate - install GPSMan updates in a Unix/Linux system 6# 7# Copyright (c) 2004 Miguel Filgueiras (mig@ncc.up.pt) / Universidade do Porto 8# 9# This program is free software; you can redistribute it and/or modify 10# it under the terms of the GNU General Public License as published by 11# the Free Software Foundation; either version 2 of the License, or 12# (at your option) any later version. 13# 14# This program is distributed in the hope that it will be useful, 15# but WITHOUT ANY WARRANTY; without even the implied warranty of 16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17# GNU General Public License for more details. 18# 19# You should have received a copy of the GNU General Public License 20# along with this program. 21# 22# Last change: 29 January 2004 23 24# after unpacking the update archive: 25# cd util 26# instupdate.tcl [-n] 27 28############# NO CONFIGURATION NEEDED 29 30if { $tcl_platform(platform) != "unix" } { 31 puts "This script needs utilities only available on Unix/Linux" 32 exit 1 33} 34 35if { $argv == "-n" } { 36 set DEBUG 1 37} elseif { $argv != "" } { 38 puts stderr "Usage: instupdate.tcl [-n]" 39 puts stderr " option -n prevents any change in the installed files" 40 exit 1 41} else { set DEBUG 0 } 42 43if { $env(USER) == "root" } { 44 set rexec 1 45} else { set rexec 0 } 46 47proc FindValues {vars file} { 48 # find out values in first "set ... ..." instruction in $file for 49 # each variable in $vars 50 # the order in the list must be the order in the file 51 # return list of values aligned with $vars 52 # could not use grep because of space being taken as argument separator 53 54 set f [open $file r] 55 set var [lindex $vars 0] ; set vars [lreplace $vars 0 0] 56 set vals "" 57 while { ! [eof $f] } { 58 gets $f line 59 if { [regexp "^(\\t| )*set $var (.+)\$" $line m m val] } { 60 lappend vals [string trim $val " \t"] 61 if { $vars == "" } { 62 close $f 63 return $vals 64 } 65 set var [lindex $vars 0] ; set vars [lreplace $vars 0 0] 66 } 67 } 68 puts stderr "No definition of $var in $file" 69 exit 1 70} 71 72proc SetValues {vars vals file tmp} { 73 # change value in first "set" instruction in $file for each variable 74 # in $vars 75 # $vals is list of values aligned with $vars 76 # $tmp is path to directory to use for temporary files 77 # the order in the list must be the order in the file 78 # not using sed because of problems with repeated replacements 79 global DEBUG 80 81 set f [open $file r] 82 set tf $tmp/TMPgiup-[clock seconds] 83 set out [open $tf w] 84 set var [lindex $vars 0] ; set vars [lreplace $vars 0 0] 85 set val [lindex $vals 0] ; set vals [lreplace $vals 0 0] 86 while { ! [eof $f] } { 87 gets $f line 88 if { $var != "" && \ 89 [regexp "^(\\t| )*set $var (.+)\$" $line m prefix m] } { 90 puts $out "${prefix}set $var $val" 91 set var [lindex $vars 0] ; set vars [lreplace $vars 0 0] 92 set val [lindex $vals 0] ; set vals [lreplace $vals 0 0] 93 } else { puts $out $line } 94 } 95 close $f 96 close $out 97 if { $var != "" } { 98 puts stderr "No definition of $var in $file" 99 file delete -force $tf 100 exit 1 101 } 102 if { ! $DEBUG } { 103 file rename -force $tf $file 104 } else { 105 puts "DEBUG: file rename -force $tf $file" 106 } 107 return 108} 109 110# start 111 112set wd [pwd] 113 114if { [set bwd [file tail $wd]] != "util" } { 115 puts stderr "After unpacking the update archive, cd to the util directory" 116 puts stderr "Usage: inst_update" 117 exit 1 118} 119 120set ugd "../gmsrc" 121 122if { ! [file isdirectory $ugd] } { 123 puts stderr "gmsrc directory from update archive not found" 124 puts stderr "After unpacking the update archive, cd to the util directory" 125 exit 1 126} 127 128## check versions 129# find update version in line "Update to GPSMan version VERSION" 130 131if { [catch {set uv [exec grep "GPSMan version" $ugd/UPDATE]}] } { 132 puts stderr "Cannot execute grep $ugd/UPDATE" 133 exit 1 134} 135 136if { ! [regexp {GPSMan version (.+)$} $uv x uv] } { 137 puts stderr "Bad format of UPDATE file" 138 exit 1 139} 140 141if { [catch {set iv [exec gpsman show version]}] } { 142 if { $rexec } { 143 puts "Will not compare installed version with that of update" 144 set iv $uv 145 set rexec 0 146 } else { 147 puts stderr "GPSMan not installed (or very old version)" 148 exit 1 149 } 150} else { set rexec 1 } 151 152if { $uv != $iv } { 153 puts stderr "GPSMan installed version ($iv) not that of the update ($uv)" 154 exit 1 155} 156 157## find installed executable to find out path to installed source directory 158 159set iex "" 160 161if { [catch {set iex [exec which gpsman]}] && \ 162 ! [catch {set exs [exec whereis gpsman]}] } { 163 foreach f $exs { 164 if { ! [file isdirectory $f] && [file executable $f] } { 165 set iex $f 166 break 167 } 168 } 169} 170 171if { $rexec } { 172 if { $iex == "" || [catch {set v [exec $iex show version]}] || \ 173 $v != $iv } { 174 puts -nonewline "Absolute path to gpsman executable? " 175 flush stdout 176 gets stdin iex 177 if { [file pathtype $iex] != "absolute" || \ 178 [catch {set v [exec $iex show version]}] || $v != $iv } { 179 puts stderr "Bad path" 180 exit 1 181 } 182 } elseif { $DEBUG } { puts "DEBUG: using $iex as GPSMan executable" } 183} elseif { $iex == "" } { 184 puts -nonewline "Absolute path to gpsman executable? " 185 flush stdout 186 gets stdin iex 187 if { [file pathtype $iex] != "absolute" } { 188 puts stderr "Bad path" 189 exit 1 190 } 191} elseif { $DEBUG } { puts "DEBUG: using $iex as GPSMan executable" } 192 193set isd [FindValues SRCDIR $iex] 194 195if { ! [file isdirectory $isd] || ! [file exists $isd/wrtdials.tcl] } { 196 puts -nonewline "Absolute path to the GPSMan source directory?" 197 flush stdout 198 gets stdin isd 199 if { [file pathtype $isd] != "absolute" || \ 200 ! [file isdirectory $isd] || ! [file exists $isd/wrtdials.tcl] } { 201 puts stderr "Bad path" 202 exit 1 203 } 204} elseif { $DEBUG } { puts "DEBUG: using $isd as installed source directory" } 205 206if { [file exists [set uex $ugd/gpsman.tcl]] } { 207 ## editing updated executable (if any) to set crucial variables to 208 # the values in the installed executable 209 # assume each set instruction still has a single line with single spaces 210 # surrounding the variable name 211 # assume the order of in which these variables are set is as follows: 212 # DEFSPORT, USERDIR, USEROPTIONS, PRINTCMD, SRCDIR 213 # and that the values for Unix-like systems appear before than those 214 # for other systems 215 216 puts "Making backup copy of $iex to $isd/gpsman.tcl-old" 217 # take care of links 218 set fiex $iex 219 while { [file type $fiex] == "link" } { 220 if { [file pathtype [set tgt [file link $fiex]]] == "relative" } { 221 set fiex [file join [file dirname $fiex] $tgt] 222 } else { set fiex $tgt } 223 } 224 if { ! $DEBUG } { 225 file copy -force $fiex $isd/gpsman.tcl-old 226 } else { 227 puts "DEBUG: file copy -force $fiex $isd/gpsman.tcl-old" 228 } 229 230 puts "The following variables in $iex will be preserved:" 231 puts "\tSRCDIR \t$isd" 232 set vars "DEFSPORT USERDIR USEROPTIONS PRINTCMD" 233 set vals [FindValues $vars $iex] 234 foreach v $vars val $vals { 235 puts "\t$v \t$val" 236 } 237 puts "Preserving any other change to $iex must be made by hand!" 238 if { ! $DEBUG } { 239 file copy -force $ugd/gpsman.tcl $fiex 240 } else { 241 puts "DEBUG: file copy -force $ugd/gpsman.tcl $fiex" 242 } 243 lappend vars SRCDIR ; lappend vals $isd 244 SetValues $vars $vals $fiex . 245 if { ! $DEBUG } { 246 file attributes $fiex -permissions 0755 247 } else { 248 puts "DEBUG: file attributes $fiex -permissions 0755" 249 } 250} 251 252# other source files and icons 253 254puts "Copying updated files to $isd..." 255 256foreach f [glob $ugd/*.tcl] { 257 if { $f != "$ugd/gpsman.tcl" } { 258 if { ! $DEBUG } { 259 file copy -force $f $isd 260 file attributes $isd/[file tail $f] -permissions 0644 261 } else { 262 puts "DEBUG: file copy -force $f $isd" 263 puts "DEBUG: file attributes $isd/[file tail $f] -permissions 0644" 264 } 265 } 266} 267 268if { [file exists $ugd/gmicons] } { 269 foreach f [glob $ugd/gmicons/*] { 270 if { ! $DEBUG } { 271 file copy -force $f $isd/gmicons 272 file attributes $isd/gmicons/[file tail $f] -permissions 0644 273 } else { 274 puts "DEBUG: file copy -force $f $isd/gmicons" 275 puts \ 276 "DEBUG: file attributes $isd/gmicons/[file tail $f] -permissions 0644" 277 } 278 } 279} 280 281# utilities 282 283set uud $ugd/util 284if { [file exists $uud] } { 285 set iud "" 286 foreach d "$isd $isd/util" { 287 if { [file exists $d] && [file isdirectory $d] && \ 288 [file exists $d/exerciser.tcl] } { 289 set iud $d 290 break 291 } 292 } 293 if { $iud == "" } { 294 puts -nonewline "Absolute path to util directory? " 295 flush stdout 296 gets stdin iud 297 if { [file pathtype $iud] != "absolute" || \ 298 ! [file isdirectory $iud] } { 299 puts stderr "Bad path" 300 exit 1 301 } 302 } 303 puts "Copying updated utilities to $iud..." 304 foreach f [glob $uud/*] { 305 if { ! $DEBUG } { 306 file copy -force $f $iud 307 file attributes $iud/[file tail $f] -permissions 0755 308 } else { 309 puts "DEBUG: file copy -force $f $iud" 310 puts "DEBUG: file attributes $iud/[file tail $f] -permissions 0755" 311 } 312 } 313 puts "The utility programs may also require configuration by hand!" 314} 315 316puts "Finished" 317 318exit 0 319 320 321 322