Annotation of libwww/Library/src/HTBind.c, revision 2.34

2.22      frystyk     1: /*                                                                  Htbind.c
2.1       frystyk     2: **     FILE SUFFIX BIND MANAGER
                      3: **
                      4: **     (c) COPYRIGHT MIT 1995
                      5: **     Please first read the full copyright statement in the file COPYRIGH.
2.34    ! kahan       6: **     @(#) $Id: HTBind.c,v 2.33 1999/02/22 22:10:10 frystyk Exp $
2.1       frystyk     7: **
                      8: **     This module sets up the binding between a file Bind and a media
                      9: **     type, language, encoding etc. In a client application the Binds
                     10: **     are used in protocols that does not support media types etc., like
                     11: **     FTP, and in server applications they are used to make the bindings
                     12: **     between the server and the local file store that the server can
                     13: **     serve to the rest of the world (well almost). The HTFormat module
                     14: **     holds this information against the accept headers received in a
                     15: **     request and uses if for format negotiation. All the binding management
                     16: **     can all be replace by a database interface. 
                     17: **
                     18: ** History:
                     19: **        Feb 91       Written Tim Berners-Lee CERN/CN
                     20: **        Apr 91       vms-vms access included using DECnet syntax
                     21: **     26 Jun 92 (JFG) When running over DECnet, suppressed FTP.
                     22: **                     Fixed access bug for relative names on VMS.
                     23: **        Sep 93 (MD)  Access to VMS files allows sharing.
                     24: **     15 Nov 93 (MD)  Moved HTVMSname to HTVMSUTILS.C
                     25: **     22 Feb 94 (MD)  Excluded two routines if we are not READING directories
                     26: **     18 May 94 (HF)  Directory stuff removed and stream handling updated,
                     27: **                     error messages introduced etc.
                     28: **     10 Maj 95 HF    Spawned off from HTFile in order to make it easier to
                     29: **                     override by a new module. It's now based on anchors
                     30: **                     and hash tables
                     31: ** Bugs:
                     32: */
                     33: 
                     34: /* Library Includes */
2.26      frystyk    35: #include "wwwsys.h"
2.21      frystyk    36: #include "WWWUtil.h"
2.24      frystyk    37: #include "HTAnchor.h"
                     38: #include "HTResponse.h"
2.1       frystyk    39: #include "HTParse.h"
                     40: #include "HTBind.h"                                     /* Implemented here */
                     41: 
                     42: typedef struct _HTBind {
                     43:     char *     suffix;
                     44:     HTFormat   type;                   /* Content-Type */
                     45:     HTEncoding encoding;               /* Content-Encoding */
2.22      frystyk    46:     HTEncoding transfer;               /* Content-Transfer-Encoding */
2.1       frystyk    47:     HTLanguage language;               /* Content-Language */
                     48:     double     quality;
                     49: } HTBind;
                     50: 
                     51: /* Suffix registration */
                     52: PRIVATE BOOL HTCaseSen = YES;                /* Are suffixes case sensitive */
                     53: PRIVATE char *HTDelimiters = NULL;                       /* Set of suffixes */
                     54: 
                     55: PRIVATE HTList **HTBindings = NULL;   /* Point to table of lists of bindings */
                     56: 
2.21      frystyk    57: PRIVATE HTBind no_suffix = { "*", NULL, NULL, NULL, NULL, 0.5 };
                     58: PRIVATE HTBind unknown_suffix = { "*.*", NULL, NULL, NULL, NULL, 0.5 };
2.1       frystyk    59: 
                     60: /* ------------------------------------------------------------------------- */
                     61: 
                     62: /*     
                     63: **     Set up the list of suffix bindings. Done by HTLibInit
                     64: */
2.11      frystyk    65: PUBLIC BOOL HTBind_init (void)
2.1       frystyk    66: {
2.8       frystyk    67:     if (!HTBindings) {
2.31      frystyk    68:        if (!(HTBindings = (HTList **) HT_CALLOC(HT_L_HASH_SIZE, sizeof(HTList *))))
2.17      frystyk    69:            HT_OUTOFMEM("HTBind_init");
2.8       frystyk    70:     }
2.1       frystyk    71:     StrAllocCopy(HTDelimiters, DEFAULT_SUFFIXES);
2.15      frystyk    72:     no_suffix.type = WWW_UNKNOWN;
2.25      frystyk    73:     no_suffix.encoding = WWW_CODING_BINARY;
2.15      frystyk    74:     unknown_suffix.type = WWW_UNKNOWN;
2.25      frystyk    75:     unknown_suffix.encoding = WWW_CODING_BINARY;
2.1       frystyk    76:     return YES;
                     77: }
                     78: 
                     79: 
                     80: /*
                     81: **     Cleans up the memory allocated by file bindings
                     82: **     Done by HTLibTerminate().
                     83: **     Written by Eric Sink, eric@spyglass.com, and Henrik
                     84: */
2.11      frystyk    85: PUBLIC BOOL HTBind_deleteAll (void)
2.1       frystyk    86: {
                     87:     int cnt;
                     88:     HTList *cur;
                     89:     if (!HTBindings)
                     90:        return NO;
2.31      frystyk    91:     for (cnt=0; cnt<HT_L_HASH_SIZE; cnt++) {
2.1       frystyk    92:        if ((cur = HTBindings[cnt])) { 
                     93:            HTBind *pres;
                     94:            while ((pres = (HTBind *) HTList_nextObject(cur)) != NULL) {
2.17      frystyk    95:                HT_FREE(pres->suffix);
                     96:                HT_FREE(pres);
2.1       frystyk    97:            }
                     98:        }
                     99:        HTList_delete(HTBindings[cnt]);
                    100:        HTBindings[cnt] = NULL;
                    101:     }
2.19      frystyk   102:     HT_FREE(HTBindings);
2.17      frystyk   103:     HT_FREE(HTDelimiters);
2.1       frystyk   104:     return YES;
                    105: }
                    106: 
                    107: 
                    108: /*     Make suffix bindings case sensitive
                    109: **     -----------------------------------
                    110: */
2.11      frystyk   111: PUBLIC void HTBind_caseSensitive (BOOL sensitive)
2.1       frystyk   112: {
                    113:     HTCaseSen = sensitive;
                    114: }
                    115: 
                    116: 
                    117: /*     Get set of suffixes
                    118: **     -------------------
                    119: */
2.20      frystyk   120: PUBLIC const char *HTBind_delimiters (void)
2.1       frystyk   121: {
                    122:     return HTDelimiters;
                    123: }
                    124: 
                    125: 
                    126: /*     Change set of suffixes
                    127: **     ----------------------
                    128: */
2.20      frystyk   129: PUBLIC void HTBind_setDelimiters (const char * new_suffixes)
2.1       frystyk   130: {
                    131:     if (new_suffixes && *new_suffixes)
                    132:        StrAllocCopy(HTDelimiters, new_suffixes);
                    133: }
                    134: 
                    135: 
                    136: /*     Define the representation associated with a file suffix
                    137: **     -------------------------------------------------------
                    138: **
                    139: **     Calling this with suffix set to "*" will set the default
                    140: **     representation.
                    141: **     Calling this with suffix set to "*.*" will set the default
                    142: **     representation for unknown suffix files which contain a "."
                    143: **
                    144: **     If filename suffix is already defined its previous
                    145: **     definition is overridden (or modified)
                    146: */
2.20      frystyk   147: PUBLIC BOOL HTBind_addType (const char *       suffix,
                    148:                            const char *        representation,
2.12      frystyk   149:                            double              value)
2.1       frystyk   150: {
2.21      frystyk   151:     return HTBind_add(suffix, representation, NULL, NULL, NULL, value);
2.1       frystyk   152: }
                    153: 
2.20      frystyk   154: PUBLIC BOOL HTBind_addEncoding (const char *   suffix,
                    155:                                const char *    encoding,
2.11      frystyk   156:                                double          value)
2.1       frystyk   157: {
2.21      frystyk   158:     return HTBind_add(suffix, NULL, encoding, NULL, NULL, value);
2.1       frystyk   159: }
                    160: 
2.21      frystyk   161: PUBLIC BOOL HTBind_addTransfer (const char *   suffix,
                    162:                                const char *    transfer,
                    163:                                double          value)
                    164: {
                    165:     return HTBind_add(suffix, NULL, NULL, transfer, NULL, value);
                    166: }
                    167: 
2.20      frystyk   168: PUBLIC BOOL HTBind_addLanguage (const char *   suffix,
                    169:                                const char *    language,
2.11      frystyk   170:                                double          value)
2.1       frystyk   171: {
2.21      frystyk   172:     return HTBind_add(suffix, NULL, NULL, NULL, language, value);
2.1       frystyk   173: }
                    174: 
2.20      frystyk   175: PUBLIC BOOL HTBind_add (const char *   suffix,
                    176:                        const char *    representation,
                    177:                        const char *    encoding,
2.21      frystyk   178:                        const char *    transfer,
2.20      frystyk   179:                        const char *    language,
2.11      frystyk   180:                        double          value)
2.1       frystyk   181: {
                    182:     HTBind * suff;
                    183:     if (!suffix)
                    184:        return NO;
                    185:     if (!strcmp(suffix, "*"))
                    186:        suff = &no_suffix;
                    187:     else if (!strcmp(suffix, "*.*"))
                    188:        suff = &unknown_suffix;
                    189:     else {
2.31      frystyk   190:        HTList * suflist;
                    191:        int hash;
                    192:        const unsigned char * p;
2.1       frystyk   193: 
                    194:        /* Select list from hash table */
2.31      frystyk   195:        for (p=suffix, hash=0; *p; p++) {
                    196:            hash = (hash * 3 + TOLOWER(*p)) % HT_L_HASH_SIZE;
                    197:        }
2.1       frystyk   198: 
2.32      frystyk   199:        if (!HTBindings) HTBind_init();
2.1       frystyk   200:        if (!HTBindings[hash]) HTBindings[hash] = HTList_new();
                    201:        suflist = HTBindings[hash];
                    202: 
                    203:        /* Look for existing binding */
                    204:        {
                    205:            HTList *cur = suflist;
                    206:            while ((suff = (HTBind *) HTList_nextObject(cur)) != NULL) {
                    207:                if (!strcmp(suff->suffix, suffix))
                    208:                    break;
                    209:            }
                    210:        }
                    211: 
                    212:        /* If not found -- create a new node */
                    213:        if (!suff) {
2.17      frystyk   214:            if ((suff = (HTBind *) HT_CALLOC(1, sizeof(HTBind))) == NULL)
                    215:                HT_OUTOFMEM("HTBind_add");
2.1       frystyk   216:            HTList_addObject(suflist, (void *) suff);
                    217:            StrAllocCopy(suff->suffix, suffix);
                    218:        }
                    219:     }
                    220: 
                    221:     /* Set the appropriate values */
                    222:     {
2.21      frystyk   223:        HTChunk * chunk = HTChunk_new(32);
2.1       frystyk   224:        char *ptr;
                    225:        if (representation) {
2.21      frystyk   226:            HTChunk_puts(chunk, representation);
                    227:            ptr = HTChunk_data(chunk);
                    228:            for (; *ptr; ptr++)
2.1       frystyk   229:                *ptr = TOLOWER(*ptr);
2.21      frystyk   230:            suff->type = HTAtom_for(HTChunk_data(chunk));
2.34    ! kahan     231:            HTChunk_truncate(chunk,0);
2.1       frystyk   232:        }
2.21      frystyk   233:        if (encoding) {
                    234:            HTChunk_puts(chunk, encoding);
                    235:            ptr = HTChunk_data(chunk);
                    236:            for (; *ptr; ptr++)
2.1       frystyk   237:                *ptr = TOLOWER(*ptr);
2.21      frystyk   238:            suff->encoding = HTAtom_for(HTChunk_data(chunk));
2.34    ! kahan     239:            HTChunk_truncate(chunk,0);
2.1       frystyk   240:        }
2.21      frystyk   241:        if (transfer) {
                    242:            HTChunk_puts(chunk, transfer);
                    243:            ptr = HTChunk_data(chunk);
                    244:            for (; *ptr; ptr++)
2.1       frystyk   245:                *ptr = TOLOWER(*ptr);
2.21      frystyk   246:            suff->transfer = HTAtom_for(HTChunk_data(chunk));
2.34    ! kahan     247:            HTChunk_truncate(chunk,0);
2.1       frystyk   248:        }
2.21      frystyk   249:        if (language) {
                    250:            HTChunk_puts(chunk, language);
                    251:            ptr = HTChunk_data(chunk);
                    252:            for (; *ptr; ptr++)
                    253:                *ptr = TOLOWER(*ptr);
                    254:            suff->language = HTAtom_for(HTChunk_data(chunk));
2.34    ! kahan     255:            HTChunk_truncate(chunk,0);
2.21      frystyk   256:        }
                    257:        HTChunk_delete(chunk);
2.1       frystyk   258:        suff->quality = value;
                    259:     }
                    260:     return YES;
                    261: }
                    262: 
                    263: 
                    264: /*     Determine a suitable suffix
                    265: **     ---------------------------
                    266: **  Use the set of bindings to find a suitable suffix (or index)
                    267: **  for a certain combination of language, media type and encoding
                    268: **  given in the anchor.
                    269: **
2.21      frystyk   270: **  Returns a pointer to a suitable suffix string that must be freed 
2.1       frystyk   271: **  by the caller. If more than one suffix is found they are all
                    272: **  concatenated using the first delimiter in HTDelimiters.
                    273: **  If no suffix is found, NULL is returned.
                    274: */
2.11      frystyk   275: PUBLIC char * HTBind_getSuffix (HTParentAnchor * anchor)
2.1       frystyk   276: {
                    277:     int cnt;
2.23      frystyk   278:     HTList * cur;
                    279:     HTChunk * suffix = HTChunk_new(48);
                    280:     char delimiter = *HTDelimiters;
2.30      frystyk   281:     char * ct=NULL, * ce=NULL, * cl=NULL;
2.24      frystyk   282:     HTFormat format = HTAnchor_format(anchor);
                    283:     HTList * encoding = HTAnchor_encoding(anchor);
                    284:     HTList * language = HTAnchor_language(anchor);
2.32      frystyk   285:     if (!HTBindings) HTBind_init();
2.1       frystyk   286:     if (anchor) {
2.31      frystyk   287:        for (cnt=0; cnt<HT_L_HASH_SIZE; cnt++) {
2.1       frystyk   288:            if ((cur = HTBindings[cnt])) { 
                    289:                HTBind *pres;
2.21      frystyk   290:                while ((pres = (HTBind *) HTList_nextObject(cur))) {
2.24      frystyk   291:                    if (!ct && (pres->type && pres->type == format)){
2.30      frystyk   292:                        ct = pres->suffix;
2.24      frystyk   293:                    } else if (!ce && pres->encoding && encoding) {
2.30      frystyk   294:                        HTList * cur_enc = encoding;
                    295:                        HTEncoding pres_enc;
                    296:                        while ((pres_enc = (HTEncoding) HTList_nextObject(cur_enc))) {
                    297:                            if (pres_enc == pres->encoding) {
                    298:                                ce = pres->suffix;
                    299:                                break;
                    300:                            }
                    301:                        }
2.24      frystyk   302:                    } else if (!cl && pres->language && language) {
2.30      frystyk   303:                        HTList * cur_lang = language;
                    304:                        HTLanguage pres_lang;
                    305:                        while ((pres_lang = (HTLanguage) HTList_nextObject(cur_lang))) {
                    306:                            if (pres_lang == pres->language) {
                    307:                                cl = pres->suffix;
                    308:                                break;
                    309:                            }
                    310:                        }
2.1       frystyk   311:                    }
                    312:                }
                    313:            }
2.30      frystyk   314:        }
                    315: 
                    316:        /* Put the found suffixes together */
                    317:        if (ct) {
                    318:            HTChunk_putc(suffix, delimiter);
                    319:            HTChunk_puts(suffix, ct);
                    320:        }
                    321:        if (ce) {
                    322:            HTChunk_putc(suffix, delimiter);
                    323:            HTChunk_puts(suffix, ce);
                    324:        }
                    325:        if (cl) {
                    326:            HTChunk_putc(suffix, delimiter);
                    327:            HTChunk_puts(suffix, cl);
2.1       frystyk   328:        }
                    329:     }
2.23      frystyk   330:     return HTChunk_toCString(suffix);
2.1       frystyk   331: }
                    332: 
2.24      frystyk   333: /*
2.1       frystyk   334: **  Use the set of bindings to find the combination of language,
2.24      frystyk   335: **  media type and encoding of a given object. This information can either be
                    336: **  stored in the anchor obejct or in the response object depending on which
                    337: **  function is called.
2.1       frystyk   338: **
2.21      frystyk   339: **  We comprise here as bindings only can have one language and one encoding.
2.1       frystyk   340: **  If more than one suffix is found they are all searched. The last suffix
                    341: **  has highest priority, the first one lowest. See also HTBind_getFormat()
                    342: */
2.24      frystyk   343: PUBLIC BOOL HTBind_getAnchorBindings (HTParentAnchor * anchor)
2.1       frystyk   344: {
                    345:     BOOL status = NO;
                    346:     double quality=1.0;                  /* @@@ Should we add this into the anchor? */
                    347:     if (anchor) {
2.28      frystyk   348:        char *addr = HTAnchor_address((HTAnchor *) anchor);
2.1       frystyk   349:        char *path = HTParse(addr, "", PARSE_PATH+PARSE_PUNCTUATION);
2.9       frystyk   350:        char *file;
                    351:        char *end;
                    352:        if ((end = strchr(path, ';')) || (end = strchr(path, '?')) ||
                    353:            (end = strchr(path, '#')))
                    354:            *end = '\0';
                    355:        if ((file = strrchr(path, '/'))) {
2.21      frystyk   356:            HTFormat format = NULL;
                    357:            HTEncoding encoding = NULL;
2.22      frystyk   358:            HTEncoding transfer = NULL;
2.21      frystyk   359:            HTLanguage language = NULL;
2.33      frystyk   360:            HTTRACE(BIND_TRACE, "Anchor...... Get bindings for `%s\'\n" _ path);
2.22      frystyk   361:            status = HTBind_getFormat(file, &format, &encoding, &transfer,
2.21      frystyk   362:                                      &language, &quality);
                    363:            if (status) {
                    364:                HTAnchor_setFormat(anchor, format);
2.25      frystyk   365:                HTAnchor_setContentTransferEncoding(anchor, transfer);
2.29      frystyk   366: 
                    367:                 HTAnchor_deleteEncodingAll(anchor);
                    368:                 HTAnchor_addEncoding(anchor, encoding);
                    369: 
                    370:                 HTAnchor_deleteLanguageAll(anchor);
                    371:                 HTAnchor_addLanguage(anchor, language);
2.21      frystyk   372:            }
2.1       frystyk   373:        }
2.27      frystyk   374:         HT_FREE(addr);
                    375:         HT_FREE(path);
2.1       frystyk   376:     }
                    377:     return status;
                    378: }
                    379: 
2.24      frystyk   380: PUBLIC BOOL HTBind_getResponseBindings (HTResponse * response, const char * url)
                    381: {
                    382:     BOOL status = NO;
                    383:     double quality = 1.0;
                    384:     if (response) {
                    385:        char * path = HTParse(url, "", PARSE_PATH + PARSE_PUNCTUATION);
                    386:        char * file;
                    387:        char * end;
                    388:        if ((end = strchr(path, ';')) || (end = strchr(path, '?')) ||
                    389:            (end = strchr(path, '#')))
                    390:            *end = '\0';
                    391:        if ((file = strrchr(path, '/'))) {
                    392:            HTFormat format = NULL;
                    393:            HTEncoding encoding = NULL;
                    394:            HTEncoding transfer = NULL;
                    395:            HTLanguage language = NULL;
2.33      frystyk   396:            HTTRACE(BIND_TRACE, "Response.... Get Bindings for `%s\'\n" _ path);
2.24      frystyk   397:            status = HTBind_getFormat(file, &format, &encoding, &transfer,
                    398:                                      &language, &quality);
                    399:            if (status) {
                    400:                HTResponse_setFormat(response, format);
2.25      frystyk   401:                HTResponse_setContentTransferEncoding(response, transfer);
2.24      frystyk   402:                HTResponse_addEncoding(response, encoding);
                    403: #if 0
                    404:                HTResponse_addLanguage(response, language);
                    405: #endif
                    406:            }
                    407:        }
                    408:        HT_FREE(path);
                    409:     }
                    410:     return status;
                    411: }
2.1       frystyk   412: 
                    413: /*     Determine the content of an file name
                    414: **     -------------------------------------
                    415: **  Use the set of bindings to find the combination of language,
2.21      frystyk   416: **  media type, encoding, and transfer encoding  of a given anchor.
2.1       frystyk   417: **  If more than one suffix is found they are all searched. The last suffix
                    418: **  has highest priority, the first one lowest. See also HTBind_getBindings()
2.10      frystyk   419: **  Either of format, encoding, or language can be NULL
2.1       frystyk   420: **  Returns the format, encoding, and language found
                    421: */
2.21      frystyk   422: PUBLIC BOOL HTBind_getFormat (const char *     filename,
                    423:                              HTFormat *        format,
                    424:                              HTEncoding *      enc,
2.22      frystyk   425:                              HTEncoding *      cte,
2.21      frystyk   426:                              HTLanguage *      lang,
                    427:                              double *          quality)
2.1       frystyk   428: {
                    429:     int sufcnt=0;
                    430:     char *file=NULL;
2.6       frystyk   431: #ifdef HT_REENTRANT
                    432:     char *lasts;                                            /* For strtok_r */
                    433: #endif
2.32      frystyk   434:     if (!HTBindings) HTBind_init();
2.1       frystyk   435:     if (*quality < HT_EPSILON)
                    436:        *quality = 1.0;                            /* Set to a neutral value */
                    437:     StrAllocCopy(file, filename);
                    438:     HTUnEscape(file);                             /* Unescape the file name */
2.6       frystyk   439: #ifdef HT_REENTRANT
                    440:     if (strtok_r(file, HTDelimiters, &lasts)) {         /* Do we have any suffixes? */
                    441: #else
2.1       frystyk   442:     if (strtok(file, HTDelimiters)) {           /* Do we have any suffixes? */
2.6       frystyk   443: #endif /* HT_REENTRANT */
2.1       frystyk   444:        char *suffix;
2.6       frystyk   445: #ifdef HT_REENTRANT
                    446:        while ((suffix=(char*)strtok_r(NULL, HTDelimiters, &lasts)) != NULL) {
                    447: #else
                    448:        while ((suffix=strtok(NULL, HTDelimiters)) != NULL) {
                    449: #endif /* HT_REENTRANT */
2.1       frystyk   450:            HTBind *suff=NULL;
2.31      frystyk   451:            int hash;
                    452:            unsigned char * p;
2.33      frystyk   453:            HTTRACE(BIND_TRACE, "Get Binding. Look for '%s\' " _ suffix);
2.1       frystyk   454:            sufcnt++;
                    455: 
                    456:            /* Select list from hash table */
2.31      frystyk   457:            for (p=suffix, hash=0; *p; p++) {
                    458:                hash = (hash * 3 + TOLOWER(*p)) % HT_L_HASH_SIZE;
                    459:            }
2.1       frystyk   460: 
                    461:            /* Now search list for entries (case or non case sensitive) */
                    462:            if (HTBindings[hash]) {
                    463:                HTList *cur = HTBindings[hash];
                    464:                while ((suff = (HTBind *) HTList_nextObject(cur))) {
                    465:                    if ((HTCaseSen && !strcmp(suff->suffix, suffix)) ||
                    466:                        !strcasecomp(suff->suffix, suffix)) {
2.33      frystyk   467:                        HTTRACE(BIND_TRACE, "Found!\n");
2.10      frystyk   468:                        if (suff->type && format) *format = suff->type;
                    469:                        if (suff->encoding && enc) *enc = suff->encoding;
2.22      frystyk   470:                        if (suff->transfer && cte) *cte = suff->transfer;
2.10      frystyk   471:                        if (suff->language && lang) *lang = suff->language;
2.1       frystyk   472:                        if (suff->quality > HT_EPSILON)
                    473:                            *quality *= suff->quality;
                    474:                        break;
                    475:                    }
                    476:                }
                    477:            }
                    478:            if (!suff) {        /* We don't have this suffix - use default */
2.33      frystyk   479:                HTTRACE(BIND_TRACE, "Not found - use default for \'*.*\'\n");
2.10      frystyk   480:                if (format) *format = unknown_suffix.type;
                    481:                if (enc) *enc = unknown_suffix.encoding;
2.21      frystyk   482:                if (cte) *cte = unknown_suffix.transfer;
2.10      frystyk   483:                if (lang) *lang = unknown_suffix.language;
2.1       frystyk   484:                *quality = unknown_suffix.quality;
                    485:            }
                    486:        } /* while we still have suffixes */
                    487:     }
                    488:     if (!sufcnt) {             /* No suffix so use default value */
2.33      frystyk   489:        HTTRACE(BIND_TRACE, "Get Binding. No suffix found - using default '%s\'\n" _ filename);
2.10      frystyk   490:        if (format) *format = no_suffix.type;
                    491:        if (enc) *enc = no_suffix.encoding;
2.21      frystyk   492:        if (cte) *cte = no_suffix.transfer;
2.10      frystyk   493:        if (lang) *lang = no_suffix.language;
2.1       frystyk   494:        *quality = no_suffix.quality;
                    495:     }
2.33      frystyk   496:     HTTRACE(BIND_TRACE, "Get Binding. Result for '%s\' is: type='%s\', encoding='%s\', cte='%s\', language='%s\' with quality %.2f\n" _ 
                    497:                filename _ 
                    498:                (format && *format) ? HTAtom_name(*format) : "unknown" _ 
                    499:                (enc && *enc) ? HTAtom_name(*enc) : "unknown" _ 
                    500:                (cte && *cte) ? HTAtom_name(*cte) : "unknown" _ 
                    501:                (lang && *lang) ? HTAtom_name(*lang) : "unknown" _ 
2.1       frystyk   502:                *quality);
2.17      frystyk   503:     HT_FREE(file);
2.1       frystyk   504:     return YES;
                    505: }
                    506: 

Webmaster