home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * The contents of this file are subject to the Netscape Public License
- * Version 1.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
- /*
- * determine the format of a file
- *
- * Started with Rob's code and
- * then hacked up by Lou.
- */
-
- #include "mkutils.h"
- #include "mkformat.h"
-
- static char *net_default_types [] = {
- # include "mktypes.h"
- 0 };
-
-
- /* func proto
- */
- PRIVATE int cinfo_parse_mcc_line(char *line, Bool is_external,
- Bool is_local, char **src_string);
- PRIVATE int net_cinfo_merge(char *fn, Bool is_local);
-
- /* ----------------------------- Static data ------------------------------ */
-
- /* The master database of content info (linked list) */
- PRIVATE XP_List * NET_ciMasterList=0;
-
- /*
- * cinfo.c: Content Information for a file, i.e. its type, etc.
- *
- * See cinfo.h for full details.
- *
- * Rob McCool
- */
-
- /* init types loads standard types so that a config file
- * is not required and can also read
- * a mime types file if filename is passed in non empty and
- * non null
- *
- * on each call to NET_InitFileFormatTypes the extension list
- * will be completely free'd and rebuilt.
- *
- * if you pass in NULL filename pointers they will not be
- * attempted to be read
- */
- PUBLIC int
- NET_InitFileFormatTypes(char * personal_file, char *global_file)
- {
- /* init the data structures
- */
- int i = 0;
-
- #ifdef XP_UNIX
- NET_CleanupFileFormat(NULL);
- #else /* !XP_UNIX */
- NET_CleanupFileFormat();
- #endif /* !XP_UNIX */
- NET_ciMasterList = XP_ListNew();
-
- TRACEMSG((" Setting up File Format code"));
-
- while (net_default_types [i])
- {
- char buf [256];
- char *src_string = 0;
- XP_STRCPY (buf, net_default_types [i]);
- StrAllocCopy(src_string, buf);
- cinfo_parse_mcc_line (buf, FALSE, FALSE, &src_string); /* destroys buf */
- i++;
- if (src_string) XP_FREE(src_string);
-
- }
-
- /* read the external mime types file and return */
- if(global_file)
- {
- net_cinfo_merge(global_file, FALSE);
- }
- if(personal_file)
- {
- net_cinfo_merge(personal_file, TRUE);
- }
-
- return(0);
- }
-
- /* -------------------------- Module structures --------------------------- */
-
-
-
- static NET_cinfo default_cinfo_type = {
- #ifdef MCC_PROXY
- MAGNUS_INTERNAL_UNKNOWN,
- #else
- UNKNOWN_CONTENT_TYPE,
- #endif
- 0,
- 0,
- 0,
- 0,
- 0,
- TRUE,
- 0
- };
-
- #ifdef NOT_USED
- static NET_cinfo default_cinfo_enc = {
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 1,
- 0
- };
- #endif /* NOT_USED */
-
- /* ------------------------------ _cinfo_free ------------------------------ */
-
-
- PRIVATE void
- _cinfo_free(NET_cinfo *ci)
- {
-
- FREEIF(ci->type);
- FREEIF(ci->encoding);
- FREEIF(ci->language);
- FREEIF(ci->desc);
- FREEIF(ci->icon);
- FREEIF(ci->alt_text);
- }
-
-
- /* ---------------------------- NET_cdataCreate ---------------------------- */
-
-
- PUBLIC NET_cdataStruct *
- NET_cdataCreate(void)
- {
- NET_cdataStruct *cd = XP_NEW(NET_cdataStruct);
-
- if(!cd)
- return(NULL);
-
- memset(cd, 0, sizeof(NET_cdataStruct));
-
- return cd;
- }
-
-
- /* ----------------------------- NET_cdataFree ---------------------------- */
-
-
- PUBLIC void
- NET_cdataFree(NET_cdataStruct *cd)
- {
- register int x;
-
- if(cd->exts)
- {
- for(x = 0; x < cd->num_exts; x++)
- XP_FREE(cd->exts[x]);
- XP_FREE(cd->exts);
- }
- if ( cd->src_string )
- XP_FREE(cd->src_string);
-
- _cinfo_free(&cd->ci);
-
- XP_FREE(cd);
- cd = 0;
- }
-
- /* ---------------------------- NET_cdataAdd ------------------------------- */
-
- PUBLIC void
- NET_cdataAdd(NET_cdataStruct *cd)
- {
- XP_ListAddObject(NET_ciMasterList, cd);
- }
-
- /* ---------------------------- NET_cdataRemove ---------------------------- */
-
- PUBLIC void
- NET_cdataRemove(NET_cdataStruct *cd)
- {
- XP_ListRemoveObject(NET_ciMasterList, cd);
-
- NET_cdataFree(cd);
- }
-
- PUBLIC NET_cdataStruct*
- NET_cdataExist(NET_cdataStruct *old_cd )
- {
- NET_cdataStruct *found_cd = NULL;
- NET_cdataStruct *cd = NULL;
- XP_List *infoList;
-
- infoList = cinfo_MasterListPointer();
-
- if ( !infoList )
- return found_cd;
-
- while ((cd= (NET_cdataStruct *)XP_ListNextObject(infoList)) != NULL)
- {
- if ( old_cd->ci.type &&
- cd->ci.type &&
- !strcasecomp(old_cd->ci.type, cd->ci.type))
- {
- /* found matching type */
- found_cd = cd;
- break;
- }
- else if ( !old_cd->ci.type &&
- old_cd->ci.encoding &&
- cd->ci.encoding &&
- !strcasecomp(old_cd->ci.encoding, cd->ci.encoding))
- {
- /* found matching encoding */
- found_cd = cd;
- break;
- }
- }
- return found_cd;
- }
-
- #if 0
- PRIVATE
- Bool
- net_cdata_exist_ext( char *ext, NET_cdataStruct *cd )
- {
- Bool not_found = FALSE;
- int n;
-
- if (!cd->exts) return not_found;
-
- for ( n = 0; n < cd->num_exts; n++ )
- {
- if (!strcasecomp(cd->exts[n], ext) )
- {
- not_found = TRUE;
- break;
- }
- }
- return not_found;
- }
- #endif
-
- /* ---------------------------- net_cdata_new_ext ----------------------------- */
-
-
- PRIVATE
- void
- net_cdata_new_ext(char *ext, NET_cdataStruct *cd)
- {
- int n = cd->num_exts;
-
- cd->exts = (char **) (n ? XP_REALLOC(cd->exts, (n+1)*sizeof(char *))
- : XP_ALLOC(sizeof(char *)));
-
- if(!cd->exts)
- return;
-
- cd->exts[n] = 0;
- StrAllocCopy(cd->exts[n], ext);
- cd->num_exts = ++n;
- }
-
-
- /* ----------------------------- cinfo_merge ------------------------------ */
-
-
- int _cinfo_parse_mimetypes(XP_File fp, char *t, Bool is_local);
- int _cinfo_parse_mcc(XP_File fp, char *t, Bool is_local);
-
- PRIVATE int
- net_cinfo_merge(char *fn, Bool is_local)
- {
- XP_File fp;
- char t[CINFO_MAX_LEN];
- int ret;
-
- TRACEMSG(("\n\nnet_cinfo_merge: called with %s\n\n\n", fn));
- if(!(fp = XP_FileOpen(fn ? fn : "mime.types", xpMimeTypes, XP_FILE_READ))) {
- TRACEMSG(("cinfo.c: File open failed"));
- return -1;
- }
-
- TRACEMSG(("Reading mime.types file"));
-
- if(!(XP_FileReadLine(t, CINFO_MAX_LEN, fp))) {
- TRACEMSG(("cinfo.c: Mime types file is empty"));
- return -1;
-
- } else if(!strncmp(t, MCC_MT_MAGIC, MCC_MT_MAGIC_LEN) ||
- !strncmp(t, NCC_MT_MAGIC, NCC_MT_MAGIC_LEN)) {
- /* Look for magic number */
- TRACEMSG(("Loading MCC mime types file"));
- ret = _cinfo_parse_mcc(fp, t, is_local);
-
- } else {
- TRACEMSG(("Loading old NCSA mime types file"));
- ret = _cinfo_parse_mimetypes(fp, t, is_local);
- }
-
- XP_FileClose(fp);
- return ret;
- }
-
-
- static NET_cinfo *
- net_cinfo_find_type_or_encoding (char *uri, XP_Bool type_p)
- {
- char *start = uri;
- char *end, *c;
- NET_cinfo *result = &default_cinfo_type;
- XP_Bool saw_encoding = FALSE;
-
- c = XP_STRRCHR (uri, '/');
- if (c) start = c;
-
- end = start + XP_STRLEN (start);
- c = XP_STRRCHR (start, '?');
- if (c) end = c;
- c = XP_STRRCHR (start, '#');
- if (c && c < end) end = c;
-
- AGAIN:
- for (c = end - 1; c >= uri; c--)
- if (*c == '/' || *c == '.')
- break;
-
- if (c >= uri && *c == '.')
- {
- int32 i;
- XP_List *list_ptr = NET_ciMasterList;
- NET_cdataStruct *cdata;
- uint32 ext_len;
- start = c + 1;
- ext_len = end - start;
- while ((cdata = (NET_cdataStruct *) XP_ListNextObject (list_ptr)) != NULL)
- for (i = cdata->num_exts - 1; i >= 0; i--)
- if (XP_STRLEN (cdata->exts[i]) == ext_len &&
- !strncasecomp (start, cdata->exts [i], ext_len))
- {
- if (type_p && cdata->ci.type)
- {
- /* We are looking for a type, and this extension represents
- one. Since this is the last one in the path (since we
- start from the end and go backwards) we're done now.
- */
- return &cdata->ci;
- }
- else if (type_p && cdata->ci.encoding)
- {
- /* We are looking for a type, and this extension represents
- an encoding. Skip over it and look for the next
- extension earlier in the file name (as that may turn out
- to be a type which we should take instead.)
-
- But, if this is the second encoding we've seen, then the
- final content-type is irrelevant, because we have no
- mechanism for decoding multiple encodings. So, while
- "foo.gif.gz" gets type gif, encoding gz, "foo.tar.gz.uu"
- gets type unknown, encoding uu. This is especially
- important for the types that we put on outgoing MIME
- attachments.
- */
- if (saw_encoding)
- return &default_cinfo_type;
- saw_encoding = TRUE;
- end = start - 1;
- goto AGAIN;
- }
- else if (cdata->ci.type)
- {
- XP_ASSERT (!type_p);
- /* We are looking for an encoding, and this extension
- represents a content-type. That means that there are
- no encodings after the type in this file name, and
- therefore it has no encoding (an encoding which occurs
- before a type doesn't count: "foo.uu.gif" should be of
- type gif with no encoding, not encoding uu. Also,
- "foo.uu.unknown" should be of an unknown type with no
- encoding; and "foo.uu.gif.Z" should be type gif,
- encoding compress.)
- */
- return &default_cinfo_type;
- }
- else if (cdata->ci.encoding)
- {
- XP_ASSERT (!type_p);
- /* We are looking for an encoding, and this extension
- represents one. It is the last one in the file name,
- so now we're done. ("foo.gz.uu" gets encoding "uu"
- instead of "gz".)
- */
- return &cdata->ci;
- }
- /* Else, this cdata is junk, or something... Skip it. */
- }
- }
-
- return (result);
- }
-
-
- PUBLIC NET_cinfo *
- NET_cinfo_find_type (char *uri)
- {
- return net_cinfo_find_type_or_encoding (uri, TRUE);
- }
-
- PUBLIC NET_cinfo *
- NET_cinfo_find_enc (char *uri)
- {
- return net_cinfo_find_type_or_encoding (uri, FALSE);
- }
-
-
- #if defined(DEBUG) && defined(XP_UNIX)
- void
- print_mime_types()
- {
- int32 i;
- XP_List *list_ptr = NET_ciMasterList;
- NET_cdataStruct *cdata;
-
- fprintf(stderr, "\n---------\n");
-
- while ((cdata = (NET_cdataStruct *) XP_ListNextObject (list_ptr)))
- {
- fprintf (stderr, "%s%s%s (%s; %s):",
- (cdata->ci.type ? cdata->ci.type : ""),
- (cdata->ci.type && *cdata->ci.type &&
- cdata->ci.encoding && *cdata->ci.encoding
- ? "+" : ""),
- (cdata->ci.encoding ? cdata->ci.encoding : ""),
- (cdata->ci.desc ? cdata->ci.desc : "no desc"),
- (cdata->ci.icon ? cdata->ci.icon : "no icon"));
-
- for (i = cdata->num_exts - 1; i >= 0; i--)
- fprintf (stderr, " %s", cdata->exts[i]);
- fprintf (stderr, "\n");
- }
- }
- #endif /* DEBUG && XP_UNIX */
-
-
- /* return a cdataStruct from a mime_type
- */
- PRIVATE NET_cdataStruct *
- NET_cinfo_find_cdata_by_type(char *mime_type)
- {
- NET_cdataStruct *cdata;
- XP_List * list_ptr;
-
- if(!mime_type)
- return(NULL);
-
- list_ptr = NET_ciMasterList;
- while((cdata = (NET_cdataStruct *) XP_ListNextObject(list_ptr)) != NULL)
- {
- if(cdata->ci.type && !strcasecomp(mime_type, cdata->ci.type))
- return(cdata);
- }
-
- return(NULL);
- }
-
- /* return a cinfo from a mime_type
- */
- PUBLIC NET_cinfo *
- NET_cinfo_find_info_by_type(char *mime_type)
- {
- NET_cdataStruct *cdata = NET_cinfo_find_cdata_by_type(mime_type);
-
- if(cdata)
- return(&cdata->ci);
- else
- return(NULL);
- }
-
-
- /* --------------------------- cinfo_find_ext ------------------------------ */
-
- /* returns an extension (without the ".") for
- * a given mime type.
- *
- * If no match is found NULL is returned.
- *
- * Do not free the returned char *
- */
- PUBLIC char *
- NET_cinfo_find_ext(char *mime_type)
- {
- NET_cdataStruct *cdata = NET_cinfo_find_cdata_by_type(mime_type);
-
- if(cdata)
- return(cdata->exts[0]);
- else
- return(NULL);
- }
-
-
- /* ----------------------------- File parsers ----------------------------- */
-
-
- #if 0
- static void
- net_build_string(char** curr_str, char *new_str)
- {
- int len;
-
- if ( new_str && *new_str )
- {
- if (!*curr_str )
- {
- len = strlen(new_str);
- *curr_str = (char *)XP_ALLOC((len+1)*sizeof(char));
- sprintf(*curr_str, "%s", new_str);
- }
- else
- {
- len = strlen(new_str) + strlen(*curr_str);
- *curr_str = (char *)XP_ALLOC((len+1)*sizeof(char));
- sprintf(*curr_str, "%s%s", *curr_str, new_str);
- }
- }
- }
- #endif /* 0 */
-
- /* Parse old NCSA mime.types files */
-
- int
- _cinfo_parse_mimetypes(XP_File fp, char *t, Bool is_local)
- {
- char *ext, *end;
- NET_cdataStruct *cd;
- char *src_string = 0;
-
- /* t is already filled. */
- while(1) {
-
- if ( src_string )
- {
- src_string = XP_AppendStr(src_string, t);
- }
- else
- {
- StrAllocCopy(src_string, t);
- }
-
- while((*t) && (XP_IS_SPACE(*t)))
- ++t;
-
- if(*t && (*t != '#')) {
- ext = t;
- while((*ext) && (!XP_IS_SPACE(*ext))) ++ext;
- if((*ext))
- *ext++ = '\0';
-
- cd = NULL;
-
- while((*ext)) {
- while((*ext) && (XP_IS_SPACE(*ext))) ++ext;
-
- if((*ext)) {
- if(!cd) {
- cd = NET_cdataCreate();
- if(!cd)
- return(-1);
- }
-
- cd->is_local = is_local;
- cd->is_external = FALSE; /* don't count these as external types */
-
- cd->is_modified = FALSE; /* default is not modified in any way */
- end = ext+1;
- while((*end) && (!XP_IS_SPACE(*end))) ++end;
- if(*end)
- *end++ = '\0';
- net_cdata_new_ext(ext, cd);
- ext = end;
- }
- }
- if(cd) {
- NET_cdataStruct *old_cd = NULL;
- FREEIF(cd->ci.type);
- cd->ci.type = 0;
- StrAllocCopy(cd->ci.type, t);
- FREEIF(cd->src_string);
- StrAllocCopy(cd->src_string, src_string);
-
- if ( (old_cd = NET_cdataExist(cd)) != NULL)
- /* Found an old one, remove it first */
- {
- /* Extra hack: if the old one defined an icon, or a desc,
- and the new one does not, carry those over. */
- char *icon = (old_cd->ci.icon && !cd->ci.icon
- ? XP_STRDUP(old_cd->ci.icon)
- : 0);
- char *desc = (old_cd->ci.desc && !cd->ci.desc
- ? XP_STRDUP(old_cd->ci.desc)
- : 0);
-
- NET_cdataRemove(old_cd);
- old_cd = 0;
-
- if (icon) cd->ci.icon = icon;
- if (desc) cd->ci.desc = desc;
- }
- /* Not an existing type, we add a new one */
- NET_cdataAdd(cd);
- XP_FREE(src_string);
- src_string = 0;
- }
- }
- if(!(XP_FileReadLine(t, CINFO_MAX_LEN, fp)))
- break;
- }
- return 0;
- }
-
-
- PUBLIC int
- cinfo_parse_mcc_line(char *line, Bool is_external, Bool is_local,
- char **src_string)
- {
- int ln = 1;
- char *t, *u, *v, *name, *value, c;
- NET_cdataStruct *cd;
-
- if(line && *line)
- {
- cd = NULL;
-
- t = line;
-
- if((*t) && (*t != '#')) {
- while(1) {
-
- while(*t && XP_IS_SPACE(*t)) ++t;
- if(!(*t))
- break;
- name = t;
-
- while(*t && (*t != '=')) ++t;
- if(!(*t)) {
- TRACEMSG(("line %d: name without =", ln));
- if(cd)
- NET_cdataFree(cd);
- return (-1);
- }
- for(u = t - 1; XP_IS_SPACE(*u); --u)
- ;
- *(u+1) = '\0'; /* terminate name */
- ++t;
- while(*t && (*t != '\"') && (XP_IS_SPACE(*t))) ++t;
- if(!(*t)) {
- TRACEMSG(("line %d: empty value", ln));
- if(cd)
- NET_cdataFree(cd);
- return (-1);
- }
- if(*t == '\"') {
- value = ++t;
- while(*t && (*t != '\"')) ++t;
- if(!(*t)) {
- TRACEMSG(("line %d: missing closing quotes", ln));
- if(cd)
- NET_cdataFree(cd);
- return (-1);
- }
- }
- else {
- value = t;
- while(*t && (!XP_IS_SPACE(*t))) ++t;
- /* null t is okay */
- }
- if(*t) *t++ = '\0';
- if(!cd) {
- cd = NET_cdataCreate();
- if(!cd)
- return(0);
-
- cd->is_external = is_external;
- cd->is_modified = FALSE; /* default is "not modified yet!*/
- cd->is_local = is_local;
- FREEIF(cd->src_string);
- cd->src_string = *src_string;
- *src_string = 0;
- }
-
- if(!strcasecomp(name, "type")) {
- FREEIF(cd->ci.type);
- cd->ci.type = 0;
- StrAllocCopy(cd->ci.type, value);
-
- } else if(!strcasecomp(name, "enc")) {
- FREEIF(cd->ci.encoding);
- cd->ci.encoding = 0;
- StrAllocCopy(cd->ci.encoding, value);
-
- } else if(!strcasecomp(name, "lang")) {
- FREEIF(cd->ci.language);
- cd->ci.language = 0;
- StrAllocCopy(cd->ci.language, value);
-
- } else if(!strcasecomp(name, "desc")) {
- FREEIF(cd->ci.desc);
- cd->ci.desc = 0;
- StrAllocCopy(cd->ci.desc, value);
-
- } else if(!strcasecomp(name, "alt")) {
- FREEIF(cd->ci.alt_text);
- cd->ci.alt_text = 0;
- StrAllocCopy(cd->ci.alt_text, value);
-
- } else if(!strcasecomp(name, "icon")) {
- FREEIF(cd->ci.icon);
- cd->ci.icon = 0;
- StrAllocCopy(cd->ci.icon, value);
-
- } else if(!strcasecomp(name, "exts")) {
- u = value;
- while(1) {
- v = u;
- while(*u && (*u != ',')) ++u;
- c = *u;
- *u = '\0';
- net_cdata_new_ext(v, cd);
- if(c)
- ++u;
- else
- break;
- }
- }
- }
-
- /* Some people like to be clever and use mime.types entries
- like "type=application/x-tar enc=x-gzip exts=tgz",
- but unfortunately, that doesn't even come close to working,
- and will override (delete) the existing tar entry, causing
- disaster of various forms.
-
- So, if this line defines *both* "type" and "enc", just throw
- it away.
- */
- if (cd &&
- cd->ci.type && *cd->ci.type &&
- cd->ci.encoding && *cd->ci.encoding)
- {
- NET_cdataFree(cd);
- cd = 0;
- }
-
- if(cd)
- {
- NET_cdataStruct *old_cd = NULL;
-
- if ((old_cd = NET_cdataExist(cd)) != NULL)
- /* Found an old one, remove it first */
- {
- /* Extra hack: if the old one defined an icon, or a desc,
- and the new one does not, carry those over. */
- char *icon = (old_cd->ci.icon && !cd->ci.icon
- ? XP_STRDUP(old_cd->ci.icon)
- : 0);
- char *desc = (old_cd->ci.desc && !cd->ci.desc
- ? XP_STRDUP(old_cd->ci.desc)
- : 0);
-
- NET_cdataRemove(old_cd);
- old_cd = 0;
-
- if (icon) cd->ci.icon = icon;
- if (desc) cd->ci.desc = desc;
- }
- NET_cdataAdd(cd);
- }
- }
-
- ln++;
- }
- return 0; /* #### what should return value be? */
- }
-
-
- /* Parse sexy new MCC mime types files */
- int
- _cinfo_parse_mcc(XP_File fp, char *line, Bool is_local)
- {
- char *end;
- char *src_string = 0;
-
- TRACEMSG(("mime.types file is MCC type"));
-
- /* t is already filled. */
-
- if ( !src_string )
- StrAllocCopy(src_string, line);
- else
- {
- src_string = XP_AppendStr(src_string, line);
- }
- while(1) {
- cinfo_parse_mcc_line(line, TRUE, is_local, &src_string);
-
- if(!(XP_FileReadLine(line, CINFO_MAX_LEN, fp)))
- break;
-
- if ( !src_string )
- StrAllocCopy(src_string, line);
- else
- {
- src_string = XP_AppendStr(src_string, line);
- }
- /* assemble extended lines
- */
- end = &line[XP_STRLEN(line)-1];
- while (end > line && (*end == CR || *end == LF))
- end--;
- while(*end == '\\')
- {
- *end = ' ';
- end++;
-
- if(!(XP_FileReadLine(end, CINFO_MAX_LEN-(end-line), fp)))
- break;
-
- if ( !src_string )
- StrAllocCopy(src_string, end);
- else
- src_string = XP_AppendStr(src_string, end);
-
-
- end = &end[XP_STRLEN(end)-1];
- while (end > line && (*end == CR || *end == LF))
- end--;
-
- if((end-line)+2 >= CINFO_MAX_LEN)
- break;
- }
- }
-
- return 0;
- }
-
- /* return the master cdata List pointer
- */
- PUBLIC XP_List *
- cinfo_MasterListPointer()
- {
- return(NET_ciMasterList);
- }
-
- /* fills in cdata structure
- *
- * if cdata for a given type do not exist, create a new one
- */
- PUBLIC void
- NET_cdataCommit(char * mimeType, char * cdataString)
- {
- XP_List * extensionList;
- NET_cdataStruct * matchInfo = NULL;
- int listSize;
- int i;
-
- extensionList = cinfo_MasterListPointer();
- if (!extensionList)
- {
- NET_ciMasterList = XP_ListNew();
- extensionList = cinfo_MasterListPointer(); /* Lou help me out here,
- create the list and
- matchInfo */
- }
- if (!extensionList)
- return;
-
- listSize = XP_ListCount(extensionList);
- for (i = 1; i<=listSize; i++)
- {
- NET_cdataStruct * cinfo =
- (NET_cdataStruct *)XP_ListGetObjectNum(extensionList, i);
- if (cinfo &&
- cinfo->ci.type &&
- (strcasecomp(mimeType, cinfo->ci.type) == 0))
- {
- int j;
- matchInfo = cinfo;
- for ( j= 0; j< matchInfo->num_exts; j++) /* Free 'em all */
- XP_FREE((char*)matchInfo->exts[j]);
- XP_FREE(matchInfo->exts);
- matchInfo->exts = NULL;
- break;
- }
- }
-
- if (matchInfo == NULL)
- {
- matchInfo = NET_cdataCreate();
- if (matchInfo == NULL)
- {
- return;
- }
- else
- {
- FREEIF(matchInfo->ci.type);
- matchInfo->ci.type = 0;
- StrAllocCopy(matchInfo->ci.type, mimeType);
- }
- NET_cdataAdd(matchInfo);
-
- }
- /* Found the right type */
- {
- char newExtension[30]; /* extension limit is 30 chars */
- char * citer;
- int newExIndex = 0;
- XP_BZERO(newExtension, sizeof(newExtension));
- citer = cdataString;
- newExtension[0] = 0;
- matchInfo->num_exts = 0;
- matchInfo->exts = (char**)XP_ALLOC(10);
- memset(newExtension, 0, 30);
- if (matchInfo->exts == NULL)
- return;
- while (*citer != 0) /* Parse the string. Skip all non-c*/
- {
- if (isalnum(*citer) && (newExIndex < 29)) /* XP_IS_ALPHA(*citer) */
- newExtension[newExIndex++] = *citer;
- else if (XP_STRLEN(newExtension) > 0)
- {
- char * newString = NULL;
- newExtension[newExIndex] = 0;
- StrAllocCopy(newString, newExtension);
- matchInfo->num_exts++;
- matchInfo->exts =
- (char**)XP_REALLOC(matchInfo->exts,
- matchInfo->num_exts * sizeof(void*));
- matchInfo->exts[matchInfo->num_exts-1] = newString;
- newExIndex = 0;
- newExtension[0] = 0;
- }
- citer++;
- }
- /* commit the last extension, if there was one */
- if (XP_STRLEN(newExtension) > 0)
- {
- char * newString = NULL;
- newExtension[newExIndex] = 0;
- StrAllocCopy(newString, newExtension);
- matchInfo->num_exts++;
- matchInfo->exts =
- (char**)XP_REALLOC(matchInfo->exts,
- matchInfo->num_exts * sizeof(void*));
- matchInfo->exts[matchInfo->num_exts-1] = newString;
- }
- }
- }
-
-
- PUBLIC XP_Bool
- NET_IsOldMimeTypes (XP_List *masterList)
- {
- NET_cdataStruct *cd;
-
- while((cd = XP_ListNextObject(masterList)) != NULL)
- {
- if ( cd->is_local && !cd->is_external )
- { /* This means that this is a old mime types */
- return TRUE;
- }
- }
- return FALSE;
- }
-
- #ifndef XP_UNIX
- static void
- net_Real_CleanupFileFormat(char *filename, Bool file_not_open)
- {
- NET_cdataStruct * cdata;
- XP_File fp = 0;
- int len = 0;
- XP_Bool failed = FALSE;
- char buffer[512];
- int i;
-
- if(!NET_ciMasterList)
- return;
-
- /* Need to remove from the end so that the next time
- around, the file will be loaded up into a list in
- the consistent way */
- while(!failed && ((cdata = (NET_cdataStruct *)XP_ListRemoveEndObject(NET_ciMasterList)) != NULL))
- {
-
- if(file_not_open &&
- (cdata->is_external|| cdata->is_modified))
- {
- /* open file
- * if it doesn't open we won't try again
- */
- fp = XP_FileOpen(filename? filename : "mime.types",
- xpMimeTypes, XP_FILE_WRITE);
- TRACEMSG(("Writing mime types file..."));
- file_not_open = FALSE;
-
- if(fp)
- {
- PR_snprintf(buffer, sizeof(buffer), "#\
- --Netscape Communications Corporation MIME Information\n#\
- Do not delete the above line. It is used to identify the file type.\n#\n");
- len = XP_FileWrite(buffer, strlen(buffer), fp);
- if (len != (int) strlen(buffer))
- failed = TRUE;
- }
- }
-
- /* Save out the modfied entries as well */
- /* cdata might be modified in FE */
-
- if((cdata->is_external||cdata->is_modified) && fp)
- {
- if(!failed && cdata->ci.type)
- {
- PR_snprintf(buffer, sizeof(buffer), "type=%.500s ",
- cdata->ci.type);
- len = XP_FileWrite(buffer, strlen(buffer), fp);
- if (len != (int) strlen(buffer))
- failed = TRUE;
- }
-
- if(!failed && cdata->ci.encoding)
- {
- PR_snprintf(buffer, sizeof(buffer), "enc=%.500s ",
- cdata->ci.encoding);
- len = XP_FileWrite(buffer, strlen(buffer), fp);
- if (len != (int) strlen(buffer))
- failed = TRUE;
- }
-
- if(!failed && (cdata->num_exts > 0))
- {
- PR_snprintf(buffer, sizeof(buffer), "exts=%.500s",
- cdata->exts[0]);
- len = XP_FileWrite(buffer, strlen(buffer), fp);
- if (len != (int) strlen(buffer))
- failed = TRUE;
-
- for(i=1; !failed, i<cdata->num_exts; i++)
- {
- PR_snprintf(buffer, sizeof(buffer), ",%.500s",
- cdata->exts[i]);
- len = XP_FileWrite(buffer, strlen(buffer), fp);
- if (len != (int) strlen(buffer))
- failed = TRUE;
- }
-
- PR_snprintf(buffer, sizeof(buffer), " ");
- len = XP_FileWrite(buffer, strlen(buffer), fp);
- if (len != (int) strlen(buffer))
- failed = TRUE;
- }
-
- if(!failed && cdata->ci.icon)
- {
- PR_snprintf(buffer, sizeof(buffer), "icon=\"%.500s\" ",
- cdata->ci.icon);
- len = XP_FileWrite(buffer, strlen(buffer), fp);
- if (len != (int) strlen(buffer))
- failed = TRUE;
- }
-
- if(!failed && cdata->ci.desc)
- {
- PR_snprintf(buffer, sizeof(buffer), "desc=\"%.500s\" ",
- cdata->ci.desc);
- len = XP_FileWrite(buffer, strlen(buffer), fp);
- if (len != (int) strlen(buffer))
- failed = TRUE;
- }
-
- if(!failed && cdata->ci.alt_text)
- {
- PR_snprintf(buffer, sizeof(buffer), "alt=\"%.500s\" ",
- cdata->ci.alt_text);
- len = XP_FileWrite(buffer, strlen(buffer), fp);
- if (len != (int) strlen(buffer))
- failed = TRUE;
- }
-
- PR_snprintf(buffer, sizeof(buffer), "%c", LF);
- len = XP_FileWrite(buffer, strlen(buffer), fp);
- if (len != (int) strlen(buffer))
- failed = TRUE;
- }
-
- /* free the data
- */
- NET_cdataFree(cdata);
- }
-
- XP_ListDestroy(NET_ciMasterList);
- NET_ciMasterList = 0;
-
- if(!file_not_open && fp)
- XP_FileClose(fp);
- /* This function should really return a return code, and handle any errors */
-
- }
- #endif /* XP_UNIX */
-
- #ifdef XP_UNIX
- PUBLIC void
- NET_CleanupFileFormat(char *filename)
- {
- NET_cdataStruct *cdata;
- XP_File fp = 0;
- int len = 0;
- XP_Bool failed = FALSE;
- Bool file_open = FALSE;
- XP_List *modifiedList = NULL;
- char buffer[512];
- Bool first = TRUE;
-
- if ( !NET_ciMasterList ) return;
-
- if ( filename )
- {
- fp = XP_FileOpen(filename, xpMimeTypes, XP_FILE_WRITE);
- /* Need to remove from the end so that the next time
- around, the file will be loaded up into a list in
- the consistent way */
-
- if ( fp )
- {
- file_open = TRUE;
- modifiedList = XP_ListNew();
- while((cdata = (NET_cdataStruct *) XP_ListRemoveEndObject(NET_ciMasterList)))
- {
- if ( cdata->is_local )
- {
- if ( first && !NET_IsOldMimeTypes(NET_ciMasterList) )
- {
- first = FALSE;
- if (cdata->src_string && *cdata->src_string &&
- strncmp(cdata->src_string, MCC_MT_MAGIC,
- MCC_MT_MAGIC_LEN) &&
- strncmp(cdata->src_string, NCC_MT_MAGIC,
- NCC_MT_MAGIC_LEN))
- {
- /* Write out standard new mime type header info */
- PR_snprintf(buffer, sizeof(buffer),
- "#\
- --Netscape Communications Corporation MIME Information\n#\
- Do not delete the above line. It is used to identify the file type.\n#\n");
- len = XP_FileWrite(buffer, strlen(buffer), fp);
- if (len != (int) strlen(buffer))
- failed = TRUE;
- }
- }
- if (!failed && cdata->src_string && *cdata->src_string )
- {
- len = XP_FileWrite(cdata->src_string,
- strlen(cdata->src_string), fp);
-
- if (cdata->src_string[strlen(cdata->src_string)-1] != '\n')
- len = XP_FileWrite("\n", strlen("\n"), fp);
- }
- NET_cdataFree(cdata);
-
- }
- else if ( cdata->is_modified )
- XP_ListAddObject(modifiedList, cdata);
- else
- NET_cdataFree(cdata);
-
- }
-
- while (!failed && (cdata = (NET_cdataStruct *) XP_ListRemoveEndObject(modifiedList)))
- {
-
- if ( first && !NET_IsOldMimeTypes(NET_ciMasterList) )
- {
- first = FALSE;
- if (cdata->src_string && *cdata->src_string &&
- strncmp(cdata->src_string, MCC_MT_MAGIC,
- MCC_MT_MAGIC_LEN) &&
- strncmp(cdata->src_string, NCC_MT_MAGIC,
- NCC_MT_MAGIC_LEN))
- {
- /* Write out standard new mime type header info */
- PR_snprintf(buffer, sizeof(buffer),
- "#\
- --Netscape Communications Corporation MIME Information\n#\
- Do not delete the above line. It is used to identify the file type.\n#\n");
- len = XP_FileWrite(buffer, strlen(buffer), fp);
- if (len != (int) strlen(buffer))
- failed = TRUE;
-
- }
- }
-
- if (!failed && cdata->src_string && *cdata->src_string )
- {
- len = XP_FileWrite(cdata->src_string,
- strlen(cdata->src_string), fp);
- if (len != (int) strlen(cdata->src_string))
- failed = TRUE;
- if ( cdata->src_string[strlen(cdata->src_string)-1] != '\n')
- {
- len = XP_FileWrite("\n", strlen("\n"), fp);
- if (len != (int) strlen("\n"))
- failed = TRUE;
- }
- }
-
- NET_cdataFree(cdata);
- }
- XP_FileClose(fp);
- }
- }
- else /* Clean up each node before deleting the root node */
- {
- while((cdata = (NET_cdataStruct *) XP_ListRemoveEndObject(NET_ciMasterList)))
- NET_cdataFree(cdata);
- }
- XP_ListDestroy(NET_ciMasterList);
- NET_ciMasterList = 0;
- /* This function should really return an error code and deal with any errors when they happen */
- }
-
- #else /* !XP_UNIX */
-
- PUBLIC void
- NET_CleanupFileFormat()
- {
- Bool file_not_open=TRUE;
- net_Real_CleanupFileFormat(NULL, file_not_open);
- }
-
- #endif /* !XP_UNIX */
-