Hello community, here is the log from the commit of package kdump for openSUSE:Factory checked in at 2014-06-02 07:00:23 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/kdump (Old) and /work/SRC/openSUSE:Factory/.kdump.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "kdump" Changes: -------- --- /work/SRC/openSUSE:Factory/kdump/kdump.changes 2014-05-23 08:05:25.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.kdump.new/kdump.changes 2014-06-02 07:00:39.000000000 +0200 @@ -1,0 +2,13 @@ +Fri May 30 11:31:44 UTC 2014 - [email protected] + +- Update to 0.8.13 + o Store current configuration if KDUMP_NETCONFIG is static + (bnc#876212). + o Modify kdump udev rules to work with systemd + (bnc#874992, bnc#809209). + o Support percent-encoded URLs for KDUMP_SAVEDIR (bnc#869590). + +- kdump-fix-udev-rules.patch: Dropped. +- kdump-urldecode.patch: Dropped. + +------------------------------------------------------------------- Old: ---- kdump-0.8.12-rpmlintrc kdump-0.8.12.tar.bz2 kdump-fix-udev-rules.patch kdump-urldecode.patch New: ---- kdump-0.8.13-rpmlintrc kdump-0.8.13.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ kdump.spec ++++++ --- /var/tmp/diff_new_pack.XA4XLr/_old 2014-06-02 07:00:40.000000000 +0200 +++ /var/tmp/diff_new_pack.XA4XLr/_new 2014-06-02 07:00:40.000000000 +0200 @@ -31,7 +31,7 @@ Url: https://github.com/ptesarik/kdump Name: kdump -Version: 0.8.12 +Version: 0.8.13 Release: 0 Requires: curl Requires: makedumpfile @@ -59,8 +59,6 @@ Source: %{name}-%{version}.tar.bz2 Source2: %{name}-%{version}-rpmlintrc Source3: kdump.service -Patch1: %{name}-fix-udev-rules.patch -Patch2: %{name}-urldecode.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build # rename "kdump-helpers" (10.3) -> "kdump" (11.0/SP2) Provides: kdump-helpers = %{version} @@ -98,9 +96,6 @@ %prep %setup -%patch1 -p1 -%patch2 -p1 -chmod +x tests/testurldecode.sh %build export CFLAGS="%optflags" ++++++ kdump-0.8.12-rpmlintrc -> kdump-0.8.13-rpmlintrc ++++++ ++++++ kdump-0.8.12.tar.bz2 -> kdump-0.8.13.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdump-0.8.12/70-kdump.rules new/kdump-0.8.13/70-kdump.rules --- old/kdump-0.8.12/70-kdump.rules 2014-05-16 19:31:02.000000000 +0200 +++ new/kdump-0.8.13/70-kdump.rules 1970-01-01 01:00:00.000000000 +0100 @@ -1,12 +0,0 @@ -# -# Kdump core headers needs to be regnerated if the CPUs or memory changes. -# For this, reload kdump. -# -# Novell Bug #389658 -# - -SUBSYSTEM=="cpu", ACTION=="online", PROGRAM="/etc/init.d/boot.kdump try-restart" -SUBSYSTEM=="cpu", ACTION=="offline", PROGRAM="/etc/init.d/boot.kdump try-restart" -SUBSYSTEM=="memory", ACTION=="add", PROGRAM="/etc/init.d/boot.kdump try-restart" -SUBSYSTEM=="memory", ACTION=="remove", PROGRAM="/etc/init.d/boot.kdump try-restart" - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdump-0.8.12/70-kdump.rules.in new/kdump-0.8.13/70-kdump.rules.in --- old/kdump-0.8.12/70-kdump.rules.in 1970-01-01 01:00:00.000000000 +0100 +++ new/kdump-0.8.13/70-kdump.rules.in 2014-05-30 13:24:24.000000000 +0200 @@ -0,0 +1,37 @@ +@if @ARCH@ s390 s390x +# +# For s390x the ELF header is created in the kdump kernel and therefore +# no kdump udev rules are required. +# +@else +# +# Kdump core headers needs to be regnerated if the CPUs or memory changes. +# For this, reload kdump. +# +# Novell Bug #389658 +# + +TEST=="/usr/bin/systemctl", GOTO="kdump_systemd" + +@if @ARCH@ ppc ppc64 ppc64le +SUBSYSTEM=="cpu", ACTION=="online", RUN+="/etc/init.d/boot.kdump try-restart" +SUBSYSTEM=="cpu", ACTION=="offline", RUN+="/etc/init.d/boot.kdump try-restart" +@endif +SUBSYSTEM=="memory", ACTION=="add", RUN+="/etc/init.d/boot.kdump try-restart" +SUBSYSTEM=="memory", ACTION=="remove", RUN+="/etc/init.d/boot.kdump try-restart" + +GOTO="kdump_end" + +# Systemd limits service start rate, so if udev events are emitted too +# often, kdump will enter failed state, unless the counter is reset here. +LABEL="kdump_systemd" + +@if @ARCH@ ppc ppc64 ppc64le +SUBSYSTEM=="cpu", ACTION=="online", RUN+="/usr/bin/systemctl reset-failed kdump", RUN+="/usr/bin/systemctl try-restart kdump" +SUBSYSTEM=="cpu", ACTION=="offline", RUN+="/usr/bin/systemctl reset-failed kdump", RUN+="/usr/bin/systemctl try-restart kdump" +@endif +SUBSYSTEM=="memory", ACTION=="add", RUN+="/usr/bin/systemctl reset-failed kdump", RUN+="/usr/bin/systemctl try-restart kdump" +SUBSYSTEM=="memory", ACTION=="remove", RUN+="/usr/bin/systemctl reset-failed kdump", RUN+="/usr/bin/systemctl try-restart kdump" + +LABEL="kdump_end" +@endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdump-0.8.12/CMakeLists.txt new/kdump-0.8.13/CMakeLists.txt --- old/kdump-0.8.12/CMakeLists.txt 2014-05-16 19:31:02.000000000 +0200 +++ new/kdump-0.8.13/CMakeLists.txt 2014-05-30 13:24:24.000000000 +0200 @@ -26,7 +26,7 @@ cmake_minimum_required(VERSION 2.6.2) set (PACKAGE_STRING "kdump") -set (PACKAGE_VERSION "0.8.12") +set (PACKAGE_VERSION "0.8.13") include_directories("${PROJECT_BINARY_DIR}") @@ -195,8 +195,26 @@ /var/adm/fillup-templates/ ) +ADD_CUSTOM_COMMAND( + OUTPUT + 70-kdump.rules + COMMAND + ARCH=${CMAKE_SYSTEM_PROCESSOR} + awk -f ${CMAKE_CURRENT_SOURCE_DIR}/process_cond.awk + ${CMAKE_CURRENT_SOURCE_DIR}/70-kdump.rules.in + > ${CMAKE_CURRENT_BINARY_DIR}/70-kdump.rules + DEPENDS + 70-kdump.rules.in +) +ADD_CUSTOM_TARGET( + kdump.rules + ALL + DEPENDS + 70-kdump.rules +) + INSTALL(FILES - ${CMAKE_CURRENT_SOURCE_DIR}/70-kdump.rules + ${CMAKE_CURRENT_BINARY_DIR}/70-kdump.rules DESTINATION /etc/udev/rules.d ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdump-0.8.12/NEWS new/kdump-0.8.13/NEWS --- old/kdump-0.8.12/NEWS 2014-05-16 19:31:02.000000000 +0200 +++ new/kdump-0.8.13/NEWS 2014-05-30 13:24:24.000000000 +0200 @@ -1,3 +1,9 @@ +0.8.13 +------ + * Store current configuration if KDUMP_NETCONFIG is static + * Modify kdump udev rules to work with systemd (and clean them up) + * Support percent-encoded URLs for KDUMP_SAVEDIR + 0.8.12 ------ * Add "ssh" target protocol to transfer the file over the standard input diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdump-0.8.12/init/mkdumprd new/kdump-0.8.13/init/mkdumprd --- old/kdump-0.8.12/init/mkdumprd 2014-05-16 19:31:02.000000000 +0200 +++ new/kdump-0.8.13/init/mkdumprd 2014-05-30 13:24:24.000000000 +0200 @@ -156,8 +156,8 @@ fi if [ "$KDUMP_NETCONFIG" = "auto" ] ; then status_message "Network: auto" - DRACUT_ARGS+=" --kernel-cmdline 'rd.neednet=1 ip=any'" if [ -n "$neednet" ]; then + DRACUT_ARGS+=" --kernel-cmdline 'rd.neednet=1 ip=any'" modules="$modules network" fi elif [ -z "$KDUMP_NETCONFIG" ] ; then @@ -166,10 +166,19 @@ interface=$(echo "$KDUMP_NETCONFIG" | cut -d ':' -f 1) mode=$(echo "$KDUMP_NETCONFIG" | cut -d ':' -f 2) - status_message "Network interface: $interface" + if [ "$interface" = "default" ] ; then + interface=$( kdump_default_netdev ) + interface="${interface% *}" + status_message "Network interface: $interface (default)" + else + status_message "Network interface: $interface" + fi + if [ "$mode" = "static" ] ; then + ipcfg="$(kdump_ip_config "$interface")" + hwaddr=$(cat "/sys/class/net/$interface/address") status_message "Network mode: Static IP" - DRACUT_ARGS+=" --kernel-cmdline 'rd.neednet=1'" + DRACUT_ARGS+=" --kernel-cmdline 'rd.neednet=1 ip=$ipcfg::$hwaddr'" else status_message "Network mode: Automatic IP (DHCP)" DRACUT_ARGS+=" --kernel-cmdline 'rd.neednet=1 ip=${interface}:dhcp'" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdump-0.8.12/init/module-setup.sh new/kdump-0.8.13/init/module-setup.sh --- old/kdump-0.8.12/init/module-setup.sh 2014-05-16 19:31:02.000000000 +0200 +++ new/kdump-0.8.13/init/module-setup.sh 2014-05-30 13:24:24.000000000 +0200 @@ -18,7 +18,9 @@ kdump_setup_files "$initdir" "${!host_fs_types[*]}" + inst_hook mount 30 "$moddir/mount-kdump.sh" inst_hook pre-pivot 90 /lib/kdump/save_dump.sh inst_multiple makedumpfile makedumpfile-R.pl kdumptool \ $KDUMP_REQUIRED_PROGRAMS + inst_simple /etc/resolv.conf } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdump-0.8.12/init/mount-kdump.sh new/kdump-0.8.13/init/mount-kdump.sh --- old/kdump-0.8.12/init/mount-kdump.sh 1970-01-01 01:00:00.000000000 +0100 +++ new/kdump-0.8.13/init/mount-kdump.sh 2014-05-30 13:24:24.000000000 +0200 @@ -0,0 +1,25 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# +# mount-kdump.sh: fake successful mount without mounting anything +# +# The kdump module adds all necessary mount points under /kdump, +# so there is no need to mount root separately. In fact, mounting +# the root filesystem may not be needed at all, e.g. with FTP dump. +# + +# override ismounted: pretend that "$NEWROOT" is mounted +# since this function must return correct result for non-root fs, +# let's modify the existing definition using sed: +eval "$( + type ismounted | + sed -e '1,/^{/s/^{.*/&\n test "$1" != "$NEWROOT" || return 0/; 1d' +)" + +# override usable_root: everything is "usable" for kdump +usable_root() +{ + return 0 +} + +# vim: set sw=4 ts=4 et: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdump-0.8.12/init/setup-kdump.functions new/kdump-0.8.13/init/setup-kdump.functions --- old/kdump-0.8.12/init/setup-kdump.functions 2014-05-16 19:31:02.000000000 +0200 +++ new/kdump-0.8.13/init/setup-kdump.functions 2014-05-30 13:24:24.000000000 +0200 @@ -46,6 +46,169 @@ ) } # }}} +# Extract the device name from a route +# +# Input: +# output of "route show" +# Output: +# device name (for each line of input) +function kdump_route2dev() # {{{ +{ + sed -n 's/.* dev \([^ ]*\) *.*/\1/p' +} # }}} + +# +# Determine the default network device. +# +# Output: +# "$ifname $mode" +# ifname default network interface name (or empty if none) +# mode initialization mode ("static" or "dhcp") +function kdump_default_netdev() # {{{ +{ + local ifname BOOTPROTO + local inffile="/etc/install.inf" + + # check current default routes + ifname=$(ip route show 0/0 | kdump_route2dev) + if [ -z "$ifname" ] ; then + ifname=$(ip -6 route show ::/0 | kdump_route2dev) + fi + + # if not found, get info from install.inf + if [ -z "$ifname" -a -f "$inffile" ] ; then + local dev hwaddr hwaddr2 + eval $( sed -ne ' + s/^NetConfig: \(.*\)/BOOTPROTO=\1/p; + s/^Netdevice: \(.*\)/ifname=\1/p; + s/HWAddr: \(.*\)/hwaddr=\1/p' + "$inffile" ) + if [ -n "$hwaddr" ] ; then + for dev in /sys/class/net/* ; do + read hwaddr2 < "$dev"/address + if [ "$hwaddr" = "$hwaddr2" ] ; then + ifname="${dev##*/}" + fi + done + fi + fi + + # if still not found, there is no network + if [ -z "$ifname" ] ; then + return 0 + fi + + # get mode from config files + if [ -z "$BOOTPROTO" ] ; then + local cfg=/etc/sysconfig/network/ifcfg-"$ifname" + if [ -f "$cfg" ] ; then + eval $(grep '^[[:space:]]*BOOTPROTO=' "$cfg") + fi + fi + + # if not found, look if there is a dhcp daemon for the interface + if [ -z "$BOOTPROTO" ] ; then + if [ -n "$(ps -C dhclient,dhclient6,dhcpcd -o cmd= | + sed -n '/.* \('"$ifname"'\)\( .*\|$\)/p' )" ] ; then + BOOTPROTO=dhcp + else + BOOTPROTO=static + fi + fi + + # if the interface is a bridge, then try to use the underlying interface + # if it is the only non-virtual interface (not tap or vif) + if [ -d "/sys/class/net/$ifname/bridge" -a \ + -d "/sys/class/net/$ifname/brif" ] ; then + + local ifname2 res count=0 + for ifname2 in "/sys/class/net/$ifname/brif"/*; do + case "$(readlink -f "$ifname2")" in + /sys/devices/virtual/*) + continue + esac + res="${ifname2##*/}" + count=$(( count+1 )) + done + + if [ "$count" -ne 1 ] ; then + echo >&2 ">>> WARNING: $ifname is a bridge with more than one" + echo >&2 ">>> underlying interface. Please specify the device" + echo >&2 ">>> in KDUMP_NETCONFIG manually." + else + ifname="$res" + fi + fi + + echo "$ifname $BOOTPROTO" +} # }}} + +# +# Convert a CIDR prefix to IPv4 netmask +# +# Parameters: +# 1) prefix the CIDR prefix (default: 32) +# Output: +# Corresponding netmask +kdump_prefix2netmask() { # {{{ + local prefix="${1:-32}" + local netmask= + local i + for i in a b c d + do + netmask="$netmask.$(( 255 - (255 >> prefix) ))" + if [ "$prefix" -gt 8 ] ; then + prefix=$(( prefix - 8 )) + else + prefix=0 + fi + done + echo "${netmask:1}" +} # }}} + +# +# Get the ip= parameter for a given device +# +# Parameters: +# 1) device device name (use default if empty) +# Output: +# ip configuration string that can be used for the ip= initrd parameter +function kdump_ip_config() # {{{ +{ + local iface="$1" + if [ -z "$iface" ] ; then + iface=$( kdump_default_netdev ) + iface="${iface% *}" + fi + [ -z "$iface" ] && return 1 + + local ipaddr peeraddr gwaddr netmask hostname iface + local family cidr rest + local prefix + while read family cidr rest + do + [ "$family" = "inet" ] || continue + + ipaddr="${cidr%/*}" + prefix="${cidr:${#ipaddr}}" + set -- $rest + + if [ "$1" == "peer" ] ; then + cidr="$2" + peeraddr=${cidr%/*} + prefix="${cidr:${#peeraddr}}" + shift 2 + fi + netmask=$( kdump_prefix2netmask "${prefix:1}" ) + + done < <(ip -4 address show dev "$iface") + + gwaddr=$(ip route show 0/0 | sed -n 's/.* via \([^ ]*\).*/\1/p') + hostname=$(hostname) + + echo "$ipaddr:$peeraddr:$gwaddr:$netmask:$hostname:$iface:none" +} # }}} + # # Get the save directory and protocol. # diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdump-0.8.12/kdumptool/CMakeLists.txt new/kdump-0.8.13/kdumptool/CMakeLists.txt --- old/kdump-0.8.12/kdumptool/CMakeLists.txt 2014-05-16 19:31:02.000000000 +0200 +++ new/kdump-0.8.13/kdumptool/CMakeLists.txt 2014-05-30 13:24:24.000000000 +0200 @@ -142,3 +142,8 @@ testprocess.cc ) target_link_libraries(testprocess common ${EXTRA_LIBS}) + +add_executable(testurldecode + testurldecode.cc +) +target_link_libraries(testurldecode common ${EXTRA_LIBS}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdump-0.8.12/kdumptool/stringutil.cc new/kdump-0.8.13/kdumptool/stringutil.cc --- old/kdump-0.8.12/kdumptool/stringutil.cc 2014-05-16 19:31:02.000000000 +0200 +++ new/kdump-0.8.13/kdumptool/stringutil.cc 2014-05-30 13:24:24.000000000 +0200 @@ -270,6 +270,19 @@ #endif // HAVE_LIBSSL +// ----------------------------------------------------------------------------- +int Stringutil::hex2int(char c) + throw (KError) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + throw KError(string("Stringutil::hex2int: '") + c + "' is not a hex digit"); +} + //}}} //{{{ KString ------------------------------------------------------------------ @@ -333,6 +346,27 @@ return strcmp(c_str() + size() - part.size(), part.c_str()) == 0; } +// ----------------------------------------------------------------------------- +KString &KString::decodeURL(bool formenc) + throw() +{ + iterator src, dst; + for (src = dst = begin(); src != end(); ++src) { + char c1, c2; + if (*src == '%' && end() - src >= 2 && + isxdigit(c1 = src[1]) && isxdigit(c2 = src[2])) { + *dst++ = (Stringutil::hex2int(c1) << 4) | + Stringutil::hex2int(c2); + src += 2; + } else if (formenc && *src == '+') + *dst++ = ' '; + else + *dst++ = *src; + } + resize(dst - begin()); + return *this; +} + //}}} // vim: set sw=4 ts=4 fdm=marker et: :collapseFolds=1: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdump-0.8.12/kdumptool/stringutil.h new/kdump-0.8.13/kdumptool/stringutil.h --- old/kdump-0.8.12/kdumptool/stringutil.h 2014-05-16 19:31:02.000000000 +0200 +++ new/kdump-0.8.13/kdumptool/stringutil.h 2014-05-30 13:24:24.000000000 +0200 @@ -200,6 +200,9 @@ throw (KError); #endif // HAVE_LIBSSL + + static int hex2int(char c) + throw (KError); }; //}}} @@ -289,6 +292,14 @@ bool endsWith(const std::string &part) const throw (); + /** + * Perform URL decoding on the string. + * + * @param[in] formenc if @c true, translate '+' into spaces + * @return reference to this object (after decoding) + */ + KString &decodeURL(bool formenc = false) + throw(); }; //}}} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdump-0.8.12/kdumptool/testurldecode.cc new/kdump-0.8.13/kdumptool/testurldecode.cc --- old/kdump-0.8.12/kdumptool/testurldecode.cc 1970-01-01 01:00:00.000000000 +0100 +++ new/kdump-0.8.13/kdumptool/testurldecode.cc 2014-05-30 13:24:24.000000000 +0200 @@ -0,0 +1,60 @@ +/* + * (c) 2014, Petr Tesarik <[email protected]>, SUSE LINUX Products GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ +#include <iostream> +#include <cstdlib> + +#include "global.h" +#include "stringutil.h" +#include "debug.h" + +using std::cout; +using std::cerr; +using std::endl; + +// ----------------------------------------------------------------------------- +int main(int argc, char *argv[]) +{ + Debug::debug()->setStderrLevel(Debug::DL_TRACE); + bool formenc = false; + + try { + int i = 1; + if (i < argc && KString(argv[i]) == "-f") { + formenc = true; + ++i; + } + + bool addspace = false; + while (i < argc) { + KString arg(argv[i]); + if (addspace) + cout << ' '; + cout << arg.decodeURL(formenc); + addspace = true; + ++i; + } + cout << endl; + + } catch(const std::exception &ex) { + cerr << "Fatal exception: " << ex.what() << endl; + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdump-0.8.12/kdumptool/urlparser.cc new/kdump-0.8.13/kdumptool/urlparser.cc --- old/kdump-0.8.12/kdumptool/urlparser.cc 2014-05-16 19:31:02.000000000 +0200 +++ new/kdump-0.8.13/kdumptool/urlparser.cc 2014-05-30 13:24:24.000000000 +0200 @@ -86,166 +86,147 @@ } // ----------------------------------------------------------------------------- -URLParser::URLParser(const std::string &url) - throw (KError) - : m_url(url), m_port(-1) +string URLParser::extractScheme(string::iterator &it, + const string::const_iterator &end) { - Debug::debug()->trace("URLParser::URLParser(%s)", url.c_str()); + string::iterator const start = it; - if (url.size() == 0) - throw KError("URL must be longer than 0 characters."); + if (it == m_url.end() || !isalpha(*it)) + return string(); - // local files that don't have URL syntax - // we support that for backward-compatibility - if (url[0] == '/') { - m_protocol = PROT_FILE; - m_path = url; - return; + do { + ++it; + if (it == m_url.end()) { + it = start; + return string(); + } + } while (*it != ':' && *it != '/' && *it != '?' && *it != '#'); + + if (*it != ':') { + it = start; + return string(); } - // - // get the protocol - // - - string::size_type first_colon = url.find(':'); - if (first_colon == string::npos) - throw KError("The URL does not contain any protocol."); - string proto_part = url.substr(0, first_colon); - Debug::debug()->trace("Setting protocol to %s", proto_part.c_str()); - m_protocol = string2protocol(proto_part); - - if (url.size() < (first_colon + 3) || - url[first_colon+1] != '/' || - url[first_colon+2] != '/') - throw KError("protocol: must be followed by '//'."); - - // - // call the parse methods matching for the protocol - // + return string(start, it++); +} - if (m_protocol == PROT_FILE) { - m_path = url.substr(first_colon+3); - } else if (m_protocol == PROT_NFS) { - parseNFSUrl(url.substr(first_colon+3)); - } else if (m_protocol == PROT_SFTP || m_protocol == PROT_SSH || - m_protocol == PROT_FTP || m_protocol == PROT_CIFS) { - parseFTPUrl(url.substr(first_colon+3)); - } else - throw KError("Invalid protocol: " + - Stringutil::number2string(m_protocol) + "."); +// ----------------------------------------------------------------------------- +string URLParser::extractAuthority(string::iterator &it, + const string::const_iterator &end) +{ + if (end - it < 2 || it[0] != '/' || it[1] != '/') + return string(); - Debug::debug()->dbg("URL parsed as: protocol=%s, host=%s, port=%d, " - "username=%s, password=%s, path=%s", - getProtocolAsString().c_str(), - getHostname().c_str(), getPort(), getUsername().c_str(), - getPassword().c_str(), getPath().c_str()); + it += 2; + string::iterator const start = it; + while (*it != '/' && *it != '?' && *it != '#') + ++it; + return string(start, it); } // ----------------------------------------------------------------------------- -void URLParser::parseUserPassHostPort(const string &userpasshostport) +URLParser::URLParser(const std::string &url) throw (KError) + : m_url(url), m_port(-1) { - // now scan for an '@' to separate userhost from hostport - string::size_type last_at = userpasshostport.rfind('@'); - string userhost; - string hostport; - if (last_at == string::npos) { - hostport = userpasshostport; - - switch (m_protocol) { - case PROT_FTP: - m_username = FTP_DEFAULT_USER; - break; - - case PROT_SFTP: - case PROT_SSH: - m_username = SFTP_DEFAULT_USER; - break; - - default: - // do nothing but make the compiler happy - break; - } + Debug::debug()->trace("URLParser::URLParser(%s)", url.c_str()); - } else { - string userpass = userpasshostport.substr(0, last_at); - hostport = userpasshostport.substr(last_at+1); + string::iterator it = m_url.begin(); - // now separate user and passwort - string::size_type firstcolon = userpass.find(':'); - if (firstcolon != string::npos) { - m_username = userpass.substr(0, firstcolon); - m_password = userpass.substr(firstcolon+1); - } else - m_username = userpass; - } + // + // extract the three main URL componenets + // + string scheme = extractScheme(it, m_url.end()); + string authority = extractAuthority(it, m_url.end()); + m_path.assign(it, m_url.end()); + // TODO: query and fragment are not handled + + if (m_path.empty() || m_path[0] != '/') + throw KError("URLParser: Only absolute paths are supported."); - // look for a literal IPv6 addresses - string::size_type last_colon = hostport.rfind(':'); - if (hostport[0] == '[') { - string::size_type bracket = hostport.find(']'); - if (bracket != string::npos && bracket > last_colon) - last_colon = string::npos; + // + // parse the authority part + // + + // Look for (optional) port + it = authority.end(); + while (it != authority.begin() && isdigit(it[-1])) + --it; + if (it != authority.begin() && it[-1] == ':') { + string port(it, authority.end()); + authority.resize(it - authority.begin() - 1); + + if (port.size() > 0) + m_port = Stringutil::string2number(port); } - // and separate host and port - if (last_colon != string::npos) { - m_hostname = hostport.substr(0, last_colon); - string portstr = hostport.substr(last_colon+1); - if (portstr.size() > 0) - m_port = Stringutil::string2number(portstr); + // look for userinfo + string::size_type last_at = authority.rfind('@'); + if (last_at != string::npos) { + m_hostname = authority.substr(last_at+1); + authority.resize(last_at); + + // now separate user and password + string::size_type first_colon = authority.find(':'); + if (first_colon != string::npos) { + m_username = authority.substr(0, first_colon); + m_password = authority.substr(first_colon+1); + } else + m_username = authority; } else - m_hostname = hostport; -} + m_hostname = authority; -// ----------------------------------------------------------------------------- -void URLParser::parseNFSUrl(const string &partUrl) - throw (KError) -{ - Debug::debug()->trace("URLParser::parseNFSUrl(%s)", partUrl.c_str()); + // + // undo percent encoding + // + m_hostname.decodeURL(); + m_password.decodeURL(); + m_username.decodeURL(); + m_path.decodeURL(); - // look for the first '/' - string::size_type first_slash = partUrl.find('/'); - if (first_slash == string::npos) - throw KError("NFS URL must contain at least one '/'."); - - m_hostname = partUrl.substr(0, first_slash); - - string::size_type last_colon = m_hostname.rfind(':'); - if (m_hostname[0] == '[') { - string::size_type bracket = m_hostname.find(']'); - if (bracket != string::npos && bracket > last_colon) - last_colon = string::npos; - } - if (last_colon != string::npos) { - string hostport = m_hostname; - m_hostname = hostport.substr(0, last_colon); - string portstring = hostport.substr(last_colon+1); - if (portstring.size() > 0) - m_port = Stringutil::string2number(hostport.substr(last_colon+1)); + // + // guess the scheme, if omitted + // + if (scheme.empty()) { + if (m_hostname.empty() || m_hostname == "localhost") { + m_protocol = PROT_FILE; + Debug::debug()->trace("URL looks like a local file"); + } else { + m_protocol = PROT_NFS; + Debug::debug()->trace("URL looks like a remote file"); + } + } else { + Debug::debug()->trace("Scheme explicitly set to %s", scheme.c_str()); + m_protocol = string2protocol(scheme); } - m_path = partUrl.substr(first_slash); -} + // + // protocol-specific defaults + // -// ----------------------------------------------------------------------------- -void URLParser::parseFTPUrl(const string &partUrl) - throw (KError) -{ - Debug::debug()->trace("URLParser::parseFTPUrl(%s)", partUrl.c_str()); + if (m_protocol == PROT_FILE && m_hostname == "localhost") + m_hostname.clear(); + + if (m_username.empty()) { + if (m_protocol == PROT_FTP) + m_username = FTP_DEFAULT_USER; + else if (m_protocol == PROT_SFTP || m_protocol == PROT_SSH) + m_username = SFTP_DEFAULT_USER; + } - // look for the first '/' to separate the host name part from the - // path name - string::size_type first_slash = partUrl.find('/'); - if (first_slash == string::npos) - throw KError(getProtocolAsString() + - " URL must contain at least one '/'."); + // + // sanity checks + // + if (m_protocol == PROT_FILE && !m_hostname.empty()) + throw KError("File protocol cannot specify a remote host"); - parseUserPassHostPort(partUrl.substr(0, first_slash)); + Debug::debug()->dbg("URL parsed as: protocol=%s, host=%s, port=%d, " + "username=%s, password=%s, path=%s", + getProtocolAsString().c_str(), + getHostname().c_str(), getPort(), getUsername().c_str(), + getPassword().c_str(), getPath().c_str()); - // and the rest is the path - m_path = partUrl.substr(first_slash); } // ----------------------------------------------------------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdump-0.8.12/kdumptool/urlparser.h new/kdump-0.8.13/kdumptool/urlparser.h --- old/kdump-0.8.12/kdumptool/urlparser.h 2014-05-16 19:31:02.000000000 +0200 +++ new/kdump-0.8.13/kdumptool/urlparser.h 2014-05-30 13:24:24.000000000 +0200 @@ -26,6 +26,7 @@ #include "global.h" #include "optionparser.h" #include "subcommand.h" +#include "stringutil.h" //{{{ URLParser ---------------------------------------------------------------- @@ -158,29 +159,32 @@ static std::string protocol2string(Protocol protocol) throw (KError); - protected: - - void parseCifsUrl(const std::string &partUrl) - throw (KError); - - void parseNFSUrl(const std::string &partUrl) - throw (KError); - - void parseUserPassHostPort(const std::string &userpasshostport) - throw (KError); - - void parseFTPUrl(const std::string &partUrl) - throw (KError); - private: - std::string m_url; + std::string m_url; Protocol m_protocol; - std::string m_hostname; - std::string m_password; - std::string m_username; + KString m_hostname; + KString m_password; + KString m_username; int m_port; - std::string m_path; - std::string m_share; + KString m_path; + + /** + * Extract scheme from a string + * + * @param[in,out] it starting position (updated if scheme is found) + * @param[in] end end of input string + */ + std::string extractScheme(std::string::iterator &it, + const std::string::const_iterator &end); + + /** + * Extract authority from a string + * + * @param[in,out] it starting position (updated if authority is found) + * @param[in] end end of input string + */ + std::string extractAuthority(std::string::iterator &it, + const std::string::const_iterator &end); }; //}}} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdump-0.8.12/process_cond.awk new/kdump-0.8.13/process_cond.awk --- old/kdump-0.8.12/process_cond.awk 2014-05-16 19:31:02.000000000 +0200 +++ new/kdump-0.8.13/process_cond.awk 2014-05-30 13:24:24.000000000 +0200 @@ -5,7 +5,12 @@ ENVIRON[var[1]] \ substr($0, RSTART + RLENGTH) stack[sp++] = remove - remove = remove || ($2 != $3) + condition = 0 + for (i = 3; i <= NF; i++) { + if ($2 == $i) + condition = 1 + } + remove = remove || !condition skip = 1 } /^@else\>/ { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdump-0.8.12/tests/CMakeLists.txt new/kdump-0.8.13/tests/CMakeLists.txt --- old/kdump-0.8.12/tests/CMakeLists.txt 2014-05-16 19:31:02.000000000 +0200 +++ new/kdump-0.8.13/tests/CMakeLists.txt 2014-05-30 13:24:24.000000000 +0200 @@ -60,3 +60,7 @@ ADD_TEST(process ${CMAKE_CURRENT_SOURCE_DIR}/process.sh ${CMAKE_BINARY_DIR}/kdumptool/testprocess) + +ADD_TEST(urldecode + ${CMAKE_CURRENT_SOURCE_DIR}/testurldecode.sh + ${CMAKE_BINARY_DIR}/kdumptool/testurldecode) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdump-0.8.12/tests/testurldecode.sh new/kdump-0.8.13/tests/testurldecode.sh --- old/kdump-0.8.12/tests/testurldecode.sh 1970-01-01 01:00:00.000000000 +0100 +++ new/kdump-0.8.13/tests/testurldecode.sh 2014-05-30 13:24:24.000000000 +0200 @@ -0,0 +1,163 @@ +#!/bin/bash +# +# (c) 2014, Petr Tesarik <[email protected]>, SUSE LINUX Products GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. +# + +# Check that results match expectation +# {{{ +function check() +{ + local arg="$1" + local expect="$2" + local result="$3" + if [ "$result" != "$expect" ] ; then + echo "failed string: $arg" + echo "Expected:" + echo "$expect" + echo "Result:" + echo "$result" + errornumber=$(( errornumber + 1 )) + fi +} +# }}} + +# +# Program {{{ +# + +# number of tested characters for random tests +NTEST=100 + +URLDECODE=$1 +HEXDUMP="od -Ax -tx1" + +if [ -z "$URLDECODE" ] ; then + echo "Usage: $0 urldecode" + exit 1 +fi + +errornumber=0 + +# TEST #1: Random uppercase %-sequences + +ARG= +EXPECT= +i=0 +while [ $i -lt $NTEST ] +do + ch=$(( $RANDOM % 256 )) + hex=$( printf "%02X" $ch ) + ARG="$ARG%$hex" + EXPECT="$EXPECT\\x$hex" + i=$(( i + 1 )) +done +EXPECT=$( echo -e "$EXPECT" | $HEXDUMP ) +RESULT=$( "$URLDECODE" "$ARG" | $HEXDUMP ) +check "$ARG" "$EXPECT" "$RESULT" + +# TEST #2: Random lowercase %-sequences + +ARG= +EXPECT= +i=0 +while [ $i -lt $NTEST ] +do + ch=$(( $RANDOM % 256 )) + hex=$( printf "%02x" $ch ) + ARG="$ARG%$hex" + EXPECT="$EXPECT\\x$hex" + i=$(( i + 1 )) +done +EXPECT=$( echo -e "$EXPECT" | $HEXDUMP ) +RESULT=$( "$URLDECODE" "$ARG" | $HEXDUMP ) +check "$ARG" "$EXPECT" "$RESULT" + +# TEST #3: Decoding '+' + +ARG=" + +begin hello+world end+" +EXPECT="+ +begin hello+world end+" +RESULT=$( "$URLDECODE" $ARG ) +check "$ARG" "$EXPECT" "$RESULT" + +# now using form decoding +EXPECT=" begin hello world end " +RESULT=$( "$URLDECODE" -f $ARG ) +check "$ARG" "$EXPECT" "$RESULT" + +# TEST #4: Transitions quoted <-> unquoted + +ARG= +EXPECT= +i=0 +while [ $i -lt $NTEST ] +do + ch=$(( $RANDOM % 256 )) + hex=$( printf "%02x" $ch ) + case $(( $ch % 3 )) in + 0) + ARG="$ARG $hex%$hex" + EXPECT="$EXPECT $hex\\x$hex" + ;; + + 1) + ARG="$ARG %$hex$hex" + EXPECT="$EXPECT \\x$hex$hex" + ;; + + 2) + ARG="$ARG $hex%$hex$hex" + EXPECT="$EXPECT $hex\\x$hex$hex" + ;; + + 3) + ARG="$ARG +%$hex+$hex" + EXPECT="$EXPECT \\x$hex $hex" + ;; + esac + i=$(( i + 1 )) +done +EXPECT=$( echo -e "$EXPECT" | $HEXDUMP ) +RESULT=$( "$URLDECODE" "$ARG" | $HEXDUMP ) +check "$ARG" "$EXPECT" "$RESULT" + +# TEST #5: Test invalid sequence + +ARG=" %invalid %0invalid %ainvalid %x0invalid %+invalid %0+invalid" +EXPECT="%invalid %0invalid %ainvalid %x0invalid % invalid %0 invalid" +RESULT=$( "$URLDECODE" -f $ARG ) +check "$ARG" "$EXPECT" "$RESULT" + +# TEST #6: More than two hex digits + +ARG="%4567 %456789abcdef0123" +EXPECT="E67 E6789abcdef0123" +RESULT=$( "$URLDECODE" $ARG ) +check "$ARG" "$EXPECT" "$RESULT" + +# TEST #7: NUL character + +ARG="NUL character here: '%00'" +EXPECT=$( echo -e "NUL character here: '\000'" | $HEXDUMP ) +RESULT=$( "$URLDECODE" $ARG | $HEXDUMP ) +check "$ARG" "$EXPECT" "$RESULT" + +exit $errornumber + +# }}} + +# vim: set sw=4 ts=4 fdm=marker et: :collapseFolds=1: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdump-0.8.12/tests/testurlparser.sh new/kdump-0.8.13/tests/testurlparser.sh --- old/kdump-0.8.12/tests/testurlparser.sh 2014-05-16 19:31:02.000000000 +0200 +++ new/kdump-0.8.13/tests/testurlparser.sh 2014-05-30 13:24:24.000000000 +0200 @@ -32,6 +32,7 @@ "cifs://bwalle:dontsay@neptunium:/var/log/dump" "smb://[email protected]:/var/log" "cifs://bwalle:dontsay@neptunium:/var/log/dump" + "ftp://pt%65sarik:don%27t%20say@fu%6eny+host/var/log/dum%70" ) # protocol:host:port:user:pass:path @@ -45,6 +46,7 @@ "cifs:neptunium:-1:bwalle:dontsay:/var/log/dump" "cifs:192.168.0.70:-1:bwalle::/var/log" "cifs:neptunium:-1:bwalle:dontsay:/var/log/dump" + "ftp:funny+host:-1:ptesarik:don't say:/var/log/dump" ) # }}} -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
