Skip to main content

a silhouette of a person's head and shoulders, used as a default avatar

Limba Project: Another progress report

And once again, it’s time for another Limba blogpost 🙂limba-small

Limba is a solution to install 3rd-party software on Linux, without interfering with the distribution’s native package manager. It can be useful to try out different software versions, use newer software on a stable OS release or simply to obtain software which does not yet exist for your distribution.

Limba works distribution-independent, so software authors only need to publish their software once for all Linux distributions.

I recently released version 0.4, with which all most important features you would expect from a software manager are complete. This includes installing & removing packages, GPG-signing of packages, package repositories, package updates etc. Using Limba is still a bit rough, but most things work pretty well already.

So, it’s time for another progress report. Since a FAQ-like list is easier to digest. compared to a long blogpost, I go with this again. So, let’s address one important general question first:

How does Limba relate to the GNOME Sandboxing approach?

(If you don’t know about GNOMEs sandboxes, take a look at the GNOME Wiki – Alexander Larsson also blogged about it recently)

First of all: There is no rivalry here and no NIH syndrome involved. Limba and GNOMEs Sandboxes (XdgApp) are different concepts, which both have their place.

The main difference between both projects is the handling of runtimes. A runtime is the shared libraries and other shared ressources applications use. This includes libraries like GTK+/Qt5/SDL/libpulse etc. XdgApp applications have one big runtime they can use, built with OSTree. This runtime is static and will not change, it will only receive critical security updates. A runtime in XdgApp is provided by a vendor like GNOME as a compilation of multiple single libraries.

Limba, on the other hand, generates runtimes on the target system on-the-fly out of several subcomponents with dependency-relations between them. Each component can be updated independently, as long as the dependencies are satisfied. The individual components are intended to be provided by the respective upstream projects.

Both projects have their individual up and downsides: While the static runtime of XdgApp projects makes testing simple, it is also harder to extend and more difficult to update. If something you need is not provided by the mega-runtime, you will have to provide it by yourself (e.g. we will have some applications ship smaller shared libraries with their binaries, as they are not part of the big runtime).

Limba does not have this issue, but instead, with its dynamic runtimes, relies on upstreams behaving nice and not breaking ABIs in security updates, so existing applications continue to be working even with newer software components.

Obviously, I like the Limba approach more, since it is incredibly flexible, and even allows to mimic the behaviour of GNOMEs XdgApp by using absolute dependencies on components.

Do you have an example of a Limba-distributed application?

Yes! I recently created a set of package for Neverball – Alexander Larsson also created a XdgApp bundle for it, and due to the low amount of stuff Neverball depends on, it was a perfect test subject.

One of the main things I want to achieve with Limba is to integrate it well with continuous integration systems, so you can automatically get a Limba package built for your application and have it tested with the current set of dependencies. Also, building packages should be very easy, and as failsafe as possible.

You can find the current Neverball test in the Limba-Neverball repository on Github. All you need (after installing Limba and the build dependencies of all components) is to run the make_all.sh script.

Later, I also want to provide helper tools to automatically build the software in a chroot environment, and to allow building against the exact version depended on in the Limba package.

Creating a Limba package is trivial, it boils down to creating a simple “control” file describing the dependencies of the package, and to write an AppStream metadata file. If you feel adventurous, you can also add automatic build instructions as a YAML file (which uses a subset of the Travis build config schema)

This is the Neverball Limba package, built on Tanglu 3, run on Fedora 21:

Limba-installed Neverball

Which kernel do I need to run Limba?

The Limba build tools run on any Linux version, but to run applications installed with Limba, you need at least Linux 3.18 (for Limba 0.4.2). I plan to bump the minimum version requirement to Linux 4.0+ very soon, since this release contains some improvements in OverlayFS and a few other kernel features I am thinking about making use of.

Linux 3.18 is included in most Linux distributions released in 2015 (and of course any rolling release distribution and Fedora have it).

Building all these little Limba packages and keeping them up-to-date is annoying…

Yes indeed. I expect that we will see some “bigger” Limba packages bundling a few dependencies, but in general this is a pretty annoying property of Limba currently, since there are so few packages available you can reuse. But I plan to address this. Behind the scenes, I am working on a webservice, which will allow developers to upload Limba packages.

This central ressource can then be used by other developers to obtain dependencies. We can also perform some QA on the received packages, map the available software with CVE databases to see if a component is vulnerable and publish that information, etc.

All of this is currently planned, and I can’t say a lot more yet. Stay tuned! (As always: If you want to help, please contact me)

Are the Limba interfaces stable? Can I use it already?

The Limba package format should be stable by now – since Limba is still Alpha software, I will however, make breaking changes in case there is a huge flaw which makes it reasonable to break the IPK package format. I don’t think that this will happen though, as the Limba packages are designed to be easily backward- and forward compatible.

For the Limba repository format, I might make some more changes though (less invasive, but you might need to rebuilt the repository).

tl;dr: Yes! Plase use Limba and report bugs, but keep in mind that Limba is still in an early stage of development, and we need bug reports!

Will there be integration into GNOME-Software and Muon?

From the GNOME-Software side, there were positive signals about that, but some technical obstancles need to be resolved first. I did not yet get in contact with the Muon crew – they are just implementing AppStream, which is a prerequisite for having any support for Limba[1].

Since PackageKit dropped the support for plugins, every software manager needs to implement support for Limba.


So, thanks for reading this (again too long) blogpost 🙂 There are some more exciting things coming soon, especially regarding AppStream on Debian/Ubuntu!

 

[1]: And I should actually help with the AppStream support, but currently I can not allocate enough time to take that additional project as well – this might change in a few weeks. Also, Muon does pretty well already!

a silhouette of a person's head and shoulders, used as a default avatar

"Incursões violinísticas" - Mark O'Connor

Não lembro se foi em 2013, mas depois de uns 10 anos parada devido à faculdade, voltei a fazer aulas de violino. Para tentar minimizar o problema do som ruim característico de iniciantes comprei um violino elétrico. Assim posso fazer a desgraça que for: quem estiver em redor vai ouvir um som muito baixo (e os vizinhos provavelmente são poupados até disso). Sim. Comprei um Stagg. Porque não

a silhouette of a person's head and shoulders, used as a default avatar

KIELUX / Teilnehmer für 13. Kieler Open Source und Linux Tage gesucht

Für die „13. Kieler Open Source und Linux Tage“ am 18. und 19. September 2015 suche ich Freiwillige, die mit mir den openSUSE-Stand in Kiel betreuen. Somit wäre openSUSE zum ersten Mal in Norddeutschland auf der KIELUX vertreten. Daher brauche ich eure Mithilfe. :-D

Welche Fähigkeiten und Kenntnisse sollte man mitbringen? Klasse wäre, wenn man sich gut in openSUSE auskennt, um die Fragen (oft auch Anwenderfragen) der interessierten Besucher beantworten zu können und den potenziellen Anwender openSUSE schmackhaft zu machen und mögliche Ängste beim Umstieg abnimmt. Auch Fragen über persönliche Erfahrungen mit openSUSE und die tägliche Arbeit mit dem System kommen vor. Es ist nicht schlimm, wenn man sich in einem Gebiet nicht auskennt, die anderen Standteilnehmer helfen gerne untereinander aus. Ganz wichtig ist, dass der Spaß nicht auf der Strecke bleibt!

Was sollte mitgebracht werden? Für eine Live-Präsentation ist ein Notebook, Tablet-PC oder ein Desktop-PC mit openSUSE sinnvoll. Je mehr Geräte vor Ort sind, um so mehr kann man sie für verschiedene Anwendungszwecke z.B. für Video-Präsentationen einsetzen.

Wieviele Teilnehmer wird für den openSUSE-Stand benötigt? Aus der Erfahrung von den anderen Veranstaltungen werden mindestens 3 Teilnehmer für den Stand benötigt. Erstens um die Stoßzeiten besser abzufedern und zweitens das jeder die Möglichkeit erhält, auch die gewünschten Vorträge zu besuchen, wenn man schon mal dort ist. ;-)

Auf der Veranstaltung werden auch Vorträge und Workshops gehalten. Es wäre super, wenn jemand einen Vortrag zu openSUSE halten kann, um mehr Menschen für openSUSE zu begeistern. Ggfs. werde ich ein Workshop ausarbeiten.

Wie kann ich mitmachen? Einfach unten im Kommentar eine Nachricht mit gültiger E-Mailadresse im E-Mailfeld hinterlassen oder eine E-Mail direkt an
mail@sebastian-siebert.de
senden. Ich werde mich dann mit weiteren Informationen bei dir melden.

Wieso auf einmal „Kieler Open Source und Linux Tage“?

Die Vorgeschichte geht so: In einem Gespräch mit dem Standkollegen Marcel Richter (openSUSE Mitglied und Befürworter) habe ich auf der CLT2015 (Chemnitzer Linux-Tage) erfahren, dass die openSUSE Community nie mit einem Stand auf der KIELUX vertreten war. 8-O Damit lag die Vor-Ort-Präsenz von openSUSE in Norddeutschland so ziemlich brach. :( Als ich unseren Partnerstand Invis-Server, dessen Projekt auf openSUSE aufsetzt, nach dieser Veranstaltung in Kiel fragte, bekam ich als Antwort zu hören, dass das Team schon immer auf die KIELUX geschielt hat. Jedoch wegen dieser Umstände nicht nach Norddeutschland kamen. :-?

Woran hat es gelegen, dass in der Vergangenheit niemand mit einem Stand für openSUSE in Kiel vertritt? Einige Standteilnehmer konnten wegen fehlender Zeit und/oder Geld nur die Ausstellungen in Wohnortnähe aufsuchen. :-|

Die openSUSE-Community sollte nicht nur in West-, Ost- und Süddeutschland auf Open-Source-Veranstaltungen vertreten sein, sondern auch in Norddeutschland. Genau das sollte sich in diesem Jahr ändern und suche ab sofort weitere Standteilnehmer für unseren openSUSE-Stand in Kiel. :wink:

Als openSUSE Mitglied (Member) wie auch Befürworter (Advocate) war ich nahezu auf jeder Veranstaltung der ORR (OpenRheinRuhr) dabei. Es hat mir bisher immer Spaß gemacht, mit den Menschen in Kontakt zu treten, die gerne über openSUSE in Erfahrung bringen möchten oder auch Hilfe bei einem speziellen Problem gesucht haben. In diesem Jahr habe ich sogar die CLT2015 (Chemnitzer Linux-Tage) mitgenommen. Jedes Mal freue ich mich, wenn ich Bekannte Gesichter auf der Ausstellung sehe und mit ihnen ins Gespräch komme und auch neue Leute kennenlerne. 8)

a silhouette of a person's head and shoulders, used as a default avatar

High Contrast Refresh

One of the major visual updates of the 3.16 release is the high contrast accessible theme. Both the shell and the toolkit have received attention in the HC department. One noteworthy aspect of the theme is the icons. To guarantee some decent amount of contrast of an icon against any background, back in GNOME 2 days, we solved it by "double stroking" every shape. The term double stroke comes from a special case, when a shape that was open, having only an outline, would get an additional inverted color outline. Most of the time it was a white outline of a black silhouette though.

Old HC theme
Fuzzy doublestroke PNGs of the old HC theme

In the new world, we actually treat icons the same way we treat text. We can adjust the best contrast by controlling the color at runtime. We do this the same way we've done it for symbolic icons, using an embedded CSS stylesheet inside SVG icons. And in fact we are using the very same symbolic icons for the HC variant. You would be right arguing that there are specific needs for high contrast, but in reality majority of the double stroked icons in HC have already been direct conversions of their symbolic counterparts.

New HC theme
Crisp recolorable SVGs of the post 3.16 world

While centralized theme that overrides all application never seemed like a good idea, as the application icon is part of its identity and should be distributed and maintained alongside the actual app, the process to create a high contrast variant of an icon was extremely cumbersome and required quite a bit of effort. With the changes in place for both the toolkit and the shell, it's far more reasonable to mandate applications to include a symbolic/high contrast variant of its app icon now. I'll be spending my time transforming the existing double stroke assets into symbolic, but if you are an application author, please look into providing a scalable stencil variant of your app icon as well. Thank you!

a silhouette of a person's head and shoulders, used as a default avatar

KDE Plasma 5 und die Windowstaste

Ich arbeite beruflich mit Windows 7 und habe mich daher an das Verhalten der Windowstaste (Startmenü öffnet sich, ich dann durch Tippen nach Programmen suchen) gewöhnt. Unter KDE Plasma 5 lässt sich das mit einem kleinen Programm von Hans Chen recht einfach nachbauen:
ksuperkey biegt kurz gesagt das durch Super ausgelöste Signal so um, dass sich das Plasma Startmenü öffnet.

Installation
ksuperkey gibt es in manchen Distributionen (Arch, ROSA, OpenMandriva) direkt aus den Paketquellen. Für OpenSUSE existiert ein OBS-Repo.
Für Debian/Ubuntu/Mint führt leider kein Weg am Kompilieren vorbei:

  • Abhängigkeiten installieren:
    sudo apt-get install gcc make libx11-dev libxtst-dev pkg-config
  • Auf manchen Debian-basierten Systemen braucht es wohl auch build-essentials, die sollte man aber eh installiert haben.
  • Code holen und bauen:
    git clone https://github.com/hanschen/ksuperkey.git
    cd ksuperkey
    make

Einrichten
Mit ./ksuperkey kannst du das Programm schon mal starten. Wichtig ist, dass Alt + F1 als Tastenkürzel für das Startmenü festgelegt ist.
Einfach überprüfen und gegebenenfalls beheben:
screenshot-ksuperkey-1

Jetzt noch mit folgenden Schritten ksuperkey automatisch starten lassen:
Systemeinstellungen → Starten und Beenden → Autostart → Programm hinzufügen– → ksuperkey suchen oder auswählen

Das war’s schon!

a silhouette of a person's head and shoulders, used as a default avatar

Изменение размера раздела

Имеется диск с тремя разделами sda1 (/boot), sda2 (swap), sda3 (/). Необходимо увеличить размер раздела /boot за счет swap.

Сначала отмонтируем все разделы и проверим файловую систему.
# swapoff  /dev/sda2 
# umount /dev/sda1 
# e2fsck /dev/sda1 
e2fsck 1.42.6 (21-Sep-2012)
/dev/sda1: clean, 49/14056 files, 47157/56196 blocks

Используем parted для того, чтобы сначала уменьшить и передвинуть второй раздел, а затем расширить первый на освободившееся место. Так как второй раздел - swap, то его мы просто передвинем, не заботясь о содержимом. Иначе говоря, сначала мы совсем сломаем, а потом заново её разметим.

# parted /dev/sda
GNU Parted 2.4
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) unit s                                                           
(parted) print                                                            
Model: ATA QEMU HARDDISK (scsi)
Disk /dev/sda: 120103200s
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start     End         Size        Type     File system     Flags
 1      63s       112454s     112392s     primary  ext2            boot, type=83
 2      112455s   1686824s    1574370s    primary  linux-swap(v1)  type=82
 3      1686825s  120101939s  118415115s  primary  reiserfs        type=83

Для изменения раздела используется команда resize номер_раздела начало конец

(parted) resize 2 224973 1686824
WARNING: you are attempting to use parted to operate on (resize) a file system.
parted's file system manipulation code is not as robust as what you'll find in
dedicated, file-system-specific packages like e2fsprogs.  We recommend
you use parted only to manipulate partition tables, whenever possible.
Support for performing most operations on most types of file systems
will be removed in an upcoming release.
(parted) print
Model: ATA QEMU HARDDISK (scsi)
Disk /dev/sda: 120103200s
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start     End         Size        Type     File system     Flags
 1      63s       112454s     112392s     primary  ext2            boot, type=83
 2      224973s   1686824s    1461852s    primary  linux-swap(v1)  type=82
 3      1686825s  120101939s  118415115s  primary  reiserfs        type=83

К сожалению в этот момент оно само подмонтировало всё назад, поэтому нужно снова отмонтировать первый раздел. Раздел swap в данный момент уже должен быть работоспособен, потому-что mkswap на нем выполнился сам автоматически. К сожалению, я не нашел способа отключить всю эту самодеятельность.

# umount /dev/sda1
# e2fsck -p /dev/sda1

Снова идем в parted:

# parted
GNU Parted 2.4
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) unit s                                                           
(parted) print                                                            
Model: ATA QEMU HARDDISK (scsi)
Disk /dev/sda: 120103200s
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start     End         Size        Type     File system     Flags
 1      63s       112454s     112392s     primary  ext2            boot, type=83
 2      224973s   1686824s    1461852s    primary  linux-swap(v1)  type=82
 3      1686825s  120101939s  118415115s  primary  reiserfs        type=83

(parted) resize 1 63 224972
WARNING: you are attempting to use parted to operate on (resize) a file system.
parted's file system manipulation code is not as robust as what you'll find in
dedicated, file-system-specific packages like e2fsprogs.  We recommend
you use parted only to manipulate partition tables, whenever possible.
Support for performing most operations on most types of file systems
will be removed in an upcoming release.
(parted) quit                                                             
Warning: You should reinstall your boot loader before rebooting.  Read section 4 of the Parted User documentation for more
information.
Information: You may need to update /etc/fstab.   

Готово, parted не только изменил размер раздела, но еще и молча расширил для нас файловую систему, а теперь предупреждает о необходимости обновить загрузчик.
a silhouette of a person's head and shoulders, used as a default avatar

Изменение размера раздела

Имеется диск с тремя разделами sda1 (/boot), sda2 (swap), sda3 (/). Необходимо увеличить размер раздела /boot за счет swap.

Сначала отмонтируем все разделы и проверим файловую систему.
# swapoff  /dev/sda2 
# umount /dev/sda1
# e2fsck /dev/sda1
e2fsck 1.42.6 (21-Sep-2012)
/dev/sda1: clean, 49/14056 files, 47157/56196 blocks

Используем parted для того, чтобы сначала уменьшить и передвинуть второй раздел, а затем расширить первый на освободившееся место. Так как второй раздел - swap, то его мы просто передвинем, не заботясь о содержимом. Иначе говоря, сначала мы совсем сломаем, а потом заново её разметим.

# parted /dev/sda
GNU Parted 2.4
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) unit s
(parted) print
Model: ATA QEMU HARDDISK (scsi)
Disk /dev/sda: 120103200s
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number Start End Size Type File system Flags
1 63s 112454s 112392s primary ext2 boot, type=83
2 112455s 1686824s 1574370s primary linux-swap(v1) type=82
3 1686825s 120101939s 118415115s primary reiserfs type=83

Для изменения раздела используется команда resize номер_раздела начало конец

(parted) resize 2 224973 1686824
WARNING: you are attempting to use parted to operate on (resize) a file system.
parted's file system manipulation code is not as robust as what you'll find in
dedicated, file-system-specific packages like e2fsprogs. We recommend
you use parted only to manipulate partition tables, whenever possible.
Support for performing most operations on most types of file systems
will be removed in an upcoming release.
(parted) print
Model: ATA QEMU HARDDISK (scsi)
Disk /dev/sda: 120103200s
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number Start End Size Type File system Flags
1 63s 112454s 112392s primary ext2 boot, type=83
2 224973s 1686824s 1461852s primary linux-swap(v1) type=82
3 1686825s 120101939s 118415115s primary reiserfs type=83

К сожалению в этот момент оно само подмонтировало всё назад, поэтому нужно снова отмонтировать первый раздел. Раздел swap в данный момент уже должен быть работоспособен, потому-что mkswap на нем выполнился сам автоматически. К сожалению, я не нашел способа отключить всю эту самодеятельность.

# umount /dev/sda1
# e2fsck -p /dev/sda1

Снова идем в parted:

# parted
GNU Parted 2.4
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) unit s
(parted) print
Model: ATA QEMU HARDDISK (scsi)
Disk /dev/sda: 120103200s
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number Start End Size Type File system Flags
1 63s 112454s 112392s primary ext2 boot, type=83
2 224973s 1686824s 1461852s primary linux-swap(v1) type=82
3 1686825s 120101939s 118415115s primary reiserfs type=83

(parted) resize 1 63 224972
WARNING: you are attempting to use parted to operate on (resize) a file system.
parted's file system manipulation code is not as robust as what you'll find in
dedicated, file-system-specific packages like e2fsprogs. We recommend
you use parted only to manipulate partition tables, whenever possible.
Support for performing most operations on most types of file systems
will be removed in an upcoming release.
(parted) quit
Warning: You should reinstall your boot loader before rebooting. Read section 4 of the Parted User documentation for more
information.
Information: You may need to update /etc/fstab.

Готово, parted не только изменил размер раздела, но еще и молча расширил для нас файловую систему, а теперь предупреждает о необходимости обновить загрузчик.
the avatar of Jeffrey Stedfast

Code Review: Microsoft's System.Net.Mail Implementation

For those reading my blog for the first time and don't know who I am, allow myself to introduce... myself.

I'm a self-proclaimed expert on the topic of email, specifically MIME, IMAP, SMTP, and POP3. I don't proclaim myself to be an expert on much, but email is something that maybe 1 or 2 dozen people in the world could probably get away with saying they know more than I do and actually back it up. I've got a lot of experience writing email software over the past 15 years and rarely do I come across mail software that does things better than I've done them. I'm also a critic of mail software design and implementation.

My latest endeavors in the email space are MimeKit and MailKit, both of which are open source and available on GitHub for your perusal should you doubt my expertise.

My point is: I think my review carries some weight, or I wouldn't be writing this.

Is that egotistical of me? Maybe a little.

I was actually just fixing a bug in MimeKit earlier and when I went to go examine Mono's System.Net.Mail.MailMessage implementation in order to figure out what the problem was with my System.Net.Mail.MailMessage to MimeKit.MimeMessage conversion, I thought, "hey, wait a minute... didn't Microsoft just recently release their BCL source code?" So I ended up taking a look and pretty quickly confirmed my suspicions and was able to fix the bug.

When I begin looking at the source code for another mail library, I can't help but critique what I find.

MailAddress and MailAddressCollection


Parsing email addresses is probably the hardest thing to get right. It's what I would say makes or breaks a library (literally). To a casual onlooker, parsing email addresses probably seems like a trivial problem. "Just String.Split() on comma and then look for those angle bracket thingies and you're done, right?" Oh God, oh God, make the hurting stop. I need to stop here before I go into a long rant about this...

Okay, I'm back. Blood pressure has subsided.

Looking at MailAddressParser.cs (the internal parser used by MailAddressCollection), I'm actually pleasantly surprised. It actually looks pretty decent and I can tell that a lot of thought and care went into it. They actually use a tokenizer approach. Interestingly, they parse the string in reverse which is a pretty good idea, I must say. This approach probably helps simplify the parser logic a bit because parsing forward makes it difficult to know what the tokens belong to (is it the name token? or is it the local-part of an addr-spec? hard to know until I consume a few more tokens...).

For example, consider the following BNF grammar:

address         =       mailbox / group
mailbox         =       name-addr / addr-spec
name-addr       =       [display-name] angle-addr
angle-addr      =       [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr
group           =       display-name ":" [mailbox-list / CFWS] ";"
                        [CFWS]
display-name    =       phrase
word            =       atom / quoted-string
phrase          =       1*word / obs-phrase
addr-spec       =       local-part "@" domain
local-part      =       dot-atom / quoted-string / obs-local-part
domain          =       dot-atom / domain-literal / obs-domain
obs-local-part  =       word *("." word)

Now consider the following email address: "Joe Example" <joe@example.com>

The first token you read will be "Joe Example" and you might think that that token indicates that it is the display name, but it doesn't. All you know is that you've got a 'quoted-string' token. A 'quoted-string' can be part of a 'phrase' or it can be (a part of) the 'local-part' of the address itself. You must read at least 1 more token before you'll be able to figure out what it actually is ('obs-local-part' makes things slightly more difficult). In this case, you'll get a '<' which indicates the start of an 'angle-addr', allowing you to assume that the 'quoted-string' you just got is indeed the 'display-name'.

If, however, you parse the address in reverse, things become a little simpler because you know immediately what to expect the next token to be a part of.

That's pretty cool. Kudos to the Microsoft engineers for thinking up this strategy.

Unfortunately, the parser does not handle the 'group' address type. I'll let this slide, however, partly because I'm still impressed by the approach the address parser took and also because I realize that System.Net.Mail is meant for creating and sending new messages, not parsing existing messages from the wild.

Okay, so how well does it serialize MailAddress?

Ugh. You know that face you make when you just see a guy get kicked in the nuts? Yea, that's the face I made when I saw line #227:

encodedAddress = String.Format(CultureInfo.InvariantCulture, "\"{0}\"", this.displayName);

The problem with the above code (and I'll soon be submitting a bug report about this) is that the displayName string might have embedded double quotes in it. You can't just surround it with quotes and expect it to work. This is the same mistake all those programmers make that allow SQL-injection attacks.

For an example of how this should be done, see MimeKit's MimeUtils.Quote() method.

I had such high hopes... at least this is a fairly simple bug to fix. I'll probably just offer them a patch.

ContentType and ContentDisposition


Their parser is decent but it doesn't handle rfc2231 encoded parameter values, so I'm not overly impressed. It'll get the job done for simple name="value" parameter syntax, though, and it will decode the values encoded with the rfc2047 encoding scheme (which is not the right way to encode values, but it is common enough that any serious parser should handle it). The code is also pretty clean and uses a tokenizer approach, so that's a plus. I guess since this isn't really meant as a full-blown MIME parser, they can get away with this and not have it be a big deal. Fair enough.

Serialization, unsurprisingly, leaves a lot to be desired. Parameter values are, as I expected, encoded using rfc2047 syntax rather than the IETF standard rfc2231 syntax. I suppose that you could argue that this is for compatibility, but really it's just perpetuating bad practices. It also means that it can't properly fold long parameter values because the encoded value just becomes one big long encoded-word token. Yuck.

Base64


Amusingly, Microsoft does not use their Convert.FromBase64() decoder to decode base64 in their System.Net.Mail implementation. I point this out mostly because it is the single most common problem users have with every one of the Open Source .NET mail libraries out there (other than MimeKit, of course) because Convert.FromBase64() relies on the data not having any line breaks, white space, etc in the input stream.

This should serve as a big hint to you guys writing your own .NET email libraries not to use Convert.FromBase64() ;-)

They use unsafe pointers, just like I do in MimeKit, but I'm not sure how their performance compares to MimeKit's yet. They do use a state machine, though, so rock on.

I approve this base64 encoder/decoder implementation.

SmtpClient


One thing they do which is pretty cool is connection pooling. This is probably a pretty decent win for the types of things developers usually use System.Net.Mail's SmtpClient for (spam, anyone?).

The SASL AUTH mechanisms that they seem to support are NTLM, GSSAPI, LOGIN and WDIGEST (which apparently is some sort of IIS-specific authentication mechanism that I had never heard of until now). For those that were curious which SASL mechanisms SmtpClient supported, well, now you know.

The code is a bit hard to follow for someone not familiar with the codebase (not nearly as easy reading as the address or content-type parsers, I'm afraid), but it seems fairly well designed.

It does not appear to support PIPELINING or BINARYMIME like MailKit does, though. So, yay! Win for MailKit ;-)

They do support SMTPUTF8, so that's good.

It seems that if you set client.EnableSsl to true, it will also try STARTTLS if it isn't able to connect on the SSL port. I wasn't sure if it did that or not before, so this was something I was personally interested in knowing.

Hopefully my SmtpClient implementation review isn't too disappointing. I just don't know what to say about it, really. It's a pretty straight-forward send-command-wait-for-reply implementation and SMTP is pretty dead simple.

Conclusion


Overall the bits I was interested in were better than I expected they'd be. The parsers were pretty good (although incomplete) and the serializers were "good enough" for normal use.

Of course, it's not as good as MimeKit, but let's be honest, MimeKit sets the bar pretty high ;-)

a silhouette of a person's head and shoulders, used as a default avatar

Quicktipp: Firefox und die Adressleiste: Wie man Wort für Wort markiert

Was mich auf meiner aktuellen OpenSUSE-Installation genervt hat, war das Verhalten beim Markieren von Text in der Firefox Adressleiste. Ich bin es gewohnt mit Strg+Shift und den Cursortasten Teile der eingegebene Adresse Wort für Wort auswählen zu können.
Scheinbar hat man das beim Paketieren für OpenSUSE jedoch nicht gemacht, sondern lässt immer die komplette Zeile markieren.

Kurz und gut, du kannst das Problem recht einfach in den Anwendungseinstellungen beheben:
1. about:config aufrufen und – falls nötig – den Warnhinweis bestätigen
2. Nach layout.word_select.stop_at_punctuation und den Wert durch Doppelklick auf “true” setzen.
2b. Wenn du Leerzeichen mit dem nächstgelegenen Wort zusammen markieren möchtest, noch layout.word_select.eat_space_to_next_word ebenfalls auf “true” umstellen.

Fertig!

a silhouette of a person's head and shoulders, used as a default avatar

KDE Plasma 5 und OpenSUSE Tumbleweed

KDE Plasma 5.2 ist seit kurzem veröffentlicht und in den Repositories von OpenSUSEs rolling release Zweig “Tumbleweed” bereits verfügbar. Der einfachste Weg um beides installiert zu bekommen ist wie folgt:

1. NetInstall ISO holen und Live-Stick (oder CD) erstellen.

  • Für 64bit:
    $ wget -c http://download.opensuse.org/tumbleweed/iso/openSUSE-Tumbleweed-NET-x86_64-Current.iso
  • Für 32bit:
    $ wget -c http://download.opensuse.org/tumbleweed/iso/openSUSE-Tumbleweed-NET-i686-Current.iso

2. Vom Installationsmedium starten und ein minimales grafisches System installieren. Hierzu bei der Desktopauswahl zuerst “Weitere” (oder “Other”) und dann “Minimal X Window” auswählen. Als entscheidenden Punkt noch “KDE Plasma 5” aktivieren.

3. Nachdem die Installation durch ist (dauert etwas, selbst über einen 100Mbit-Leitung musste ich ca. 45 Minuten warten) startest du das System zum ersten Mal – und boom! – landest in einem hässlichen twm Loginfenster. Und wenn du dich einloggst, bekommst du twm als Windowmanager gestartet.
Um das zu beheben änderst du Folgendes:
$ sudo vim /etc/sysconfig/displaymanager
Hier die Variable DISPLAYMANAGER auf kdm oder sddm (falls installiert) setzen.

$ sudo vim /etc/sysconfig/windowmanager
Hier änderst du den Wert für DEFAULT_WM auf “plasma5”.

Jetzt einfach neu booten oder den Displaymanager neu starten:
$ sudo service display-manager restart
Das war’s!