Fix Jazz Jackrabbit 2 on Wine

0009:err:seh:setup_exception_record stack overflow 992 bytes in thread 0009 eip 7e572f2a esp 00240f50 stack 0x240000-0x241000-0x340000
0044:err:ntdll:RtlpWaitForCriticalSection section 0x7e5cb7a0 "freetype.c: freetype_cs" wait timed out in thread 0044, blocked by 0009, retrying (60 sec)
^C0045:fixme:console:CONSOLE_DefaultHandler Terminating process 8 on event 0

This issue was particularly difficult to nail down. At one point, I saw a stack trace (but failed to save the output) where some amd driver was the next-to-last in the stack, so I think this issue is related to my AMD Radeon card (nothing to write home about).

The error tends to happen when loading a new level of the game. However, it is possible to trigger it within a level.

Running the game with the “-Safe” flag to run in safe mode prevents the crashes entirely.

I thought at first the freetype.c thing meant it was font-related, and that possibly I was missing an i686 package for a font. However, I had every i686 package for every x86_64 one, so it wasn’t loading the wrong type. I also ensured I started wine with WINEARCH=win32.

I eventually fixed the issue by changing the game settings for the audio! To prevent game crashes, you need to configure “Sound & Music Properties” and uncheck “Use DirectSound (faster).” If you leave that option checked, it will crash the game usually when loading levels.

Advertisements

Extract icons from .exe files

In this cross-platform world, sometimes you just really need an icon from a .exe binary. Thanks to the StackOverflow community, here is the definitive method to do that.
Install icoutils.

dnf install icoutils
# OR
sudo apt-get install icoutils

Use resource 14 (icon groups) to extract the icons.

wrestool -x -t 14 mybinary.exe -o outputdir/

Instructions for Setting Up a CentOS 7 System with Bridged Networking for Virtual Machines

CentOS 7 bridging network card for virtual machines

My goal is to set up virtualization where the guests can access the entire LAN as well as the host over the network. The host should also be able to reach all the guests via the network.

This task was so simple, but somehow it eluded me for over a year. I use this document to establish a new kvm host in my network pool.

Install virtualization tools

sudo yum -y install libvirt qemu-kvm virt-install
sudo systemctl enable libvirtd.service ; sudo systemctl start libvirtd.service
sudo setsebool -P virt_use_nfs 1

Adjust the ethernet configuration

sudo su -
{
this_nic="$( nmcli device show | awk '/^GENERAL.DEVICE:/ && $2 ~ /e.*/ {print $2}' )"
indir=/etc/sysconfig/network-scripts
this_bridge=br0
this_nic_count="$( printf "%s\n" "${this_nic}" | sed '/^\s*$/d' | wc -l )"
if test ${this_nic_count} -ne 1 ;
then
   echo "Other than 1 nic detected. Please deal with manually. Aborted."
else
   # prepare values for bridge definition
   this_mac="$( ip -o link | grep "${this_nic}" | grep -oE 'ether [a-fA-F0-9:]{17}' | awk '{print $2}' | tr '[[:lower:]]' '[[:upper:]]' )"
   this_ipaddr="$( ip -o address show "${this_nic}" | grep -oE 'inet [0-9\.]{7,15}' | awk '{print $2}' )"
   # define bridge interface
   {
      echo "DEVICE=${this_bridge}"
      echo "TYPE=Bridge"
      echo "ONBOOT=yes"
      echo "DELAY=0"
      grep -h -E 'DNS1|DNS2|DOMAIN|IPADDR|PREFIX|BOOTPROTO|GATEWAY|DEFROUTE' "${indir}/ifcfg-${this_nic}"
   } > "${indir}/ifcfg-${this_bridge}"
   # define ethernet card
   old_nic_file="${indir}/ifcfg-${this_nic}"
   temp_nic_file="${indir}/ifcfg-${this_nic}-new"
   {
      echo "DEVICE=${this_nic}"
      echo "HWADDR=${this_mac}"
      echo "ONBOOT=yes"
      echo "BRIDGE=${this_bridge}"
      grep -h -E 'UUID' "${old_nic_file}"
   } > "${temp_nic_file}"
   chmod --reference "${old_nic_file}" "${temp_nic_file}"
   /bin/mv -f "${temp_nic_file}" "${old_nic_file}"
fi
}

systemctl restart network.service NetworkManager.service

Using the virtual host

With the setup complete, the environment is ready to serve virtual machines!

Install a virtual machine

vm=c7-03a ; time sudo virt-install -n "${vm}" --memory 2048 --vcpus=1 --os-variant=centos7.0 --accelerate -v --disk path=/var/lib/libvirt/images/"${vm}".qcow2,size=20 -l /mnt/public/Support/SetupsBig/Linux/CentOS-7-x86_64-Minimal-1804.iso --initrd-inject=/mnt/public/Support/Platforms/CentOS7/centos7-ks.cfg --extra-args "ks=file:/centos7-ks.cfg SERVERNAME=${vm} NOTIFYEMAIL=bgstack15@ipa.example.com" --debug --network type=bridge,source=br0 --noautoconsole

Delete a virtual machine

vm=c7-03a; sudo virsh destroy "${vm}"; sudo virsh undefine --remove-all-storage "${vm}";

References

Weblinks

  1. https://wiki.libvirt.org/page/Networking

Internal files

  1. file:///mnt/public/Support/Platforms/CentOS7/centos7-ks.cfg

Setup Yum Repository with Security Metadata

Define repository

Prepare the repo file on the server, so clients can download it.

cd /var/www/html/yum
cat <<'EOF' > hosting.repo
[hosting]
name=Hosting Delivery
baseurl=http://yum5.ipa.example.com/yum/hosting/
enabled=0
gpgcheck=0
EOF

Make or update repository

Use createrepo tool to make the repository. A wrapper script for creating or updating the existing repository is shown here.

tf=/usr/local/bin/updaterepo.sh
cat <<'EOF' > "${tf}"
#!/bin/sh
# reference:
#    https://gitlab.com/bgstack15/mirror/blob/master/usr/share/mirror/examples/rpm/update-smith122rpm.sh

# Prepare directory and files
test -z "${UR_REPODIR}" && UR_REPODIR=/var/www/html/yum/hosting
test -z "${UR_BASEURL}" && UR_BASEURL=http://yum5.ipa.example.com/yum/hosting
test -z "${UR_OWNERSHIP}" && UR_OWNERSHIP="root.root"
test -z "${UR_FILETYPES}" && UR_FILETYPES="rpm"

find "${UR_REPODIR}" -exec chown "${UR_OWNERSHIP}" {} + 1>/dev/null 2>&1
find "${UR_REPODIR}" -type f -exec chmod "0664" {} + 1>/dev/null 2>&1
find "${UR_REPODIR}" -type d -exec chmod "0775" {} + 1>/dev/null 2>&1
chmod 0754 "$0"
restorecon -RF "${UR_REPODIR}"

# Prepare repo for rpm
cd "${UR_REPODIR}"
createrepo -v -u "${UR_BASEURL}" --basedir "${UR_REPODIR}" --simple-md-filenames --no-database --update --pretty .
EOF

Run this script.

/usr/local/bin/updaterepo.sh

Manually make the security metadata

The security metadata that yum interprets is stored in updateinfo.xml.gz. To make this file and include it in repomd.xml, you need to prepare it and learn some information about it.

This is a trim example of updateinfo.xml. Please see the epel metadata for a full example. I do not have an automatic process for generating this file yet.

tf=updateinfo.xml
cat <<'EOF' > "${tf}"
<?xml version="1.0" encoding="UTF-8"?>
<updates>
  <update status="final" type="security" version="1" from="bgstack15@gmail.com">
    <id>HELP-210217</id>
    <title>bgscripts-core update</title>
    <release>Enterprise Linux 7</release>
    <issued date="2018-04-02"/>
    <rights>CC-BY-SA 4.0</rights>
    <description>bgscripts-core
[1.3-8]
- latest version from upstream
</description>
    <solution>This update is internal to the company.</solution>
    <references>
      <reference href="https://gitlab.com/bgstack15/bgscripts" type="self" title="bgscripts-core" />
    </references>
    <pkglist>
      <collection short="bgscripts">
        <name>bgscripts suite</name>
        <package name="bgscripts-core" version="1.3-8" release="" epoch="0" arch="noarch">
          <filename>bgscripts-core-1.3-8.noarch.rpm</filename>
          <sum type="md5">eaa20075720bf12d6e837a4f546241ab</sum>
        </package>
     </collection>
    </pkglist>
  </update>
</updates>
EOF

Update the repo metadata to include updateinfo.xml

A yum repository includes metadata of the package metadata, and stores this meta-metadata in repomd.xml. Insert the metadata for this new file, updateinfo.xml in the repomd file.
This script is an update version of updaterepo.sh, which was listed earlier in this document.

tf=/usr/local/bin/updaterepo.sh
        cat <<'EOF' > "${tf}"
#!/bin/sh
# reference:
#    https://gitlab.com/bgstack15/mirror/blob/master/usr/share/mirror/examples/rpm/update-smith122rpm.sh

# Prepare directory and files
test -z "${UR_REPODIR}" && UR_REPODIR=/var/www/html/yum/hosting
test -z "${UR_BASEURL}" && UR_BASEURL=http://yum5.ipa.example.com/yum/hosting
test -z "${UR_OWNERSHIP}" && UR_OWNERSHIP="root.root"
test -z "${UR_FILETYPES}" && UR_FILETYPES="rpm"
test -z "${UR_UPDATEINFO_INPUT}" && UR_UPDATEINFO_INPUT=/var/www/html/yum/build-hosting-repo/updateinfo.xml

find "${UR_REPODIR}" -exec chown "${UR_OWNERSHIP}" {} + 1>/dev/null 2>&1
find "${UR_REPODIR}" -type f -exec chmod "0664" {} + 1>/dev/null 2>&1
find "${UR_REPODIR}" -type d -exec chmod "0775" {} + 1>/dev/null 2>&1
chmod 0754 "$0"
restorecon -RF "${UR_REPODIR}"

# Prepare basic repo
cd "${UR_REPODIR}"
createrepo -v -u "${UR_BASEURL}" --basedir "${UR_REPODIR}" --simple-md-filenames --no-database --update --pretty .

# Inject custom updateinfo
# this task assumes the repomd file does not include node <data type="updateinfo"> yet.
UR_repomd="${UR_REPODIR}/repodata/repomd.xml"
UR_updateinfo_gz_short="repodata/updateinfo.xml.gz"
UR_updateinfo_gz="${UR_REPODIR}/${UR_updateinfo_gz_short}"

if ! test -e "${UR_UPDATEINFO_INPUT}" ;
then
   # file is absent, so decide how to fail.
   :
else
   # file exists, so continue with custom injection

   # learn open-size and open-checksum
   UR_updateinfo_opensize="$( /usr/bin/stat -c "%s" "${UR_UPDATEINFO_INPUT}" )"
   UR_updateinfo_openchecksum="$( /usr/bin/sha256sum "${UR_UPDATEINFO_INPUT}" | awk '{print $1}' )"

   # compress file and learn size and checksum
   /usr/bin/gzip < "${UR_UPDATEINFO_INPUT}" > "${UR_updateinfo_gz}"
   UR_updateinfo_size="$( /usr/bin/stat -c "%s" "${UR_updateinfo_gz}" )"
   UR_updateinfo_checksum="$( /usr/bin/sha256sum "${UR_updateinfo_gz}" | awk '{print $1}' )"
   UR_updateinfo_timestamp="$( /usr/bin/stat -c "%Y" "${UR_updateinfo_gz}" )"

   # insert information into repomd
   this_string="<data type=\"updateinfo\">
  <checksum type=\"sha256\">${UR_updateinfo_checksum}</checksum>
  <open-checksum type=\"sha256\">${UR_updateinfo_openchecksum}</open-checksum>
  <location xml:base=\"${UR_BASEURL}\" href=\"${UR_updateinfo_gz_short}\"/>
  <timestamp>${UR_updateinfo_timestamp}</timestamp>
  <size>${UR_updateinfo_size}</size>
  <open-size>${UR_updateinfo_opensize}</open-size>
</data>"

   {
      sed -r -e '/<\/repomd>/d' "${UR_repomd}"
      printf "%s\n%s\n" "${this_string}" "</repomd>"
   } > "${UR_repomd}.$$"
   /bin/touch --reference "${UR_repomd}" "${UR_repomd}.$$"
   /bin/mv -f "${UR_repomd}.$$" "${UR_repomd}"
fi
EOF

Summary

Using bash to modify xml files is obviously not ideal. However, this xml file is simple enough so this ugly mechanism suffices. For teams that know how to manage custom yum repositories and also want to just use yum update –security, this process should be a good basis or even complete solution!

Appendices

Appendix A: http proxy

If you use an http proxy for your yum traffic, the proxy might cache old versions of the metadata or package files. A quick and dirty way to clean up a squid proxy of the metadata file follows.

time squidclient -h localhost -r -p 3128 -m PURGE http://yum5.ipa.example.com/yum/hosting/repodata/updateinfo.xml.gz

Squid unfortunately does not allow recursive purging, so you will have to loop over all the metadata files and any package files you want to ensure get cleared.

References

Local file /var/cache/yum/x86_64/7Server/epel/69b82df00108c0ac8ac82fafbd0f3b89cc98d8dfe4fa350af7a23331a878fea2-updateinfo.xml.bz2

Fix CentOS 7 and motherboard clock UTC problem

If you have a freshly installed CentOS 7 system, and when you reboot the time is a few hours off, you might find this info useful.

A probably reason for this error is the system is fetching the hardware clock which is not set in UTC, and so the offset is basically doubled. Or possible the hardware clock is set in UTC but GNU/Linux doesn’t know that.

Here’s how to fix it (courtesy of Michael Hampton at Stack Overflow— what doesn’t he know?).

Fix the date.

# You might need to stop ntpd first.
#systemctl stop ntpd
ntpdate 192.168.1.10

Ensure the date is correct

date

 

# sync hardware clock to the system time
hwclock -wu

And just remember to start up ntpd if you need it.

Changing screen resolution on Linux terminal server

If you’re using xvnc on Linux (for example, if you’re running Xfce on xrdp on Fedora) and you want to resize the display, here’s a way to do it.

DISPLAY=:10 xrandr --output VNC-0 --mode 1024x768

You could also use an –auto instead of a –mode XxY setting.

Apparently I like to redo my own work.
Check out resize.sh from my bgscripts package.

for word in $( xrandr --listactivemonitors | awk 'NR != 1 { print $NF; }'; ); do xrandr --output ${word} --auto 1>/dev/null 2>&1; done