[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: SMTP slow???



At 06:17 AM 5/29/96 -0700, Dave Darnell wrote:
>  
>Sounds interesting.  I, for one, would be interested in seeing your work.

Some fast cutting and pasting, hope you all can read this:


Attached are 5 files:

1. EDI.html (HTML)		This is the web frontend for everything 

2. upload.cgi (shell/CGI script) This is the CGI which is called from EDI.html.
				 It a) sucks in the raw (MIME) file uploads,
				 b) creates the directory for all of the 
				 file body parts to go into, c) calls 
				 "splitparts" to do the actual splitting, and 
				 d) provides the appropriate HTML feedback to
				 the user.
				 
3. splitparts.c (C program)	This is a program I whipped up to split the MIME
				data stream into separate file body parts. I
				could not use the standard UNIX command-line
				tools here (sed, awk, etc.) because most of 
				those tools choke on lines > 1024 chars, and
				it is commonplace for the "lines" of a binary
				datastream to exceed that limit

4. form (regcmp(1) input file)	This is a file that the regcmp(1) command on
				UNIX can use to precompile a regular expression
				for use by the regex(3) library call. It is used
				to create the "form.i" file which is needed to
				build the "splitparts" program
				
5. Makefile (make(1) input file)	This is the Makefile which can be used
					to build the "splitparts" executable
				
NOTE: I HAVE NOT INCLUDED THE SOURCE FOR THE "cgiparse" PROGRAM. I CONSIDER THIS
      A STANDARD PART OF THE WWW TOOLKIT, JUST AS "awk", "sed" ETC. ARE STANDARD
      PARTS OF THE UNIX TOOLKIT. BUT I CAN PROVIDE THE SOURCE IF NEED BE.
      ALTERNATIVELY, "cgiparse" IS PART OF THE CERN HTTPD SOURCE DISTRIBUTION...
      Content-Type: text/html
Content-Transfer-Encoding: 7bit
Content-MD5: IYut0Dfwf0NwQ1nYt22S1g==
Content-Description: EDI.html

<TITLE>EDI Upload Proof of Concept</TITLE>
<H1>EDI Upload Proof of Concept</H1>
<PRE>
<FORM ENCTYPE="multipart/form-data" ACTION=/cgi-bin/upload.cgi METHOD=POST>
Originator:                          <INPUT TYPE="text" NAME="originator"
MAXLENGTH="80"> <P>
Recipients:                          <INPUT TYPE="text" NAME="recipients"
MAXLENGTH="80"> <P>
EDI-bodypart-type:                   <INPUT TYPE="text" NAME="bodypart-type"
MAXLENGTH="80"> <P>
Cross-referencing-information:       <INPUT TYPE="text" NAME="xref-info"
MAXLENGTH="80"> <P>
Application-Reference:               <INPUT TYPE="text" NAME="appl"
MAXLENGTH="80"> <P>
File 1:       <INPUT TYPE=FILE NAME="foo" MAXLENGTH="80"> <P>
File 2:       <INPUT TYPE=FILE NAME="bar" MAXLENGTH="80"> <P>
<INPUT TYPE="submit" VALUE="Submit">
</FORM>
</PRE>Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-MD5: G0Qkydof4SDEC7w8LHU4Dw==
Content-Description: upload.cgi
X-Sun-Data-Type: shell-script

#!/bin/sh

CGI=/global/site/pd/lbin/cgiparse

${CGI} -read > /tmp/blah.$$

echo Content-type: text/html
echo

echo "<html>"
cd /clocal/tech/user/ftp/pub
DIR=${REMOTE_ADDR}/`date '+%m-%d-%y-%T'`
mkdir -p ${DIR}
echo "<p>Created directory ${DIR}</p>"
cd ${DIR}
echo "<ul>"
/global/tech/lbin/splitparts /tmp/blah.$$ |
while read i
do
	echo "<li>${i}"
done
echo "</ul></html>"
#rm /tmp/blah.$$Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-MD5: JxOxjQ7dR7M/Ney+Wazzrw==
Content-Description: splitparts.c
X-Sun-Data-Type: c-file

#include <stdio.h>
#include <libgen.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

#include "form.i"

extern char *sys_errlist[];

main(argc, argv)
int argc;
char *argv[];
{
	struct stat statbuf;
	int fd;
	long offset, size;
	char *mmap_buf, *ptr, *marker, *end;

	if (argc < 2) {
		fprintf(stderr, "Usage: %s <form-data>\n", basename(argv[0]));
		exit(1);
	}
	fd = open(argv[1], O_RDONLY);
	if (fd < 0) {
		fprintf(stderr, "Could not open %s: %s\n", 
			argv[1], sys_errlist[errno]);
		exit(errno);
	}
	if (fstat(fd, &statbuf) < 0) {
		fprintf(stderr, "stat() for %s failed: %s", 
			argv[1], sys_errlist[errno]);
		exit(errno);
	}

	mmap_buf = mmap(0L, statbuf.st_size, 
			PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0L);
	offset = 0L;
	size = statbuf.st_size;
	end = mmap_buf + size;
	ptr = strchr(mmap_buf, '\r');
	if (!ptr) {
		fputs("Corrupted file (missing <CR>)! Exiting...", stderr);
		exit(1);
	}
	ptr[0] = '\0';
	marker = regcmp("\r\n", mmap_buf, "(--){0,1}\r\n", (char *)0);
	ptr += 2;
	while (ptr != end) {
		char *partname;
		int fileflag;

		extract_partname(&partname, &fileflag, &ptr, end);
		do_body_part(partname, fileflag, marker, &ptr, end);
	}
	if (!mmap_buf) {
		fprintf(stderr, "Could not mmap() %s: %s\n", 
			argv[1], sys_errlist[errno]);
		exit(errno);
	} 
	munmap(mmap_buf, statbuf.st_size);
	close(fd);
	exit(0);
}

extract_partname(partname, fileflag, begin, end)
char **partname, **begin, *end;
int *fileflag;
{
	static char namebuf[BUFSIZ];
	char *ptr, *nextchar;

	ptr = *begin;
	nextchar = regex(tag, ptr, namebuf);
	if (strncmp(nextchar, "; filename=", 11) == 0)
		*fileflag = 1;
	else
		*fileflag = 0;
	while (strncmp(ptr, "\r\n\r\n", 4) != 0)
		ptr++;
	ptr += 4;
	*begin = ptr;
	*partname = namebuf;
}

do_body_part(partname, fileflag, markstring, begin, end)
char *partname, *markstring, **begin, *end;
int fileflag;
{
	char *ptr, *nextchar;
	FILE *fp;

	ptr = *begin;
	while (ptr != end) {
		char *cr;

		cr = memchr(ptr, '\r', end - ptr);
		fflush(stdout);
		if (!cr)
			return(0);
		ptr = cr;
		nextchar = regex(markstring, ptr);
		if (nextchar != NULL)
			break;
		ptr++;
	}
	if (ptr == end)
		return(0);
	if (fileflag) {
		fp = fopen(partname, "w");
		if (!fp) {
			fprintf(stderr, "Could not create %s: %s\n", partname,
				sys_errlist[errno]);
			exit(errno);
		}
		fwrite(*begin, 1, __loc1 - *begin, fp);
		fclose(fp);
		printf("wrote file \"%s\", %ld bytes\n", 
	       	       partname, (long)(__loc1 - *begin));
	} else {
		printf("value of form variable \"%s\" passed as: ", partname);
		fwrite(*begin, 1, __loc1 - *begin, stdout);
		puts("");
	}
	*begin = nextchar;
}Content-Type: application/octet-stream
Content-Transfer-Encoding: 7bit
Content-MD5: eBxFJeN6fgbQvX7SnafwCw==
Content-Description: form

Attachment Converted: C:\data\EUDORA\FILES\EDI File Upload Source
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-MD5: IeA6njveV0yBoeHjlrNkLg==
Content-Description: Makefile
X-Sun-Data-Type: Makefile

splitparts: splitparts.o
	$(CC) splitparts.o -lgen -o splitparts

splitparts.o: splitparts.c form.i
	$(CC) $(CFLAGS) -c splitparts.c

form.i: form
	regcmp form

Robert Moskowitz
Chrysler Corporation
(810) 758-8212