mmencode.c
上传用户:minyiyu
上传日期:2018-12-24
资源大小:864k
文件大小:7k
源码类别:

Telnet服务器

开发平台:

Unix_Linux

  1. /*
  2. a lite version of mmencode, this version ONLY can be base64 
  3. encodeing/decodeing
  4. Copyright (c) 1999 BBS Express Project.
  5. */
  6. /*
  7. CVS: $Id: mmencode.c,v 1.1 2000/01/15 01:45:32 edwardc Exp $
  8. */
  9. /*
  10. Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore)
  11. Permission to use, copy, modify, and distribute this material 
  12. for any purpose and without fee is hereby granted, provided 
  13. that the above copyright notice and this permission notice 
  14. appear in all copies, and that the name of Bellcore not be 
  15. used in advertising or publicity pertaining to this 
  16. material without the specific, prior written permission 
  17. of an authorized representative of Bellcore.  BELLCORE 
  18. MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY 
  19. OF THIS MATERIAL FOR ANY PURPOSE.  IT IS PROVIDED "AS IS", 
  20. WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
  21. */
  22. #define MMCODE
  23. #include <stdio.h>
  24. #include <ctype.h>
  25. #define NEWLINE_CHAR 10
  26. char mmencode_c[] = 
  27.    "$Id: mmencode.c,v 1.1 2000/01/15 01:45:32 edwardc Exp $";
  28. extern char *index();
  29. static char basis_64[] =
  30.    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  31. static char index_64[128] = {
  32.     -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  33.     -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  34.     -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
  35.     52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
  36.     -1, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,
  37.     15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
  38.     -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
  39.     41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
  40. };
  41. #define char64(c)  (((c) < 0 || (c) > 127) ? -1 : index_64[(c)])
  42. /* the following gets a character, but fakes it properly into two chars if there's a newline character */
  43. static int InNewline=0;
  44. int nextcharin(infile, PortableNewlines)
  45. FILE *infile;
  46. int PortableNewlines;
  47. {
  48.     int c;
  49.     if (!PortableNewlines) return(getc(infile));
  50.     if (InNewline) {
  51.         InNewline = 0;
  52.         return(10); /* LF */
  53.     }
  54.     c = getc(infile);
  55.     if (c == NEWLINE_CHAR) {
  56.         InNewline = 1;
  57.         return(13); /* CR */
  58.     }
  59.     return(c);
  60. }
  61. to64(infile, outfile, PortableNewlines) 
  62. FILE *infile, *outfile;
  63. int PortableNewlines;
  64. {
  65.     int c1, c2, c3, ct=0;
  66.     InNewline = 0; /* always reset it */
  67.     while ((c1 = nextcharin(infile, PortableNewlines)) != EOF) {
  68.         c2 = nextcharin(infile, PortableNewlines);
  69.         if (c2 == EOF) {
  70.             output64chunk(c1, 0, 0, 2, outfile);
  71.         } else {
  72.             c3 = nextcharin(infile, PortableNewlines);
  73.             if (c3 == EOF) {
  74.                 output64chunk(c1, c2, 0, 1, outfile);
  75.             } else {
  76.                 output64chunk(c1, c2, c3, 0, outfile);
  77.             }
  78.         }
  79.         ct += 4;
  80.         if (ct > 71) {
  81.             putc('n', outfile);
  82.             ct = 0;
  83.         }
  84.     }
  85.     if (ct) putc('n', outfile);
  86.     fflush(outfile);
  87. }
  88. output64chunk(c1, c2, c3, pads, outfile)
  89. FILE *outfile;
  90. {
  91.     putc(basis_64[c1>>2], outfile);
  92.     putc(basis_64[((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)], outfile);
  93.     if (pads == 2) {
  94.         putc('=', outfile);
  95.         putc('=', outfile);
  96.     } else if (pads) {
  97.         putc(basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)], outfile);
  98.         putc('=', outfile);
  99.     } else {
  100.         putc(basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)], outfile);
  101.         putc(basis_64[c3 & 0x3F], outfile);
  102.     }
  103. }
  104. PendingBoundary(s, Boundaries, BoundaryCt)
  105. char *s;
  106. char **Boundaries;
  107. int *BoundaryCt;
  108. {
  109.     int i;
  110.     for (i=0; i < *BoundaryCt; ++i) {
  111.         if (!strncmp(s, Boundaries[i], strlen(Boundaries[i]))) {
  112.             char Buf[2000];
  113.             strcpy(Buf, Boundaries[i]);
  114.             strcat(Buf, "--n");
  115.             if (!strcmp(Buf, s)) *BoundaryCt = i;
  116.             return(1);
  117.         }
  118.     }
  119.     return(0);
  120. }
  121. /* If we're in portable newline mode, we have to convert CRLF to the 
  122.     local newline convention on output */
  123. static int CRpending = 0;
  124. almostputc(c, outfile, PortableNewlines)
  125. int c;
  126. FILE *outfile;
  127. int PortableNewlines;
  128. {
  129.     if (CRpending) {
  130.         if (c == 10) {
  131.             putc(NEWLINE_CHAR, outfile);
  132.         } else {
  133.             putc(13, outfile);
  134.             putc(c, outfile);
  135.         }
  136.         CRpending = 0;
  137.     } else {
  138.         if (PortableNewlines && c == 13) {
  139.             CRpending = 1;
  140.         } else {
  141.             putc(c, outfile);
  142.         }
  143.     }
  144. }
  145. from64(infile, outfile, boundaries, boundaryct, PortableNewlines) 
  146. FILE *infile, *outfile;
  147. char **boundaries;
  148. int *boundaryct;
  149. int PortableNewlines;
  150. {
  151.     int c1, c2, c3, c4;
  152.     int newline = 1, DataDone = 0;
  153.     /* always reinitialize */
  154.     CRpending = 0;
  155.     while ((c1 = getc(infile)) != EOF) {
  156.         if (isspace(c1)) {
  157.             if (c1 == 'n') {
  158.                 newline = 1;
  159.             } else {
  160.                 newline = 0;
  161.             }
  162.             continue;
  163.         }
  164.         if (newline && boundaries && c1 == '-') {
  165.             char Buf[200];
  166.             /* a dash is NOT base 64, so all bets are off if NOT a boundary */
  167.             ungetc(c1, infile);
  168.             fgets(Buf, sizeof(Buf), infile);
  169.             if (boundaries
  170.                  && (Buf[0] == '-')
  171.                  && (Buf[1] == '-')
  172.                  && PendingBoundary(Buf, boundaries, boundaryct)) {
  173.                 return;
  174.             }
  175.             fprintf(stderr, "Ignoring unrecognized boundary line: %sn", Buf);
  176.             continue;
  177.         }
  178.         if (DataDone) continue;
  179.         newline = 0;
  180.         do {
  181.             c2 = getc(infile);
  182.         } while (c2 != EOF && isspace(c2));
  183.         do {
  184.             c3 = getc(infile);
  185.         } while (c3 != EOF && isspace(c3));
  186.         do {
  187.             c4 = getc(infile);
  188.         } while (c4 != EOF && isspace(c4));
  189.         if (c2 == EOF || c3 == EOF || c4 == EOF) {
  190.             fprintf(stderr, "Premature EOF!n");
  191.             return;
  192.         }
  193.         if (c1 == '=' || c2 == '=') {
  194.             DataDone=1;
  195.             continue;
  196.         }
  197.         c1 = char64(c1);
  198.         c2 = char64(c2);
  199.         almostputc(((c1<<2) | ((c2&0x30)>>4)), outfile, PortableNewlines);
  200.         if (c3 == '=') {
  201.             DataDone = 1;
  202.         } else {
  203.             c3 = char64(c3);
  204.             almostputc((((c2&0XF) << 4) | ((c3&0x3C) >> 2)), outfile, PortableNewlines);
  205.             if (c4 == '=') {
  206.                 DataDone = 1;
  207.             } else {
  208.                 c4 = char64(c4);
  209.                 almostputc((((c3&0x03) <<6) | c4), outfile, PortableNewlines);
  210.             }
  211.         }
  212.     }
  213.     if (CRpending) putc(13, stdout);
  214. }
  215. #define hexchar(c)  (((c) < 0 || (c) > 127) ? -1 : index_hex[(c)])
  216. int
  217. mm(int encode, char *fin, char *fout)
  218. {
  219.     int portablenewlines = 0;
  220.     FILE *in, *out;
  221.     
  222.     if ( fin != NULL )
  223.        in = fopen(fin, "r");
  224.     else
  225.        in = stdin;
  226.     
  227.     if ( fout != NULL )
  228.        out = fopen(fout, "w");
  229.     else
  230.        out = stdout;
  231.        
  232.     if (encode) 
  233.       to64(in, out, portablenewlines); 
  234.     else 
  235.       from64(in, out, NULL, 0, portablenewlines);
  236.       
  237.     if ( fout != NULL )
  238.        fclose(out);
  239.        
  240.     if ( fin != NULL )
  241.        fclose(in);
  242.        
  243.     return(0);
  244. }