UNIXwork

dav Einführung

2017-08-23 10:55:54.0

Dieser Artikel soll einen kleinen Überblick über den WebDAV-Kommandozeilen-Client dav geben.

Features

Alle WebDAV-Methoden des Basisprotokolls sind implementiert und es stehen Subcommands dafür bereit, wobei diese die WebDAV-Methoden mehr oder weniger abstrahieren.

Im Detail unterstützt dav:

URL

Alle Befehle von dav erwarten als Argument eine URL. Die URL kann eine normale http/https-URL sein, man kann aber auch nur den Hostnamen und Pfad angeben. Da dav intern libcurl verwendet, können wie bei curl auch der Benutzername und das Passwort mit der URL angegeben werden.

Um den Inhalt von http://example.com/webdav/ anzuzeigen geht also:

dav list http://example.com/webdav/
dav list example.com/webdav/
dav list user@example.com/webdav/
dav list user:pw@example.com/webdav/

Es ist jedoch auch möglich, Repositories für seine Lieblingsserver zu konfigurieren. In der dav Konfigurationsdatei muss für den Server der Repository-Name und die Basis-URL konfiguriert sein. Statt der ganzen URL reicht es dann nur den Repositorynamen und optional noch einen Pfad anzugeben.

Für unseren Beispielserver könnte die Konfigurationsdatei $HOME/.dav/config.xml dann so aussehen:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <repository>
        <name>myserver</name>
        <url>http://example.com/webdav/</url>

        <!-- optional: username -->
        <user>user</user>
        <!-- optional: base64 encoded password -->
        <password>MTIzNDU2Nzg=</password>
    </repository>
</configuration>

Den Inhalt der Basis-URL anzuzeigen geht dann mit:

dav list myserver

Auf beliebige Ressourcen unterhalb der Basis-URL kann man zugreifen, in dem man an den Repositorynamen einen Pfad anhängt:

dav list myserver/collection/

Dies würde dann den Inhalt von http://example.com/webdav/collection/ anzeigen.

Anstatt das Repository per Hand in der config.xml Datei zu konfigurieren kann man auch den dav Befehl add-repository verwenden. Dieser startet einen kleinen Assistenten der den Namen des Repositories, die Basis-URL, den Benutzername und das Passwort abfragt und die Konfiguration dafür dann anlegt.

Befehle

list

Den list Befehl haben wir schon gesehen. Dieser zeigt alle Kind-Ressourcen (Dateien) einer Collection (Verzeichnis) an. Dieser funktioniert ähnlich wie das Unix-Tool ls (statt dav list kann man auch dav ls schreiben). Ohne Optionen werden nur die Namen der Member angezeigt:

$ dav list myserver
collection
file1
file2
file3

Wie bei ls gibt es auch die -l Option, mit der zusätzliche Informationen pro Ressource angezeigt werden:

$ dav list -l myserver
d-              Feb 08 13:13  collection
--     4.2 KiB  Oct 11  2016  file1
--     95 bytes Oct 11  2015  file2
--     5.7 MiB  May 24 21:13  file3

Das kleine d in der ersten Spalte zeigt an, dass die Ressource eine Collection ist.

get

Mit get können einzelne Ressourcen oder ganze Collections gedownloadet werden.

Eine einzelne Ressource downloaden geht mit:

dav get myserver/file1

Um eine Collection zu downloaden muss man die -R Option angeben. Es werden dabei die Member der Collection direkt in das aktuelle Arbeitsverzeichnis gedownloadet.

dav get -R myserver/collection

put

Mit put können Dateien und Verzeichnisse geuploadet werden. Das erste Argument ist die Ziel-URL, das zweite die zu uploadende Datei.

Ist das Ziel eine Collection wird dort eine neue Ressource mit dem Namen der Datei erstellt:

dav put myserver localfile.txt

Man kann beim Uploaden auch den Namen der Ziel-Ressource angeben:

dav put myserver/newfilename.txt localfile.txt

Auch alle Dateien eines lokalen Verzeichnisses können geuploadet werden:

dav put -R myserver/newdir/ localdir

andere Befehle

Mit mkdir können WebDAV-Collections erstellt werden:

dav mkdir myserver/newcol/

Ressourcen und Collections können mit remove entfernt werden:

dav remove myserver/file1

Eine komplette Übersicht über alle Befehle gibt es hier.

Autor: Olaf | 0 Kommentare | Tags: dav, shell, curl

dav 1.0 veröffentlicht

2017-08-13 13:19:45.0

Nach langer Entwicklungszeit kann ich jetzt endlich dav 1.0 veröffentlichen. Dabei handelt es sich um einen Kommandozeilen-WebDAV-Client. Mit dabei ist auch das Tool dav-sync, welches lokale Verzeichnisse mit WebDAV-Server synchronisieren kann.

Neben der Grundfunktionalität wie Dateien up- und downloaden, Collections zu durchsuchen und was man sonst noch so mit WebDAV anstellen kann, bietet dav zwei besondere Features.

Das erste ist, dass man in einer Konfigurationsdatei die Zugriffsinformationen für seine WebDAV-Server, auf die man oft zugreifen will, hinterlegen kann. Das klingt zwar trivial, ich wollte es allerdings erwähnen, da es einen das Leben deutlich vereinfacht. Statt langen URLs muss man dann nur noch den Server-Alias und optional einen Pfad angeben.

Das eigentliche Killer-Feature ist jedoch die integrierte clientseitige AES-Verschlüsselung. Dateien können on-the-fly beim uploaden verschlüsselt werden und beim downloaden werden diese Dateien auch automatisch entschlüsselt. Neben den Dateiinhalten kann auch der Dateiname verschlüsselt werden. Die Benutzung von dav mit aktivierter Verschlüsselung unterscheidet sich dabei kaum.

Das zweite Programm ist dav-sync, für bidirektionale Dateisynchronisation. Ein häufiges Problem von Synctools ist Datenverlust, daher lag mein Fokus darauf genau das zu verhindern. Falls Dateien auf beiden Seiten verändert wurden, wird dies selbstverständlich beim Synchronisieren erkannt. Für zusätzliche Sicherheit sorgt aber ein Trash-Verzeichnis. Wann immer dav-sync Dateien löschen möchte, werden diese dann in dieses Verzeichnis verschoben. Optional können auch Dateien, bevor sie mit einer Version vom Server überschrieben werden, dorthin verschoben werden.

Genau wie dav unterstützt auch dav-sync clientseitige Verschlüsselung. Dateisynchronisierung über einen fremden Cloud-Server ist somit sicher.

Beide Programme kommen in einem Paket und können hier oder auf SourceForge gedownloadet werden. Auf SourceForge gibt es auch Windows Binaries.

Die Dokumentation liegt dem Quellcode bei und ist auch online verfügbar.

Autor: Olaf | 1 Kommentare | Tags: dav, webdav, curl, shell

Apple gibt zu, dass der Mac Pro für die Tonne ist

2017-04-06 19:40:11.0

2013 stellte Apple den kontrovers diskutierten neuen Mac Pro vor. Statt einer klassischen Workstation war dieser deutlich kleiner, hatte nur einen CPU-Sockel, keine wechselbaren Grafikkarten und keine Slots für herkömmliches Storage. Für Erweiterungen waren nur mehrere Thunderbolt-Ports vorgesehen. Dieses radikal neue Konzept löste bei einigen wenigen vielleicht Begeisterung aus, die Mehrheit war dem eher abgeneigt. Nicht nur war die CPU- und GPU-Power stark begrenzt, wer PCIe- oder Storage-Erweiterungen braucht, muss dies extern realisieren, was nicht nur deutlich teurer ist, sondern auch mehr Platz verbraucht und umständliche und hässliche Verkabelungen zur Folge hat.

Zusätzlich dazu hielt es Apple auch nicht für nötig, den Mac Pro zu updaten, obwohl Intel fleißig neue CPU-Generationen gebracht hat. Damit ist der Mac Pro mitlerweile völlig zum Witz geworden. Überteuert war er schon 2013 (im Vergleich mit anderen Workstations versteht sich), im Jahr 2017 hingegen ist es nur noch lächerlich, wenn man den alten Preis noch für veraltete Hardware zahlen muss.

Das hat nun auch Apple eingesehen. Zum einen haben sie geringfügig die Preise für das aktuelle Modell angepasst (natürlich immer noch lächerlich überteuert), zum anderen angekündigt, dass sie den Mac Pro komplett überdenken. Sie geben zu, dass das aktuelle Modell für viele Pro-User ungeeignet ist. In Zukunft soll der Mac Pro wieder ein modulares Design haben, so dass es auch für Apple deutlich einfacher ist, Upgrades zu liefern.

Interessant ist auch, dass laut Apple das Kühlungssystem, was das eigentlich Innovative am aktuellen Mac Pro sein sollte, nicht ordentlich funktioniert. Damit ist eigentlich auch der letzte Vorteil, den Fans der Apfel-Tonne immer betont haben, widerlegt.

Jetzt muss man natürlich warten, was Apple letztendlich entwickelt. Es besteht natürlich immer die Möglichkeit, dass sie eine noch schlechtere Idee haben.

Autor: Olaf | 0 Kommentare | Tags: apple, mac, workstation, rant

Linkdump

2017-04-04 09:15:38.0
Autor: Olaf | 0 Kommentare | Tags: links, c, curl, rust

File Descriptor zwischen Prozessen austauschen

2017-03-05 14:38:12.0

Es ist möglich, dass mehrere Prozesse Zugriff auf die gleichen File-Deskriptoren haben. Beispielsweise werden bei einem Fork alle File-Deskriptoren kopiert. Der Kind-Prozess kann dann auf die selben Dateien oder Sockets zugreifen.

Man kann auch nach einem Fork oder mit nicht-verwandten Prozessen File-Deskriptoren austauschen. Dies geht über Unix Domain Sockets mit den Funktionen sendmsg und recvmsg.

ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

Die Nachricht vom Typ struct msghdr hat so einige Felder, die man erstmal ausfüllen muss.

struct msghdr {
    void         *msg_name;       /* optional address */
    socklen_t     msg_namelen;    /* size of address */
    struct iovec *msg_iov;        /* scatter/gather array */
    size_t        msg_iovlen;     /* # elements in msg_iov */
    void         *msg_control;    /* ancillary data, see below */
    size_t        msg_controllen; /* ancillary data buffer len */
    int           msg_flags;      /* flags on received message */
 };

Das Feld msg_name wird hier nicht benötigt, daher setzen wir msg_name und msg_namelen auf 0.

struct msghdr msg;
msg.msg_name = NULL;
msg.msg_namelen = 0;

Die eigentlichen Daten überträgt man mit dem Feld msg_iov, ein Array an Buffern, wie man es von writev kennt. Man erstellt ein Array mit struct iovec Elementen und gibt jeweils einen Pointer auf die Daten und die Länge an. Es reicht natürlich, nur einen Buffer anzugeben.

struct iovec iov[1] ;
iov[0].iov_base = (void*)buf;
iov[0].iov_len = len;

msg.msg_iov = iov;
msg.msg_iovlen = 1;

Jetzt wollen wir noch einen Filedescriptor übertragen. Für solche (und andere) Zwecke gibt es das Feld msg_control für folgende struct:

struct cmsghdr {
    size_t cmsg_len;    /* Data byte count, including header
                           (type is socklen_t in POSIX) */
    int    cmsg_level;  /* Originating protocol */
    int    cmsg_type;   /* Protocol-specific type */
    /* followed by
       unsigned char cmsg_data[]; */
};

Nach den Feldern der struct müssen also noch zusätzliche Daten im Speicher liegen. Für den Fall, dass man Filedeskriptoren übertragen möchte, müssen ein oder mehrere Integer folgen. Es empfiehlt sich zunächst einen statischen Buffer mit der entsprechenden Größe anzulegen. Hierfür gibt es das Makro CMSG_SPACE, was die Größe des Buffers liefert.

char cmsg_buf[CMSG_SPACE(sizeof(int))];

Anschließend setzen wir die Felder der struct.

struct cmsghdr *cmsg = (struct cmsghdr*)cmsg_buf;
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS; // indicates fd payload data

Jetzt fehlt nur noch der Filedescriptor. Dieser muss, wie schon erwähnt, hinter der struct liegen. Mit dem Makro CMSG_DATA erhält man einen Pointer auf die Payload-Data.

int *data = (int*)CMSG_DATA(cmsg);
*data = fd;

Jetzt setzen wir nur noch msg_control und msg_controllen, sowie msg_flags. Danach kann sendmsg aufgerufen werden.

msg.msg_control = cmsg;
msg.msg_controllen = CMSG_LEN(sizeof(int));

msg.msg_flags = 0;

sendmsg(sock, &msg, 0);

Um einen Filedescriptor zu empfangen nutzt man recvmsg, was in der Benutzung ähnlich ist. Dort kommt die selbe struct für die Message zum Einsatz und man muss die Felder auch genauso setzen.

Ich hab ein kleines Beispielprogramm geschrieben, welches nach einem Fork eine Datei im Elternprozess öffnet und anschließend den Filedescriptor dieser Datei an den Kindprozess sendet. Das Kind empfängt dann den Filedescriptor und schreibt etwas in diese Datei.

Autor: Olaf | 0 Kommentare | Tags: unix, c, socket, ipc
Zurück Weiter