Back to index

courier  0.68.2
Defines | Functions | Variables
contentlanguage.c File Reference
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "http11.h"
#include "../rfc2045/rfc2045charset.h"

Go to the source code of this file.

Defines

#define dirent   direct
#define NAMLEN(dirent)   ((dirent)->d_namlen)

Functions

void error (const char *)
static void enomem ()
FILE * http11_open_langfile (const char *libdir, const char *subdir, const char *file)
static size_t parse_accept_string (const char *acc_lang, char **languages, double *weights)
char * http11_best_content_language (const char *libdir, const char *acc_lang)
static const char * get_http11 (const char *libdir, const char *subdir, char *buf, const char *file, const char *def)
const char * http11_content_language (const char *libdir, const char *acc_lang)
const char * http11_content_locale (const char *libdir, const char *acc_lang)
const char * http11_content_ispelldict (const char *libdir, const char *acc_lang)
const char * http11_content_charset (const char *libdir, const char *acc_lang)

Variables

static const char defaultlang [] = HTTP11_DEFAULTLANG

Define Documentation

#define dirent   direct

Definition at line 22 of file contentlanguage.c.

#define NAMLEN (   dirent)    ((dirent)->d_namlen)

Definition at line 23 of file contentlanguage.c.


Function Documentation

static void enomem ( ) [static]

Definition at line 37 of file contentlanguage.c.

{
       error("Out of memory.");
}

Here is the call graph for this function:

Here is the caller graph for this function:

void error ( const char *  )

Definition at line 23 of file showmsg2html.c.

{
       fprintf(stderr, "%s\n", p);
       exit(1);
}

Here is the call graph for this function:

static const char* get_http11 ( const char *  libdir,
const char *  subdir,
char *  buf,
const char *  file,
const char *  def 
) [static]

Definition at line 199 of file contentlanguage.c.

{
FILE   *fp=http11_open_langfile(libdir, subdir, file);

       if (fp != 0)
       {
       size_t n=fread(buf, 1, 79, fp);

              if (n <= 0)   n=0;
              buf[n]=0;
              fclose(fp);
              return (strtok(buf, "\r\n"));
       }
       return (def);
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* http11_best_content_language ( const char *  libdir,
const char *  acc_lang 
)

Definition at line 124 of file contentlanguage.c.

{
size_t naccept=parse_accept_string(acc_lang, 0, 0);
char **languages=malloc(naccept ? sizeof(char *)*naccept:1);
double *weights=malloc(naccept ? sizeof(double)*naccept:1);
DIR    *p;
struct dirent *de;
size_t i;
#if 0
double missweight=1;
#endif
char   *bestlang=0;
double bestweight=0;
int    found_nondefault_match=0;

       if (!languages || !weights)
       {
              if (languages)       free(languages);
              if (weights)  free(weights);
              enomem();
       }
       (void)parse_accept_string(acc_lang, languages, weights);
#if 0
       for (i=0; i<naccept; i++)
              if (strcmp(languages[i], "*") == 0)       missweight=weights[i];
              /* Default weight */
#endif
       p=opendir(libdir);
       while (p && (de=readdir(p)) != 0)
       {
       FILE   *fp;

              if (*de->d_name == '.')     continue;

              if ((fp=http11_open_langfile(libdir, de->d_name, "LOCALE"))
                            != 0)
              {
#if 0
              double myweight=missweight;
#else
              double  myweight=0;
#endif

                     fclose(fp);
                     for (i=0; i<naccept; i++)
                            if (strcmp(languages[i], de->d_name) == 0)
                            {
                                   myweight=weights[i];
                                   break;
                            }
                     if (!bestlang || myweight > bestweight)
                     {
                            if (bestlang) free(bestlang);
                            bestlang=strdup(de->d_name);
                            if (!bestlang)       enomem();
                            bestweight=myweight;
                            if (i < naccept)
                                   found_nondefault_match=1;
                     }
              }
       }
       if (p) closedir(p);
       if (!bestlang || !found_nondefault_match)
       {
              if (bestlang) free(bestlang);
              if ((bestlang=malloc(sizeof(defaultlang))) == 0) enomem();
              strcpy(bestlang, defaultlang);
       }
       for (i=0; i<naccept; i++)
              free(languages[i]);
       free(languages);
       free(weights);
       return (bestlang);
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* http11_content_charset ( const char *  libdir,
const char *  acc_lang 
)

Definition at line 239 of file contentlanguage.c.

{
       char buf[80];
       static char buf2[80];
       size_t naccept;
       char **charsets;
       double *weights;
       const char *p;
       size_t i;

       strcpy(buf2, get_http11(libdir, acc_lang, buf, "CHARSET",
                            RFC2045CHARSET));

       p=getenv("HTTP_ACCEPT_CHARSET");

       if (!p) p="";

       naccept=parse_accept_string(p, 0, 0);
       charsets=malloc(naccept ? sizeof(char *)*naccept:1);
       weights=malloc(naccept ? sizeof(double)*naccept:1);

       if (!charsets || !weights)
       {
              if (charsets) free(charsets);
              if (weights)  free(weights);
              enomem();
       }

       (void)parse_accept_string(p, charsets, weights);
       strcpy(buf, buf2);

       for (p=strtok(buf, ", \t\r\n"); p != NULL; p=strtok(NULL, ", \t\r\n"))
       {
              for (i=0; i<naccept; i++)
                     if (strcmp(charsets[i], p) == 0)
                     {
                            strcpy(buf2, charsets[i]);
                            for (i=0; i<naccept; i++)
                                   free(charsets[i]);
                            free(charsets);
                            free(weights);
                            return buf2;
                     }
       }

       p=strtok(buf2, ", \t\r\n");
       if (!p)
              p=RFC2045CHARSET;
       for (i=0; i<naccept; i++)
              free(charsets[i]);
       free(charsets);
       free(weights);
       return p;
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* http11_content_ispelldict ( const char *  libdir,
const char *  acc_lang 
)

Definition at line 232 of file contentlanguage.c.

{
static char buf[80];

       return (get_http11(libdir, acc_lang, buf, "ISPELLDICT", defaultlang));
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* http11_content_language ( const char *  libdir,
const char *  acc_lang 
)

Definition at line 217 of file contentlanguage.c.

{
static char   buf[80];

       return (get_http11(libdir, acc_lang, buf, "LANGUAGE", defaultlang));
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* http11_content_locale ( const char *  libdir,
const char *  acc_lang 
)

Definition at line 224 of file contentlanguage.c.

{
static char buf[80];
const char *p=get_http11(libdir, acc_lang, buf, "LOCALE", "C");

       return (p);
}

Here is the call graph for this function:

Here is the caller graph for this function:

FILE* http11_open_langfile ( const char *  libdir,
const char *  subdir,
const char *  file 
)

Definition at line 49 of file contentlanguage.c.

{
char   *p=malloc(strlen(libdir)+strlen(subdir)+strlen(file)+3);
FILE   *fp;

       if (!p)       return (0);
       strcat(strcat(strcat(strcat(strcpy(p, libdir), "/"), subdir), "/"),
              file);

       fp=fopen(p, "r");
       free(p);
       return (fp);
}

Here is the caller graph for this function:

static size_t parse_accept_string ( const char *  acc_lang,
char **  languages,
double *  weights 
) [static]

Definition at line 68 of file contentlanguage.c.

{
char *p=strdup(acc_lang ? acc_lang:"");
size_t cnt=0;
char   *q, *r;
int    has_weights=0;
double *save_weights=weights;

       if (!p)       enomem();
       for (q=p; (q=strtok(q, ", ")) != 0; q=0)
       {
              if (languages)
              {
                     q=strdup(q);
                     if (!q)       enomem();
                     *languages++=q;
              }
              if (weights)  *weights=1;   /* Until further notice */
              for (r=q; *r; r++)
                     *r=tolower(*r);
              if ((r=strchr(q, ';')) != 0)
              {
                     *r++=0;
                     if (*r == 'q' && r[1] == '=')
                     {
                     double weight=atof(r+2);

                            if (weights)  *weights=weight;
                            has_weights=1;
                     }
              }
              if (weights)  ++weights;
              ++cnt;
       }
       free(p);
       if (!has_weights && weights)
       {
       size_t i;
       double weight=1;

       /*
       ** Broken HTTP/1.1 clients do not specify quality factors, and expect
       ** the server to pick the first one on the list
       */
              for (i=cnt; i; )
              {
                     --i;
                     save_weights[i]=weight;
                     weight = weight + 1;
              }
       }
       
       return (cnt);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

const char defaultlang[] = HTTP11_DEFAULTLANG [static]

Definition at line 42 of file contentlanguage.c.