
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <string.h>

#define max_line_length 250
#define MAXPATH 1024

extern int errno;

int ValidMIME (char *);

char  * ReadInput( FILE * __stream, char * __s, int _q, int * __n);

char char_set[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int char_table[128];

main (int argc, char *argv[])
{
         FILE *inputfile;
         char inputpath[MAXPATH+1];
         char inputfilename[MAXPATH+1];
         char input_string[max_line_length];
         char * tempchar;
         char argoutputfilename[MAXPATH+1];
         int files_processed = 0;
         int ii,jj;
         int line_counter = 0;

         for (ii=0 ; ii<128 ; ++ii)
                  char_table[ii] = -1;
         tempchar = char_set;
         for (ii=0 ; ii <= strlen(char_set) ; ii++)
                  {
                        char_table[*tempchar++] = ii;
                  }

         if (argc<2 || argc>3)
                 {
                  printf("Invalid number of parameters %u\n",argc-1);
                  printf("Usage: de-mime inputfile [outputfile]\n");
                  return 8;
                 }
         else
                  strcpy(inputfilename,argv[1]);
         if (argc > 2)
                  {
                        strcpy(argoutputfilename,argv[2]);
                  }

         inputfile = fopen(inputfilename,"rb");

         if (inputfile == NULL)
                  {
                        printf("Input file - %s - could not be opened\n",inputfilename);
                        return 4;
                  }

         tempchar = strrchr(inputfilename,'\\') ;

         if  (tempchar != NULL)
                  {
                        ii = (int) (tempchar-inputfilename+1);
                        strncpy(inputpath,inputfilename,ii);
                        inputpath[ii] = '\0';
                  }
         else
                  {
                        inputpath[0] = '\0';
                  }

         if (ReadInput(inputfile,input_string,max_line_length,&line_counter) == NULL)
                  {
                        printf("File %s is empty\n",argv[1]);
                        fclose(inputfile);
                        return 4;
                  }

         for (;feof(inputfile)==0;)
                  {
                        char *nameptr;
                        char suggestedfilename[MAXPATH+1];
                        char outputfilename[MAXPATH+1];
                        FILE *outputfile;
                        int ii;
                        int start_line;
                        long int output_size;
                        char quotechar;

                        suggestedfilename[0] = '\0';

                        for ( ; (!ValidMIME(input_string) || strlen(input_string) < 12) &&
                                          feof(inputfile)==0 ; )
                                 {
                                  nameptr = strstr(input_string,"name=");
                                  if (nameptr != NULL)
                                                {
                                                 strcpy(suggestedfilename,nameptr+6);
                                                 nameptr = nameptr+5;
                                                 quotechar = *nameptr;
                                                 for (ii=0 ; suggestedfilename[ii]!=quotechar ; ii++)
                                                          ;
                                                 suggestedfilename[ii] = '\0';
                                                }
                                  ReadInput(inputfile,input_string,max_line_length,&line_counter);
                                 }

                        if (feof(inputfile) != 0)
                                 break;

                        if (suggestedfilename[0] != '\0')
                                 {
                                  strcpy(outputfilename,inputpath);
                                  strcat(outputfilename,suggestedfilename);
                                 }
                        else
                                 {
                                  if (argc > 2)
                                                {
                                                 for (ii = 0; (argoutputfilename[ii] != '\\') &&
                                                                                        (ii < strlen(argoutputfilename)) ; ++ii) ;
                                                 if (argoutputfilename[ii] != '\\')
                                                          {
                                                                strcpy(outputfilename,inputpath);
                                                                strcat(outputfilename,argoutputfilename);
                                                          }
                                                 else
                                                          {
                                                                strcpy(outputfilename,argoutputfilename);
                                                          }
                                                }
                                  else
                                                {
                                                 outputfilename[0] = '\0';
                                                }
                                 }

                        for (outputfile = NULL ; outputfile == NULL ; )
                                 {
                                  if (outputfilename[0] != '\0')
                                                {
                                                 outputfile=fopen(outputfilename,"rb");
                                                 if (outputfile != NULL)
                                                          {
                                                                printf("Outputfile %s already exists\n",outputfilename);
                                                                fclose(outputfile);
                                                                outputfile = NULL;
                                                          }
                                                 else
                                                          {
                                                                outputfile=fopen(outputfilename,"wb");
                                                                if (outputfile == NULL)
                                                                         {
                                                                          printf("Error creating output file %s",
                                                                                                                                                         outputfilename);
                                                                          printf(" Errno=%d, _doserrno=%d\n",
                                                                                                                                                        errno,errno);
                                                                         }
                                                          }
                                                }
                                  else
                                                {
                                                 printf("Output filename not specified\n");
                                                }
                                  if (outputfile == NULL)
                                                {
                                                 printf("Enter outputfile name: ");
                                                 for (ii = 0; ii < 64; ++ii)
                                                          {
                                                                int GottonChar;
                                                                GottonChar = getchar();
                                                                suggestedfilename[ii] = GottonChar;
                                                                if (GottonChar == '\n' || GottonChar == EOF)
                                                                         {
                                                                          suggestedfilename[ii] = '\0';
                                                                          break;
                                                                         }
                                                          }
                                                 for (ii = 0; (suggestedfilename[ii] != '\\') &&
                                                                                        (ii < strlen(suggestedfilename)) ; ++ii)
                                                          ;
                                                 if (suggestedfilename[ii] != '\\')
                                                          {
                                                                strcpy(outputfilename,inputpath);
                                                                strcat(outputfilename,suggestedfilename);
                                                          }
                                                 else
                                                          {
                                                                strcpy(outputfilename,suggestedfilename);
                                                          }
                                                }
                                 }

                        printf("Creating output file #%d - %s - starting at line %d\n",
                                                                          ++files_processed,outputfilename,line_counter);

                        start_line = line_counter;
                        output_size = 0;

                        for ( ; feof(inputfile) == 0 ; )
                                 {
                                  char output_buffer[3];
                                  int output_length;
                                  char * charptr;
                                  int ii;
                                  int sextet[4];

                                  charptr = &input_string[0];

                                  for (ii=0 ; ii<strlen(input_string); ii=ii+4)
                                                {
                                                 for (jj=0; jj<4; jj++)
                                                          {
                                                                sextet[jj] = char_table[*charptr++];
                                                          }
                                                 if (sextet[0] < 0)
                                                          {
                                                                output_length = 0;
                                                                break;
                                                          }
                                                 if (sextet[2] < 0)
                                                          output_length = 1;
                                                 else
                                                          if (sextet[3] < 0)
                                                                        output_length = 2;
                                                          else
                                                                        output_length = 3;

                                                 output_buffer[0] = 4*sextet[0]+sextet[1]/16;
                                                 output_buffer[1] = 16*(sextet[1]%16)+sextet[2]/4;
                                                 output_buffer[2] = 64*(sextet[2]%64)+sextet[3];

                                                 fwrite(&output_buffer[0],output_length,1,outputfile);

                                                 output_size += output_length;

                                                 if (output_length < 3)
                                                          break;
                                                }
                                  ReadInput(inputfile,input_string,max_line_length,&line_counter);

                                  if (output_length < 3)
                                                break;
                                 }

                        printf("%s succesfully created, lines = %d, bytes = %d\n",
                                                 outputfilename,line_counter-start_line+1,output_size);

                        fclose(outputfile);
                  }

         fclose(inputfile);

         if (files_processed == 0)
                  {
                        printf("No valid MIME input was detected\n");
                        return 4;
                  }
         printf("%d output files created\n",files_processed);
         return 0 ;
}

int ValidMIME (char *input_string)
{
 if ((strlen(input_string)%4 > 0)  ||  (strlen(input_string)==0))
          {
                printf("Invalid MIME - %s\n",input_string);
                return 0;
          }
 return (strspn(input_string,char_set) == strlen(input_string));
}

char * ReadInput (FILE * inputfile, char * input_string,
                                                int input_string_size, int * line_counter)
{
 char * read_result;
 int ii;
 read_result = fgets(input_string,input_string_size,inputfile);
 if (read_result != NULL)
          {
                ++(*line_counter);
                ii = strlen(input_string)-1;
                input_string[ii] = '\0';
          }
 return read_result;
}

