SAI || Sommersemester 1997 || Systemnahe Software II || Übungen

<- Alle Module

Lösung zu Blatt 7 (Aufgabe 8): streamio.c

Ein- und Ausgabe mit Streams.

streamio.c

#include "stream.h"
#include <stdio.h>

#define HTTP    80                              /* HTTP-Port    */

extern void *calloc();
extern char *strchr();
extern char *strstr();
extern char *strlwr();

/*
 * schaut sich das Protokoll des HTTP-Servers an
 * return 1: Dokument gesendet
 * return 0: Dokument NICHT gesendet
 */

static int testhttp(STREAM *s)
{       char buf[BUFSIZ];
        char *type = "content-type";            /* Zeile fuer Dokumenttyp */

        if (!getstream(buf, BUFSIZ, s))
                return 0;
        if (!strstr(buf, "200"))                /* 200 = OK !   */
                return 0;
                                                /* bis zur Leerzeile lesen */
        while (*buf != '\n' && getstream(buf, BUFSIZ, s))
                if (!strncmp(strlwr(buf), type, strlen(type)))
                        if (!strstr(buf, "html"))
                                return 0;       /* Dokutyp KEIN Html    */

        return 1;
}

/*
 * oeffnet die Verbindung zu einer Datei und spaeter zu einem Socket
 * erwartetes Format: server/datei
 */

STREAM *openstream(char *adr)
{       STREAM *new;
        int sock;
        char *jogg;
        char buf[BUFSIZ];

        strcpy(buf, adr);

        if (!(jogg = strchr(buf, '/')))         /* Adresse nicht korrekt */
        {       fprintf(stderr, "address %s not correct\n", adr);
                return NULL;
        }
        *jogg = 0;                              /* grenzt Server ab !   */

        if ((sock = call_socket(buf, HTTP)) <0)
        {       fprintf(stderr, "Server %s not found\n", adr);
                return NULL;                    /* keine Verbindung     */
        }
                
        if (!(new = calloc(1, sizeof(STREAM)))) /* Platz fuer Struktur holen */
        {       close(sock);
                fprintf(stderr, "no more space available\n");
                return NULL;
        }
        new->sock = sock;
        sprintf(buf, "GET /%s HTTP 1.0\n\n", strchr(adr, '/')+1);
        write(sock, buf, strlen(buf));          /* request abschicken   */

        if (testhttp(new))                      /* Dokument uebergeben ?*/
                return new;
        else                                    /* Doku nicht vorhanden */
        {       closestream(new);
                fprintf(stderr, "not found/no html:%s\n", adr);
                return NULL;
        }
}

/*
 * schliesst die Verbindung, die hinter einem Stream steht, wieder
 */

void closestream(STREAM *s)
{
        if (s)
                close(s->sock),
                free(s);
}

/*
 * holt auf einen Rutsch eine Menge Zeichen in den Zwischenbuffer
 */

static int readbuf(STREAM *s)
{
        s->end = read(s->sock, s->buf, sizeof(s->buf));
        s->beg = 0;
        
        return s->end >0;
}

/*
 * holt die nexte Zeile aus dem Stream (incl. Newline)
 */

char *getstream(char *buf, int len, STREAM *s)
{       char *ori = buf;

        if (!s || !buf || !len)
                return NULL;
        
                                /* ggf. Dokument einlesen       */
        if (!s->end || (s->beg >= s->end))
                if (!readbuf(s))        /* Buffer fuellen       */
                        return NULL;

        if (s->end && (s->beg < s->end)) /* Ok: Zeichen im Puffer       */
        {       while (len >0 && (s->beg <s->end))
                {       *buf = s->buf[s->beg++];
                        if (*buf == '\n')       /* Zeilenende           */
                        {       *++buf = 0;     /* 0Byte dranhaengen    */
                                return ori;
                        }
                        buf++, len--;
                        if ((s->beg >= s->end) && !readbuf(s))
                                break;
                }
        }
        *++buf = '\n';
        *++buf = 0;
        return ori;
}
<- Alle Module
SAI || Sommersemester 1997 || Systemnahe Software II || Übungen

Matthias Grabert, Juli 1997