Purplepixie Software and Dave's Blog

Tag Archives: cgi file upload

A long time ago when I still had (some) hair and hadn’t bitten the PHP bullet I played around with C++ CGIs. Owing to a lack of then available HOW-TO docs I went on to write a (badly written and error-filled) CGI in C/C++ HOW-TO and also a CGI Variable Wrapper. The HOW-TO did what it said on the tin and the wrapper provided an easy API to read/write GET and POST variables as well as cookies.

Surprisingly both the HOW-TO and the wrapper are still in use and I get contacted form time to time with queries. The most common query regards file upload which the wrapper doesn’t support. To illustrate a simple file upload I cobbled together a quick and dirty C example which I’ve provided via email ever since.

So here, for general reference, is my demonstration C code. Please note this is very untested and unrobust, even dodgier than my usual fare. I keep meddling with the idea of finding time to do a proper job either of a standalone file upload API or integrating support into the CGI wrapper. All of this is really just for kicks though as there are better solutions available.

C/C++ CGI File Upload Example

C

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

/** Very rough-and-ready CGI file upload in C/C++

This is demonstration code only really and, of course,

no liability accepted for anything!

David Cutting

http://www.purplepixie.org/dave/

http://blog.purplepixie.org/

dcutting [at] purplepixie [dot] org

Code Copyright DMC 22/05/2011

**/

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

intmain(void)

{

FILE*out;

char*rawdata;// pointer for rawdata

char*data;// will be an offset of rawdata after the two newlines

unsignedlonglength;// length of data to be read used for malloc

unsignedlongwritelength;// use for the length of the write

char*pos;// used in the loop

printf("Content-type: text/html\n\n<HTML><PRE>");// for debug output

// Various bits of debug output are included - comment out for live

// and replace with whatever output you'd like to send to the client

out=fopen("/var/www/test.jpg","wb+");// open the output file

length=atol(getenv("CONTENT_LENGTH"));

writelength=length;

printf("Content Length: %u\n",length);

rawdata=malloc(length+1);// malloc required buffer

fread(rawdata,length,1,stdin);// read into buffer

// now comes the loop, there are better ways but not that I can find quickly enough

for(pos=rawdata;pos<(rawdata+length-4);pos++)

{

writelength--;// decrement the write length

printf("%c %d\n",pos[0],pos[0]);// used for debug output (comment out for live)

if((pos[0]==13)&&(pos[1]==10)&&(pos[2]==13)&&(pos[3]==10)&&((pos[4]<32)||(pos[4]>127)))// pattern to find two double-newlines

{

data=pos+4;// move data pointer forward 4 to start of actual data

pos=rawdata+length+2;// break loop

printf("Found\n");// another debug line - comment out for live

writelength-=3;// decrement writelength by three (done one already above for this loop)