home *** CD-ROM | disk | FTP | other *** search
- /* (C) Copyright 1993 by John G. Myers
- * All Rights Reserved.
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without
- * fee, provided that the above copyright notice appear in all copies
- * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the name of John G.
- * Myers not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. John G. Myers makes no representations about the
- * suitability of this software for any purpose. It is provided "as
- * is" without express or implied warranty.
- *
- * JOHN G. MYERS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL JOHN G. MYERS BE LIABLE FOR ANY SPECIAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
- #include <stdio.h>
- #include <string.h>
-
- extern char *magic_look();
- extern char *os_genid();
- extern char *md5digest();
-
- #define NUMREFERENCES 4
-
- /*
- * Encode a file named into one or more MIME messages, each
- * no larger than 'maxsize'. A 'maxsize' of zero means no size limit.
- */
- int encode(fname, descfname, subject, headers, maxsize, typeoverride, outfname)
- char *fname, *descfname, *subject, *headers;
- long maxsize;
- char *typeoverride, *outfname;
- {
- char *type;
- FILE *infile, *descfile, *outfile;
- char *cleanfname, *p;
- char *digest;
- long filesize, l, written;
- int thispart, numparts = 1;
- char *multipartid, *msgid, *referenceid[NUMREFERENCES];
- char buf[1024];
- int i;
-
- /* Open files */
- infile = fopen(fname, "rb");
- if (!infile) {
- os_perror(fname);
- return 1;
- }
- if (descfname) {
- descfile = fopen(descfname, "r");
- if (!descfile) {
- os_perror(descfname);
- return 1;
- }
- }
-
- /* Clean up fname for printing */
- cleanfname = fname;
- if (p = strrchr(cleanfname, '/')) cleanfname = p+1;
- if (p = strrchr(cleanfname, '\\')) cleanfname = p+1;
- if (p = strrchr(cleanfname, ':')) cleanfname = p+1;
-
- /* Find file type */
- if (typeoverride) {
- type = typeoverride;
- }
- else {
- type = magic_look(infile);
- }
-
- /* Compute MD5 digest */
- digest = md5digest(infile, &filesize);
-
- /* See if we have to do multipart */
- if (maxsize) {
- filesize = (filesize / 54) * 73; /* Allow for base64 expansion */
-
- /* Add in size of desc file */
- if (descfname) {
- free(md5digest(descfile, &l)); /* XXX */
- filesize += l;
- }
-
- numparts = (filesize-1000)/maxsize + 1;
- if (numparts < 1) numparts = 1;
- }
-
- multipartid = os_genid();
- for (i=0; i<NUMREFERENCES; i++) {
- referenceid[i] = 0;
- }
-
- for (thispart=1; thispart <= numparts; thispart++) {
- written = 0;
-
- /* Open output file */
- if (numparts == 1) {
- outfile = fopen(outfname, "w");
- if (!outfile) os_perror(outfname);
- }
- else {
- sprintf(buf, "%s.%02d", outfname, thispart);
- outfile = fopen(buf, "w");
- if (!outfile) os_perror(buf);
- }
- if (!outfile) return 1;
-
- msgid = os_genid();
- fprintf(outfile, "Message-ID: <%s>\n", msgid);
- fprintf(outfile, "Mime-Version: 1.0\n");
- if (headers) fputs(headers, outfile);
- if (numparts > 1) {
- fprintf(outfile, "Subject: %s (%02d/%02d)\n", subject,
- thispart, numparts);
- if (thispart == 1) {
- referenceid[0] = msgid;
- }
- else {
- /* Put out References: header pointing to previous parts */
- fprintf(outfile, "References: <%s>\n", referenceid[0]);
- for (i=1; i<NUMREFERENCES; i++) {
- if (referenceid[i]) fprintf(outfile, "\t <%s>\n",
- referenceid[i]);
- }
- for (i=2; i<NUMREFERENCES; i++) {
- referenceid[i-1] = referenceid[i];
- }
- referenceid[NUMREFERENCES-1] = msgid;
- }
- fprintf(outfile,
- "Content-Type: message/partial; number=%d; total=%d;\n",
- thispart, numparts);
- fprintf(outfile, "\t id=\"%s\"\n", multipartid);
- fprintf(outfile, "\n");
- }
-
- if (thispart == 1) {
- if (numparts > 1) {
- fprintf(outfile, "Message-ID: <%s>\n", multipartid);
- fprintf(outfile, "MIME-Version: 1.0\n");
- }
- fprintf(outfile, "Subject: %s\n", subject);
- fprintf(outfile,
- "Content-Type: multipart/mixed; boundary=\"-\"\n");
- fprintf(outfile,
- "\nThis is a MIME encoded message. Decode it with \"munpack\"\n");
- fprintf(outfile,
- "or any other MIME reading software. Mpack/munpack is available\n");
- fprintf(outfile,
- "in Volume 3 of comp.sources.reviewed or via anonymous FTP in\n");
- fprintf(outfile, "export.acs.cmu.edu:pub/mpack/\n");
- written = 300;
-
- /* Spit out description section */
- if (descfname) {
- fprintf(outfile, "---\n\n");
- while (fgets(buf, sizeof(buf), descfile)) {
- /* Strip multiple leading dashes as they may become MIME
- * boundaries
- */
- p = buf;
- if (*p == '-') {
- while (p[1] == '-') p++;
- }
-
- fputs(p, outfile);
- written += strlen(p);
- }
- fprintf(outfile, "\n");
- fclose(descfile);
- }
-
- fprintf(outfile, "---\n");
- fprintf(outfile, "Content-Type: %s; name=\"%s\"\n", type, cleanfname);
- fprintf(outfile, "Content-Transfer-Encoding: base64\n");
- fprintf(outfile, "Content-Disposition: inline; filename=\"%s\"\n",
- cleanfname);
- fprintf(outfile, "Content-MD5: %s\n\n", digest);
- free(digest);
- written += 80;
- }
-
- if (written == maxsize) written--; /* avoid a nasty fencepost error */
-
- to64(infile, outfile, (thispart == numparts) ? 0 : (maxsize-written));
-
- if (thispart == numparts) {
- fprintf(outfile, "\n-----\n");
- }
-
- fclose(outfile);
- }
-
- return 0;
- }
-