From 0e7ca733b81ba5d3fcdc8546c10d09da819ad014 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Minisini?= Date: Sat, 6 Apr 2013 13:21:29 +0000 Subject: [PATCH] [GB.DESKTOP] * BUG: Desktop.SendMail() does not quote the "-" character in e-mail addresses anymore. git-svn-id: svn://localhost/gambas/trunk@5613 867c0c6c-44f3-4631-809d-bfa615b0a4ec --- app/other/MakeWebSite/.settings | 2 +- app/other/MakeWebSite/.src/MMain.module | 2 +- .../gambas.sourceforge.net/home.html | 6 +- app/src/gambas3/support.txt | 2 +- .../xdg-utils-1.0.3.pre.patch/xdg-email | 730 ++++++++++++++++++ gb.desktop/src/gb.desktop/xdg-utils/xdg-email | 4 +- 6 files changed, 739 insertions(+), 7 deletions(-) create mode 100644 gb.desktop/src/gb.desktop/.hidden/xdg-utils-1.0.3.pre.patch/xdg-email diff --git a/app/other/MakeWebSite/.settings b/app/other/MakeWebSite/.settings index b7fb2a7d0..6d46b5bc5 100644 --- a/app/other/MakeWebSite/.settings +++ b/app/other/MakeWebSite/.settings @@ -37,7 +37,7 @@ SearchString=True [OpenFile] Active=1 -File[1]=".src/MMain.module:59.29" +File[1]=".src/MMain.module:16.31" File[2]="gambas.sourceforge.net/menu.html:57.61" File[3]="gambas.sourceforge.net/home.html.template:55.48" File[4]="gambas.sourceforge.net/style.css:12.14" diff --git a/app/other/MakeWebSite/.src/MMain.module b/app/other/MakeWebSite/.src/MMain.module index 0b7dfe876..894d03ea1 100644 --- a/app/other/MakeWebSite/.src/MMain.module +++ b/app/other/MakeWebSite/.src/MMain.module @@ -14,7 +14,7 @@ Sub InitVar() 'DIM aDev AS String[] = ["92", "91", "90", "51"] $cVar["OLD_VERSION"] = "2.24.0" - $cVar["DEV_VERSION"] = "3.4.0" + $cVar["DEV_VERSION"] = "3.4.1" InitAuthor diff --git a/app/other/MakeWebSite/gambas.sourceforge.net/home.html b/app/other/MakeWebSite/gambas.sourceforge.net/home.html index 6109726cb..3673c7b52 100644 --- a/app/other/MakeWebSite/gambas.sourceforge.net/home.html +++ b/app/other/MakeWebSite/gambas.sourceforge.net/home.html @@ -56,10 +56,10 @@
- - {Download} Gambas 3.4.0 + + {Download} Gambas 3.4.1 - +
diff --git a/app/src/gambas3/support.txt b/app/src/gambas3/support.txt index 25b9d8a8b..5a3cbed06 100644 --- a/app/src/gambas3/support.txt +++ b/app/src/gambas3/support.txt @@ -1,4 +1,4 @@ -54 Maurizio Da Lio +55 Maurizio Da Lio 37 GNU/Linex 33 Radoslav Dejanovic 20 Ricardo Díaz Martin diff --git a/gb.desktop/src/gb.desktop/.hidden/xdg-utils-1.0.3.pre.patch/xdg-email b/gb.desktop/src/gb.desktop/.hidden/xdg-utils-1.0.3.pre.patch/xdg-email new file mode 100644 index 000000000..f50a50f8a --- /dev/null +++ b/gb.desktop/src/gb.desktop/.hidden/xdg-utils-1.0.3.pre.patch/xdg-email @@ -0,0 +1,730 @@ +#!/bin/sh +#--------------------------------------------- +# xdg-email +# +# Utility script to open the users favorite email program, using the +# RFC 2368 mailto: URI spec +# +# Refer to the usage() function below for usage. +# +# Copyright 2009-2010, Fathi Boudra +# Copyright 2009-2010, Rex Dieter +# Copyright 2006, Kevin Krammer +# Copyright 2006, Jeremy White +# +# LICENSE: +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +#--------------------------------------------- + +manualpage() +{ +cat << _MANUALPAGE +Name + +xdg-email - command line tool for sending mail using the user's preferred +e-mail composer + +Synopsis + +xdg-email [--utf8] [--cc address] [--bcc address] [--subject text] [--body text +] [--attach file] [ mailto-uri | address(es) ] + +xdg-email { --help | --manual | --version } + +Description + +xdg-email opens the user's preferred e-mail composer in order to send a mail to +address(es) or mailto-uri. RFC2368 defines mailto: URIs. xdg-email limits +support to, cc, subject and body fields in mailto-uri, all other fields are +silently ignored. address(es) must follow the syntax of RFC822. Multiple +addresses may be provided as separate arguments. + +All information provided on the command line is used to prefill corresponding +fields in the user's e-mail composer. The user will have the opportunity to +change any of this information before actually sending the e-mail. + +xdg-email is for use inside a desktop session only. It is not recommended to +use xdg-email as root. + +See http://portland.freedesktop.org/EmailConfig for information on how the user +can change the e-mail composer that is used. + +Options + +--utf8 + Indicates that all command line options that follow are in utf8. Without + this option, command line options are expected to be encoded according to + locale. If the locale already specifies utf8 this option has no effect. + This option does not affect mailto URIs that are passed on the command + line. +--cc address + Specify a recipient to be copied on the e-mail. +--bcc address + Specify a recipient to be blindly copied on the e-mail. +--subject text + Specify a subject for the e-mail. +--body text + Specify a body for the e-mail. Since the user will be able to make changes + before actually sending the e-mail, this can be used to provide the user + with a template for the e-mail. text may contain linebreaks. +--attach file + + Specify an attachment for the e-mail. file must point to an existing file. + + Some e-mail applications require the file to remain present after xdg-email + returns. + +--help + Show command synopsis. +--manual + Show this manualpage. +--version + Show the xdg-utils version information. + +Environment Variables + +xdg-email honours the following environment variables: + +XDG_UTILS_DEBUG_LEVEL + Setting this environment variable to a non-zero numerical value makes + xdg-email do more verbose reporting on stderr. Setting a higher value + increases the verbosity. + +Exit Codes + +An exit code of 0 indicates success while a non-zero exit code indicates +failure. The following failure codes can be returned: + +1 + Error in command line syntax. +2 + One of the files passed on the command line did not exist. +3 + A required tool could not be found. +4 + The action failed. +5 + No permission to read one of the files passed on the command line. + +Configuration + +Visit http://portland.freedesktop.org/EmailConfig for information how to +configure xdg-email to use the email client of your choice. + +Examples + +xdg-email 'Jeremy White ' + +xdg-email --attach /tmp/logo.png \ + --subject 'Logo contest' \ + --body 'Attached you find the logo for the contest.' \ + 'jwhite@example.com' + +xdg-email --subject 'Your password is about to expire' \ + 'jwhite@example.com' 'bastian@example.com' 'whipple@example.com' + +_MANUALPAGE +} + +usage() +{ +cat << _USAGE +xdg-email - command line tool for sending mail using the user's preferred +e-mail composer + +Synopsis + +xdg-email [--utf8] [--cc address] [--bcc address] [--subject text] [--body text +] [--attach file] [ mailto-uri | address(es) ] + +xdg-email { --help | --manual | --version } + +_USAGE +} + +#@xdg-utils-common@ + +#---------------------------------------------------------------------------- +# Common utility functions included in all XDG wrapper scripts +#---------------------------------------------------------------------------- + +DEBUG() +{ + [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && return 0; + [ ${XDG_UTILS_DEBUG_LEVEL} -lt $1 ] && return 0; + shift + echo "$@" >&2 +} + +#------------------------------------------------------------- +# Exit script on successfully completing the desired operation + +exit_success() +{ + if [ $# -gt 0 ]; then + echo "$@" + echo + fi + + exit 0 +} + + +#----------------------------------------- +# Exit script on malformed arguments, not enough arguments +# or missing required option. +# prints usage information + +exit_failure_syntax() +{ + if [ $# -gt 0 ]; then + echo "xdg-email: $@" >&2 + echo "Try 'xdg-email --help' for more information." >&2 + else + usage + echo "Use 'man xdg-email' or 'xdg-email --manual' for additional info." + fi + + exit 1 +} + +#------------------------------------------------------------- +# Exit script on missing file specified on command line + +exit_failure_file_missing() +{ + if [ $# -gt 0 ]; then + echo "xdg-email: $@" >&2 + fi + + exit 2 +} + +#------------------------------------------------------------- +# Exit script on failure to locate necessary tool applications + +exit_failure_operation_impossible() +{ + if [ $# -gt 0 ]; then + echo "xdg-email: $@" >&2 + fi + + exit 3 +} + +#------------------------------------------------------------- +# Exit script on failure returned by a tool application + +exit_failure_operation_failed() +{ + if [ $# -gt 0 ]; then + echo "xdg-email: $@" >&2 + fi + + exit 4 +} + +#------------------------------------------------------------ +# Exit script on insufficient permission to read a specified file + +exit_failure_file_permission_read() +{ + if [ $# -gt 0 ]; then + echo "xdg-email: $@" >&2 + fi + + exit 5 +} + +#------------------------------------------------------------ +# Exit script on insufficient permission to write a specified file + +exit_failure_file_permission_write() +{ + if [ $# -gt 0 ]; then + echo "xdg-email: $@" >&2 + fi + + exit 6 +} + +check_input_file() +{ + if [ ! -e "$1" ]; then + exit_failure_file_missing "file '$1' does not exist" + fi + if [ ! -r "$1" ]; then + exit_failure_file_permission_read "no permission to read file '$1'" + fi +} + +check_vendor_prefix() +{ + file_label="$2" + [ -n "$file_label" ] || file_label="filename" + file=`basename "$1"` + case "$file" in + [a-zA-Z]*-*) + return + ;; + esac + + echo "xdg-email: $file_label '$file' does not have a proper vendor prefix" >&2 + echo 'A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated' >&2 + echo 'with a dash ("-"). An example '"$file_label"' is '"'example-$file'" >&2 + echo "Use --novendor to override or 'xdg-email --manual' for additional info." >&2 + exit 1 +} + +check_output_file() +{ + # if the file exists, check if it is writeable + # if it does not exists, check if we are allowed to write on the directory + if [ -e "$1" ]; then + if [ ! -w "$1" ]; then + exit_failure_file_permission_write "no permission to write to file '$1'" + fi + else + DIR=`dirname "$1"` + if [ ! -w "$DIR" -o ! -x "$DIR" ]; then + exit_failure_file_permission_write "no permission to create file '$1'" + fi + fi +} + +#---------------------------------------- +# Checks for shared commands, e.g. --help + +check_common_commands() +{ + while [ $# -gt 0 ] ; do + parm="$1" + shift + + case "$parm" in + --help) + usage + echo "Use 'man xdg-email' or 'xdg-email --manual' for additional info." + exit_success + ;; + + --manual) + manualpage + exit_success + ;; + + --version) + echo "xdg-email 1.1.0 rc1" + exit_success + ;; + esac + done +} + +check_common_commands "$@" + +[ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && unset XDG_UTILS_DEBUG_LEVEL; +if [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt 1 ]; then + # Be silent + xdg_redirect_output=" > /dev/null 2> /dev/null" +else + # All output to stderr + xdg_redirect_output=" >&2" +fi + +#-------------------------------------- +# Checks for known desktop environments +# set variable DE to the desktop environments name, lowercase + +detectDE() +{ + if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; + elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; + elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; + elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; + elif [ x"$DESKTOP_SESSION" == x"LXDE" ]; then DE=lxde; + else DE="" + fi +} + +#---------------------------------------------------------------------------- +# kfmclient exec/openURL can give bogus exit value in KDE <= 3.5.4 +# It also always returns 1 in KDE 3.4 and earlier +# Simply return 0 in such case + +kfmclient_fix_exit_code() +{ + [ x"$KDE_SESSION_VERSION" = x"4" ] && return 0; + version=`LC_ALL=C.UTF-8 kde-config --version 2>/dev/null | grep '^KDE'` + major=`echo $version | sed 's/KDE.*: \([0-9]\).*/\1/'` + minor=`echo $version | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/'` + release=`echo $version | sed 's/KDE.*: [0-9]*\.[0-9]*\.\([0-9]\).*/\1/'` + test "$major" -gt 3 && return $1 + test "$minor" -gt 5 && return $1 + test "$release" -gt 4 && return $1 + return 0 +} + +run_thunderbird() +{ + local THUNDERBIRD MAILTO NEWMAILTO TO CC BCC SUBJECT BODY ATTACH + THUNDERBIRD="$1" + MAILTO=$(echo "$2" | sed 's/^mailto://') + echo "$MAILTO" | grep -qs "^?" + if [ "$?" = "0" ] ; then + MAILTO=$(echo "$MAILTO" | sed 's/^?//') + else + MAILTO=$(echo "$MAILTO" | sed 's/^/to=/' | sed 's/?/\&/') + fi + + MAILTO=$(echo "$MAILTO" | sed 's/&/\n/g') + TO=$(echo "$MAILTO" | grep '^to=' | sed 's/^to=//' | awk '{ printf "%s,",$0 }') + CC=$(echo "$MAILTO" | grep '^cc=' | sed 's/^cc=//' | awk '{ printf "%s,",$0 }') + BCC=$(echo "$MAILTO" | grep '^bcc=' | sed 's/^bcc=//' | awk '{ printf "%s,",$0 }') + SUBJECT=$(echo "$MAILTO" | grep '^subject=' | tail -n 1) + BODY=$(echo "$MAILTO" | grep '^body=' | tail -n 1) + ATTACH=$(echo "$MAILTO" | sed 's/^attach=/\n\nfile:\/\//g' | awk '/^file:/ { printf "%s,",$0 }' | sed 's/,$//') + + if [ -z "$TO" ] ; then + NEWMAILTO= + else + NEWMAILTO="to='$TO'" + fi + if [ -n "$CC" ] ; then + NEWMAILTO="${NEWMAILTO},cc='$CC'" + fi + if [ -n "$BCC" ] ; then + NEWMAILTO="${NEWMAILTO},bcc='$BCC'" + fi + if [ -n "$SUBJECT" ] ; then + NEWMAILTO="${NEWMAILTO},$SUBJECT" + fi + if [ -n "$BODY" ] ; then + NEWMAILTO="${NEWMAILTO},$BODY" + fi + + if [ -n "$ATTACH" ] ; then + NEWMAILTO="${NEWMAILTO},attachment='${ATTACH}'" + fi + + NEWMAILTO=$(echo "$NEWMAILTO" | sed 's/^,//') + DEBUG 1 "Running $THUNDERBIRD -compose \"$NEWMAILTO\"" + echo "Running $THUNDERBIRD -compose \"$NEWMAILTO\"" + "$THUNDERBIRD" -compose "$NEWMAILTO" + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_kde() +{ + local client kde_email_profile_name + kde_email_profile_name=`kreadconfig --file emaildefaults --group Defaults --key Profile` + client=`kreadconfig --file emaildefaults --group PROFILE_"$kde_email_profile_name" --key EmailClient | cut -d ' ' -f 1` + echo $client | grep thunderbird > /dev/null 2>&1 + if [ $? -eq 0 ] ; then + run_thunderbird "$client" "$1" + fi + + if [ -f /etc/SuSE-release ] ; then + # Workaround for SUSE 10.0 + [ -z "$client" ] && client="kmail" + if ! which "$client" > /dev/null 2> /dev/null; then + DEBUG 3 "KDE has $client configured as email client which isn't installed" + if which gnome-open > /dev/null 2> /dev/null && which evolution > /dev/null 2> /dev/null; then + DEBUG 3 "Try gnome-open instead" + open_gnome "$1" + fi + fi + fi + DEBUG 1 "Running kmailservice \"$1\"" + if [ x"$KDE_SESSION_VERSION" = x"4" ]; then + KMAILSERVICE=`kde4-config --locate kmailservice --path exe 2>/dev/null` + else + KMAILSERVICE=`which kmailservice 2>/dev/null` + fi + # KDE uses locale's encoding when decoding the URI, so set it to UTF-8 + LC_ALL=C.UTF-8 $KMAILSERVICE "$1" + kfmclient_fix_exit_code $? + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_gnome() +{ + local client + client=`gconftool-2 --get /desktop/gnome/url-handlers/mailto/command | cut -d ' ' -f 1` || "" + echo $client | grep thunderbird > /dev/null 2>&1 + if [ $? -eq 0 ] ; then + run_thunderbird "$client" "$1" + fi + + if gvfs-open --help 2>/dev/null 1>&2; then + DEBUG 1 "Running gvfs-open \"$1\"" + gvfs-open "$1" + else + DEBUG 1 "Running gnome-open \"$1\"" + gnome-open "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + + +open_xfce() +{ + DEBUG 1 "Running exo-open \"$1\"" + exo-open "$1" + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_generic() +{ + IFS=":" + for browser in $BROWSER; do + if [ x"$browser" != x"" ]; then + + browser_with_arg=`printf "$browser" "$1" 2>/dev/null` + if [ $? -ne 0 ]; then browser_with_arg=$browser; + fi + + if [ x"$browser_with_arg" = x"$browser" ]; then "$browser" "$1"; + else $browser_with_arg; + fi + + if [ $? -eq 0 ]; then exit_success; + fi + fi + done + + exit_failure_operation_impossible "no method available for opening '$1'" +} + +url_encode() +{ +result=$(echo "$1" | $utf8 | awk ' + BEGIN { + for ( i=1; i<=255; ++i ) ord [ sprintf ("%c", i) "" ] = i + 0 + e = "" + linenr = 1 + } + { + if ( linenr++ != 1 ) { + e = e "%0D%0A" + } + for ( i=1; i<=length ($0); ++i ) { + c = substr ($0, i, 1) + if ( ord [c] > 127 ) { + e = e "%" sprintf("%02X", ord [c]) + } else if ( ord[c] == 45 ) { + e = e c + } else if ( c ~ /[@a-zA-Z0-9.\\\/]/ ) { + e = e c + } else { + e = e "%" sprintf("%02X", ord [c]) + } + } + } + END { + print e + } +') +} + +options= +mailto= +utf8="iconv -t utf8" +while [ $# -gt 0 ] ; do + parm="$1" + shift + + case "$parm" in + --utf8) + utf8="cat" + ;; + + --to) + if [ -z "$1" ] ; then + exit_failure_syntax "email address argument missing for --to" + fi + url_encode "$1" + options="${options}to=${result}&" + shift + ;; + + --cc) + if [ -z "$1" ] ; then + exit_failure_syntax "email address argument missing for --cc" + fi + url_encode "$1" + options="${options}cc=${result}&" + shift + ;; + + --bcc) + if [ -z "$1" ] ; then + exit_failure_syntax "email address argument missing for --bcc" + fi + url_encode "$1" + options="${options}bcc=${result}&" + shift + ;; + + --subject) + if [ -z "$1" ] ; then + exit_failure_syntax "text argument missing for --subject option" + fi + url_encode "$1" + options="${options}subject=${result}&" + shift + ;; + + --body) + if [ -z "$1" ] ; then + exit_failure_syntax "text argument missing for --body option" + fi + url_encode "$1" + options="${options}body=${result}&" + shift + ;; + + --attach) + if [ -z "$1" ] ; then + exit_failure_syntax "file argument missing for --attach option" + fi + check_input_file "$1" + file=`readlink -f "$1"` # Normalize path + if [ -z "$file" -o ! -f "$file" ] ; then + exit_failure_file_missing "file '$1' does not exist" + fi + + url_encode "$file" + options="${options}attach=${result}&" + shift + ;; + + -*) + exit_failure_syntax "unexpected option '$parm'" + ;; + + mailto:*) + mailto="$parm" + ;; + + *@*) + url_encode "$parm" + if [ -z "${mailto}" ] ; then + mailto="mailto:"${result}"?" + else + options="${options}to=${result}&" + fi + ;; + + *) + exit_failure_syntax "unexpected argument '$parm'" + ;; + esac +done + +if [ -z "${mailto}" ] ; then + # TO address is optional + mailto="mailto:?" +fi + +case $mailto in + *\?) + mailto="${mailto}${options}" + ;; + + *\?*) + mailto="${mailto}&${options}" + ;; + + *) + mailto="${mailto}?${options}" + ;; +esac + +# Strip trailing ? and & +mailto=`echo "${mailto}"| sed 's/[?&]$//'` + +# Shouldn't happen +[ x"${mailto}" != x"" ] || exit_failure_syntax + +if which xdg-email-hook.sh > /dev/null 2> /dev/null; then + xdg-email-hook.sh "${mailto}" + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +fi + +detectDE + +if [ x"$DE" = x"" ]; then + DE=generic +fi + +# if BROWSER variable is not set, check some well known browsers instead +if [ x"$BROWSER" = x"" ]; then + BROWSER=links2:links:lynx:w3m + if [ -n "$DISPLAY" ]; then + BROWSER=firefox:mozilla:epiphany:konqueror:chromium-browser:google-chrome:$BROWSER + fi +fi + +case "$DE" in + kde) + open_kde "${mailto}" + ;; + + gnome) + open_gnome "${mailto}" + ;; + + xfce) + open_xfce "${mailto}" + ;; + + generic|lxde) + open_generic "${mailto}" + ;; + + *) + exit_failure_operation_impossible "no method available for opening '${mailto}'" + ;; +esac diff --git a/gb.desktop/src/gb.desktop/xdg-utils/xdg-email b/gb.desktop/src/gb.desktop/xdg-utils/xdg-email index 6ead03352..4e1990d4e 100644 --- a/gb.desktop/src/gb.desktop/xdg-utils/xdg-email +++ b/gb.desktop/src/gb.desktop/xdg-utils/xdg-email @@ -548,7 +548,9 @@ result=$(echo "$1" | $utf8 | awk ' c = substr ($0, i, 1) if ( ord [c] > 127 ) { e = e "%" sprintf("%02X", ord [c]) - } else if ( c ~ /[@a-zA-Z0-9.-\\\/]/ ) { + } else if ( ord[c] == 45 ) { + e = e c + } else if ( c ~ /[@a-zA-Z0-9.\\\/]/ ) { e = e c } else { e = e "%" sprintf("%02X", ord [c])