home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 52
/
Amiga_Dream_52.iso
/
Amiga
/
Workbench
/
Archivers
/
mpackPPC.lha
/
mpackPPC
/
src
/
encode.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-04-08
|
7KB
|
246 lines
/* (C) Copyright 1993,1994 by Carnegie Mellon University
* 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 Carnegie
* Mellon University not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. Carnegie Mellon University makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY 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 into one or more MIME messages, each
* no larger than 'maxsize'. A 'maxsize' of zero means no size limit.
* If 'applefile' is non-null, it is the first part of a multipart/appledouble
* pair.
*/
int encode(infile, applefile, fname, descfile, subject, headers, maxsize, typeoverride, outfname)
FILE *infile, *applefile, *descfile;
char *fname, *subject, *headers;
long maxsize;
char *typeoverride, *outfname;
{
char *type;
FILE *outfile;
char *cleanfname, *p;
char *digest, *appledigest;
long filesize, l, written;
int thispart, numparts = 1;
int wrotefiletype = 0;
char *multipartid, *msgid, *referenceid[NUMREFERENCES];
char buf[1024];
int i;
/* Clean up fname for printing */
cleanfname = fname;
#ifdef __riscos
/* This filename-cleaning knowledge will probably
* be moved to the os layer in a future version.
*/
if (p = strrchr(cleanfname, '.')) cleanfname = p+1;
#else
if (p = strrchr(cleanfname, '/')) cleanfname = p+1;
if (p = strrchr(cleanfname, '\\')) cleanfname = p+1;
#endif
if (p = strrchr(cleanfname, ':')) cleanfname = p+1;
/* Find file type */
if (typeoverride) {
type = typeoverride;
}
else {
type = magic_look(infile);
}
/* Compute MD5 digests */
digest = md5digest(infile, &filesize);
if (applefile) {
appledigest = md5digest(applefile, &l);
filesize += l;
}
/* See if we have to do multipart */
if (maxsize) {
filesize = (filesize / 54) * 73; /* Allow for base64 expansion */
/* Add in size of desc file */
if (descfile) {
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 {
#ifdef __riscos
/* Arrgh, riscos uses '.' as directory separator */
sprintf(buf, "%s/%02d", outfname, thispart);
#else
sprintf(buf, "%s.%02d", outfname, thispart);
#endif
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,
"via anonymous FTP in ftp.andrew.cmu.edu:pub/mpack/\n");
written = 300;
/* Spit out description section */
if (descfile) {
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");
}
fprintf(outfile, "---\n");
if (applefile) {
fprintf(outfile,
"Content-Type: multipart/appledouble; boundary=\"=\"; name=\"%s\"\n",
cleanfname);
fprintf(outfile,
"Content-Disposition: inline; filename=\"%s\"\n",
cleanfname);
fprintf(outfile, "\n\n--=\n");
fprintf(outfile, "Content-Type: application/applefile\n");
fprintf(outfile, "Content-Transfer-Encoding: base64\n");
fprintf(outfile, "Content-MD5: %s\n\n", appledigest);
free(appledigest);
written += 100;
}
}
if (applefile && !feof(applefile)) {
if (written == maxsize) written--; /* avoid a nasty fencepost error */
written += to64(applefile, outfile,
(thispart == numparts) ? 0 : (maxsize-written));
if (!feof(applefile)) {
fclose(outfile);
continue;
}
fprintf(outfile, "\n--=\n");
}
if (!wrotefiletype++) {
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 */
written += to64(infile, outfile,
(thispart == numparts) ? 0 : (maxsize-written));
if (thispart == numparts) {
if (applefile) fprintf(outfile, "\n--=--\n");
fprintf(outfile, "\n-----\n");
}
fclose(outfile);
}
return 0;
}