CVS diff for mime.c between 1.5 and 1.1:

Revision 1.1 Revision 1.5
Line 4 Line 4
 * This file is still quite primitive as you can see. 
*/ 
 
 * This file is still quite primitive as you can see. 
*/ 
 
# include <stdlib.h>
# include <string.h>
# include "mime.h"
# include "utl.h" 
#include "cow.h"
#include "cow_config.h"
#include "mime.h"
#include "utl.h" 

            

            
Mime mime[256]; 
#define NUMMIME 512
 
Mime mime[NUMMIME];
Mime* mimepop[NUMMIME];      /* Pointers into mime, sorted by popularity */
int mime_idx; 
 
// char* mime_tab[3];
int mime_idx; 
 
// char* mime_tab[3];
char default_type[16]; 
 

            

            
void
void add_mime_type(FILE * fp, char *media_type) 
add_mime_type (FILE * fp, char *media_type)
 
{
{
  int h;
  int j;
  int k;
  int flg = 0;
  char sux[16];
  for (;;)
  {
    j = 0;
    k = 1;
    flg = 0;
    h = eat_ws (fp);
    if ('\n' == h || '\r' == h || '\0' == h)
      return;
    mime[mime_idx].types[0] = '\0';
    strncat (mime[mime_idx].types, media_type, strlen (media_type));
    sux[0] = h;
    sux[1] = '\0';
    for (;;)
    {
      h = getc (fp);
      if (' ' == h || '\t' == h)
	break;
      if ('\n' == h || '\r' == h)
      {
	flg = 1;
	break;
      }
      sux[k++] = h;
      sux[k] = '\0'; 
    int h;
    int j;
    int k;
    int flg = 0;
    char sux[16];

    if (mime_idx >= NUMMIME)
        return;

    for (;;) {
	j = 0;
	k = 1;
	flg = 0;
	h = eat_ws(fp);
	if ('\n' == h || '\r' == h || '\0' == h)
	    return;
	mime[mime_idx].types[0] = '\0';
	strncat(mime[mime_idx].types, media_type, strlen(media_type));
	sux[0] = h;
	sux[1] = '\0';
	for (;;) {
	    h = getc(fp);
	    if (' ' == h || '\t' == h)
		break;
	    if ('\n' == h || '\r' == h) {
		flg = 1;
		break;
	    }
	    sux[k++] = h;
 
	    sux[k] = '\0';
	}
	mime[mime_idx].suffix[0] = '\0';
	strncat(mime[mime_idx].suffix, sux, strlen(sux));
        mime[mime_idx].hits = 0;
        mimepop[mime_idx] = &mime[mime_idx];
	mime_idx++;
	if (flg)
	    return;
    }
    }
    mime[mime_idx].suffix[0] = '\0';
    strncat (mime[mime_idx].suffix, sux, strlen (sux));
    mime_idx++;
    if (flg)
      return;
  } 
 


int
int mime_init(FILE * fp) 
mime_init (FILE * fp)
 
{
{
  int h;
  char mt_buf[128]; 
    int h;
    char mt_buf[128]; 

            

            
  default_type[0] = '\0';
  strcat (default_type, "text/html"); 
    /*
     * If a global mime type was set in the config file, we'll just use that
 
     * and we don't need to read the list.
     */
    if (global_mime)
        return 0;

            

            
  mime_idx = 0;
  for (;;)
  {
    h = eat_ws (fp);
    if (EOF == h)
    {
      return 0; 
    mime_idx = 0;
    for (;;) {
	h = eat_ws(fp);
	if (EOF == h) {
	    return 0;
	}
	else if ('#' == h) {
 
	    eat_line(fp);
	}
	else {
	    int j = 0;
	    /* media type */
	    mt_buf[j++] = h;
	    for (;;) {
		h = getc(fp);
		if (' ' == h || '\t' == h) {
		    mt_buf[j++] = '\0';
		    add_mime_type(fp, mt_buf);
		    j = 0;
		    break;
		}
		else if (h == '\0')
		    return 0;
		else if (h == '\n' || h == '\r')
		    break;
		else
		    mt_buf[j++] = h;
	    }
	}
    }
    }
    else if ('#' == h)
    {
      eat_line (fp);
    }
    else
    {
      int j = 0;
      /* media type */
      mt_buf[j++] = h;
      for (;;)
      {
	h = getc (fp);
	if (' ' == h || '\t' == h)
	{
	  mt_buf[j++] = '\0';
	  add_mime_type (fp, mt_buf);
	  j = 0;
	  break;
	}
	else if (h == '\0')
	  return 0;
	else if (h == '\n' || h == '\r')
	  break;
	else
	  mt_buf[j++] = h;
      }
    }
  } 
 


char *
get_mime_type (char *filename)
{
  char *suffix;
  int i = 0; 
 

            

            
  suffix = strrchr (filename, '.'); 
/****
 
 * get_mime_type()
 *
 * Returns the mimetype for a file based on filename extension.  This
 * routine will slowly sort its list of mime types over time so that
 * the more popular types bubble up to the top.  Since most servers only
 * serve a couple types of files, the loop will essentially be eliminated.
 *
 * @param filename The file to determine the mime type for.
 *
 * @return The mime type associated with the specified file.  This is
 *         generally based on an entry in /etc/mime.types but can also
 *         be overridden in the config file.
 ****/
char *get_mime_type(char *filename) {
    char *suffix;
    int i = 0;

            

            
  if (!suffix || '\0' == *suffix)
    return default_type; 
    /* If there's a global mime type defined, return that */
    if (global_mime)
 
        return global_mime;

            

            
  suffix++;			// don't want '.' 
    suffix = strrchr(filename, '.');
 
    if (!suffix || '\0' == *suffix)
	return default_mime ? default_mime : "text/plain";

            

            
  for (; i < mime_idx; i++)
    suffix++;			// don't want '.' 
  {
    if (!strcmp (mime[i].suffix, suffix))
      return mime[i].types;
  }
 

            

            
  return default_type; 
    for (; i < mime_idx; i++) {
 
	if (!strcmp(mimepop[i]->suffix, suffix)) {
            /*
             * This is the mime type we want.
             */
            Mime* tmp;

            /*
             * Bubble this type up (but only by a single slot) if it's more
             * popular than the one above it.
             */
            if (i > 0 && (++(mimepop[i]->hits) >= mimepop[i-1]->hits)) {
                /* Swap this type with the one above it */
                tmp = mimepop[i-1];
                mimepop[i-1] = mimepop[i];
                mimepop[i] = tmp;

                /* Since we've swapped positions, return i-1 instead of i */
                return mimepop[i-1]->types;
            } else {
                return mimepop[i]->types;
            }
        }
    }

    /*
     * Suffix not found in list.  If a default was set in the config file,
     * return that.  If not, just return text/plain.
     */
    return default_mime ? default_mime : "text/plain";




Legend
Lines deleted from 1.5  
Lines Modified
  Lines added in revision 1.1