Basically, the directory client/o2k13 is for static downloads. These are mostly service packs, which are downloaded using predefined lists. For example, the directory client/o2k13/enu corresponds to the lists static/StaticDownloadLinks-o2k13-enu.txt and static/StaticDownloadLinks-o2k13-x64-enu.txt, if Office 64-bit support is enabled with the Windows script cmd/AddOffice2010x64Support.cmd.
The directory client/ofc contains dynamic updates for all office versions.
But there are several bugs, how the script DownloadUpdates.sh calculates these updates.
Note: Skip the rest of this post, if you don't like to read technical details. This is more to bother the official maintainer of the Linux scripts.IntroductionThe script DownloadUpdates.sh switches between command line processing and the interactive setup of parameters in this if-statement:
DownloadUpdates.sh v. 10.2.1+ (r709), line 396 - 411- Code: Select all
#check if parameters are valid
if [ "$1" != "" ]; then
externparam="1"
evaluateparams $@
else
#get parameters
getsystem
getlanguage
getservicepack
getdotnet
getmsse
getwddefs
getwle
getproxy
makeiso
fi
This means:
- If parameters are passed on the command line, then the function evaluateparams() is called to process these parameters.
- If the script is called without any parameters, then the individual functions getsystem(), getlanguage(), ..., are called to setup all options interactively.
An important point is:
At the end of this if-statement, the setup must be the same.Any processing, which is done in the function evaluateparams(), must
also be done in the individual functions, and vice versa.
But there are four omissions, where some processing is done in evaluateparams(), but not in the functions getsystem(), getlanguage(), and getwddefs().
Setup of the systemIf one of the office updates is selected, the function evaluateparams() does some postprocessing to setup two variables:
commonparts.inc, 10.2.1+ (r709), line 101 - 107- Code: Select all
sys_old=""
case $sys in
o2k*)
sys_old=$sys
sys="ofc"
;;
esac
Afterwards, these variables have the values:
- $sys_old is the original parameter as passed on the command line, for example o2k7
- $sys is set to "ofc"
But this type of postprocessing is missing in getsystem(). This function only initializes the variable $sys_old to an empty string:
DownloadUpdates.sh, 10.2.1+ (r709), line 188- Code: Select all
sys_old=""
This is the likely reason, why the script doesn't process "ofc" at all, if the interactive setup is used.
Setup of the languageIn the function evaluateparams(), the language will be set to "glb" for Windows Vista, 7, 8 and 8.1:
commonparts.inc, 10.2.1+ (r709), line 92 - 99- Code: Select all
Origlang=$lang
case $sys in
w6[0-3]*)
# echo "Setting language to glb..."
lang="glb"
;;
esac
After this postprocessing, $Origlang is the original language as set on the command line, and $lang is changed to "glb" for Windows Vista (w60*) to Windows 8.1 (w63*). But this case-statement should also include Windows 10.0 and possibly Office 2016.
This logic is missing at all in the function getlanguage(). This function just sets both variables the same:
DownloadUpdates.sh, 10.2.1+ (r709), line 233 - 234- Code: Select all
lang=$1
Origlang=$lang
The definition of the locales ($LANG_SHORT) is done in the function evaluateparams(), but missing in getlanguage().
Setup of wddefsThe function evaluateparams() changes the parameter from /wddefs to /msse for Windows 8.0:
commonparts.inc, 10.2.1+ (r709), line 157 - 168- Code: Select all
if grep -q /wddefs <<< $Cmdline ; then
case $sys in
w62*)
param5=/msse
msse="1"
;;
*)
param7=/wddefs
wddefs="1"
;;
esac
fi
In this case-statement, Windows 8.1 and Windows 10.0 are missing.
In the function getwddefs(), the complete application logic is missing.
Change listTo correct these omissions, we basically need two steps:
- Correct two case-statements in the function evaluateparams()
- Copy the missing application logic from the function evaluateparams() to the functions getsystem(), getlanguage(), and getwddefs().
Then we get this change list:
Changes to file commonparts.inc, version 10.2.1+ (r709)
function evaluateparams()
- three calls of printparams() are inserted, to display the usage page in case of missing or wrong parameters
- the variable $lang is set to glb for Windows 10
- the command line parameter /wddefs is treated as /msse for Windows 8.1 and 10.0
Changes to file DownloadUpdates.sh, version 10.2.1+ (r709)
function getsystem()
- Office 2016 is inserted into the selection menu
- the variables $sys and $sys_old are initialized as in evaluateparams()
function getlanguage()
- the variable $lang is initialized as in evaluateparams()
- the setup of the locales ($LANG_SHORT) is copied from evaluateparams()
function getwddefs()
- the parameter /wddefs is treated as /msse as in evaluateparams()
The revised functions then look like:
- Code: Select all
evaluateparams ()
{
Cmdline="$@";
paramlist=("/excludesp" "/dotnet" "/msse" "/makeiso" "/nocleanup" "/proxy" "/wddefs" "/wle");
EXCLUDE_SP="0";
EXCLUDE_STATICS="0";
CLEANUP_DOWNLOADS="1";
createiso="0";
dotnet="0";
msse="0";
wddefs="0";
wle="0";
param1="";
param2="";
param3="";
param4="";
param5="";
param6="";
param7="";
param8="";
# determine system
grep -q -w $1 <<< $syslist && sys=$1;
test "$sys" || {
echo system $1 does not exist.;
printusage $Cmdline;
exit 1
};
case $sys in
*-x64)
OS_ARCH=x64;
OS_sys=$sys
;;
*)
OS_ARCH=x86;
OS_sys=${sys}-x86
;;
esac;
# determine language
test "$2" || {
echo language is not set.;
printusage $Cmdline;
exit 1
};
grep -q -w $2 <<< $langlist && lang=$2;
test "$lang" || {
echo language $2 does not exist.;
printusage $Cmdline;
exit 1
};
# changing $lang to "glb" for global updates
Origlang=$lang;
case $sys in
w6[0-3]* | w100*)
lang="glb"
;;
esac;
# postprocessing for office updates
sys_old="";
case $sys in
o2k*)
sys_old=$sys;
sys="ofc"
;;
esac;
# setting locales for office updates
case "$lang" in
enu)
LANG_SHORT=en
;;
fra)
LANG_SHORT=fr
;;
esn)
LANG_SHORT=es
;;
jpn)
LANG_SHORT=ja
;;
kor)
LANG_SHORT=ko
;;
rus)
LANG_SHORT=ru
;;
ptg)
LANG_SHORT=pt
;;
ptb)
LANG_SHORT=pt-br
;;
deu)
LANG_SHORT=de
;;
nld)
LANG_SHORT=nl
;;
ita)
LANG_SHORT=it
;;
chs)
LANG_SHORT=zh-cn
;;
cht)
LANG_SHORT=zh-tw
;;
plk)
LANG_SHORT=pl
;;
hun)
LANG_SHORT=hu
;;
csy)
LANG_SHORT=cs
;;
sve)
LANG_SHORT=sv
;;
trk)
LANG_SHORT=tr
;;
ell)
LANG_SHORT=el
;;
ara)
LANG_SHORT=ar
;;
heb)
LANG_SHORT=he
;;
dan)
LANG_SHORT=da
;;
nor)
LANG_SHORT=no
;;
fin)
LANG_SHORT=fi
;;
esac;
# determine optional parameters
if grep -q /makeiso <<< $Cmdline; then
param1=/makeiso;
createiso="1";
fi;
if grep -q /dotnet <<< $Cmdline; then
param2=/dotnet;
dotnet="1";
fi;
if grep -q /excludesp <<< $Cmdline; then
param3=/excludesp;
EXCLUDE_SP="1";
fi;
if grep -q /nocleanup <<< $Cmdline; then
param4=/nocleanup;
CLEANUP_DOWNLOADS="0";
fi;
if grep -q /msse <<< $Cmdline; then
param5=/msse;
msse="1";
fi;
if grep -q /wddefs <<< $Cmdline; then
case $sys in
w62* | w63* | w100*)
param5=/msse;
msse="1"
;;
*)
param7=/wddefs;
wddefs="1"
;;
esac;
fi;
if grep -q /wle <<< $Cmdline; then
param8=/wle;
wle="1";
fi;
# determine proxy settings
shift 2;
while [ "$1" != "" ]; do
if [ "$1" == "/proxy" ]; then
http_proxy="$2";
param6="$1 $2";
break;
else
shift;
fi;
done;
# rather useless default call of printusage
if [ "$sys" == "" -o "$lang" == "" ]; then
printusage $Cmdline;
fi
}
getsystem ()
{
cat <<END
Please select your OS:
[1] Windows Vista / Server 2008 [2] Windows Vista / Server 2008 64 bit
[3] Windows 7 (w61) [4] Windows 7 / Server 2008 R2 64 bit
[5] Windows 8 (w62) [6] Windows 8 / Server 2012 64 bit
[7] Windows 8.1 (w63) [8] Windows 8.1 / Server 2012 R2 64 bit
[9] Windows 10 (w100) [10] Windows 10 / Server 2016 64 bit
[11] All Windows 32 bit [12] All Windows 64 bit
[13] Office 2007 [14] Office 2010 [15] Office 2013
[16] Office 2016
[17] All Office updates (2007 - 2016)
[18] all Windows 7 [19] all Windows 8 [20] all Windows 8.1
[21] all Windows 10
END
read -p "which number? " syschoice
sysmax=$(wc -w <<< $syslist);
test "$syschoice" || exit 1;
if [ $syschoice -lt 1 -o $syschoice -gt $sysmax ]; then
echo "Program aborted.";
echo;
exit 1;
fi;
set -- $(echo $syslist);
shift $((syschoice -1));
sys=$1;
case $sys in
*-x64)
OS_ARCH=x64;
OS_sys=$sys
;;
*)
OS_ARCH=x86;
OS_sys=${sys}-x86
;;
esac
# postprocessing for office updates
sys_old="";
case $sys in
o2k*)
sys_old=$sys;
sys="ofc"
;;
esac;
}
getlanguage ()
{
# Bug: the variable $lang is not set at this point. Actually, the language
# selection should always stay enabled to allow the inclusion of localized
# installers for .Net Frameworks and other optional downloads.
#if [ "$lang" != "glb" ]; then
cat <<END
Please select your OS language:
[a] enu [b] deu [c] nld [d] esn
[e] fra [f] ptg [g] ptb [h] ita
[i] rus [j] plk [k] ell [l] csy
[m] dan [n] nor [o] sve [p] fin
[q] jpn [r] kor [s] chs [t] cht
[u] hun [v] trk [w] ara [x] heb
END
read -p "which letter? " langchoice
langmax=$(($(wc -w <<< $langlist) - 1 ));
test "$langchoice" || {
echo "Program aborted";
exit 1
};
echo;
langnr=$(($(printf '%d' "'$langchoice'") - 97));
if [ $langnr -lt 0 -o $langnr -gt $langmax ]; then
echo "Program aborted.";
exit 1;
fi;
set -- $(echo $langlist);
shift $langnr;
lang=$1;
# changing $lang to "glb" for global updates
Origlang=$lang;
case $sys in
w6[0-3]* | w100*)
lang="glb"
;;
esac;
# setting locales for office updates
case "$lang" in
enu)
LANG_SHORT=en
;;
fra)
LANG_SHORT=fr
;;
esn)
LANG_SHORT=es
;;
jpn)
LANG_SHORT=ja
;;
kor)
LANG_SHORT=ko
;;
rus)
LANG_SHORT=ru
;;
ptg)
LANG_SHORT=pt
;;
ptb)
LANG_SHORT=pt-br
;;
deu)
LANG_SHORT=de
;;
nld)
LANG_SHORT=nl
;;
ita)
LANG_SHORT=it
;;
chs)
LANG_SHORT=zh-cn
;;
cht)
LANG_SHORT=zh-tw
;;
plk)
LANG_SHORT=pl
;;
hun)
LANG_SHORT=hu
;;
csy)
LANG_SHORT=cs
;;
sve)
LANG_SHORT=sv
;;
trk)
LANG_SHORT=tr
;;
ell)
LANG_SHORT=el
;;
ara)
LANG_SHORT=ar
;;
heb)
LANG_SHORT=he
;;
dan)
LANG_SHORT=da
;;
nor)
LANG_SHORT=no
;;
fin)
LANG_SHORT=fi
;;
esac;
#fi
}
getwddefs ()
{
wddefs="0";
read -p "Download Microsoft Windows Defender definition files? [y/n] " addwddefs;
if [ "$addwddefs" == "y" ]; then
case $sys in
w62* | w63* | w100*)
param5="/msse";
msse="1"
;;
*)
param7="/wddefs";
wddefs="1"
;;
esac;
fi
}
Testing and comparing the resultsTo compare the setup, all mentioned variables could be printed after the if-statement:
- Code: Select all
#check if parameters are valid
if [ "$1" != "" ]; then
externparam="1"
evaluateparams $@
else
#get parameters
getsystem
getlanguage
getservicepack
getdotnet
getmsse
getwddefs
getwle
getproxy
makeiso
fi
# comparing the results after different modes of initialization
echo "========================================"
echo "Values of internal variables after setup"
echo "Original system: $sys_old"
echo "System: $sys"
echo "Original language: $Origlang"
echo "Language: $lang"
echo "Language locale: $LANG_SHORT"
echo "Parameter 5: $param5"
echo "Option msse: $msse"
echo "Parameter 7: $param7"
echo "Option wddefs: $wddefs"
echo "========================================"
The expected result is, that the output is the same for the interactive setup and the evaluation of command line parameters.
Additional commentsInstead of duplicating the missing code, the common parts could also be inserted below the if-statement, just like the output of the variables shown above. The common parts could then be removed from the function evaluteparams(). On the other hand, the function evaluteparams() is also used in CreateISOImage.sh, and then this script had to be revised, too.
The script DownloadUpdates.sh defines a list "ofc", which includes "o2k7 o2k10 o2k13 o2k16".
DownloadUpdates.sh, 10.2.1+ (r709), line 465 - 473- Code: Select all
Liste=""
case $sys in
# ...
ofc) test "$sys_old" || Liste="o2k7 o2k10 o2k13 o2k16" ;;
But I think, it is highly confusing and error-prone, if "ofc" is used with two completely different meanings:
- as a built-in list for "o2k7 o2k10 o2k13 o2k16"
- as a subtask to get dynamic updates for all Office versions
The list "ofc" should be renamed to "all-o2k" or similar.
The variable $sys_old could also be renamed to $orig_sys or similar, to make its meaning more obvious.
Swapping options like wddefs and msse behind the scenes seems to confuse users more than it helps:
Maybe a third option for Windows 8 and higher would really be helpful. This would be derived from msse, but only download the virus definition updates without the installers.
Mixing the interactive setup and command line processing obscures the flow of control. The interactive setup of parameters and the processing of the downloads should be done in two separate scripts. On the Windows side, the UpdateGenerator.exe does the setup, and the script DownloadUpdates.cmd runs without any user interaction.
TL;DRThere are several major omissions in the processing of parameters, if the interactive setup is used. "ofc" for dynamic office updates is not used, and the language locales are not defined.