SAI ||
Sommersemester 1997 ||
Systemnahe Software II ||
Übungen
<- Alle Module
Lösung zu Blatt 7 (Aufgabe 8): streamio.c
Ein- und Ausgabe mit Streams.
#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