home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / uucp / MPack1_2_1.lha / MPack / src / encode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-05  |  5.8 KB  |  204 lines

  1. /* (C) Copyright 1993 by John G. Myers
  2.  * All Rights Reserved.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software
  5.  * and its documentation for any purpose is hereby granted without
  6.  * fee, provided that the above copyright notice appear in all copies
  7.  * and that both that copyright notice and this permission notice
  8.  * appear in supporting documentation, and that the name of John G.
  9.  * Myers not be used in advertising or publicity pertaining to
  10.  * distribution of the software without specific, written prior
  11.  * permission.  John G. Myers makes no representations about the
  12.  * suitability of this software for any purpose.  It is provided "as
  13.  * is" without express or implied warranty.
  14.  *
  15.  * JOHN G. MYERS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  16.  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  17.  * FITNESS, IN NO EVENT SHALL JOHN G. MYERS BE LIABLE FOR ANY SPECIAL,
  18.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  19.  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
  21.  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  */
  23. #include <stdio.h>
  24. #include <string.h>
  25.  
  26. extern char *magic_look();
  27. extern char *os_genid();
  28. extern char *md5digest();
  29.  
  30. #define NUMREFERENCES 4
  31.  
  32. /*
  33.  * Encode a file named into one or more MIME messages, each
  34.  * no larger than 'maxsize'.  A 'maxsize' of zero means no size limit.
  35.  */
  36. int encode(fname, descfname, subject, headers, maxsize, typeoverride, outfname)
  37. char *fname, *descfname, *subject, *headers;
  38. long maxsize;
  39. char *typeoverride, *outfname;
  40. {
  41.     char *type;
  42.     FILE *infile, *descfile, *outfile;
  43.     char *cleanfname, *p;
  44.     char *digest;
  45.     long filesize, l, written;
  46.     int thispart, numparts = 1;
  47.     char *multipartid, *msgid, *referenceid[NUMREFERENCES];
  48.     char buf[1024];
  49.     int i;
  50.  
  51.     /* Open files */
  52.     infile = fopen(fname, "rb");
  53.     if (!infile) {
  54.     os_perror(fname);
  55.     return 1;
  56.     }
  57.     if (descfname) {
  58.     descfile = fopen(descfname, "r");
  59.     if (!descfile) {
  60.         os_perror(descfname);
  61.         return 1;
  62.     }
  63.     }
  64.  
  65.     /* Clean up fname for printing */
  66.     cleanfname = fname;
  67.     if (p = strrchr(cleanfname, '/')) cleanfname = p+1;
  68.     if (p = strrchr(cleanfname, '\\')) cleanfname = p+1;
  69.     if (p = strrchr(cleanfname, ':')) cleanfname = p+1;
  70.  
  71.     /* Find file type */
  72.     if (typeoverride) {
  73.     type = typeoverride;
  74.     }
  75.     else {
  76.     type = magic_look(infile);
  77.     }
  78.  
  79.     /* Compute MD5 digest */
  80.     digest = md5digest(infile, &filesize);
  81.  
  82.     /* See if we have to do multipart */
  83.     if (maxsize) {
  84.     filesize = (filesize / 54) * 73; /* Allow for base64 expansion */
  85.  
  86.     /* Add in size of desc file */
  87.     if (descfname) {
  88.         free(md5digest(descfile, &l));     /* XXX */
  89.         filesize += l;
  90.     }
  91.  
  92.     numparts = (filesize-1000)/maxsize + 1;
  93.     if (numparts < 1) numparts = 1;
  94.     }
  95.  
  96.     multipartid = os_genid();
  97.     for (i=0; i<NUMREFERENCES; i++) {
  98.     referenceid[i] = 0;
  99.     }
  100.  
  101.     for (thispart=1; thispart <= numparts; thispart++) {
  102.     written = 0;
  103.  
  104.     /* Open output file */
  105.     if (numparts == 1) {
  106.         outfile = fopen(outfname, "w");
  107.         if (!outfile) os_perror(outfname);
  108.     }
  109.     else {
  110.         sprintf(buf, "%s.%02d", outfname, thispart);
  111.         outfile = fopen(buf, "w");
  112.         if (!outfile) os_perror(buf);
  113.     }
  114.     if (!outfile) return 1;
  115.     
  116.     msgid = os_genid();
  117.     fprintf(outfile, "Message-ID: <%s>\n", msgid);
  118.     fprintf(outfile, "Mime-Version: 1.0\n");
  119.     if (headers) fputs(headers, outfile);
  120.     if (numparts > 1) {
  121.         fprintf(outfile, "Subject: %s (%02d/%02d)\n", subject,
  122.             thispart, numparts);
  123.         if (thispart == 1) {
  124.         referenceid[0] = msgid;
  125.         }
  126.         else {
  127.         /* Put out References: header pointing to previous parts */
  128.         fprintf(outfile, "References: <%s>\n", referenceid[0]);
  129.         for (i=1; i<NUMREFERENCES; i++) {
  130.             if (referenceid[i]) fprintf(outfile, "\t <%s>\n",
  131.                         referenceid[i]);
  132.         }
  133.         for (i=2; i<NUMREFERENCES; i++) {
  134.             referenceid[i-1] = referenceid[i];
  135.         }
  136.         referenceid[NUMREFERENCES-1] = msgid;
  137.         }
  138.         fprintf(outfile,
  139.             "Content-Type: message/partial; number=%d; total=%d;\n",
  140.             thispart, numparts);
  141.         fprintf(outfile, "\t id=\"%s\"\n", multipartid);
  142.         fprintf(outfile, "\n");
  143.     }
  144.  
  145.     if (thispart == 1) {
  146.         if (numparts > 1) {
  147.         fprintf(outfile, "Message-ID: <%s>\n", multipartid);
  148.         fprintf(outfile, "MIME-Version: 1.0\n");
  149.         }
  150.         fprintf(outfile, "Subject: %s\n", subject);
  151.         fprintf(outfile,
  152.             "Content-Type: multipart/mixed; boundary=\"-\"\n");
  153.         fprintf(outfile,
  154. "\nThis is a MIME encoded message.  Decode it with \"munpack\"\n");
  155.         fprintf(outfile,
  156. "or any other MIME reading software.  Mpack/munpack is available\n");
  157.         fprintf(outfile,
  158. "in Volume 3 of comp.sources.reviewed or via anonymous FTP in\n");
  159.         fprintf(outfile, "export.acs.cmu.edu:pub/mpack/\n");
  160.         written = 300;
  161.  
  162.         /* Spit out description section */
  163.         if (descfname) {
  164.         fprintf(outfile, "---\n\n");
  165.         while (fgets(buf, sizeof(buf), descfile)) {
  166.             /* Strip multiple leading dashes as they may become MIME
  167.              * boundaries
  168.              */
  169.             p = buf;
  170.             if (*p == '-') {
  171.             while (p[1] == '-') p++;
  172.             }
  173.  
  174.             fputs(p, outfile);
  175.             written += strlen(p);
  176.         }
  177.         fprintf(outfile, "\n");
  178.         fclose(descfile);
  179.         }
  180.     
  181.         fprintf(outfile, "---\n");
  182.         fprintf(outfile, "Content-Type: %s; name=\"%s\"\n", type, cleanfname);
  183.         fprintf(outfile, "Content-Transfer-Encoding: base64\n");
  184.         fprintf(outfile, "Content-Disposition: inline; filename=\"%s\"\n",
  185.             cleanfname);
  186.         fprintf(outfile, "Content-MD5: %s\n\n", digest);
  187.         free(digest);
  188.         written += 80;
  189.     }
  190.  
  191.     if (written == maxsize) written--; /* avoid a nasty fencepost error */
  192.  
  193.     to64(infile, outfile, (thispart == numparts) ? 0 : (maxsize-written));
  194.  
  195.     if (thispart == numparts) {
  196.         fprintf(outfile, "\n-----\n");
  197.     }
  198.     
  199.     fclose(outfile);    
  200.     }
  201.  
  202.     return 0;
  203. }
  204.