Nouveau script pour d=c3=a9coder les ent=c3=aates MIME

Le
Olivier Miakinen
Bonjour,

J'ai fait une nouvelle version de mon script. Au lieu de prendre en
paramètre une ou plusieurs chaînes à décoder, il prend en paramètre
un ou plusieurs noms de fichiers contenant les entêtes complets.
On peut aussi lui faire lire les données sur stdin si on ne met pas
de paramètre, ou qu'on met « - » à la place d'un nom de fichier.

Par exemple, si on saisit :

decode_headers <<POTIRON
Message-ID: <c5a9-1@part.org>
From: Arvo =?UTF-8?Q?Pärt?= <arvo@part.org>
To: =?Latin1?Q?Frdric_Chopin?= <fred@chopin.org>,
=?Latin2?Q?Antonn_Dvok?= <anton@dvorak.org>
References: <A65R-4d@chopin.org> <c5a7-3@part.org>
<A72Q-5a@chopin.org>
In-Reply-To: <A72Q-5a@chopin.org>
Subject: Re: Going to =?Shift-JIS?B?k4yLngo=?= (Tokyo) =?UTF-8?B?zpEK?=
=?UTF-8?B?zrjOrs69zrEK?= (Athens) and =?ISO-8859-5?Q??=
=?ISO-8859-5?Q??= (Moscow)
POTIRON

On obtiendra :

Message-ID: <c5a9-1@part.org>
From: Arvo Pärt <arvo@part.org>
To: Frédéric Chopin <fred@chopin.org>, Antonín Dvořák <anton@dvorak.org>
References: <A65R-4d@chopin.org> <c5a7-3@part.org> <A72Q-5a@chopin.org>
In-Reply-To: <A72Q-5a@chopin.org>
Subject: Re: Going to 東京 (Tokyo) Αθήνα (Athens) and Москва (Moscow)

(Note : le mot POTIRON n'a rien de spécial, c'est juste pour aider
OuiOui à améliorer son karma)


Voici le script. Attention, pour l'adapter au Mac il faudra modifier les
variables CUT, DECODE_QP, DECODE_B64, TR et ICONV définies vers le début
du fichier.


#!/bin/bash
####################################################################
# Name:
# decode_headers
#
# Description:
# Script used for decoding RFC 2047 MIME encoded headers.
#
# Example:
# decode_headers <<POTIRON
# Message-ID: <c5a9-1@part.org>
# From: Arvo =?UTF-8?Q?Pärt?= <arvo@part.org>
# To: =?Latin1?Q?Frdric_Chopin?= <fred@chopin.org>,
# =?Latin2?Q?Antonn_Dvok?= <anton@dvorak.org>
# References: <A65R-4d@chopin.org> <c5a7-3@part.org>
# <A72Q-5a@chopin.org>
# In-Reply-To: <A72Q-5a@chopin.org>
# Subject: Re: Going to =?Shift-JIS?B?k4yLngo=?= (Tokyo) =?UTF-8?B?zpEK?=
# =?UTF-8?B?zrjOrs69zrEK?= (Athens) and =?ISO-8859-5?Q??=
# =?ISO-8859-5?Q??= (Moscow)
# POTIRON
# ->
# Message-ID: <c5a9-1@part.org>
# From: Arvo Pärt <arvo@part.org>
# To: Frédéric Chopin <fred@chopin.org>, Antonín Dvořák <anton@dvorak.org>
# References: <A65R-4d@chopin.org> <c5a7-3@part.org> <A72Q-5a@chopin.org>
# In-Reply-To: <A72Q-5a@chopin.org>
# Subject: Re: Going to 東京 (Tokyo) Αθήνα (Athens) and Москва (Moscow)
#
# Known bugs:
# Can't handle encoded-words which are not clearly separated
# from non-blank characters, e.g. in comments: (=??.??=)
####################################################################

#
# The following constants should be adapted for your system.
# For example, the executable base64 could be at /usr/local/bin instead
# of /usr/bin, and it could require parameter -D instead of -d.
#
CUT="/usr/bin/cut"
DECODE_QP="/usr/bin/qprint -d"
DECODE_B64="/usr/bin/base64 -d"
TR="/usr/bin/tr"
ICONV="/usr/bin/iconv"

#
# This script uses the following global variables
# VARY
# used when a function has to return a string and not only a number
# DECODED_LINE
# The current state of a header being currently decoded
# STATUS
# Has three possible values:
# - "none" at the beginning of a new header
# - "decoded-word" after a correctly decoded MIME part
# - "normal" after any other string
#
VARY=""
DECODED_LINE=""
STATUS="none"

#
# Function: usage
#
usage()
{
printf "Usage: %s [OPTION] [FILE]" $0
printf "Decode headers from given files for RFC 2047 MIME encodings."
printf ""
printf "With no FILE, or when FILE is -, read standard input."
printf ""
printf " -h, --help Give this help list"
exit 1
}

#
# Function: decode_word
#
# Description:
# Check that the parameter is an encoded word, then decode it and
# convert it to UTF-8.
#
# Parameter:
# A single (possibly MIME-encoded) word.
#
# Return value:
# If decoding is ok, set the result into VARY and return 0
# Otherwise return 1
#
decode_word()
{
word="$*"
###################################################################
# An encoded word contains only ASCII characters in range from
# '!' (Ascii value 0x21) to '~' (Ascii value 0x7e). This excludes
# in particular the SPACE (Ascii 0x20) and the TAB (Ascii 0x09).
#
# More specifically, it consists of five parts separated by
# question marks '?'
# 1. A character "="
# 2. The charset, e.g. "UTF-8" or "ISO-8859-1"
# 3. The encoding, B or Q in upper or lower case
# 4. The encoded text
# 5. A character "="
###################################################################

# Check that:
# - there is no character outside range from '!' to '~'
# - the 1st part is a "="
# - the 5th part is a "=" and it is the end of the string
if [ $(LANG=C expr "_$word" : '_=?[!-~]*=$') = 0 ]; then return 1; fi
end=$(printf "$word" | $CUT -f 5- -d '?')
if [ "$end" != "=" ]; then return 1; fi

# Extract charset, encoding, and encoded text
charset=$(printf "$word" | $CUT -f 2 -d '?')
encoding=$(printf "$word" | $CUT -f 3 -d '?')
encoded=$(printf "$word" | $CUT -f 4 -d '?')

case $encoding in
B | b)
decoded=$(printf "$encoded" | $DECODE_B64 2>/dev/null)
if [ $? != 0 ]; then return 1; fi
;;
Q | q)
decoded=$(printf "$encoded" | $TR "_" " " | $DECODE_QP 2>/dev/null)
if [ $? != 0 ]; then return 1; fi
;;
*)
return 1
;;
esac

VARY=$(printf "$decoded" | $ICONV -f $charset -t UTF-8 2>/dev/null)
return $?
}

#
# Function: add_word
#
# Description:
# Try to decode a new word, and update DECODED_LINE and STATUS
# depending on the result and the previous STATUS.
#
# Parameter:
# A single (possibly MIME-encoded) word.
#
# Return value:
# None
#
# Side effects:
# Change DECODED_LINE and STATUS
#
add_word()
{
word="$*"
if decode_word "$word"; then
if [ "$STATUS" = "normal" ]; then
DECODED_LINE="${DECODED_LINE} "
fi
DECODED_LINE="${DECODED_LINE}${VARY}"
STATUS="decoded-word"
else
if [ "$STATUS" != "none" ]; then
DECODED_LINE="${DECODED_LINE} "
fi
DECODED_LINE="${DECODED_LINE}${word}"
STATUS="normal"
fi
}

#
# Function: flush_line
#
# Description:
# Before beginning to manage a new header, or just before ending
# the script, print the pending DECODED_LINE if any.
#
# Parameter:
# None
#
# Return value:
# None
#
# Side effects:
# Print things to stdout
# Change DECODED_LINE and STATUS
#
flush_line()
{
if [ -n "${DECODED_LINE}" ]; then
printf "%s" "${DECODED_LINE}"
DECODED_LINE=""
STATUS="none"
fi
}

#
# Function: manage_line
#
# Description:
# Manage a new line, which can be either the beginning or the
# continuation of a mail/news header.
# This function prints the previous line if this is a new one,
# then it adds successive parts to the new DECODED_LINE, while
# updating STATUS as needed.
#
# Parameter:
# An input
line.

#
# Return value:
# None
#
# Side effects:
# Print things to stdout
# Change DECODED_LINE and STATUS
#
manage_line()
{
line="$*"

# Is it a continuation line?
if [ $(LANG=C expr "$line" : "[ t]") = 0 ]; then
# No: new header
flush_line
fi

for word in $line; do
add_word "$word"
done
}

#
# Function: manage_file
#
# Description:
# Call manage_line for each line in a given file
#
# Parameter:
# A file name, or "-" for stdin
#
# Return value:
# None
#
# Side effects:
# Same as manage_line
#
manage_file()
{
file=${1--} # POSIX-compliant; ${1:--} can be used either.
while IFS= read -r line; do
manage_line "$line"
done < <(cat -- "$file")
}

#
# Parse arguments for -h or --help
#
for i in "$@"; do
case $i in
-h | --help)
usage
;;
-)
;;
-*)
printf "Unknown argument '%s'" "$i"
usage
;;
esac
done

#
# Main loop.
# Call manage_file for each filename in parameters,
# then print the last pending DECODED_LINE if any.
#
for file in "$@"; do
manage_file "$file"
done
flush_line

exit 0


--
Olivier Miakinen
  • Partager ce contenu :
Vos réponses Page 1 / 4
Trier par : date / pertinence
M.V.
Le #26528515
C'est toujours un plaisir de lire Olivier Miakinen qui nous a
gratifié, le 16 octobre 2019, des propos suivants :
From: Arvo Pärt

Ma mie interprète souvent avec son ensemble vocal des créations du
monsieur et elle prend son pied… Pour moi, c'est un peu plus
délicat ! ;-)
Bonne journée.
--
Michel VAUQUOIS - http://michelvauquois.fr
Olivier Miakinen
Le #26528521
Le 17/10/2019 01:55, j'avais copicollé mon script :
[...]
#
# Function: manage_line
#
# Description:
# Manage a new line, which can be either the beginning or the
# continuation of a mail/news header.
# This function prints the previous line if this is a new one,
# then it adds successive parts to the new DECODED_LINE, while
# updating STATUS as needed.
#
# Parameter:
# An input
line.======================================================================= >
#
[...]

Petite erreur de manip ici. Il faudra bien sûr le corriger en :
# Parameter:
# An input line.
#

--
Olivier Miakinen
M.V.
Le #26528538
C'est toujours un plaisir de lire Olivier Miakinen qui nous a
gratifié, le 16 octobre 2019, des propos suivants :
Attention, pour l'adapter au Mac il faudra modifier les
variables CUT, DECODE_QP, DECODE_B64, TR et ICONV définies vers le début
du fichier.

Sauf erreur de ma part, il n'y a que DECODE_QP à modifier pour le Mac.
Mais, j'obtiens :
####################################################################: bad interpreter: No such file or directory
Bonne journée.
--
Michel VAUQUOIS - http://michelvauquois.fr
Olivier Miakinen
Le #26528556
Le 17/10/2019 à 13:59, M.V. a écrit :
C'est toujours un plaisir de lire Olivier Miakinen qui nous a
gratifié, le 16 octobre 2019, des propos suivants :

Sympa, ta ligne d'attribution ! Mais ajouter l'heure pourrait servir
à ceux dont le nouvelleur ne permet pas facilement de cliquer sur
les MID du champ References.
Attention, pour l'adapter au Mac il faudra modifier les
variables CUT, DECODE_QP, DECODE_B64, TR et ICONV définies vers le début
du fichier.

Sauf erreur de ma part, il n'y a que DECODE_QP à modifier pour le Mac.

J'avais cru comprendre que base64 aussi était dans /usr/local/bin au
lieu de /usr/bin, et surtout qu'il fallait lui passer le paramètre -D
au lieu de -d.
Mais, j'obtiens :
####################################################################: bad interpreter: No such file or directory

C'est la ligne de commentaire qui est la deuxième ligne du script :
####################################################################
Tu as bien recopié la première ligne, quitte à remplacer /bin/bash par
le chemin correct sur Mac ?
Cordialement,
--
Olivier Miakinen
josephb
Le #26528555
M.V.
Sauf erreur de ma part, il n'y a que DECODE_QP à modifier pour le Mac.

pas encore essayé, mais à lire le code je vois que le base64 est
commandé par "-d" au lieu de "-D", pour le Mac
quant à qprint, il faut aller le chercher dans usr/local/bin
--
J. B.
Olivier Miakinen
Le #26528554
Le 17/10/2019 à 09:33, M.V. a écrit :
From: Arvo Pärt

Ma mie interprète souvent avec son ensemble vocal des créations du
monsieur et elle prend son pied… [...]

Par curiosité, elle chante dans quelle région, et avec quel ensemble
vocal ?
--
Olivier Miakinen
M.V.
Le #26528560
Le 17 octobre 2019, le très estimable Olivier Miakinen s'est exprimé
en ces termes :
Mais ajouter l'heure pourrait servir
à ceux dont le nouvelleur ne permet pas facilement de cliquer sur
les MID du champ References.

Va falloir demander ça au chef !
Sauf erreur de ma part, il n'y a que DECODE_QP à modifier pour le Mac.

J'avais cru comprendre que base64 aussi était dans /usr/local/bin au
lieu de /usr/bin, et surtout qu'il fallait lui passer le paramètre -D
au lieu de -d.

J'avais bien dit "Sauf erreur de ma part" et effectivement…
J'avais pourtant modifié le script ainsi :
CUT="/usr/bin/cut"
DECODE_QP="/usr/local/qprint -d"
DECODE_B64="/usr/bin/base64 -D"
TR="/usr/bin/tr"
ICONV="/usr/bin/iconv"
donc double erreur de ma part : j'ai bien modifié les 2 (DECODE_QP et
DECODE_B64) contrairement à ce que j'avais répondu et je me suis
planté en modifiant DECODE_QP !!!!!
Je viens de corriger le DECODE_QP et ça ne marche toujours pas.
Par contre, alors que j'avais fait un script qui me permettait de
décoder au choix un des champs From:, Reply-to:, Organization: et
Subject:, tu m'as donné l'idée de faire un script qui décoderait
l'entête complet… et j'y suis parvenu au prix de jongleries et
bricolages dont Joseph-B sait que je suis fervent ! ;-)
Si ça intéresse Joseph-B, je lui mettrai à disposition.
Bonne soirée.
--
Michel VAUQUOIS - http://michelvauquois.fr
M.V.
Le #26528563
Le 17 octobre 2019, le très estimable Olivier Miakinen s'est exprimé
en ces termes :
Par curiosité, elle chante dans quelle région, et avec quel ensemble
vocal ?

À Brive dans l'ensemble vocal des «Ateliers de la Tempête".
Le chef de cet ensemble et de « La Tempête », S-P Bestion, est une
pointure et a obtenu il y a quelques années un diapason d'or alors
qu'il avait tout juste 25 ans.
Bonne soirée.
--
Michel VAUQUOIS - http://michelvauquois.fr
M.V.
Le #26528572
Ainsi parlait Olivier Miakinen le 17 octobre 2019 :
Oui, c'est ce que j'écrivais dans « known bugs », et c'est pour ça
que je posais la question pour le tien.

Ça c'est le nouveau script (que je n'arrive pas à faire fonctionner).
Moi je parlais de celui de dimanche tard dans la nuit quon a fini par
faire fonctionner sur le Mac.
Bonne soirée.
--
Michel VAUQUOIS - http://michelvauquois.fr
M.V.
Le #26528571
Je me suis peut-être un peu précipité le 17 octobre 2019 en écrivant :
et "?=)" par "=? *$%£)"

Il faut lire : par "?= *$%£)"
bien entendu.
Bonne soirée.
--
Michel VAUQUOIS - http://michelvauquois.fr
Poster une réponse
Anonyme