12. April 2011

E-Mail Header auslesen

Mal wieder ein paar technische Grundlagen, die ich hier zum besten geben möchte :)

E-Mails... wahrscheinlich jeder meiner Leser kennt sie,
versendet haufenweise davon und erhält wahrscheinlich nochmal soviel als Spam ^^

Doch wie sieht eine E-Mail eigentlich aus? Wie ist sie aufgebaut?

Da ich mir das E-Mail Konzept natürlich nicht selber ausgedacht und aufgebaut habe,
brauche ich das Rad nicht zwei mal erfinden, sondern poste einfach das bereits verfügbare Wissen aus Wikipedia:


Eine Internet-E-Mail besteht aus dem Header-Abschnitt (von englisch für: „Kopfzeile“) und dem Body (dem eigentlichen Inhalt der Nachricht). Der Header enthält als Pflichtangabe lediglich eine Absenderangabe und das Datum der Erstellung der E-Mail. Darüber hinaus kann der Header einer E-Mail eine Reihe optionaler Angaben enthalten. In der Regel finden sich Informationen über den Weg, den die E-Mail genommen hat, über den Inhalt der Nachricht und deren Format sowie Angaben zu den Empfängern.
Der Header enthält keine für die technische Zustellung einer E-Mail notwendigen Informationen. Absender und Empfänger werden durch den Envelope Sender und Envelope To angegeben.
Der Aufbau einer E-Mail ist im RFC 5322 festgelegt – hier wird im Gegensatz zu vorherigen Standards nicht mehr von header gesprochen, sondern header field für den Inhalt einer einzelnen Kopfzeile undheader section für den gesamten Kopfbereich der E-Mail (alle Kopfzeilen zusammen) verwendet, um Verwirrungen zu vermeiden.

Inhaltsverzeichnis

 [Verbergen]

Darstellung und Anzeige [Bearbeiten]

Viele Empfänger interessieren sich nicht oder nur selten für alle Header-Zeilen. Deshalb zeigen die meisten Mail-Clients standardmäßig nur einen kleinen Teil der tatsächlich in der E-Mail enthaltenen Header-Zeilen an. Das sind insbesondere die Zeilen mit den Tags:
  • „From:“ – der Absender
  • „To:“ – der Empfänger
  • „Cc:“ – weitere Empfänger
  • „Subject:“ – der Betreff
  • „Date:“ – der Zeitpunkt der Erstellung
Weitere oder alle Header-Zeilen werden in der Regel nur mit der Wahl spezieller Optionen angezeigt. Diese sind je nach Mail-Client sehr unterschiedlich. Bei einigen Mail-Clients (z. B. mutt) lässt sich konfigurieren, welche Header-Zeilen standardmäßig angezeigt werden. Einige E-Mail-Clients ersetzen die Header-Tags bei der Anzeige durch eine landessprachliche Entsprechung.

Beispielmail [Bearbeiten]

In der folgenden Beispiel-E-Mail werden die Header-Informationen, die von den meisten E-Mail-Programmen angezeigt werden, blau dargestellt. Die zumeist ausgeblendeten Header-Informationen sind orange, der Body ist grau. Die erste Zeile enthält den sogenannten Envelope Sender – sie ist nicht Teil des Headers, geht ihm aber im mbox-Format voraus und wird auch sonst häufig zusammen mit den Header-Zeilen dargestellt; sie wird im Simple Mail Transfer Protocol (SMTP) nicht als Teil der Mailheader, sondern mit einem speziellen Befehl übertragen.
From alex@mailgate.exam.ple Mon Dec 4 17:02:25 2006Envelope Sender
Received: (qmail 12345 invoked by alias); Mon, 04 Dec 2006 13:51:40 +0000
Received: by server1 (Postfix, from userid 1000)
  id D344F45681; Mon, 4 Dec 2006 14:51:39 +0100 (CET)
Mehrere „Received“-Zeilen zeigen den Weg, den die E-Mail vom Sender zum Empfänger genommen hat. Jeder Server, der die Mail weiterleitet, fügt seine Kennung und das Datum am Anfang der E-Mail hinzu.
Date: Mon, 4 Dec 2006 15:51:37 +0100Absendedatum
Subject: Der Sinn des LebensBetreff der E-Mail
Message-ID: <434571BC.8070702@example.net>Eindeutige Zeichenfolge, die diese E-Mail identifiziert
From: Alex Absender Absender
To: Erwin Empfaenger Empfänger
Cc: ErwinsSekretariat Empfänger einer Kopie der E-Mail
Content-Type: text/plain; charset=ISO-8859-1Art und Zeichensatz des Body-Text
In-Reply-To: <134535224@example.com>Diese E-Mail ist eine Antwort auf die E-Mail mit dieser Message-ID
Die erste Leerzeile trennt die Kopfzeilen vom Nachrichtentext
Hallo Erwin,

wir müssen einen Termin vereinbaren.

Bis dann,
Alex
Inhalt („message body“)

Mögliche Einträge im Header [Bearbeiten]

Einträge im E-Mail-Header werden durch einen Zeilenumbruch (CRLF) voneinander getrennt. Der E-Mail-Header wird durch eine Leerzeile (CRLF CRLF) vom E-Mail-Body getrennt.

Date: Absendedatum und Uhrzeit [Bearbeiten]

Pflichtangabe nach RFC 5322. Der Zeitpunkt des Absendens der E-Mail.

From: Absender [Bearbeiten]

Pflichtangabe nach RFC 5322. Eine oder mehrere durch Kommata getrennte E-Mail-Adressen, die den oder die Absender einer E-Mail bezeichnen. Die meisten E-Mail-Clients unterstützen nur einen einzelnen Absender.

Sender: Technischer Absender [Bearbeiten]

Ist der technische Absender ein anderer, als im From-Header bezeichnet, kann dieser im Sender-Header vermerkt werden. Das Sender-Feld darf nur eine einzelne E-Mail-Adresse enthalten. Beispiel: Die E-Mail-Adresse eines Sekretärs, der eine E-Mail nach Diktat des Chefs verschickt, gehört ins Sender-Feld. Die E-Mail-Adresse des Chefs gehört ins From-Feld. Wenn der Verfasser einer E-Mail und der technische Absender identisch sind, sollte das Sender-Feld nicht verwendet werden, sonst sollten beide (From- und Sender-Feld) verwendet werden.

Reply-To: Antwortadresse [Bearbeiten]

Eine oder mehrere durch Kommata getrennte E-Mail-Adressen, an die eine Antwort auf die E-Mail geschickt werden soll (falls unterschiedlich zum From-Feld).

To: Der Empfänger [Bearbeiten]

Eine oder mehrere durch Kommata getrennte E-Mail-Adressen, an die die E-Mail primär gesendet wird. Jedem Adressaten werden auch alle andren E-Mail-Adressen mitgeteilt.

CC: Carbon Copy, die Kopie [Bearbeiten]

Eine oder mehrere durch Kommata getrennte E-Mail-Adressen, an die eine Kopie der E-Mail gesendet wird.
Der Begriff kommt vom früher benutzten Durchschlag. Dabei wurden beim Schreiben mit einem harten Stift oder der Schreibmaschine Kopien erstellt, indem mehrere Papierseiten mit jeweils einem Kohlepapierdazwischen übereinandergelegt wurden.
Beim Schreiben einer E-Mail wird dieses Feld verwendet, um Kopien an einen oder mehrere Empfänger zu senden. Mit einem Eintrag in diesem Feld wird gleichzeitig symbolisiert, dass diese E-Mail sich nicht direkt an diesen Benutzer wendet, sondern lediglich „zur Beachtung“ bzw. „zur Kenntnisnahme“ an ihn versendet wurde. Die Einträge im CC-Feld werden (im Gegensatz zum BCC-Feld) bei allen Empfängern angezeigt und sind somit bekannt.
Umgangssprachlich wird auch ab und an (vornehmlich in den USA) fälschlicherweise „Courtesy Copy“ als Bedeutung für CC benutzt, was soviel wie „Höflichkeitskopie“ bedeutet (courtesy „Höflichkeit“, copy„Kopie“).

BCC: Blind Carbon Copy, die Blindkopie [Bearbeiten]

Das BCC-Feld enthält eine oder mehrere durch Kommata getrennte E-Mail-Adressen, an die eine Kopie der E-Mail gesendet wird, ohne dass dies jedoch für die anderen angegebenen Empfänger sichtbar sein soll („Blindkopie“). Durch eine Blindkopie sollen die Empfänger von Rund-Mails vor der Adressen-Sammlung von bösartigen Diensten wie z. B. Spambots gesichert werden.
Da die Adressaten (also auch die BCC-Adressaten) dem Mailserver vor der Übertragung der E-Mail mitgeteilt werden, kann das Prinzip technisch einfach umgesetzt werden: BCC-Adressaten werden als Empfänger genannt, in der anschließend übermittelten E-Mail entfällt dann die BCC-Zeile oder wird verändert übertragen. Die Handhabung der BCC-Zeile ist aber nicht eindeutig vorgegeben. Je nach Implementierung im verwendeten E-Mail-Programm und der beteiligten Mailserver ergeben sich folgende Möglichkeiten:
  • Die BCC-Zeile wird vor der Übertragung vollständig aus dem Header der E-Mail entfernt. Die Nachricht wird jedoch trotzdem an alle Empfänger übermittelt. Die BCC-Empfänger sehen bei Eingang der E-Mail nicht, dass sie im BCC-Feld geführt wurden. Die Gefahr ist dann größer, dass sie versehentlich an alle Empfänger antworten und damit ihre E-Mail-Adresse und die Tatsache preisgeben, dass sie auch die E-Mail erhalten haben.
  • Die in der To- und CC-Zeile genannten Empfänger erhalten wie oben eine Kopie der E-Mail, aus welcher die BCC-Zeile entfernt wurde. Die in der BCC-Zeile aufgeführten Adressaten hingegen erhalten eine Kopie, in der die BCC-Zeile erhalten bleibt. Je nach E-Mail-Programm erhält entweder jeder BCC-Adressat eine Kopie, in der nur seine E-Mail-Adresse steht, oder alle Empfänger erhalten die gleiche BCC-Zeile. In letzterem Fall ist es Empfängern einer Blindkopie möglich, alle anderen BCC-Adressaten zu sehen.
  • Der Inhalt der BCC-Zeile wird bei der Übertragung entfernt. Personen, welche die E-Mail via BCC bekommen, können sich nicht gegenseitig identifizieren. Allen Empfängern wird aber signalisiert, dass die E-Mail zusätzlich als Blindkopie versendet wurde.
Während E-Mail-Programme und Server üblicherweise nach der ersten Variante vorgehen, sollte man sich im Zweifelsfall nicht darauf verlassen.

Subject: Der Betreff [Bearbeiten]

Das Subject (im Deutschen auch Betreff) stellt eine Beziehung des Senders und/oder des Empfängers zu einer Sache, erforderlichen Aktion oder zu einem Ereignis her. Es ist für den Empfänger eine wichtige Kurzinformation über den Inhalt der Mail und sollte daher nicht fehlen. In Anbetracht der steigenden Anzahl unerwünschter E-Mails (UBE/UCE/Spam) wächst die Bedeutung des Betreff-Felds, denn oft lassen sich unerwünschte Nachrichten bereits am Betreff erkennen.

Weitere Header-Zeilen [Bearbeiten]

Wesentlich sind weiterhin folgende Header-Zeilen:
  • Zeichensatz der E-Mail (z. B. „charset=utf-8“), damit der Empfänger auch Fremdsprachen oder Sonderzeichen im Text richtig angezeigt bekommt.
  • Content-Type, falls nicht nur reiner Text verwendet wird, bei HTML z. B. „text/html“
    • Bei gesetztem Content-Type ist auch der Mime-Type zu senden, z. B. „MIME-Version: 1.0“
Weitere Informationen werden automatisch in den Header eingefügt, sowohl vom Mailprogramm (Mail User Agent) des Absenders als auch von den an der Leitung der Mail beteiligten Mailservern (Mail Transfer Agents). So lässt sich in der Regel an den Received-Zeilen die Reihenfolge und Adresse aller am Versand beteiligten Mailserver ablesen. Weiterhin erscheinen gegebenenfalls Informationen über eine erfolgteViren-Prüfung oder Spam-Klassifizierung oder -Filterung in den Header-Zeilen der E-Mail.

Authentizität von Header-Informationen [Bearbeiten]

Wie alle Teile einer E-Mail-Nachricht werden auch Header-Zeilen nicht auf inhaltliche Korrektheit geprüft. Die dort angezeigten Informationen sind fälschbar. So setzen findige Spam-Versender in der Regel fingierte Header-Zeilen ein, um die wirkliche Herkunft der E-Mail zu verschleiern oder um Spam-Filter in die Irre zu führen, damit ihre Mails ungefiltert zugestellt werden. Dazu gehören Header-Zeilen, die auf ein legitimes Standard-Mailprogramm (und damit einen menschlichen Absender) hindeuten sollen oder auch Header-Zeilen, die eine bereits erfolgte Spamprüfung vorspiegeln, in der Hoffnung, die Mail werde dann vom Spam-Filter ungeprüft weitergeleitet.



Für mich war die Festlegung der Blind- und Carbon Copy wichtig,
der Rest aber auch überaus interessant ^^


Nun haben wir wieder was gelernt,
vielen Dank für zuhören (lesen), bis zum nächsten Mal

- the incredible Leitman

11. April 2011

Bitmaps in .net vergleichen

...funktioniert nicht xD

Naja, zumindest nicht direkt.
Die "Equals"-Methode sowie der Vergleichsoperator verwenden lediglich Referenzen,
der Inhalt wird dabei nicht berücksichtigt :-s


Jedoch, komplett hilflos ist man nicht ;)

Eine Möglichkeit ist, die Bilder in Bytearrays auszulesen
und diese, zuerst nach Größe, dann Byte für Byte zu vergleichen.

Klingt nicht ziemlich effizient,
denke ist es auch nicht -.-
Aber solange ich keine optimalere Möglichkeit gefunden habe, werde ich wohl bei diesem Weg bleiben müssen.

Codemäßig in Visual C++.net sieht das folgendermaßen aus:


   1:  // compare

   2:  {
   3:      System::IO::MemoryStream ^stream = gcnew System::IO::MemoryStream();
   4:      System::Drawing::Bitmap ^bm = System::Drawing::Bitmap::FromFile("file");
   5:      bm->Save(stream, System::Drawing::Imaging::ImageFormat::Bmp);
   6:      stream->Flush();
   7:      array ^arr = stream->ToArray();
   8:   
   9:      stream = gcnew System::IO::MemoryStream();
  10:      bm = System::Drawing::Bitmap::FromFile("otherfile");
  11:      bm->Save(stream, System::Drawing::Imaging::ImageFormat::Bmp);
  12:      stream->Flush();
  13:      array ^arr2 = stream->ToArray();
  14:   
  15:      if (arr->Length != arr2->Length)
  16:      {
  17:          // sure not equal
  18:      }
  19:      else
  20:      {
  21:          int length = arr->Length;
  22:          for (int i = 0; i < length; ++i)
  23:          {
  24:              if (arr[i] != arr2[i])
  25:              {
  26:                  // not equal
  27:                  break;
  28:              }
  29:          }
  30:      }
  31:  }



Mit obigen code snippet ist es jedoch leider nur möglich,
zu vergleichen ob die Bilder komplett ident sind.
Für Ähnlichkeiten oder um herauszufinden, ob sich in einem bestimmten Bild ein anderes befindet bietet sich eine so genannte "pattern recognition" an.
(Erster Google Link auf tutorials.de)


Viel Erfolg und happy coding :D

the incredible Leitman

7. April 2011

How do I change the mouse cursor to a hourglass?

... in a dotnet Form?


Das ist die leichte Frage ;)


this.Cursor = Cursors.WaitCursor;

To change it back to normal after the application has stopped loading:


this.Cursor = Cursors.Default;

As IntelliSense points out, you can change the mouse cursor to various shapes (crosshair, hand, help, etc.).




... gut, wie gesagt, das war leicht ;)
Aber wie sieht das Ganze aus, wenn man das aus einer statischen Methode machen möchte oder eben außerhalb eines .net control containers?



Cursor.Current = Cursors.WaitCursor; 
Cursor.Current = Cursors.Default;

(wie üblich in VC++ .net werden aus . einfach :: )


oder alternativ:

Application.UseWaitCursor = true;
// Do stuff
Application.UseWaitCursor = false;

... okay, das war jetzt auch nicht viel schwerer xD

Ich hoffe, wenigstens iiiiirgendwem damit geholfen zu haben
und sei es bloß mir selbst, wenn ich das wieder mal vergessen sollte und nachschlagen möchte ^^


happy coding
incredible Leitman

4. April 2011

gemanagte Referenzen in einer nicht gemanagten Klasse speichern


Wenn man C++ CLI und normales C++ in einem Projekt zusammen einsetzt, tauchen früher oder später scheinbar unlösbare Probleme auf. Bei einem Videoplayer den wir zur Zeit programmieren, war es nun soweit.
Um den Programmcode etwas zu entschlacken und den darunter liegenden Algorithmus zur Erstellung eines DirectShow Aufnahmegraphen wieder sichtbar zu machen, wurde es endlich Zeit eine Referenz auf ein gemanagtes Objekt in einer nativen Klasse zu speichern.
Im WPF-Frontend (C#) stellt der Nutzer ein, von welcher Kamera er aufnehmen will und in welches Format das geschehen soll. Diese Konfiguration wird an das Backend (C++) übergeben, in dem schließlich der Aufnahmegraph aufgebaut wird. Dabei kann es sehr viele unterschiedliche Kombination der Konfigurationsparameter geben. Die Art der Kamera (DV, USB, …), die Audioquelle, TimeShift (darüber werde ich bei Gelegenheit auch noch einen Blog-Eintrag schreiben => das war meine Diplomarbeit!) und noch einige mehr spielen hierbei eine Rolle.
Der Aufbau des Aufnahmegraphen erfolgte in einer großen Klasse mit etlichen Funktionen, und immer wieder wurde als Parameter dieser Funktionen ein Parameter vom Typ ICaptureConfiguration^ übergeben. Also habe ich das ganze aufgeflochten und in mehrere Klassen verteilt. Eine abstrakte Basisklasse mit statischen Hilfsfunktionen und einem Interface mit den wichtigsten Methoden, welche dann durch die Detail-Klassen abgedeckt sein müssen. Und um nicht ständig die Konfiguration als Parameter übergeben zu müssen, wird dieser Kontraktur als Member gespeichert.
Doch oh Schreck, was ist das: “Der Typ ICaptureConfiguration^ kann nicht als Membervariable einer nicht C++ CLI Klasse verwendet werden!” Ist ja eigentlich auch logisch, wie soll sonst der Speichermanager der CLR mitbekommen, wann die Referenz nicht mehr gebraucht wird und er das Objekt wieder freigeben kann. Oder noch schlimmer, wenn der Speichermanager des Objekt in seinem Speicher an eine andere Adresse schiebt um Platz zu schaffen, wäre die Referenz plötzlich ungültig! Es gibt nun nur zwei Möglichkeiten: entweder alles auf C++ CLI umstellen, was mindesten 100 Tage oder mehr dauern würde oder aber doch einen Weg finden, die Referenz zu speichern.
Dank google, der MSDN und anderen Seiten ist es mir zum Glück schließlich doch gelungen die Referenz zu speichern. Genau dafür gibt es nämlich das Template gcroot. Es sorgt dafür, dass die zugewiesene Referenz immer erreichbar ist. Da man solch eine Referenz immer mit delete wieder freigeben müsste, ist es besser man nutzt auto_gcroot. Das wird nämlich wie alle Wrapper dieser Art automatisch freigegeben. Im Code sieht das ganze dann in etwa so aus:
#include 
#using 

using namespace System;
...

class CCaptureMgrBase
{
    CCaptureMgrBase(ICaptureConfiguration^ captureConfig)
    {
        m_captureConfig = captureConfig;
    }
    ...
    msclr::auto_gcroot m_captureConfig;
}
Mit –> kann man nun ganz normal auf die Referenz zugreifen und Funktionen aufrufen.
Eine kleine Anmerkung habe ich allerdings noch. Man kann m_captureConfig nicht mehr einfach so an eine Funktion übergeben, welche ein ICaptureConfiguration^ als Parameter erwarte! Dafür muss man nunm_captureConfig.get() aufrufen.
class CCaptureMgrBase
{
    ...
    void Render()
    {
        // geht nicht:
        CCaptureMgrBase::Helper(m_captureConfig);

        // so ist es richtig
        CCaptureMgrBase::Helper(m_captureConfig.get());
    }

    static void Helper(ICaptureConfiguration^ captureConfig) { ... }
}

Beitrag "gestohlen" mit freundlicher Unterstützung vom CPlusSharp Blog

Vielen Dank, mit freundlichen Grüßen
Euer incredible Leitman

3. April 2011

Direktlinks auf zeitliche Positionen in YouTube-Videos

Vor Längerem wurde ein lang ersehntes und sinnvolles Feature auf der Video-Plattform YouTube gelaunched: es ist nun eine direkte Verlinkung einer Stelle in einem Video möglich. Wenn sich also beispielsweise bei 5 Minuten und 29 Sekunden eines 8-minütigen Videos eine Stelle befindet, die sich gut eignet, um eine Aussage zu unterstreichen, dann kann direkt auf diesen Punkt verlinkt werden.

Bloß ich merke mir das leider nie, deswegen erstelle ich nun hier diesen lang veralteten, weitaus verspäteten Post:
Das Ganze sieht so aus, hier der normale Link zum YouTube-Video:
und so kann man direkt zur Minute 0 und Sekunde 40 springen:
also einfach an den normalen YouTube-Link ein “#t=” und dann die Zeit in Minuten und Sekunden anhängen (z.B. “2m29“). Bei 0 Minuten war das “0m” bis vor einiger Zeit nicht notwendig, derzeit ist dies allerdings nicht mehr so.
Das gefällt mir sehr gut, da so ohne lästiges Geschnipsel oder etwaige Urheberrechts-Probleme gezielt Zitate aus Videos verwendet werden können. Viel Spaß beim Direkt-Linken ;)
Blog-Beitrag zum Thema im YouTube-Blog (english)

31. März 2011

dotnet ComboBox SelectedText always returning empty string o.O

Das Property SelectedText einer .Net ComboBox gibt ausschließlich einen leeren String (String::Empty) zurück?

Tja, das wird wohl daran liegen,
dass diese Eigenschaft etwas anderes zurückgibt, als (von mir) erwartet -.-

Aus der Hilfe:
"If DropDownStyle is set to ComboBoxStyle.DropDownList, the return is an
empty string ("")."



Jedenfalls,
um den aktuell selektierten Text einer ComboBox zu erhalten, WENN es eine DropDownList ist,
verwendet man SelectedItem.


Eigentlich keine große Sache...
... wenn man es weiß :-s