input type="file" in c verstehe ich nicht
hans schmidt
- webserver
Hallo,
ich gehöre zu den wenigen, die cgi in ansi-c schreiben.
ich habe ein problem mit type="file".
nach meinem verständniss müste :
************************************************************
<head>
<META HTTP-EQUIV="Content-Type" content="text/html; charset=iso-8859-1">
<title>kundeand</title>
<body BGCOLOR="#FFFFCC" LINK="#0000AA" ALINK="#FF0000">
<h1>Logo für kunde : 00 , AMV</h1>
<form action="/cgi-bin/smq/kunden/kunden_jpg_upl.exe" enctype="multipart/form-data" method="post">
<p>
Wählen Sie eine Bild-Datei (jpg, gif) bis 100 kb von Ihrem Rechner aus:<br>
<input name="Datei" type="file" size="50" maxlength="100000">
</p>
<input type="Submit" name="ok" value="Datei Senden">
</form>
</body>
</html>
*************************************************************
die ausgewählte datei in stdin schreiben und das cgi:
*************************************************************
main()
{
text *qu;
text *qu2;
int buchst;
char fi[10000];
int i=0;
print_header("kundeand");
qu=getenv("REQUEST_METHOD");
qu2=getenv("CONTENT_LENGTH");
printf("%s<br>\n%s<br>\n",qu,qu2);
while(1)
{
buchst=getchar();
if (buchst==EOF || buchst=='\n') break;
fi[i]=buchst;
i++;
fi[i]='\0';
}
printf("%s",fi);
print_end();
return(0);
}
*****************************************************
das file ausgeben.
es macht aber nur undef-zeichen.
danke hans
Hallo,
ich gehöre zu den wenigen, die cgi in ansi-c schreiben.
Na, so wenige sind das gar nicht ;-)
ich habe ein problem mit type="file".
nach meinem verständniss müste :
************************************************************
<head>
Hast Du <html> nur vergessen hier zu listen?
<META HTTP-EQUIV="Content-Type" content="text/html; charset=iso-8859-1">
<title>kundeand</title>
Dito </head>?
<body BGCOLOR="#FFFFCC" LINK="#0000AA" ALINK="#FF0000">
<h1>Logo für kunde : 00 , AMV</h1>
<form action="/cgi-bin/smq/kunden/kunden_jpg_upl.exe"
Iiih, Windows ;-)
enctype="multipart/form-data" method="post">
Wie sieht denn die Anfrage an den Server genau aus?
<p>
Wählen Sie eine Bild-Datei (jpg, gif) bis 100 kb von Ihrem Rechner aus:<br>
<input name="Datei" type="file" size="50" maxlength="100000">
(100000 sind keine 100kb und hat auch sonst wenig damit zu tun ;-)
</p>
<input type="Submit" name="ok" value="Datei Senden">
</form>
</body>
</html>
*************************************************************
die ausgewählte datei in stdin schreiben und das cgi:
*************************************************************
main()
Hey, ANSI-C ist das nicht!
int main(void)
{
text *qu;
text *qu2;
int buchst;
char fi[10000];
Das sind nur 10.000 Bytes. Fehlt eine Null.
int i=0;
print_header("kundeand");
Achso, hier kommt der Rest, sorry. Aber der </head> fehlt trotzdem ;-)
qu=getenv("REQUEST_METHOD");
qu2=getenv("CONTENT_LENGTH");
printf("%s<br>\n%s<br>\n",qu,qu2);
Was kommt denn hier raus?
while(1)
Overflow möglich, teste i auf <10000
{
buchst=getchar();
getchar() liest von STDIN. Allerdings werden die Daten von der Form per Argument übergeben. Du müßtest die dann auslesen. (was für eine Lib benutzt Du denn? Mit Version bitte). Schau doch einfach mal nach, was denn Deinem Progrämmchen beim Start beigegeben wird.
Also obenhin
int main(int argc, char **argv)
if (buchst==EOF || buchst=='\n') break;
fi[i]=buchst;
i++;
fi[i]='\0';
}
printf("%s",fi);
Und hierhin:
for(i=0;i<argc;i++){
printf("ARGV(%d) = %s\n",i, argv[i]);
}
Sollte die einzelnen Argumente beim Aufruf Deines Programmes rauschmeißen.
print_end();
return(0);
}
*****************************************************
das file ausgeben.
es macht aber nur undef-zeichen.
Je nach Art der CGI-Lib mußt Du dieselbe meist auch initialisieren.
Was sagt der Compiler beim Bauen?
Was für einen nimmst Du überhaupt?
Aber mal abgesehen von all dem. Meinst Du nicht, daß es in PHP oder ähnlichem bedeutend leichter ginge? In PHP z.b. sind das etwa 5 Zeilen einfachster Code um einen Datei auf dem Server zu empfangen und zu speichern ;-)
Wenn Du also nicht gerade _wirklich_ arge Probleme mit schwachbrüstiger Hardware hast, ist für den simplen Zweck C ein wenig "overdressed" ;-)
Also alleine um die Datei zu speichern, brauchst Du schon etwa 30 Zeilen, wenn Du das ordentlich machen willst.
Wenn Du jedoch das emfangene Bild im gleichem Programm weiterverabeiten willst, ist C vielleicht doch nicht so die schlechteste Wahl. Es wird aber verdammt nicht einfach!
so short
Christoph Zurnieden
Hallo, vielen dank für die antwort.
ich arbeite mit visual c++ 5.0
beim compile keine fehlermeldungen.
ich benutze keine cgi-lib.
die funktion print_header("kundeand");gibt head ect. aus
print_end(); </html.....
bei printf("%s<br>\n%s<br>\n",qu,qu2); gibt er den inhalt der
env-var's REQUEST_METHOD CONTENT_LENGTH aus ( zum test)
die daten werden doch mit method=post übergeben werden doch in stdin geschrieben und nicht als argument übergeben.
die ausgabe der arg's ist :
ARGV(0) = d:\PROGRA~1\vscommon\webroot\cgi-bin\smq\kunden\KU514E~1.EXE
gruß hans
Hallo,
ich arbeite mit visual c++ 5.0
Aha, da haben wir doch den Fehler >;->
Nimm lieber einen der gängigen ANSI-C Compiler (LCCWin32 ist ein ganz ansprechender für Windows und vor allem gratis. GCC ist kompletter, aber zu aufwändig zu installieren und benutzen für den Anfänger)
BTW: was sagt denn Dein CLint über Deinen Code? ;-)
beim compile keine fehlermeldungen.
Sollte "Warnmeldungen" heißen, sorry.
Sind evt nicht eingeschaltet. Wie das bei dem Visual-Crap funktioniert entnimm bitte der Anleitung.
ich benutze keine cgi-lib.
Doch das tust Du, sonst kämst Du nicht an die Environment Variablen.
die funktion print_header("kundeand");gibt head ect. aus
print_end(); </html.....
Eigene Funktionen, oder von der CGI-Lib?
bei printf("%s<br>\n%s<br>\n",qu,qu2); gibt er den inhalt der
env-var's REQUEST_METHOD CONTENT_LENGTH aus ( zum test)
Wer setzt die?
Womit kommst Du da ran?
Wieviele gibt es noch?
die daten werden doch mit method=post übergeben werden doch in stdin geschrieben und nicht als argument übergeben.
Es kommt ganz auf den Server an, in welche Datei die Daten geschrieben werden.
STDIN ist aber bei POST üblich, ja.
Welcher Server ist es eigentlich?
Beim IIS hast Du die Schnittstelle ISAPI, die wäre dann zu empfehlen. Beim Apachen könntest Du Dich auch noch in Modulen versuchen ;-)
die ausgabe der arg's ist :
ARGV(0) = d:\PROGRA~1\vscommon\webroot\cgi-bin\smq\kunden\KU514E~1.EXE
Warum ist der Pfad so verhutzelt?
Allerdings wird die ganze Sache eh schwierig, da MS alles andere als "üblich" oder gar Standardkonform ist. So ein Server läuft gewöhnlich in einer Unixwelt und da ist die Sache allgemein etwas leichter, da vieles schon eingebaut ist.
Zudem arbeitest Du mit einem C++ Compiler. Du solltest mal versuchen herauszufinden, welche Schreibweise des Macros "cplusplus" er bevorzugt und dann folgendes einfügen (Manchmal hilfts, hier aber wohl weniger ;-):
#ifdef cplusplus
extern "C" {
#endif
Dein Code kömmt dann hierhin
#ifdef cplusplus
}
#endif
so short
Christoph Zurnieden
hallo,
ich habe einen sourcecode gefunden der hilft...
http://www.kessels.com/upload
gruß hans
hallo,
ich habe einen sourcecode gefunden der hilft...
http://www.kessels.com/upload
Da mußt Du aber vor Benutzung noch einmal ran, wenn Du ihn benutzen willst.
Da aber eine Lizenz nicht auf die Schnelle zu finden war, weiß ich nicht, ob Du da etwas verändern darfst.
lclint +gnuextensions +trytorecover +posixlib upload.c
(Die Gnuextensions und Posixlib brauche ich nur für meine Header, haben sonst nix mit dem Code selber zu tun)
[...]
upload.c:224,5: Fresh storage p1 not released before assignment:
p1 = strrchrs(s2, "/\")
A memory leak has been detected. Newly-allocated or only-qualified storage is
not released before the last reference to it is lost. (-mustfree will
suppress message)
upload.c:221,3: Fresh storage p1 allocated
[...]
Finished LCLint checking --- 52 code errors found
Daneben habe ich nch einige mögliche BufferOverflows speziell bei der Benutzung von sprintf() gefunden. Mindestens einer davon könnte sich für einen Exploit eignen.
so short
Christoph Zurnieden
Hi Christoph,
ich benutze keine cgi-lib.
Doch das tust Du, sonst kämst Du nicht an die Environment Variablen.
Wieso das?
Der Webserver baut das CGI-Environment auf.
Dabei setzt er insbesondere einige Environment-Variablen.
Eine CGI-Bibliothek macht deren Inhalt vielleicht handlicher, ist
aber zwingend nicht notwendig, um prinzipiell darauf zuzugreifen.
Schreib Dir mal ein kleines shell-Skript, welches einfach nur das
Environment ausgibt, und rufe das via CGI auf ... oder nimm Dir als
Beispiel
http://aktuell.de.selfhtml.org/artikel/cgiperl/inbetriebnahme/#a18,
was ebenfalls keine CGI-Analyse-Bibliothek verwendet.
Viele Grüße
Michael
Hallo,
ich benutze keine cgi-lib.
Doch das tust Du, sonst kämst Du nicht an die Environment Variablen.
Wieso das?
Der Webserver baut das CGI-Environment auf.
Dabei setzt er insbesondere einige Environment-Variablen.
Das ist für Windows, ich dachte immer, da würde getenv() nur bei initialisierter ISAPI funktionieren, aber ich habe schon lange nichts mehr für Windowsserver gemacht. (Gottseidank! ;-)
Eine CGI-Bibliothek macht deren Inhalt vielleicht handlicher, ist
aber zwingend nicht notwendig, um prinzipiell darauf zuzugreifen.
Wär ja auch noch schöner! ;-)
Aber wie schon oben erwähnt, bei Windows zweifele ich aus Prinzip. >;->
(Es geht das Gerücht das WinNT, -2k, -XP auf VMS aufbauen. Mmh... ;-)
Schreib Dir mal ein kleines shell-Skript, welches einfach nur das
Environment ausgibt, und rufe das via CGI auf ... oder nimm Dir als
Beispiel
http://aktuell.de.selfhtml.org/artikel/cgiperl/inbetriebnahme/#a18,
was ebenfalls keine CGI-Analyse-Bibliothek verwendet.
Das letzte in C für den Apachen hatte ich direkt als Modul gelinkt. IMHO habe ich (in C) noch nie eine CGI-Bibliothek benutzt. Alleine aus dem Grund, daß sie alle recht lahmarschig sind. Oder besser einschränkend "waren", habe die Entwicklung nicht besonders verfolgt.
Aber schon der prinzipielle Overhead einer CGI-Lib würde mich stören. ;-)
Nun bin ich in dem kurzem Thread hier schon dreimal aus eigener Schusseligkeit (Schlampigkeit? ;-) auf die Schnauze gefallen.
Einsamer Rekord ;-)
Aber ich verspreche in mich zu gehen und daran zu arbeiten.
so short
Christoph Zurnieden
Hi,
enctype="multipart/form-data" method="post">
buchst=getchar();
getchar() liest von STDIN. Allerdings werden die Daten von der Form
per Argument übergeben. Du müßtest die dann auslesen.
Aber nicht doch. POST liefert die Daten wirklich via stdin.
(Eine komplette Datei in den URL zu quetschen wäre auch keine Art ... ;-)
Was ich aber grundsätzlich vermisse, ist eine Behandlung des CGI-Multipart-
Formates. Das ist ganz schön lästig - da steht nämlich keineswegs einfach
der Inhalt der Datei drin, sondern wesentlich mehr, und das mußt Du alles
mühsam in einzelne Felder zerlegen und Dir diejenigen Informationen heraus
suchen, die Du brauchst. (Beispielsweise wird ja auch der Name der hochge-
ladenen Datei mitgeliefert).
Tips, damit Du auf die Füße fällst:
a) Lade mal eine einfache Textdatei mit "Hello world" drin hoch, speichere
alles ab, was über stdin kommt, und schaue es Dir an.
b) Gib mal den Inhalt sämtlicher Environment-Variablen aus. Irgendwo darin
findest Du denjenigen Wert, welcher die einzelnen Multipart-Abschnitte
voneinander trennt - den brauchst Du, um sie wieder zerlegen zu können.
Ansonsten muß ich Christoph voll und ganz zustimmen: Das ist keine Aufgabe,
die ich unbedingt in C lösen möchte.
In PHP und Perl gibt es das praktisch als fertiges Produkt.
Viele Grüße
Michael
Hallo,
enctype="multipart/form-data" method="post">
buchst=getchar();
getchar() liest von STDIN. Allerdings werden die Daten von der Form
per Argument übergeben. Du müßtest die dann auslesen.
Aber nicht doch. POST liefert die Daten wirklich via stdin.
Ja, mein Fehler.
Peinlich peinlich!
*Öchött* ,-)
(Eine komplette Datei in den URL zu quetschen wäre auch keine Art ... ;-)
Ooooch, warum? ;-)
Was ich aber grundsätzlich vermisse, ist eine Behandlung des CGI-Multipart-
Formates. Das ist ganz schön lästig - da steht nämlich keineswegs einfach
der Inhalt der Datei drin, sondern wesentlich mehr, und das mußt Du alles
mühsam in einzelne Felder zerlegen und Dir diejenigen Informationen heraus
suchen, die Du brauchst. (Beispielsweise wird ja auch der Name der hochge-
ladenen Datei mitgeliefert).
Es schien mir eine minimierte Fassung zu sein, nur um zu prüfen, ob überhaupt was ankommt. (Sonst hätter er ja wohl auch den CONTENT_LENGTH benutzt et al) Und das tat es eben nicht, das war das Problem.
Ich finde auch so keinen Fehler, entweder bin ich blind auf den Augen(wahrscheinlich, wenn man schon "post" als "get" liest ;-), oder irgendwas stimmt in der Umgebung nicht.
(Auch nicht gerade unwahrscheinlich, ist ja schließlich Windows ;-)
Tips, damit Du auf die Füße fällst:
a) Lade mal eine einfache Textdatei mit "Hello world" drin hoch, speichere
alles ab, was über stdin kommt, und schaue es Dir an.
b) Gib mal den Inhalt sämtlicher Environment-Variablen aus. Irgendwo darin
findest Du denjenigen Wert, welcher die einzelnen Multipart-Abschnitte
voneinander trennt - den brauchst Du, um sie wieder zerlegen zu können.
Vielleicht hätte ich eben vor dem Posten meines anderen Beitrags nochmal nachschauen sollen ;-)
Ansonsten muß ich Christoph voll und ganz zustimmen: Das ist keine Aufgabe,
die ich unbedingt in C lösen möchte.
In PHP und Perl gibt es das praktisch als fertiges Produkt.
Aber, wie ich auch schon sagte: wer weiß, was er mit den empfangenen Daten so alles anstellen will. Die Datei mit PHP zu empfangen, um von dort aus eine zweites Programm zur Bearbeitung zu starten ist zwar einfacher, aber für Highspeed Enthusiasten ... ;-)
so short
Christoph Zurnieden
(Eine komplette Datei in den URL zu quetschen wäre auch keine Art ... ;-)
Ooooch, warum? ;-)
http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.2.1
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.15