Upload-2.6/ 40777 0 0 0 7156322712 5611 5Upload-2.6/cgi-bin/ 40777 0 0 0 7166722106 7123 5Upload-2.6/cgi-bin/upload.cfg100666 0 0 431 7166722106 11063 Config = Default Root = /usr/local/upload/upload FileMask = * IgnoreSubdirs = YES Overwrite = YES LogFile = /usr/local/upload/upload.log OkPage = /WWW/html/OkPage.html BadPage = /WWW/html/BadPage.html Debug = 0 Upload-2.6/html/ 40777 0 0 0 7166722105 6556 5Upload-2.6/html/BadPage.html100666 0 0 134 7166722105 10722

Sorry!


Upload-2.6/html/index.html100666 0 0 346 7166722105 10553

Upload example


Upload-2.6/html/OkPage.html100666 0 0 231 7166722105 10603

Success!


File uploaded:
Bytes uploaded:

Upload-2.6/sources/ 40777 0 0 0 7166722106 7276 5Upload-2.6/sources/Makefile100666 0 0 773 7166722105 10741 # Settings: BINDIR = . CFLAGS = -O LDFLAGS = # Make the program(s): all: upload # Dependencies for the program(s): upload: Makefile upload.o $(CC) $(CFLAGS) upload.o -o upload $(LDFLAGS) # Dependencies for the object file(s): upload.o: Makefile upload.c # Install: install: Makefile upload -cp upload $(BINDIR)/upload.exe chmod 755 $(BINDIR)/upload.exe chmod u+s $(BINDIR)/upload.exe # Cleanup: clean: rm -f *.o a.out core tags upload # Make tags for Elvis: ctags: *.c *.h ctags -stv *.[ch] & Upload-2.6/sources/upload.c100666 0 0 63720 7166722106 10773 /* upload.exe -- Upload a file to a server using forms. DESCRIPTION This is a CGI program to upload one or more files to a WWW server, using standard HTML forms instead of FTP. It works with Netscape 3.0 and 4.0, and Internet Explorer 4.0. See the manpage for more information. AUTHOR Jeroen C. Kessels Internet Engineer mailto:jeroen@kessels.com http://www.kessels.com/ Tel: +31(0)654 744 702 COPYRIGHT Jeroen C. Kessels 9 december 2000 VERSION 2.6 */ #include #include #include #include #ifdef unix #include #else #include #ifdef _MSC_VER #include #else #include #endif #endif #include #ifdef unix #define stricmp strcasecmp #define strnicmp strncasecmp #endif #define COPYRIGHT "
Upload v2.6
© 2000 Jeroen C. Kessels
\n
" #define NO 0 #define YES 1 #define MUST 2 /* Define DIRSEP, the character that will be used to separate directories. */ #ifdef unix #define DIRSEP "/\\" #else #define DIRSEP "\\/" #endif /* Configuration parameters from the configuration file. */ char Root[BUFSIZ]; char FileMask[BUFSIZ]; int IgnoreSubdirs; int OverWrite; char LogFile[BUFSIZ]; char OkPage[BUFSIZ]; char OkUrl[BUFSIZ]; char BadPage[BUFSIZ]; char BadUrl[BUFSIZ]; char UpFileName[BUFSIZ]; int Debug; long FileCount; long ByteCount; char LastFileName[BUFSIZ]; /* Translate character to lowercase. */ char clower(char c) { if ((c >= 'A') && (c <= 'Z')) return((c - 'A') + 'a'); return(c); } /* Compare a string with a mask, case-insensitive. If it matches then return YES, otherwise NO. The mask may contain wildcard characters '?' (any character) '*' (any characters). */ int MatchMask(char *String, char *Mask) { char *m; char *s; if (String == NULL) return NO; /* Just to speed up things. */ if (Mask == NULL) return NO; if (strcmp(Mask,"*") == 0) return YES; m = Mask; s = String; while ((*m != '\0') && (*s != '\0')) { if ((clower(*m) != clower(*s)) && (*m != '?')) { if (*m != '*') return NO; m++; if (*m == '\0') return YES; while (*s != '\0') { if (MatchMask(s,m) == YES) return YES; s++; } return NO; } m++; s++; } while (*m == '*') m++; if ((*s == '\0') && (*m == '\0')) return YES; return NO; } /* Translate the URL separator '/' into the directory separator ('/' for Unix, '\\' for DOS), making a proper pathname. */ void Url2Dir(char *Dir, char *Url) { char *p1; char *p2; p1 = Url; p2 = Dir; while (*p1 != '\0') { if (*p1 == '/') { *p2++ = *DIRSEP; p1++; } else { *p2++ = *p1++; } } *p2 = '\0'; } /* Return the last position in a string of any character from collection. The haystack string is scanned from end to begin until a character is found from the needle string. The pointer to the found character is returned, or NULL if not found. This subroutine is designed to find a directory separator in a path, where the directory separator can be '\\' (DOS) or '/' (Unix). */ char *strrchrs(char *haystack,char *needle) { char *h_here; char *n_here; long h_length; if ((haystack == NULL) || (needle == NULL)) return(NULL); for (h_length = 0, h_here = haystack; *h_here != '\0'; h_here++, h_length++); while (h_length > 0) { h_here--; h_length--; n_here = needle; while (*n_here != '\0') { if (*n_here == *h_here) return(h_here); n_here++; } } return(NULL); } /* Create all directories in the path. The permissions of the directory at From are used for the new directory, leave NULL for default permissions. If IsAdir=NO then the path points to a filename, otherwise it is a directoryname. */ void CreatePath(char *To, char *From, int IsAdir) { #ifdef unix struct stat statbuf; #endif char s1[BUFSIZ]; char s2[BUFSIZ]; char *p1; if (To == NULL) return; /* If the Path contains subdirectories, then strip the last directory and iterate. */ strcpy(s1,To); if (From != NULL) { strcpy(s2,From); } else { *s2 ='\0'; } p1 = strrchrs(s1,DIRSEP); if (p1 != NULL) { *p1 = '\0'; p1 = strrchrs(s2,DIRSEP); if (p1 == NULL) p1 = s2; *p1 = '\0'; CreatePath(s1,s2,YES); } /* Create the directory. */ if (IsAdir == YES) { #ifdef unix if ((From != NULL) && (*From != '\0') && (stat(From,&statbuf) == 0)) { mkdir(To,statbuf.st_mode & 0777); } else { mkdir(To,0755); } #else if ((strlen(To) > 2) || (To[1] != ':')) mkdir(To); #endif } } /* Show the BadPage, with macro MESSAGE. */ void ShowBadPage(char *Message) { FILE *Fin; char Line[BUFSIZ]; char s1[BUFSIZ]; char *p1; if (*BadUrl != '\0') { fprintf(stdout,"Location: %s\n\n",BadUrl); return; } if (Debug == 0) fprintf(stdout,"Content-type: text/html\n\n"); Fin = fopen(BadPage,"r"); if (Fin == NULL) { fprintf(stdout,"\n\n",Message); if (*BadPage != '\0') { fprintf(stdout,"Error: could not open the BadPage: %s

\n",BadPage); fprintf(stdout,"The original error message was:
\n"); } fprintf(stdout,"%s\n",Message); fprintf(stdout,"\n\n",Message); exit(0); } while (fgets(Line,BUFSIZ,Fin) != NULL) { p1 = Line; while (*p1 != '\0') { if (strnicmp(p1,"",15) == 0) { *p1 = '\0'; sprintf(s1,"%s%s%s",Line,Message,p1 + 16); strcpy(Line,s1); } p1++; } fprintf(stdout,"%s",Line); } exit(0); } /* Write a line to the logging file. */ void WriteLogLine(char *Line) { FILE *Fout; char s1[BUFSIZ]; time_t Now; if (*LogFile == '\0') return; Fout = fopen(LogFile,"a"); if (Fout == NULL) { sprintf(s1,"I could not open the logfile: %s",LogFile); ShowBadPage(s1); } Now = time(NULL); strcpy(s1,ctime(&Now)); s1[24] = '\0'; fprintf(Fout,"%s %s\n",s1,Line); fclose(Fout); } /* Show the OkPage, with statistics about the file. */ void ShowOkPage(void) { FILE *Fin; char Line[BUFSIZ]; char s1[BUFSIZ]; char *p1; if (*OkUrl != '\0') { fprintf(stdout,"Location: %s\n\n",OkUrl); return; } Fin = fopen(OkPage,"r"); if (Fin == NULL) { sprintf(s1,"I could not open the OkPage: %s",OkPage); ShowBadPage(s1); } if (Debug == 0) fprintf(stdout,"Content-type: text/html\n\n"); while (fgets(Line,BUFSIZ,Fin) != NULL) { p1 = Line; while (*p1 != '\0') { if (strnicmp(p1,"",18) == 0) { *p1 = '\0'; sprintf(s1,"%s%lu%s",Line,FileCount,p1 + 18); strcpy(Line,s1); } if (strnicmp(p1,"",18) == 0) { *p1 = '\0'; sprintf(s1,"%s%lu%s",Line,ByteCount,p1 + 18); strcpy(Line,s1); } if (strnicmp(p1,"",21) == 0) { *p1 = '\0'; sprintf(s1,"%s%s%s",Line,LastFileName,p1 + 21); strcpy(Line,s1); } p1++; } fprintf(stdout,"%s",Line); } exit(0); } /* Load the proper segment from the configuration file. */ void LoadConfig(char *ProgramPath, char *ConfigID) { FILE *Fin; char Path[BUFSIZ]; char Line[BUFSIZ]; char Name[BUFSIZ]; char Value[BUFSIZ]; int Accept; int NewDebug; char *p1; char *p2; strcpy(Path,ProgramPath); p1 = strrchrs(Path,"./\\"); if (p1 != NULL) { strcpy(p1,".cfg"); } else { strcat(Path,".cfg"); } Fin = fopen(Path,"rt"); if (Fin == NULL) { p1 = getenv("PATH"); while ((p1 != NULL) && (*p1 != '\0')) { p2 = Value; while ((*p1 != '\0') && (*p1 != ';')) *p2++ = *p1++; *p2 = '\0'; if (*p1 == ';') p1++; sprintf(Name,"%s%cupload.cfg",Value,*DIRSEP); Fin = fopen(Name,"rt"); if (Fin != NULL) break; } } if (Fin == NULL) ShowBadPage("I could not open the configuration file."); if (Debug > 0) fprintf(stdout,"

\n"); Accept = NO; NewDebug = Debug; while (fgets(Line,BUFSIZ,Fin) != NULL) { *Name = *Value = '\0'; if (sscanf(Line,"%[^ \t=]%*[ \t=]%[^\n\r]",Name,Value) != 2) { sscanf(Line,"%*[ \t]%[^ \t=]%*[ \t=]%[^\n\r]",Name,Value); } if (stricmp(Name,"Config") == 0) { if (Accept == YES) { if (Debug > 0) fprintf(stdout,"\n
\n

\n"); if ((Debug == 0) && (NewDebug > 0)) { fprintf(stdout,"Content-type: text/html\n\n"); fprintf(stdout,"\n\n"); fprintf(stdout,"\n"); fprintf(stdout,"\n\n"); fprintf(stdout,"%s\n",COPYRIGHT); } Debug = NewDebug; return; } if ((ConfigID == NULL) || (*ConfigID == '\0')) { Accept = YES; } else { if (stricmp(ConfigID,Value) == 0) Accept = YES; } if (Debug > 0) { if (Accept == YES) { fprintf(stdout,"

Loading configuration

\"%s\"\n",Value); fprintf(stdout,"\n"); } } continue; } if (Accept != NO) { if (Debug > 0) { fprintf(stdout,"\n",Name,Value); } if (stricmp(Name,"Debug") == 0) NewDebug = atoi(Value); if (stricmp(Name,"Root") == 0) { Url2Dir(Root,Value); p1 = strchr(Root,'\0'); if (p1 != Root) p1--; if ((p1 != Root) && (strchr(DIRSEP,*p1) == NULL)) { p1++; *p1++ = *DIRSEP; *p1 = '\0'; } } if (stricmp(Name,"FileMask") == 0) strcpy(FileMask,Value); if (stricmp(Name,"LogFile") == 0) Url2Dir(LogFile,Value); if (stricmp(Name,"OkPage") == 0) Url2Dir(OkPage,Value); if (stricmp(Name,"OkUrl") == 0) strcpy(OkUrl,Value); if (stricmp(Name,"BadPage") == 0) Url2Dir(BadPage,Value); if (stricmp(Name,"BadUrl") == 0) strcpy(BadUrl,Value); if (stricmp(Name,"OverWrite") == 0) { if (stricmp(Value,"no") == 0) OverWrite = NO; if (stricmp(Value,"yes") == 0) OverWrite = YES; if (stricmp(Value,"must") == 0) OverWrite = MUST; } if (stricmp(Name,"IgnoreSubdirs") == 0) { if (stricmp(Value,"no") == 0) IgnoreSubdirs = NO; if (stricmp(Value,"yes") == 0) IgnoreSubdirs = YES; } } } if (Debug > 0) { if (Accept == YES) { fprintf(stdout,"
%s%s
\n\n

\n"); } else { fprintf(stdout, "\nConfiguration \"%s\" not found, using defaults instead.

\n", ConfigID); } } if ((Debug == 0) && (NewDebug > 0)) { fprintf(stdout,"Content-type: text/html\n\n"); fprintf(stdout,"\n\n"); fprintf(stdout,"\n"); fprintf(stdout,"\n\n"); fprintf(stdout,"%s\n",COPYRIGHT); } Debug = NewDebug; } /* Skip a line in the input stream. */ void SkipLine(char **Input, /* Pointer into the incoming stream. */ long *InputLength) { /* Bytes left in the incoming stream. */ while ((**Input != '\0') && (**Input != '\r') && (**Input != '\n')) { *Input = *Input + 1; *InputLength = *InputLength - 1; } if (**Input == '\r') { *Input = *Input + 1; *InputLength = *InputLength - 1; } if (**Input == '\n') { *Input = *Input + 1; *InputLength = *InputLength - 1; } } /* Accept a single segment from the incoming mime stream. Each field in the form will generate a mime segment. Return a pointer to the beginning of the Boundary, or NULL if the stream is exhausted. */ void AcceptSegment(char **Input, /* Pointer into the incoming stream. */ long *InputLength, /* Bytes left in the incoming stream. */ char *Boundary, /* Character string that delimits segments. */ char *ProgramPath) { char FieldName[BUFSIZ]; /* Name of the variable from the form. */ char FileName[BUFSIZ]; /* The filename, as selected by the user. */ char *ContentStart; /* Pointer to the file content. */ char *ContentEnd; char ContentAsString[BUFSIZ]; long ContentLength; /* Bytecount of the content. */ char Key1[BUFSIZ]; char Key2[BUFSIZ]; char Path[BUFSIZ]; FILE *Fout; long Result; char s1[BUFSIZ]; char *p1; int i; /* The input stream should begin with a Boundary line. Error-exit if not found. */ if (strncmp(*Input,Boundary,strlen(Boundary)) != 0) { sprintf(s1,"Missing boundary in input."); WriteLogLine(s1); ShowBadPage(s1); } /* Skip the Boundary line. */ *Input = *Input + strlen(Boundary); *InputLength = *InputLength - strlen(Boundary); SkipLine(Input,InputLength); /* Return NULL if the stream is exhausted (no more segments). */ if ((**Input == '\0') || (strncmp(*Input,"--",2) == 0)) { *InputLength = 0; return; } /* The first line of a segment must be a "Content-Disposition" line. It contains the fieldname, and optionally the original filename. Error-exit if the line is not recognised. */ if (sscanf(*Input,"%[^:]: %[^;]; name=\"%[^\"]\"; filename=\"%[^\"]\"", Key1,Key2,FieldName,FileName) != 4) { *FileName = '\0'; if (sscanf(*Input,"%[^:]: %[^;]; name=\"%[^\"]\"",Key1,Key2, FieldName) != 3) { *FieldName = '\0'; if (sscanf(*Input,"%[^:]: %[^;]; filename=\"%[^\"]\"",Key1,Key2, FileName) != 3) { sscanf(*Input,"%[^\r\n]",Key1); sprintf(s1,"Disposition line not recognised: %s",Key1); WriteLogLine(s1); ShowBadPage(s1); } } } if (stricmp(Key1,"content-disposition") != 0) { sprintf(s1,"\"Content-Disposition\" expected, but I got \"%s\" instead.", Key1); WriteLogLine(s1); ShowBadPage(s1); } if (stricmp(Key2,"form-data") != 0) { sprintf(s1,"\"form-data\" expected, but I got \"%s\" instead.",Key2); WriteLogLine(s1); ShowBadPage(s1); } /* Skip the Disposition line and one or more mime lines, until an empty line is found. */ SkipLine(Input,InputLength); while ((**Input != '\r') && (**Input != '\n')) SkipLine(Input,InputLength); SkipLine(Input,InputLength); /* The following data in the stream is binary. The Boundary string is the end of the data. There may be a CRLF just before the Boundary, which must be stripped. */ ContentStart = *Input; ContentLength = 0; while ((*InputLength > 0) && (memcmp(*Input,Boundary,strlen(Boundary)) != 0)) { *Input = *Input + 1; *InputLength = *InputLength - 1; ContentLength = ContentLength + 1; } ContentEnd = *Input - 1; if ((ContentLength > 0) && (*ContentEnd == '\n')) { ContentEnd--; ContentLength = ContentLength - 1; } if ((ContentLength > 0) && (*ContentEnd == '\r')) { ContentEnd--; ContentLength = ContentLength - 1; } i = BUFSIZ - 1; if (ContentLength < i) i = ContentLength; strncpy(ContentAsString,ContentStart,i); ContentAsString[i] = '\0'; if (ContentEnd) {}; /* Keep lint happy... */ /* Show debugging information. */ if (Debug > 0) { fprintf(stdout,"\n"); fprintf(stdout," "); if (*FieldName != '\0') fprintf(stdout,"%s",FieldName); fprintf(stdout,"\n"); fprintf(stdout," "); if (*FileName != '\0') { fprintf(stdout,"%s",FileName); } else { fprintf(stdout,"%s",ContentAsString); } fprintf(stdout,"\n"); fprintf(stdout," %ld\n",ContentLength); fprintf(stdout," \n"); } /* If this field is the "Config" field, then load the configuration and leave. */ if ((stricmp(FieldName,"Config") == 0) && (*FileName == '\0') && (*ContentStart != '\0')) { if (Debug > 0) fprintf(stdout,""); LoadConfig(ProgramPath,ContentAsString); if (Debug > 0) fprintf(stdout,"\n"); return; } /* If this field is the "FileName" field, then store it and leave. */ if ((stricmp(FieldName,"FileName") == 0) && (*FileName == '\0') && (*ContentStart != '\0')) { strcpy(UpFileName,ContentAsString); if (Debug > 0) { fprintf(stdout,"New filename stored.\n"); } return; } /* If this field is the "OkPage" field, then store it and leave. */ if ((stricmp(FieldName,"OkPage") == 0) && (*FileName == '\0') && (*ContentStart != '\0')) { Url2Dir(OkPage,ContentAsString); if (Debug > 0) { fprintf(stdout,"New OkPage stored.\n"); } return; } /* If this field is the "OkUrl" field, then store it and leave. */ if ((stricmp(FieldName,"OkUrl") == 0) && (*FileName == '\0') && (*ContentStart != '\0')) { strcpy(OkUrl,ContentAsString); if (Debug > 0) { fprintf(stdout,"New OkUrl stored.\n"); } return; } /* If this field is the "BadPage" field, then store it and leave. */ if ((stricmp(FieldName,"BadPage") == 0) && (*FileName == '\0') && (*ContentStart != '\0')) { Url2Dir(BadPage,ContentAsString); if (Debug > 0) { fprintf(stdout,"New BadPage stored.\n"); } return; } /* If this field is the "BadUrl" field, then store it and leave. */ if ((stricmp(FieldName,"BadUrl") == 0) && (*FileName == '\0') && (*ContentStart != '\0')) { strcpy(BadUrl,ContentAsString); if (Debug > 0) { fprintf(stdout,"New BadUrl stored.\n"); } return; } /* Do nothing if this is not a file, but some other kind of field. */ if ((FileName == NULL) || (*FileName == '\0')) { if (Debug > 0) { fprintf(stdout,"FieldName not recognised.\n"); } return; } /* Determine the filename to store the file. If the UpFileName field was defined then use it, otherwise use the name of the incoming file. The ROOT is always prepended. */ if (*UpFileName == '\0') strcpy(UpFileName,FileName); if (IgnoreSubdirs == YES) { p1 = strrchrs(UpFileName,DIRSEP); if (p1 != NULL) { p1++; strcpy(UpFileName,p1); } } sprintf(Path,"%s%s",Root,UpFileName); /* Test if the filename matches the mask. */ if (MatchMask(Path,FileMask) == NO) { sprintf(s1, "The file is rejected because it does not match the mask.
Filename: %s
Mask: %s", Path,FileMask); WriteLogLine(s1); ShowBadPage(s1); } /* Test if the file already exists. */ if (OverWrite != YES) { Fout = fopen(Path,"r"); if ((OverWrite == NO) && (Fout != NULL)) { fclose(Fout); sprintf(s1, "The file could not be uploaded because it already exists.
Filename: %s", Path); WriteLogLine(s1); ShowBadPage(s1); } if ((OverWrite == MUST) && (Fout == NULL)) { sprintf(s1, "The file could not be uploaded because it does not exist already.
Filename: %s", Path); WriteLogLine(s1); ShowBadPage(s1); } if (Fout != NULL) fclose(Fout); } /* If needed then create directories for the file. */ CreatePath(Path,NULL,NO); /* Open the file for writing. */ #ifndef unix Fout = fopen(Path,"w"); #else Fout = fopen(Path,"wb"); #endif if (Fout == NULL) { sprintf(s1, "The file could not be uploaded because write permission is denied.
Filename: %s", Path); WriteLogLine(s1); ShowBadPage(s1); } #ifndef unix setmode(fileno(Fout),O_BINARY); #endif /* Write the file to disk. */ Result = fwrite(ContentStart,1,ContentLength,Fout); fclose(Fout); /* If the wrong number of bytes were written to disk, then show an error message. */ if (Result != ContentLength) { sprintf(s1, "The wrong number of bytes were written.
Written: %ld
Bytes in input: %ld", Result,ContentLength); WriteLogLine(s1); ShowBadPage(s1); } /* Show debugging information. */ if (Debug > 0) { fprintf(stdout,"\n"); fprintf(stdout," File written: %s\n",Path); fprintf(stdout," \n"); } FileCount = FileCount + 1; ByteCount = ByteCount + ContentLength; strcpy(LastFileName,UpFileName); sprintf(s1,"File uploaded succesfully: %s (%lu bytes)", UpFileName,ContentLength); WriteLogLine(s1); /* Clear the filename. */ *UpFileName = '\0'; return; } int main(int argc, char *argv[], char *environment[]) { char *Method; /* Pointer to REQUEST_METHOD environment variable. */ char *ContentLength; /* Pointer to CONTENT_LENGTH environment variable. */ char *ContentType; /* Pointer to CONTENT_TYPE environment variable. */ long InCount; /* The supposed number of incoming bytes. */ long RealCount; /* Actual number of incoming bytes. */ char *Content; /* Copy in memory of the Content. */ char *Here; /* Position into the Content. */ char Boundary[BUFSIZ]; /* The boundary string between segments. */ char Char; long MoreCount; char *p1; char s1[BUFSIZ]; if (argc > 1) { fprintf(stdout,"Error: %s is a cgi program, and should not be ",argv[0]); fprintf(stdout,"started from the command line.\n"); exit(1); } *Root = '\0'; /* Setup defaults. */ strcpy(FileMask,"*"); IgnoreSubdirs = YES; OverWrite = YES; *LogFile = '\0'; *OkPage = '\0'; *OkUrl = '\0'; *BadPage = '\0'; *BadUrl = '\0'; Debug = 0; *UpFileName = '\0'; FileCount = 0; ByteCount = 0; *LastFileName = '\0'; if (environment) {}; /* Keep lint() happy. */ if (Debug > 0) { fprintf(stdout,"Content-type: text/html\n\n"); fprintf(stdout,"\n\n"); fprintf(stdout,"\n"); fprintf(stdout,"\n\n"); fprintf(stdout,"%s\n",COPYRIGHT); } LoadConfig(argv[0],""); /* Load default configuration. */ /* Test if the program was started by a METHOD=POST form. */ Method = getenv("REQUEST_METHOD"); if ((Method == NULL) || (*Method == '\0') || (stricmp(Method,"post") != 0)) { ShowBadPage("Sorry, this program only supports METHOD=POST."); } if (Debug > 0) fprintf(stdout,"

Loading input

\n",Method); if (Debug > 0) fprintf(stdout,"Method = %s
\n",Method); /* Test if the program was started with ENCTYPE="multipart/form-data". */ ContentType = getenv("CONTENT_TYPE"); if ((ContentType == NULL) || (strnicmp(ContentType,"multipart/form-data; boundary=",30) != 0)) { ShowBadPage("Sorry, this program only supports ENCTYPE=\"multipart/form-data\"."); } if (Debug > 0) fprintf(stdout,"Enctype = %s
\n",ContentType); /* Determine the Boundary, the string that separates the segments in the stream. The boundary is available from the CONTENT_TYPE environment variable. */ Here = strchr(ContentType,'=') + 1; sprintf(Boundary,"--%s",Here); if (Debug > 0) fprintf(stdout,"Boundary = %s
\n",Boundary); /* Get the total number of bytes in the input stream from the CONTENT_LENGTH environment variable. */ ContentLength = getenv("CONTENT_LENGTH"); if (ContentLength == NULL) { WriteLogLine("Error: no CONTENT_LENGTH found."); ShowBadPage("Error: no CONTENT_LENGTH found."); } InCount = atol(ContentLength); if (InCount == 0) { WriteLogLine("Error: CONTENT_LENGTH is zero."); ShowBadPage("Error: CONTENT_LENGTH is zero."); } if (Debug > 0) fprintf(stdout,"Content_Length = %d
\n",InCount); /* Allocate sufficient memory for the incoming data. */ Content = (char *)malloc(InCount + 1); if (Content == NULL) { WriteLogLine("Error: malloc() returned NULL."); ShowBadPage("Error: malloc() returned NULL."); } /* Load the data from standard input into memory. */ #ifndef unix setmode(fileno(stdin),O_BINARY); /* Make sure the input is binary... */ #endif p1 = Content; RealCount = 0; /* For some reason fread() of Borland C 4.52 barfs if the bytecount is bigger than 2.5Mb, so I have to do it like this. */ while (fread(p1++,1,1,stdin) == 1) { RealCount++; if (RealCount >= InCount) break; } *p1 = '\0'; /* Ignore any extra caracters. We have to read them, or the server will give an error message. */ if (RealCount < InCount) { MoreCount = InCount - RealCount; while ((MoreCount > 0) && (fread(&Char,1,1,stdin) == 1)) MoreCount--; } if (RealCount != InCount) { free(Content); sprintf(s1, "Error: The number of bytes received (%ld) is not what the CONTENT_LENGTH environment variable says it sould be (%ld).", RealCount + MoreCount, InCount); WriteLogLine(s1); ShowBadPage(s1); return(0); } if (Debug > 0) fprintf(stdout,"Input succesfully loaded into memory.
\n"); /* Handle all segments in the incoming data, that has been stored in memory. */ Here = Content; if (Debug > 0) { fprintf(stdout,"

\n

\n

Parsing input

\n"); fprintf(stdout,"\n"); fprintf(stdout,"\n"); fprintf(stdout," \n"); fprintf(stdout," \n"); fprintf(stdout," \n"); fprintf(stdout," \n"); } while (RealCount > 0) AcceptSegment(&Here,&RealCount,Boundary,argv[0]); if (Debug > 0) fprintf(stdout,"
FieldnameContentsSize
\n
\n"); /* Cleanup. */ free(Content); if (*LastFileName == '\0') ShowBadPage("You have not specified a file, so nothing was uploaded."); /* Display the OkPage. */ if (Debug > 0) { fprintf(stdout,"

Finished

\n"); } ShowOkPage(); return(0); } /* Ideeen: - Multiple filemasks. - Maximum directory size. - Maximum and Minimum file size. - Result-macros as parameters to OkUrl. */