Back to home page

MITgcm

 
 

    


File indexing completed on 2018-03-02 18:44:46 UTC

view on githubraw file Latest commit e768bd12 on 2008-02-26 17:05:00 UTC
ec6cf3b09d Ed H*0001 /* (C) Copyright 1993,1994 by Carnegie Mellon University
                0002  * All Rights Reserved.
                0003  *
                0004  * Permission to use, copy, modify, distribute, and sell this software
                0005  * and its documentation for any purpose is hereby granted without
                0006  * fee, provided that the above copyright notice appear in all copies
                0007  * and that both that copyright notice and this permission notice
                0008  * appear in supporting documentation, and that the name of Carnegie
                0009  * Mellon University not be used in advertising or publicity
                0010  * pertaining to distribution of the software without specific,
                0011  * written prior permission.  Carnegie Mellon University makes no
                0012  * representations about the suitability of this software for any
                0013  * purpose.  It is provided "as is" without express or implied
                0014  * warranty.
                0015  *
                0016  * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
                0017  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
                0018  * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
                0019  * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                0020  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
                0021  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
                0022  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                0023  * SOFTWARE.
                0024  */
                0025 #include <stdio.h>
e768bd1221 Jean*0026 #include <stdlib.h>
ec6cf3b09d Ed H*0027 #include <string.h>
                0028 
                0029 extern char *magic_look(FILE *infile);
                0030 extern char *os_genid(void);
                0031 extern FILE *os_createnewfile(char *fname);
                0032 extern char *md5digest(FILE *infile, long int *len);
e768bd1221 Jean*0033 extern void os_perror(char *str);
                0034 extern int to64(FILE *infile, FILE *outfile, long int limit);
ec6cf3b09d Ed H*0035 
                0036 #define NUMREFERENCES 4
e768bd1221 Jean*0037 int attachment;
ec6cf3b09d Ed H*0038 
                0039 /*
                0040  * Encode a file into one or more MIME messages, each
                0041  * no larger than 'maxsize'.  A 'maxsize' of zero means no size limit.
                0042  * If 'applefile' is non-null, it is the first part of a multipart/appledouble
                0043  * pair.
                0044  */
                0045 int encode(FILE *infile, FILE *applefile, char *fname, FILE *descfile, char *subject, char *headers, long int maxsize, char *typeoverride, char *outfname)
                0046 {
                0047     char *type;
                0048     FILE *outfile;
                0049     char *cleanfname, *p;
e768bd1221 Jean*0050     char *digest, *appledigest = NULL;
ec6cf3b09d Ed H*0051     long filesize, l, written;
                0052     int thispart, numparts = 1;
                0053     int wrotefiletype = 0;
                0054     char *multipartid, *msgid, *referenceid[NUMREFERENCES];
                0055     char buf[1024];
                0056     int i;
                0057 
                0058     /* Clean up fname for printing */
                0059     cleanfname = fname;
                0060 #ifdef __riscos
                0061     /* This filename-cleaning knowledge will probably
                0062      * be moved to the os layer in a future version.
                0063      */
e768bd1221 Jean*0064     if ((p = strrchr(cleanfname, '.'))) cleanfname = p+1;
ec6cf3b09d Ed H*0065 #else
e768bd1221 Jean*0066     if ((p = strrchr(cleanfname, '/'))) cleanfname = p+1;
                0067     if ((p = strrchr(cleanfname, '\\'))) cleanfname = p+1;
ec6cf3b09d Ed H*0068 #endif
e768bd1221 Jean*0069     if ((p = strrchr(cleanfname, ':'))) cleanfname = p+1;
ec6cf3b09d Ed H*0070 
                0071     /* Find file type */
                0072     if (typeoverride) {
                0073     type = typeoverride;
                0074     }
                0075     else {
                0076     type = magic_look(infile);
                0077     }
                0078 
                0079     /* Compute MD5 digests */
                0080     digest = md5digest(infile, &filesize);
                0081     if (applefile) {
                0082     appledigest = md5digest(applefile, &l);
                0083     filesize += l;
                0084     }
                0085 
                0086     /* See if we have to do multipart */
                0087     if (maxsize) {
                0088     filesize = (filesize / 54) * 73; /* Allow for base64 expansion */
                0089 
                0090     /* Add in size of desc file */
                0091     if (descfile) {
                0092         free(md5digest(descfile, &l));  /* XXX */
                0093         filesize += l;
                0094     }
                0095 
                0096     numparts = (filesize-1000)/maxsize + 1;
                0097     if (numparts < 1) numparts = 1;
                0098     }
                0099 
                0100     multipartid = os_genid();
                0101     for (i=0; i<NUMREFERENCES; i++) {
                0102     referenceid[i] = 0;
                0103     }
                0104 
                0105     for (thispart=1; thispart <= numparts; thispart++) {
                0106     written = 0;
                0107 
                0108     /* Open output file */
                0109     if (numparts == 1) {
                0110         outfile = os_createnewfile(outfname);
                0111     }
                0112     else {
                0113 #ifdef __riscos
                0114         /* Arrgh, riscos uses '.' as directory separator */
                0115         sprintf(buf, "%s/%02d", outfname, thispart);
                0116 #else
                0117         sprintf(buf, "%s.%02d", outfname, thispart);
                0118 #endif
                0119         outfile = os_createnewfile(buf);
                0120     }
                0121     if (!outfile) {
                0122         os_perror(buf);
                0123             return 1;
                0124         }
                0125     
                0126     msgid = os_genid();
                0127     fprintf(outfile, "Message-ID: <%s>\n", msgid);
                0128     fprintf(outfile, "Mime-Version: 1.0\n");
                0129     if (headers) fputs(headers, outfile);
                0130     if (numparts > 1) {
                0131         fprintf(outfile, "Subject: %s (%02d/%02d)\n", subject,
                0132             thispart, numparts);
                0133         if (thispart == 1) {
                0134         referenceid[0] = msgid;
                0135         }
                0136         else {
                0137         /* Put out References: header pointing to previous parts */
                0138         fprintf(outfile, "References: <%s>\n", referenceid[0]);
                0139         for (i=1; i<NUMREFERENCES; i++) {
                0140             if (referenceid[i]) fprintf(outfile, "\t <%s>\n",
                0141                         referenceid[i]);
                0142         }
                0143         for (i=2; i<NUMREFERENCES; i++) {
                0144             referenceid[i-1] = referenceid[i];
                0145         }
                0146         referenceid[NUMREFERENCES-1] = msgid;
                0147         }
                0148         fprintf(outfile,
                0149             "Content-Type: message/partial; number=%d; total=%d;\n",
                0150             thispart, numparts);
                0151         fprintf(outfile, "\t id=\"%s\"\n", multipartid);
                0152         fprintf(outfile, "\n");
                0153     }
                0154 
                0155     if (thispart == 1) {
                0156         if (numparts > 1) {
                0157         fprintf(outfile, "Message-ID: <%s>\n", multipartid);
                0158         fprintf(outfile, "MIME-Version: 1.0\n");
                0159         }
                0160         fprintf(outfile, "Subject: %s\n", subject);
                0161         fprintf(outfile,
                0162             "Content-Type: multipart/mixed; boundary=\"-\"\n");
                0163         fprintf(outfile,
                0164 "\nThis is a MIME encoded message.  Decode it with \"munpack\"\n");
                0165         fprintf(outfile,
                0166 "or any other MIME reading software.  Mpack/munpack is available\n");
                0167         fprintf(outfile,
                0168 "via anonymous FTP in ftp.andrew.cmu.edu:pub/mpack/\n");
                0169         written = 300;
                0170 
                0171         /* Spit out description section */
                0172         if (descfile) {
                0173         fprintf(outfile, "---\n\n");
                0174         while (fgets(buf, sizeof(buf), descfile)) {
                0175             /* Strip multiple leading dashes as they may become MIME
                0176              * boundaries
                0177              */
                0178             p = buf;
                0179             if (*p == '-') {
                0180             while (p[1] == '-') p++;
                0181             }
                0182 
                0183             fputs(p, outfile);
                0184             written += strlen(p);
                0185         }
                0186         fprintf(outfile, "\n");
                0187         }
                0188     
                0189         fprintf(outfile, "---\n");
                0190 
                0191         if (applefile) {
                0192         fprintf(outfile,
                0193     "Content-Type: multipart/appledouble; boundary=\"=\"; name=\"%s\"\n",
                0194             cleanfname);
                0195         fprintf(outfile,
e768bd1221 Jean*0196             "Content-Disposition: %s; filename=\"%s\"\n",
                0197                 attachment ? "attachment" : "inline", cleanfname);
ec6cf3b09d Ed H*0198         fprintf(outfile, "\n\n--=\n");
                0199         fprintf(outfile, "Content-Type: application/applefile\n");
                0200         fprintf(outfile, "Content-Transfer-Encoding: base64\n");
                0201         fprintf(outfile, "Content-MD5: %s\n\n", appledigest);
                0202         free(appledigest);
                0203         written += 100;
                0204         }
                0205 
                0206     }
                0207 
                0208     if (applefile && !feof(applefile)) {
                0209         if (written == maxsize) written--; /* avoid a nasty fencepost error */
                0210         written += to64(applefile, outfile,
                0211                 (thispart == numparts) ? 0 : (maxsize-written));
                0212 
                0213         if (!feof(applefile)) {
                0214         fclose(outfile);
                0215         continue;
                0216         }
                0217 
                0218         fprintf(outfile, "\n--=\n");
                0219     }
                0220 
                0221 
                0222     if (!wrotefiletype++) {
                0223         fprintf(outfile, "Content-Type: %s; name=\"%s\"\n", type,
                0224             cleanfname);
                0225         fprintf(outfile, "Content-Transfer-Encoding: base64\n");
e768bd1221 Jean*0226         fprintf(outfile, "Content-Disposition: %s; filename=\"%s\"\n",
                0227             attachment ? "attachment" : "inline", cleanfname);
ec6cf3b09d Ed H*0228         fprintf(outfile, "Content-MD5: %s\n\n", digest);
                0229         free(digest);
                0230         written += 80;
                0231     }
                0232 
                0233     if (written == maxsize) written--; /* avoid a nasty fencepost error */
                0234 
                0235     written += to64(infile, outfile,
                0236             (thispart == numparts) ? 0 : (maxsize-written));
                0237 
                0238     if (thispart == numparts) {
                0239         if (applefile) fprintf(outfile, "\n--=--\n");
                0240         fprintf(outfile, "\n-----\n");
                0241     }
                0242     
                0243     fclose(outfile);    
                0244     }
                0245 
                0246     return 0;
                0247 }