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.
- */
- /*
- *
- * Implemented by Lou Montulli '94-'98
- *
- * this is the dumping grounds for random Netlib functions
- * Home for utility functions and anything else that
- * doesn't fit elsewhere.
- */
-
- #include "rosetta.h"
- #include "mkutils.h"
- #include "gui.h"
- #include "mknews.h"
- #include "mkparse.h"
- #include "mkaccess.h"
- #include "libi18n.h"
- #include "msgcom.h"
- #include "mkcache.h"
- #include "mkextcac.h"
- #include "mime.h"
- #include "secrng.h"
- #include "ssl.h"
- #include "prefapi.h"
- #include "secnav.h"
- #include "preenc.h"
- #include "mkselect.h"
-
- #include "xp_error.h"
- #include "xpgetstr.h"
-
- #include "mimeenc.h"
- #include "intl_csi.h"
-
- #ifdef XP_MAC
- #include "MacBinSupport.h"
- #endif
-
- typedef struct {
- char *buffer;
- int32 size;
- int32 pos;
- } BufferStruct;
-
- #ifndef MAX
- #define MAX(x, y) (((x) > (y)) ? (x) : (y))
- #endif
-
- static int
- net_buffer_output_fn ( const char *buf, int32 size, void *closure);
-
- extern int MK_OUT_OF_MEMORY;
- extern int MK_UNABLE_TO_LOCATE_FILE;
- extern int XP_ERRNO_EWOULDBLOCK;
- extern int MK_TCP_WRITE_ERROR;
- extern int XP_ERRNO_EALREADY;
- extern int XP_ALERT_URN_USEHTTP;
- extern int XP_ALERT_NFS_USEHTTP;
- extern int MK_NO_WAIS_PROXY;
-
- /* print network progress to the front end
- */
- MODULE_PRIVATE void
- NET_Progress(MWContext *context, char *msg)
- {
- FE_Progress(context, msg);
- }
-
- /* note: on the Macintosh local_dir_name will be in the following format: */
- /* file:///Hard%20Disk/Folder%20Name/File.html */
- PUBLIC char **
- NET_AssembleAllFilesInDirectory(MWContext *context, char * local_dir_name)
- {
- XP_Dir dir_ptr;
- XP_DirEntryStruct *dir_entry;
- XP_StatStruct stat_entry;
- char **files_to_post;
- char *file_to_post = 0;
- int32 i, cur_array_size;
- int end;
- Bool have_slash;
- #define INITIAL_ARRAY_SIZE 10
- #define EXPAND_ARRAY_BY 5
-
- XP_ASSERT(local_dir_name);
-
- #ifdef XP_MAC
- local_dir_name += 7; // chop-off "file://"
- #endif
-
- if(NULL == (dir_ptr = XP_OpenDir(local_dir_name, xpFileToPost)))
- {
- FE_Alert(context, "Unable to open local directory");
- return NULL;
- }
-
- /* make sure local_dir_name doesn't have a slash at the end */
- end = XP_STRLEN(local_dir_name)-1;
- have_slash = (local_dir_name[end] == '/') || (local_dir_name[end] == '\\');
-
- files_to_post = (char**) XP_ALLOC(INITIAL_ARRAY_SIZE * sizeof(char*));
- if(!files_to_post)
- return NULL;
- cur_array_size = INITIAL_ARRAY_SIZE;
-
- i=0;
- while((dir_entry = XP_ReadDir(dir_ptr)) != NULL)
- {
- /* skip . and .. */
- if(!XP_STRCMP(dir_entry->d_name, ".") || !XP_STRCMP(dir_entry->d_name, ".."))
- continue;
-
- /* assemble full pathname first so we can test if its a directory */
- file_to_post = XP_STRDUP(local_dir_name);
- if ( ! file_to_post ){
- return NULL;
- }
-
- /* Append slash to directory if we don't already have one */
- if( !have_slash )
- {
- #ifdef XP_WIN
- StrAllocCat(file_to_post, "\\");
- #else
- StrAllocCat(file_to_post, "/");
- #endif
- }
- if ( ! file_to_post )
- {
- return NULL;
- }
-
- StrAllocCat(file_to_post, dir_entry->d_name);
- if ( ! file_to_post )
- {
- return NULL;
- }
-
- /* skip over subdirectory names */
- if(-1 != XP_Stat(file_to_post, &stat_entry, xpFileToPost) && S_ISDIR(stat_entry.st_mode) )
- {
- XP_FREE(file_to_post);
- continue;
- }
-
- /* expand array if necessary
- * always leave room for the NULL terminator */
- if(i >= cur_array_size-1)
- {
- files_to_post = (char**) XP_REALLOC(files_to_post, (cur_array_size + EXPAND_ARRAY_BY) * sizeof(char*));
- if(!files_to_post)
- return NULL;
- cur_array_size += EXPAND_ARRAY_BY;
- }
-
- files_to_post[i++] = XP_STRDUP(file_to_post);
-
- XP_FREE(file_to_post);
- }
-
- /* NULL terminate the array, space is guarenteed above */
- files_to_post[i] = NULL;
-
- return(files_to_post);
- }
-
- /********KILL this, use NET_PublishFilesTo ************/
- /* upload a set of local files (array of char*)
- * all files must have full path name
- * first file is primary html document,
- * others are included images or other files
- * in the same directory as main file
- */
- PUBLIC void
- NET_PublishFiles(MWContext *context,
- char **files_to_publish,
- char *remote_directory)
- {
- URL_Struct *URL_s;
-
- XP_ASSERT(context && files_to_publish && remote_directory);
- if(!context || !files_to_publish || !*files_to_publish || !remote_directory)
- return;
-
- /* create a URL struct */
- URL_s = NET_CreateURLStruct(remote_directory, NET_SUPER_RELOAD);
- if(!URL_s)
- {
- FE_Alert(context, "Error: not enough memory for file upload");
- return; /* does not exist */
- }
-
- FREE_AND_CLEAR(URL_s->content_type);
-
- /* add the files that we are posting and set the method to POST */
- URL_s->files_to_post = files_to_publish;
- URL_s->method = URL_POST_METHOD;
-
- /* start the load */
- FE_GetURL(context, URL_s);
- }
-
- /* upload a set of local files (array of char*)
- * first file is primary html document,
- * others are included images or other files.
- *
- * It is legal to pass in NULL as the value of publish_to. This will duplicate
- the functionality of the old NET_PublishFiles.
- * files_to_publish and publish_to are used by and will be freed by NET_PublishFilesTo,
- * base_url is copied */
- PUBLIC void
- NET_PublishFilesTo(MWContext *context,
- char **files_to_publish,
- char **publish_to, /* Absolute URLs of the location to
- * publish the files to. Used only if HTTP.
- * Ignored if FTP (except to delete memory.)*/
- XP_Bool *add_crlf, /* For each file in files_to_publish, should every line
- end in a CRLF. */
- char *base_url, /* Directory to publish to, or the destination
- * URL of the root HTML document. */
- char *username,
- char *password,
- Net_GetUrlExitFunc *exit_func,
- void *fe_data)
- {
- URL_Struct *URL_s;
-
- if(!context || !files_to_publish || !*files_to_publish || !base_url) {
- XP_ASSERT(0);
- return;
- }
-
- /* create a URL struct */
- URL_s = NET_CreateURLStruct(base_url, NET_SUPER_RELOAD);
- if(!URL_s)
- {
- FE_Alert(context, "Error: not enough memory for file upload");
- return; /* does not exist */
- }
-
- if (username)
- URL_s->username = XP_STRDUP(username);
- if (password)
- URL_s->password = XP_STRDUP(password);
-
- FREE_AND_CLEAR(URL_s->content_type);
-
- /* add the files that we are posting and set the method to POST */
- URL_s->files_to_post = files_to_publish;
- URL_s->post_to = publish_to;
- URL_s->add_crlf = add_crlf;
- URL_s->method = URL_POST_METHOD;
- URL_s->pre_exit_fn = exit_func; /* May be NULL */
- URL_s->fe_data = fe_data;
-
- /* start the load */
- FE_GetURL(context, URL_s);
- }
-
- /* assemble username, password, and ftp:// or http:// URL into
- * ftp://user:password@/blah format for uploading
- */
- PUBLIC Bool
- NET_MakeUploadURL( char **full_location, char *location,
- char *user_name, char *password )
- {
- char *start;
- char *pSrc;
- char *destination;
- char *at_ptr;
- int iSize;
-
- if( !full_location || !location ) return FALSE;
- if( *full_location ) XP_FREE(*full_location);
-
- iSize = strlen(location) + 4;
- if( user_name ) iSize += strlen(user_name);
- if( password ) iSize += strlen(password);
-
- *full_location = (char*)XP_ALLOC(iSize);
- if( !*full_location ){
- /* Return an empty string */
- *full_location = strdup("");
- return FALSE;
- }
- **full_location = '\0';
-
- /* Find start just past http:// or ftp:// */
- start = XP_STRSTR(location, "//");
- if( !start ) return FALSE;
-
- /* Point to just past the host part */
- start += 2;
- pSrc = location;
- destination = *full_location;
- /* Copy up to and including "//" */
- while( pSrc < start ) *destination++ = *pSrc++;
- *destination = '\0';
-
- /* Skip over any user:password in supplied location */
- at_ptr = XP_STRCHR(start, '@');
- if( at_ptr ){
- start = at_ptr + 1;
- }
- /* Append supplied "user:password@"
- * (This can be used without password)
- */
- if( user_name && XP_STRLEN(user_name) > 0 ){
- XP_STRCAT(*full_location, user_name);
- if ( password && XP_STRLEN(password) > 0 ){
- XP_STRCAT(*full_location,":");
- XP_STRCAT(*full_location, password);
- }
- XP_STRCAT(*full_location, "@");
- }
- /* Append the rest of location */
- XP_STRCAT(*full_location, start);
-
- return TRUE;
- }
-
- /* extract the username, password, and reassembled location string
- * from an ftp:// or http:// URL
- */
- PUBLIC Bool
- NET_ParseUploadURL( char *full_location, char **location,
- char **user_name, char **password )
- {
- char *start;
- char *skip_dest;
- char *at_ptr;
- char *colon_ptr;
- char at;
- char colon;
-
- if( !full_location || !location ) return FALSE;
-
- /* Empty exitisting strings... */
- if(*location) XP_FREE(*location);
- if( user_name && *user_name) XP_FREE(*user_name);
- if( password && *password) XP_FREE(*password);
-
- /* Find start just past http:// or ftp:// */
- start = XP_STRSTR(full_location, "//");
- if( !start ) return FALSE;
-
- /* Point to just past the host part */
- start += 2;
-
- /* Start by simply copying full location
- * (may waste some bytes, but much simpler!)
- */
- *location = XP_STRDUP(full_location);
- if( !*location ) return FALSE;
-
- /* Destination to append location without
- * user:password is same place copied string
- */
- skip_dest = *location + (start - full_location);
-
- /* Skip over any user:password in supplied location
- * while copying those to other strings
- */
- at_ptr = XP_STRCHR(start, '@');
- colon_ptr = XP_STRCHR(start, ':');
-
- if( at_ptr ){
- /* save character */
- at = *at_ptr;
-
- /* Copy part past the @ over previously-copied full string */
- XP_STRCPY(skip_dest, (at_ptr + 1));
-
- /* Terminate for the password (or user) string */
- *at_ptr = '\0';
- if( colon_ptr ){
- /* save character */
- colon = *colon_ptr;
-
- if( password ){
- *password = XP_STRDUP((colon_ptr+1));
- }
- /* terminate for the user string */
- *colon_ptr = '\0';
- } else if( password ) {
- *password = XP_STRDUP("");
- }
- if( user_name ){
- *user_name = XP_STRDUP(start);
- }
- /* restore characters */
- *at_ptr = at;
- if( colon_ptr ) *colon_ptr = colon;
-
- } else {
- /* Supply empty strings for these */
- if( user_name ){
- *user_name = XP_STRDUP("");
- }
- if( password ){
- *password = XP_STRDUP("");
- }
- }
- return TRUE;
- }
-
-
- /* returns a malloc'd string containing a unique id
- * generated from the sec random stuff.
- */
- PUBLIC char *
- NET_GetUniqueIdString(void)
- {
- #define BYTES_OF_RANDOMNESS 20
- char rand_buf[BYTES_OF_RANDOMNESS+10];
- char *rv=0;
-
-
- RNG_GenerateGlobalRandomBytes(rand_buf, BYTES_OF_RANDOMNESS);
-
- /* now uuencode it so it goes across the wire right */
- rv = (char *) XP_ALLOC((BYTES_OF_RANDOMNESS * (4/3)) + 10);
-
- if(rv)
- NET_UUEncode((unsigned char *)rand_buf, (unsigned char *)rv, BYTES_OF_RANDOMNESS);
-
- return(rv);
-
- #undef BYTES_OF_RANDOMNESS
- }
-
-
- /* The magic set of 64 chars in the uuencoded data */
- PRIVATE unsigned char uuset[] = {
- 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9','+'
- ,'/' };
-
- MODULE_PRIVATE int
- NET_UUEncode(unsigned char *src, unsigned char *dst, int srclen)
- {
- int i, r;
- unsigned char *p;
-
- /* To uuencode, we snip 8 bits from 3 bytes and store them as
- 6 bits in 4 bytes. 6*4 == 8*3 (get it?) and 6 bits per byte
- yields nice clean bytes
-
- It goes like this:
- AAAAAAAA BBBBBBBB CCCCCCCC
- turns into the standard set of uuencode ascii chars indexed by numbers:
- 00AAAAAA 00AABBBB 00BBBBCC 00CCCCCC
-
- Snip-n-shift, snip-n-shift, etc....
-
- */
-
- for (p=dst,i=0; i < srclen; i += 3) {
- /* Do 3 bytes of src */
- register char b0, b1, b2;
-
- b0 = src[0];
- if (i==srclen-1)
- b1 = b2 = '\0';
- else if (i==srclen-2) {
- b1 = src[1];
- b2 = '\0';
- }
- else {
- b1 = src[1];
- b2 = src[2];
- }
-
- *p++ = uuset[b0>>2];
- *p++ = uuset[(((b0 & 0x03) << 4) | ((b1 & 0xf0) >> 4))];
- *p++ = uuset[(((b1 & 0x0f) << 2) | ((b2 & 0xc0) >> 6))];
- *p++ = uuset[b2 & 0x3f];
- src += 3;
- }
- *p = 0; /* terminate the string */
- r = (unsigned char *)p - (unsigned char *)dst; /* remember how many we
- did */
-
- /* Always do 4-for-3, but if not round threesome, have to go
- clean up the last extra bytes */
-
- for( ; i != srclen; i--)
- *--p = '=';
-
- return r;
- }
-
-
- PRIVATE char *
- NET_RemoveQuotes(char * string)
- {
- char *rv;
- char *end;
-
- rv = XP_StripLine(string);
-
- if(*rv == '"' || *rv == '\'')
- rv++;
-
- end = &rv[XP_STRLEN(rv)-1];
-
- if(*end == '"' || *end == '\'')
- *end = '\0';
-
- return(rv); }
-
- #define POST_DATA_BUFFER_SIZE 2048
-
- struct WritePostDataData {
- char *buffer;
- XP_Bool last_line_was_complete;
- int32 amt_in_buffer;
- int32 amt_sent;
- int32 total_amt_sent;
- int32 file_size;
- XP_File fp;
- int32 headerSize;
- int32 headerAmountSent;
- XP_Bool CRSent;
- XP_Bool LFSent;
- };
-
- PUBLIC void
- NET_free_write_post_data_object(struct WritePostDataData *obj)
- {
- XP_ASSERT(obj);
-
- if(!obj)
- return;
-
- if (obj->fp)
- XP_FileClose(obj->fp);
-
- FREEIF(obj->buffer);
- FREE(obj);
- }
-
- /* returns whether or not the socket error was expected. If it was not, all the write post data
- object was free'd, and the url_s->error_msg was set */
- PRIVATE XP_Bool
- net_expected_error(URL_Struct *URL_s, struct WritePostDataData **data_obj)
- {
- int err = PR_GetError();
- if(err == PR_WOULD_BLOCK_ERROR || err == PR_IS_CONNECTED_ERROR)
- return TRUE;
- URL_s->error_msg = NET_ExplainErrorDetails(MK_TCP_WRITE_ERROR, err);
- NET_free_write_post_data_object(*data_obj);
- *data_obj = NULL;
- return FALSE;
- }
-
- /* this function is called repeatably to write
- * the post data body and headers onto the network.
- *
- * Returns negative on fatal error
- * Returns zero when done
- * Returns positive if not yet completed
- */
- PUBLIC int
- NET_WritePostData(MWContext *context,
- URL_Struct *URL_s,
- PRFileDesc *sock,
- void **write_post_data_data,
- XP_Bool add_crlf_to_line_endings)
- {
- struct WritePostDataData *data_obj = (struct WritePostDataData *)
- *write_post_data_data;
-
- /* init the data object */
- if(!data_obj)
- {
- data_obj = XP_NEW(struct WritePostDataData);
- *write_post_data_data = data_obj;
-
- if(!data_obj)
- return(MK_OUT_OF_MEMORY);
-
- XP_MEMSET(data_obj, 0, sizeof(struct WritePostDataData));
-
- data_obj->last_line_was_complete = TRUE;
- data_obj->buffer = (char *) XP_ALLOC(POST_DATA_BUFFER_SIZE);
-
- if(!data_obj->buffer)
- {
- NET_free_write_post_data_object(data_obj);
- *write_post_data_data=NULL;
- return 0;
- }
-
- if(URL_s->post_headers)
- data_obj->headerSize = XP_STRLEN(URL_s->post_headers);
- else
- data_obj->headerSize = 0;
-
- data_obj->headerAmountSent = 0;
- data_obj->CRSent = FALSE;
- data_obj->LFSent = FALSE;
- data_obj->amt_sent = 0;
- }
-
- if(!data_obj->fp && URL_s->post_data_is_file)
- {
- XP_StatStruct stat_entry;
-
- /* Send the headers */
- if( URL_s->post_headers &&
- (data_obj->headerSize > data_obj->headerAmountSent) )
- {
- int32 amtWritten = 0;
- amtWritten = PR_Write(sock,
- URL_s->post_headers + data_obj->headerAmountSent,
- data_obj->headerSize - data_obj->headerAmountSent);
-
- /* if there was a problem */
- if( amtWritten < 0 ) {
- /* determine whether it was expected */
- if( net_expected_error(URL_s, (struct WritePostDataData **) write_post_data_data) )
- return 1;
- else
- return(MK_TCP_WRITE_ERROR);
- }
-
- #ifdef DEBUG
- NET_NTrace("Tx: ", 4);
- NET_NTrace(URL_s->post_headers + data_obj->headerAmountSent,
- amtWritten);
- #endif
-
- data_obj->headerAmountSent += amtWritten;
-
- if(data_obj->headerSize > data_obj->headerAmountSent)
- return 1;
-
- } /* END: URL_s->post_headers ... */
-
- /* stat the file to get the size
- */
- if(-1 != XP_Stat(URL_s->post_data, &stat_entry, xpFileToPost))
- {
- data_obj->file_size = stat_entry.st_size;
- }
-
- /* open the post data file
- */
- data_obj->fp = XP_FileOpen(URL_s->post_data, xpFileToPost, XP_FILE_READ_BIN);
-
- if(!data_obj->fp)
- {
- URL_s->error_msg = NET_ExplainErrorDetails(
- MK_UNABLE_TO_LOCATE_FILE,
- URL_s->post_data);
- NET_free_write_post_data_object(data_obj);
- *write_post_data_data = NULL;
- return(MK_UNABLE_TO_LOCATE_FILE);
- }
- }
-
- if(URL_s->post_data_is_file)
- {
- int32 amt_to_wrt;
- int32 amt_wrt;
-
- int type = NET_URL_Type (URL_s->address);
- XP_Bool quote_lines_p = (type == MAILTO_TYPE_URL ||
- type == NEWS_TYPE_URL ||
- type == INTERNAL_NEWS_TYPE_URL);
-
- /* do file based operations
- */
- if(data_obj->amt_in_buffer < 1 || data_obj->amt_sent >= data_obj->amt_in_buffer)
- {
- /* read more data from the file
- */
- if (quote_lines_p || add_crlf_to_line_endings)
- {
- char *line;
- char *b = data_obj->buffer;
- int32 bsize = POST_DATA_BUFFER_SIZE;
- data_obj->amt_in_buffer = 0;
- do {
- int L;
-
- line = XP_FileReadLine(b, bsize-5, data_obj->fp);
-
- if (!line)
- break;
-
- L = XP_STRLEN(line);
-
- /* escape periods only if quote_lines_p is set
- */
- if (quote_lines_p &&
- data_obj->last_line_was_complete && line[0] == '.')
- {
- /* This line begins with "." so we need to quote it
- by adding another "." to the beginning of the line.
- */
- int i;
- line[L+1] = 0;
- for (i = L; i > 0; i--)
- line[i] = line[i-1];
- L++;
- }
-
- /* set default */
- data_obj->last_line_was_complete = TRUE;
-
- if (L > 1 && line[L-2] == CR && line[L-1] == LF)
- {
- /* already ok */
- }
- else if(L > 0 && (line[L-1] == LF || line[L-1] == CR))
- {
- /* only add the crlf if required
- * we still need to do all the
- * if comparisons here to know
- * if the line was complete
- */
- if(add_crlf_to_line_endings)
- {
- /* Change newline to CRLF. */
- L--;
- line[L++] = CR;
- line[L++] = LF;
- line[L] = 0;
- }
- }
- else
- {
- data_obj->last_line_was_complete = FALSE;
- }
-
- bsize -= L;
- b += L;
- data_obj->amt_in_buffer += L;
- } while (line && bsize > 100);
- }
- else
- {
- data_obj->amt_in_buffer = XP_FileRead(data_obj->buffer,
- POST_DATA_BUFFER_SIZE-1,
- data_obj->fp);
- }
-
- HG29784
-
- if(data_obj->amt_in_buffer < 1)
- {
- /* end of file, all done
- */
- /*
- * handled by NET_free_write_post_data_object
- *
- XP_FileClose(data_obj->fp);
- */
- XP_ASSERT(data_obj->total_amt_sent >= data_obj->file_size);
- NET_free_write_post_data_object(data_obj);
- *write_post_data_data = NULL;
- return(0);
- }
-
- data_obj->amt_sent = 0;
- }
-
- amt_to_wrt = data_obj->amt_in_buffer-data_obj->amt_sent;
-
- /* write some data to the socket
- */
- amt_wrt = PR_Write(sock,
- data_obj->buffer+data_obj->amt_sent,
- amt_to_wrt);
-
- #ifdef DEBUG
- NET_NTrace("Tx: ", 4);
- NET_NTrace(data_obj->buffer+data_obj->amt_sent,
- amt_to_wrt);
- #endif /* DEBUG */
-
- if(amt_wrt < 0)
- {
- int err = PR_GetError();
- if(err == PR_WOULD_BLOCK_ERROR
- || err == PR_IS_CONNECTED_ERROR)
- return(1); /* continue */
-
- URL_s->error_msg = NET_ExplainErrorDetails(MK_TCP_WRITE_ERROR, err);
- /*
- * handled by net_free_write_post_data
- XP_FileClose(data_obj->fp);
- */
-
- NET_free_write_post_data_object(data_obj);
- *write_post_data_data = NULL;
-
- return(MK_TCP_WRITE_ERROR);
- }
-
- #if defined(XP_UNIX) && defined(DEBUG)
- if(amt_wrt < amt_to_wrt)
- fprintf(stderr, "Fwrite wrote less than requested!\n");
- #endif
-
- /* safty for broken SSL_write */
- if(amt_wrt > amt_to_wrt)
- amt_wrt = amt_to_wrt;
-
- #if defined(XP_UNIX) && defined(DEBUG)
- if(MKLib_trace_flag)
- {
- fwrite("Tx: ", 1, 4, stderr);
- fwrite(data_obj->buffer+data_obj->amt_sent, 1, amt_wrt, stderr);
- fwrite("\n", 1, 1, stderr);
- }
- #endif
-
- data_obj->amt_sent += amt_wrt;
- data_obj->total_amt_sent += amt_wrt;
-
- /* return the amount of data written
- * so that callers can provide progress
- * if necessary. If the amt_wrt was
- * zero (I don't think it can ever happen)
- * return 1 because zero means all done
- */
- if(amt_wrt > 0)
- return(amt_wrt);
- else
- return(1);
- }
- else
- {
- /* do memory based operations */
- int32 amtWritten;
-
- /* send the headers if there are any && and they haven't been sent */
- if( URL_s->post_headers && (data_obj->headerSize > data_obj->headerAmountSent) )
- {
- amtWritten = PR_Write(sock,
- URL_s->post_headers + data_obj->headerAmountSent,
- data_obj->headerSize - data_obj->headerAmountSent);
-
- /* if there was a problem */
- if(amtWritten < 0) {
- /* determine whether it was expected */
- if( net_expected_error(URL_s, (struct WritePostDataData **) write_post_data_data) )
- return 1;
- else
- return(MK_TCP_WRITE_ERROR);
- }
-
- #ifdef DEBUG
- NET_NTrace("Tx: ", 4);
- NET_NTrace(URL_s->post_headers + data_obj->headerAmountSent,
- amtWritten);
- NET_NTrace("\n", 1);
- #endif
-
- data_obj->headerAmountSent += amtWritten;
-
- /* If all the header data hasn't been sent, return 1 (not done). */
- if(data_obj->headerSize > data_obj->headerAmountSent)
- return 1;
- }
-
- /* Separate the headers from the data with a CR and LF. */
- if(!data_obj->CRSent) {
- data_obj->buffer[0] = CR;
- data_obj->buffer[1] = LF;
- data_obj->buffer[2] = '\0';
- amtWritten = PR_Write(sock, data_obj->buffer, XP_STRLEN(data_obj->buffer));
-
- if(amtWritten < 0) {
- /* determine whether it was expected */
- if( net_expected_error(URL_s, (struct WritePostDataData **) write_post_data_data) )
- return 1;
- else
- return(MK_TCP_WRITE_ERROR);
- }
- /* If no data was sent, return 1 (not done). */
- if(amtWritten == 0)
- return 1;
-
- if(amtWritten >= 1)
- data_obj->CRSent = TRUE;
- if(amtWritten >= 2)
- data_obj->LFSent = TRUE;
- }
-
- if(!data_obj->LFSent) {
- data_obj->buffer[0] = LF;
- data_obj->buffer[1] = '\0';
- amtWritten = PR_Write(sock, data_obj->buffer, XP_STRLEN(data_obj->buffer));
-
- if(amtWritten < 0) {
- /* determine whether it was expected */
- if( net_expected_error(URL_s, (struct WritePostDataData **) write_post_data_data) )
- return 1;
- else
- return(MK_TCP_WRITE_ERROR);
- }
- /* If no data was sent, return 1 (not done). */
- if(amtWritten == 0)
- return 1;
- data_obj->LFSent = TRUE;
-
- TRACEMSG(("Adding \\n to command"));
- }
-
- if(!URL_s->post_data)
- {
- NET_free_write_post_data_object(data_obj);
- *write_post_data_data = NULL;
- return(MK_OUT_OF_MEMORY);
- }
-
- /* Send the data if we haven't already sent it */
- if(URL_s->post_data_size > data_obj->amt_sent) {
- amtWritten = PR_Write(sock,
- URL_s->post_data+data_obj->amt_sent,
- URL_s->post_data_size-data_obj->amt_sent);
-
- if(amtWritten < 0) {
- /* determine whether it was expected */
- if( net_expected_error(URL_s, (struct WritePostDataData **) write_post_data_data) )
- return 1;
- else
- return(MK_TCP_WRITE_ERROR);
- }
- /* If no data was sent, return 1 (not done). */
- if(amtWritten == 0)
- return 1;
-
- #ifdef DEBUG
- NET_NTrace("Tx: ", 4);
- NET_NTrace(URL_s->post_data+data_obj->amt_sent,
- amtWritten);
- NET_NTrace("\n", 1);
- #endif
-
- data_obj->amt_sent += amtWritten;
-
- /* if all data has been written, return done */
- if(data_obj->amt_sent >= URL_s->post_data_size) {
- NET_free_write_post_data_object(data_obj);
- *write_post_data_data = NULL;
- return 0;
- }
- else {
- return amtWritten;
- }
- }
- else {
- NET_free_write_post_data_object(data_obj);
- *write_post_data_data = NULL;
- return 0;
- }
- }
-
- /* By this time all headers and data should have been sent, shouldn't get here */
- XP_ASSERT(0);
- NET_free_write_post_data_object(data_obj);
- *write_post_data_data = NULL;
- return(-1); /* shouldn't ever get here */
-
- }
-
- void
- NET_ParseContentTypeHeader(MWContext *context, char *value, URL_Struct *URL_s, XP_Bool is_http)
- {
- char *first_arg, *next_arg;
-
- if(URL_s->preset_content_type)
- return;
-
- first_arg = XP_STRTOK(value, ";");
-
- StrAllocCopy(URL_s->content_type, XP_StripLine(value));
- TRACEMSG(("Found content_type: %s",URL_s->content_type));
-
- /* assign and compare
- *
- * search for charset
- * and boundry
- */
- while((next_arg = XP_STRTOK(NULL, ";")) != NULL)
- {
- next_arg = XP_StripLine(next_arg);
-
- if(!strncasecomp(next_arg,"CHARSET=", 8))
- {
- #ifdef MOZILLA_CLIENT
- char *charset_tag = NET_RemoveQuotes(next_arg+8);
- /*
- * To make http LOAD-FROM-NET and LOAD-FROM-CACHE
- * charset tag handling consistant just put the http
- * charset info in the url struct.
- * We will use this later when setting up charset converter.
- * (we do this because: on a reload from cache this code will not get called)
- */
- if (is_http)
- {
- /* record HTTP charset tag so we can: */
- /* 1) use it to figure out the doc_csid */
- /* 2) report it to the user */
- StrAllocCopy(URL_s->charset, charset_tag);
- TRACEMSG(("Found HTTP charset: %s", charset_tag));
- }
- else
- {
- INTL_CCCReportMetaCharsetTag(context, charset_tag);
- TRACEMSG(("Found Meta charset: %s", charset_tag));
- }
- #else
- XP_ASSERT(0);
- #endif /* MOZILLA_CLIENT */
- }
- else if(!strncasecomp(next_arg,"BOUNDARY=", 9))
- {
- StrAllocCopy(URL_s->boundary, NET_RemoveQuotes(next_arg+9));
- TRACEMSG(("Found boundary: %s", URL_s->boundary));
- }
- else if(!strncasecomp(next_arg,"AUTOSCROLL", 10))
- {
-
- #define DEFAULT_AUTO_SCROLL_BUFFER 100
- if(*next_arg+10 == '=')
- URL_s->auto_scroll = atoi(NET_RemoveQuotes(next_arg+11));
-
- if(!URL_s->auto_scroll)
- URL_s->auto_scroll = DEFAULT_AUTO_SCROLL_BUFFER;
-
- TRACEMSG(("Found autoscroll attr.: %ud", URL_s->auto_scroll));
- }
- }
- }
-
- /* parse a mime header.
- *
- * Both name and value strings will be modified during
- * parsing. If you need to retain your strings make a
- * copy before passing them in.
- *
- * Values will be placed in the URL struct.
- *
- * returns TRUE if it found a valid header
- * and FALSE if it didn't
- */
-
- PUBLIC Bool
- NET_ParseMimeHeader(FO_Present_Types outputFormat,
- MWContext *context,
- URL_Struct *URL_s,
- char *name,
- char *value,
- XP_Bool is_http)
- {
- Bool found_one = FALSE;
- Bool ret_value = FALSE;
- char empty_string[2];
- char *colon_ptr;
-
- if(!name || !URL_s)
- return(FALSE);
-
- name = XP_StripLine(name);
-
- if(value)
- {
- value = XP_StripLine(value);
- }
- else
- {
- *empty_string = '\0';
- value = empty_string;
- }
-
- colon_ptr = XP_STRCHR(name, ':');
- if (colon_ptr) {
- *colon_ptr = '\0';
- }
- ret_value = NET_AddToAllHeaders(URL_s, name, value);
- if (colon_ptr) {
- *colon_ptr = ':';
- }
- if (!ret_value) {
- return(FALSE);
- }
-
- switch(toupper(*name))
- {
- case 'A':
- if(!strncasecomp(name,"ACCEPT-RANGES:",14)
- || !strncasecomp(name, "ALLOW-RANGES:",13))
- {
- char * next_arg = XP_STRTOK(value, ";");
-
- found_one = TRUE;
-
- while(next_arg)
- {
- next_arg = XP_StripLine(next_arg);
-
- if(!strncasecomp(next_arg,"BYTES", 5))
- {
- TRACEMSG(("Document Allows for BYTERANGES!"));
- URL_s->server_can_do_byteranges = TRUE;
- }
-
- next_arg = XP_STRTOK(NULL, ";");
- }
- }
- else if(!strncasecomp(name, "AGE:",4))
- {
- long age;
-
- XP_STRTOK(value, ";"); /* terminate at ';' */
-
- age = atol(value);
- /* Small deviation from the spec. Assumption being made-
- Req. time ~= Resp Time ~= now */
- if (URL_s->server_date)
- {
- time_t now = time(NULL);
- time_t correction = now - MAX(age, MAX(0, now- URL_s->server_date));
- if (URL_s->expires)
- URL_s->expires += correction;
- }
- }
- case 'C':
- if (!strncasecomp(name,"CACHE-CONTROL:",14))
- {
- /* Potential values include */
- /* public */
- /* private[=field-name] */
- /* no-cache [=field-name] */
- /* no-store */
- /* no-transform - this is only applicable for proxies and hence not put here*/
- /* must-revalidate */
- /* proxy-revalidate */
- /* max-age=delta-seconds */
- /* s-maxage=delta-seconds */
-
- /* any cache extension */
-
- char * control = NET_RemoveQuotes(value);
-
- if (!strncasecomp(control, "NO-CACHE", 8))
- {
- /* same as pragma=no-cache */
- URL_s->dont_cache = TRUE;
- }
- else if (!strncasecomp(control, "MAX-AGE=", 8))
- {
- /* Takes precedence over the Expires header.
- Corrected Expires is Max-age + Server Date */
- if (URL_s->server_date)
- {
- URL_s->expires = URL_s->server_date + atol(XP_STRTOK(control+8,";"));
- }
- }
- #if 0 /* Unimplemented */
- else if (!strncasecomp(control, "PUBLIC", 6))
- {
- /* Place holder for shared cache concepts */
- }
- else if (!strncasecomp(control, "PRIVATE", 7))
- {
- /* Place holder for shared cache concepts */
- }
- else if (!strncasecomp(control, "NO-STORE", 8))
- {
- /* According to the spec this "should" disable explicit saving
- of the document outside the caching system, eg. in "Save As..."
- dialogs. Since this idea sucks, this is a place holder. */
- }
- else if (!strncasecomp(control, "MUST-REVALIDATE", 15))
- {
- /* The cache must do an end-to-end revalidation every time, if
- the response headers suggest an entity is stale. We do this
- anyway. */
- }
- else if (!strncasecomp(control, "PROXY-REVALIDATE", 16))
- {
- /* Same as must-revalidate except that it does not apply to
- non-shared user agents (like us) */
- }
- else if (!strncasecomp(control, "S-MAXAGE", 8))
- {
- /* Applicable for shared caches. Place holder. */
- }
- else
- {
- /* A new cache extension */
- }
- #endif /* Unimplemented */
- }
- else if(!strncasecomp(name,"CONTENT-DISPOSITION:",20))
- {
- char *next_arg;
-
- found_one = TRUE;
-
- next_arg = XP_STRTOK(value, ";");
-
- while(next_arg)
- {
- next_arg = XP_StripLine(next_arg);
-
- if(!strncasecomp(next_arg,"filename=", 9))
- {
- StrAllocCopy(URL_s->content_name,
- NET_RemoveQuotes(next_arg+9));
- }
- next_arg = XP_STRTOK(NULL, ";");
- }
-
- }
- else if(!strncasecomp(name,"CONTENT-TYPE:",13))
- {
- found_one = TRUE;
- NET_ParseContentTypeHeader(context, value, URL_s, is_http);
- }
- else if(!strncasecomp(name,"CONTENT-LENGTH:",15))
- {
- found_one = TRUE;
-
- XP_STRTOK(value, ";"); /* terminate at ';' */
-
- /* don't reset the content-length if
- * we have already set it from the content-range
- * header. If high_range is set then we must
- * have seen a content-range header.
- */
- if(!URL_s->high_range)
- URL_s->content_length = atol(value);
- }
- else if(!strncasecomp(name,"CONTENT-ENCODING:",17))
- {
- found_one = TRUE;
-
- XP_STRTOK(value, ";"); /* terminate at ';' */
- StrAllocCopy(URL_s->content_encoding, value);
- }
- else if(!strncasecomp(name,"CONTENT-RANGE:",14))
- {
- unsigned long low, high, length;
- XP_STRTOK(value, ";"); /* terminate at ';' */
-
- /* range header looks like:
- * Range: bytes x-y/z
- * where:
- *
- * X is the number of the first byte returned
- * (the first byte is byte number zero).
- *
- * Y is the number of the last byte returned
- * (in case of the end of the document this
- * is one smaller than the size of the document
- * in bytes).
- *
- * Z is the total size of the document in bytes.
- *
- * Scan through temp variables because %l is 64 bits on OSF1
- */
- sscanf(value, "bytes %lu-%lu/%lu", &low, &high, &length);
- URL_s->low_range = (int32) low;
- URL_s->high_range = (int32) high;
- URL_s->content_length = (int32) length;
-
- /* if we get a range header set the "can-do-byteranges"
- * since it must be doing byteranges
- */
- URL_s->server_can_do_byteranges = TRUE;
- }
- else if(!strncasecomp(name,"CONNECTION:",11))
- {
- XP_STRTOK(value, ";"); /* terminate at ';' */
- XP_STRTOK(value, ","); /* terminate at ',' */
- if(!strcasecomp("KEEP-ALIVE", XP_StripLine(value)))
- URL_s->can_reuse_connection = TRUE;
- if(!strcasecomp("CLOSE", XP_StripLine(value)))
- URL_s->can_reuse_connection = FALSE;
- }
- break;
-
- case 'D':
- if(!strncasecomp(name,"DATE:",5))
- {
- found_one = TRUE;
- URL_s->server_date = NET_ParseDate(value);
- }
- #if 0
- else if(!strncasecomp(name,"DEST-IP:",8))
- {
- found_one = TRUE;
- URL_s->destIP = XP_STRDUP(value);
- }
- #endif
- break;
- case 'E':
- if(!strncasecomp(name,"EXPIRES:",8))
- {
- char *cp, *expires = NET_RemoveQuotes(value);
- Bool is_number=TRUE;
-
- /* Expires: 123 - number of seconds
- * Expires: date - absolute date
- */
-
- XP_STRTOK(value, ";"); /* terminate at ';' */
-
- /* check to see if the expires date is just a
- * value in seconds
- */
- for(cp = expires; *cp != '\0'; cp++)
- if(!isdigit(*cp))
- {
- is_number=FALSE;
- break;
- }
-
- if(is_number)
- URL_s->expires = time(NULL) + atol(expires);
- else
- URL_s->expires = NET_ParseDate(expires);
-
- /* if we couldn't parse the date correctly
- * make it already expired, as per the HTTP spec
- */
- if(!URL_s->expires)
- URL_s->expires = 1;
-
- found_one = TRUE;
- }
- else if(!strncasecomp(name,"EXT-CACHE:",10))
- {
- #ifdef MOZILLA_CLIENT
- char * next_arg = XP_STRTOK(value, ";");
- char * name=0;
- char * instructions=0;
-
- found_one = TRUE;
-
- while(next_arg)
- {
- next_arg = XP_StripLine(next_arg);
-
- if(!strncasecomp(next_arg,"name=", 5))
- {
- TRACEMSG(("Found external cache name: %s", next_arg+5));
- name = NET_RemoveQuotes(next_arg+5);
- }
- else if(!strncasecomp(next_arg,"instructions=", 13))
- {
- TRACEMSG(("Found external cache instructions: %s",
- next_arg+13));
- instructions = NET_RemoveQuotes(next_arg+13);
- }
-
- next_arg = XP_STRTOK(NULL, ";");
- }
-
- if(name)
- NET_OpenExtCacheFAT(context, name, instructions);
- #else
- XP_ASSERT(0);
- #endif /* MOZILLA_CLIENT */
- }
- else if (!strncasecomp(name, "ETAG:",5))
- {
- /* Weak Validators are skipped for now*/
- char* etag;
- if (!strncasecomp(value, "W/", 2))
- etag = NET_RemoveQuotes(value+2);
- else
- etag = NET_RemoveQuotes(value);
-
- StrAllocCopy(URL_s->etag,etag);
- }
- break;
-
- case 'L':
- if(!strncasecomp(name,"LOCATION:",9))
- {
- found_one = TRUE;
-
- /* don't do this here because a url can
- * contain a ';'
- * XP_STRTOK(value, ";");
- */
-
- URL_s->redirecting_url = NET_MakeAbsoluteURL(
- URL_s->address,
- XP_StripLine(value));
-
- TRACEMSG(("Found location: %s\n",URL_s->redirecting_url));
-
- if(MOCHA_TYPE_URL == NET_URL_Type(URL_s->redirecting_url))
- {
- /* don't allow mocha URL's as refresh
- */
- FREE_AND_CLEAR(URL_s->redirecting_url);
- }
- }
- else if(!strncasecomp(name,"LAST-MODIFIED:",14))
- {
- found_one = TRUE;
-
- URL_s->last_modified = NET_ParseDate(value);
- TRACEMSG(("Found last modified date: %d\n",URL_s->last_modified));
- }
- else if(!strncasecomp(name,"LINK:",5))
- {
- #define PAGE_SERVICES_REL "pageServices"
- char * next_arg = XP_STRTOK(value, ";");
- char * link_val;
- enum { UNKNOWN_REL_TYPE, PAGE_SERVICES_REL_TYPE } rel_type;
-
- found_one = TRUE;
-
- rel_type = UNKNOWN_REL_TYPE;
-
- /* strip the < and > from the url */
- if(*value == '<')
- {
- value++;
- /* strip the end one too */
- value[XP_STRLEN(value)-1] = '\0';
- }
-
- /* ok if malloc fails */
- link_val = NET_MakeAbsoluteURL(URL_s->address,
- XP_StripLine(value));
- while(next_arg)
- {
- next_arg = XP_StripLine(next_arg);
-
- if(!strncasecomp(next_arg,"rel=", 4))
- {
- char * rel = NET_RemoveQuotes(next_arg+4);
-
- if(!strcasecomp(rel, PAGE_SERVICES_REL))
- rel_type = PAGE_SERVICES_REL_TYPE;
- }
-
- next_arg = XP_STRTOK(NULL, ";");
- }
-
- /* if we fount a rel for page services assign it */
- if(rel_type == PAGE_SERVICES_REL_TYPE)
- URL_s->page_services_url = link_val;
- else
- XP_FREEIF(link_val);
-
- }
- break;
-
- case 'P':
- if(!strncasecomp(name,"PROXY-AUTHENTICATE:",19))
- {
- char *auth = value;
-
- found_one = TRUE;
-
- XP_STRTOK(value, ";"); /* terminate at ';' */
-
- if (net_IsBetterAuth(auth, URL_s->proxy_authenticate))
- StrAllocCopy(URL_s->proxy_authenticate, auth);
- }
- else if(!strncasecomp(name,"PROXY-CONNECTION:",17))
- {
- XP_STRTOK(value, ";"); /* terminate at ';' */
- XP_STRTOK(value, ","); /* terminate at ',' */
- if(!strcasecomp("KEEP-ALIVE", XP_StripLine(value)))
- URL_s->can_reuse_connection = TRUE;
- }
- else if(!strncasecomp(name,"PRAGMA:",7))
- {
- found_one = TRUE;
-
- XP_STRTOK(value, ";"); /* terminate at ';' */
-
- if(!strcasecomp(value, "NO-CACHE"))
- URL_s->dont_cache = TRUE;
- }
- break;
-
- case 'R':
-
- if(!strncasecomp(name,"RANGE:",6))
- {
- unsigned long low, high, length;
- XP_STRTOK(value, ";"); /* terminate at ';' */
-
- /* range header looks like:
- * Range: bytes x-y/z
- * where:
- *
- * X is the number of the first byte returned
- * (the first byte is byte number zero).
- *
- * Y is the number of the last byte returned
- * (in case of the end of the document this
- * is one smaller than the size of the document
- * in bytes).
- *
- * Z is the total size of the document in bytes.
- *
- * Scan through temp variables because %l is 64 bits on OSF1
- */
- sscanf(value, "bytes %lu-%lu/%lu", &low, &high, &length);
- URL_s->low_range = (int32) low;
- URL_s->high_range = (int32) high;
- URL_s->content_length = (int32) length;
-
- /* if we get a range header set the "can-do-byteranges"
- * since it must be doing byteranges
- */
- URL_s->server_can_do_byteranges = TRUE;
- }
- else if(!strncasecomp(name,"REFRESH:",8) && !EDT_IS_EDITOR(context))
- {
- char *first_arg, *next_arg;
-
- found_one = TRUE;
-
- /* clear any previous refresh URL */
- if(URL_s->refresh_url)
- {
- FREE(URL_s->refresh_url);
- URL_s->refresh_url=0;
- }
-
- first_arg = XP_STRTOK(value, ";");
-
- URL_s->refresh = atol(value);
- TRACEMSG(("Found refresh header: %d",URL_s->refresh));
-
- /* assign and compare
- */
- while((next_arg = XP_STRTOK(NULL, ";")) != NULL)
- {
- next_arg = XP_StripLine(next_arg);
-
-
- if(!strncasecomp(next_arg,"URL=", 4))
- {
- URL_s->refresh_url = NET_MakeAbsoluteURL(
- URL_s->address,
- NET_RemoveQuotes(next_arg+4));
- TRACEMSG(("Found refresh url: %s",
- URL_s->refresh_url));
-
- if(MOCHA_TYPE_URL == NET_URL_Type(URL_s->refresh_url))
- {
- /* don't allow mocha URL's as refresh
- */
- FREE_AND_CLEAR(URL_s->refresh_url);
- }
- }
- }
-
- if(!URL_s->refresh_url)
- StrAllocCopy(URL_s->refresh_url, URL_s->address);
- }
- break;
-
- case 'S':
- if(!strncasecomp(name,"SET-COOKIE:",11))
- {
- found_one = TRUE;
- NET_SetCookieStringFromHttp(outputFormat, URL_s, context, URL_s->address, value);
- }
- else if(!strncasecomp(name, "SERVER:", 7))
- {
- found_one = TRUE;
-
- if(strcasestr(value, "NETSITE"))
- URL_s->is_netsite = TRUE;
- else if(strcasestr(value, "NETSCAPE"))
- URL_s->is_netsite = TRUE;
- }
- break;
-
- case 'T':
- if(!strncasecomp(name,"TRANSFER-ENCODING:",18))
- {
- found_one = TRUE;
-
- XP_STRTOK(value, ";"); /* terminate at ';' */
- StrAllocCopy(URL_s->transfer_encoding, value);
- }
-
- case 'W':
- if(!strncasecomp(name,"WWW-AUTHENTICATE:",17))
- {
- found_one = TRUE;
-
- XP_STRTOK(value, ";"); /* terminate at ';' */
-
- StrAllocCopy(URL_s->authenticate, value);
- }
- else if(!strncasecomp(name, "WWW-PROTECTION-TEMPLATE:", 24))
- {
- found_one = TRUE;
-
- XP_STRTOK(value, ";"); /* terminate at ';' */
-
- StrAllocCopy(URL_s->protection_template, value);
- }
- else if(!strncasecomp(name, "WINDOW-TARGET:", 14))
- {
- found_one = TRUE;
-
- XP_STRTOK(value, ";"); /* terminate at ';' */
-
- if (URL_s->window_target == NULL)
- {
- if ((XP_IS_ALPHA(value[0]) != FALSE)||
- (XP_IS_DIGIT(value[0]) != FALSE)||
- (value[0] == '_'))
- {
- StrAllocCopy(URL_s->window_target, value);
- }
- }
- }
- break;
-
- default:
- /* ignore other headers */
- break;
- }
-
- return(found_one);
- }
-
-
-
- /* scans a line for references to URL's and turns them into active
- * links. If the output size is exceeded the line will be
- * truncated. "output" must be at least "output_size" characters
- * long
- *
- * This also quotes other HTML forms, and italicizes citations,
- * unless `urls_only' is true.
- */
-
- #ifndef MOZILLA_CLIENT
- /* If we're not in the client, stub out the libmsg interface to the
- citation-highlighting code.
- */
- # define MSG_PlainFont 0
- # define MSG_BoldFont 1
- # define MSG_ItalicFont 2
- # define MSG_BoldItalicFont 3
- # define MSG_NormalSize 4
- # define MSG_Bigger 5
- # define MSG_Smaller 6
- #endif /* MOZILLA_CLIENT */
-
- static MSG_FONT CitationFont = MSG_ItalicFont;
- static int32 CitationSize = 0;
- static char *CitationColor = 0;
- static int CitationDataValid = -1; /* -1=first time, 0=changed; 1=data ok */
-
-
-
- /* fix Mac warning about missing prototype */
- int PR_CALLBACK
- net_citation_style_changed(const char* name, void* closure);
-
- int PR_CALLBACK
- net_citation_style_changed(const char* name, void* closure)
- {
- CitationDataValid = 0;
- return 0;
- }
-
-
-
-
-
- PUBLIC int
- NET_ScanForURLs(MSG_Pane* pane, const char *input, int32 input_size,
- char *output, int output_size, XP_Bool urls_only)
- {
- int col = 0;
- const char *cp;
- const char *end = input + input_size;
- char *output_ptr = output;
- char *end_of_buffer = output + output_size - 40; /* add safty zone :( */
- Bool line_is_citation = FALSE;
- const char *cite_open1, *cite_close1;
- const char *cite_open2, *cite_close2;
- const char* color = NULL;
-
- if (urls_only)
- {
- cite_open1 = cite_close1 = "";
- cite_open2 = cite_close2 = "";
- }
- else
- {
- #ifdef MOZILLA_CLIENT
- if (CitationDataValid != 1) {
- int32 value = (int32) MSG_ItalicFont;
- if (CitationDataValid < 0) {
- PREF_RegisterCallback("mail.quoted_style",
- net_citation_style_changed,
- NULL);
- PREF_RegisterCallback("mail.quoted_size",
- net_citation_style_changed,
- NULL);
- PREF_RegisterCallback("mail.citation_color",
- net_citation_style_changed,
- NULL);
- }
- PREF_GetIntPref("mail.quoted_style", &value);
- CitationFont = (MSG_FONT) value;
- CitationSize = 0;
- PREF_GetIntPref("mail.quoted_size", &CitationSize);
- FREEIF(CitationColor);
- CitationColor = NULL;
- PREF_CopyCharPref("mail.citation_color", &CitationColor);
- CitationDataValid = 1;
- }
-
- switch (CitationFont)
- {
- case MSG_PlainFont:
- cite_open1 = "", cite_close1 = "";
- break;
- case MSG_BoldFont:
- cite_open1 = "<B>", cite_close1 = "</B>";
- break;
- case MSG_ItalicFont:
- cite_open1 = "<I>", cite_close1 = "</I>";
- break;
- case MSG_BoldItalicFont:
- cite_open1 = "<B><I>", cite_close1 = "</I></B>";
- break;
- default:
- XP_ASSERT(0);
- cite_open1 = cite_close1 = "";
- break;
- }
- switch (CitationSize) {
- case 0: /* Normal */
- cite_open2 = "", cite_close2 = "";
- break;
- case 1: /* Bigger */
- cite_open2 = "<FONT SIZE=+1>", cite_close2 = "</FONT>";
- break;
- case 2: /* Smaller */
- case -1: /* backwards compatability with some old code */
- cite_open2 = "<FONT SIZE=-1>", cite_close2 = "</FONT>";
- break;
- default:
- XP_ASSERT(0);
- cite_open2 = cite_close2 = "";
- break;
- }
-
- #else
- XP_ASSERT(0);
- #endif /* MOZILLA_CLIENT */
- }
-
- if (!urls_only)
- {
- /* Decide whether this line is a quotation, and should be italicized.
- This implements the following case-sensitive regular expression:
-
- ^[ \t]*[A-Z]*[]>]
-
- Which matches these lines:
-
- > blah blah blah
- > blah blah blah
- LOSER> blah blah blah
- LOSER] blah blah blah
- */
- const char *s = input;
- while (s < end && XP_IS_SPACE (*s)) s++;
- while (s < end && *s >= 'A' && *s <= 'Z') s++;
-
- if (s >= end)
- ;
- else if (input_size >= 6 && *s == '>' &&
- !XP_STRNCMP (input, ">From ", 6)) /* sendmail... */
- ;
- else if (*s == '>' || *s == ']')
- {
- line_is_citation = TRUE;
- XP_STRCPY(output_ptr, cite_open1);
- output_ptr += XP_STRLEN(cite_open1);
- XP_STRCPY(output_ptr, cite_open2);
- output_ptr += XP_STRLEN(cite_open2);
- if (CitationColor &&
- output_ptr + XP_STRLEN(CitationColor) + 20 < end_of_buffer) {
- XP_STRCPY(output_ptr, "<FONT COLOR=");
- output_ptr += XP_STRLEN(output_ptr);
- XP_STRCPY(output_ptr, CitationColor);
- output_ptr += XP_STRLEN(output_ptr);
- XP_STRCPY(output_ptr, ">");
- output_ptr += XP_STRLEN(output_ptr);
- }
- }
- }
-
- /* Normal lines are scanned for buried references to URL's
- Unfortunately, it may screw up once in a while (nobody's perfect)
- */
- for(cp = input; cp < end && output_ptr < end_of_buffer; cp++)
- {
- /* if NET_URL_Type returns true then it is most likely a URL
- But only match protocol names if at the very beginning of
- the string, or if the preceeding character was not alphanumeric;
- this lets us match inside "---HTTP://XXX" but not inside of
- things like "NotHTTP://xxx"
- */
- int type = 0;
- if(!XP_IS_SPACE(*cp) &&
- (cp == input || (!XP_IS_ALPHA(cp[-1]) && !XP_IS_DIGIT(cp[-1]))) &&
- (type = NET_URL_Type(cp)) != 0)
- {
- const char *cp2;
-
- for(cp2=cp; cp2 < end; cp2++)
- {
- /* These characters always mark the end of the URL. */
- if (XP_IS_SPACE(*cp2) ||
- *cp2 == '<' || *cp2 == '>' ||
- *cp2 == '`' || *cp2 == ')' ||
- *cp2 == '\'' || *cp2 == '"' ||
- *cp2 == ']' || *cp2 == '}') break;
- }
-
- /* Check for certain punctuation characters on the end, and strip
- them off. */
- while (cp2 > cp &&
- (cp2[-1] == '.' || cp2[-1] == ',' || cp2[-1] == '!' ||
- cp2[-1] == ';' || cp2[-1] == '-' || cp2[-1] == '?' ||
- cp2[-1] == '#'))
- cp2--;
-
- col += (cp2 - cp);
-
- /* if the url is less than 7 characters then we screwed up
- * and got a "news:" url or something which is worthless
- * to us. Exclude the A tag in this case.
- *
- * Also exclude any URL that ends in a colon; those tend
- * to be internal and magic and uninteresting.
- *
- * And also exclude the builtin icons, whose URLs look
- * like "internal-gopher-binary".
- */
- if (cp2-cp < 7 ||
- (cp2 > cp && cp2[-1] == ':') ||
- !XP_STRNCMP(cp, "internal-", 9))
- {
- XP_MEMCPY(output_ptr, cp, cp2-cp);
- output_ptr += (cp2-cp);
- *output_ptr = 0;
- }
- else
- {
- char *quoted_url;
- int32 size_left = output_size - (output_ptr-output);
-
- if(cp2-cp > size_left)
- return MK_OUT_OF_MEMORY;
-
- XP_MEMCPY(output_ptr, cp, cp2-cp);
- output_ptr[cp2-cp] = 0;
- quoted_url = NET_EscapeHTML(output_ptr);
- if (!quoted_url) return MK_OUT_OF_MEMORY;
- PR_snprintf(output_ptr, size_left,
- "<A HREF=\"%s\">%s</A>",
- quoted_url,
- quoted_url);
- output_ptr += XP_STRLEN(output_ptr);
- XP_FREE(quoted_url);
- }
-
- cp = cp2-1; /* go to next word */
- }
- else
- {
- /* Make sure that special symbols don't screw up the HTML parser
- */
- if(*cp == '<')
- {
- XP_STRCPY(output_ptr, "<");
- output_ptr += 4;
- col++;
- }
- else if(*cp == '>')
- {
- XP_STRCPY(output_ptr, ">");
- output_ptr += 4;
- col++;
- }
- else if(*cp == '&')
- {
- XP_STRCPY(output_ptr, "&");
- output_ptr += 5;
- col++;
- }
- else
- {
- *output_ptr++ = *cp;
- col++;
- }
- }
- }
-
- *output_ptr = 0;
-
- if (line_is_citation) /* Close off the highlighting */
- {
- if (CitationColor) {
- XP_STRCPY(output_ptr, "</FONT>");
- output_ptr += XP_STRLEN(output_ptr);
- }
-
- XP_STRCPY(output_ptr, cite_close2);
- output_ptr += XP_STRLEN (cite_close2);
- XP_STRCPY(output_ptr, cite_close1);
- output_ptr += XP_STRLEN (cite_close1);
- }
-
- return 0;
- }
-
-
- static void
- Append(char** output, int32* output_max, char** curoutput, const char* buf,
- int32 length)
- {
- if (length + (*curoutput) - (*output) >= *output_max) {
- int offset = (*curoutput) - (*output);
- do {
- (*output_max) += 1024;
- } while (length + (*curoutput) - (*output) >= *output_max);
- *output = XP_REALLOC(*output, *output_max);
- if (!*output) return;
- *curoutput = *output + offset;
- }
- XP_MEMCPY(*curoutput, buf, length);
- *curoutput += length;
- }
-
-
- char*
- NET_ScanHTMLForURLs(const char* input)
- {
- char* output = NULL;
- char* curoutput;
- int32 output_max;
- char* tmpbuf = NULL;
- int32 tmpbuf_max;
- int32 inputlength;
- const char* inputend;
- const char* linestart;
- const char* lineend;
-
- XP_ASSERT(input);
- if (!input) return NULL;
- inputlength = XP_STRLEN(input);
-
- output_max = inputlength + 1024; /* 1024 bytes ought to be enough to quote
- several URLs, which ought to be as many
- as most docs use. */
- output = XP_ALLOC(output_max);
- if (!output) goto FAIL;
-
- tmpbuf_max = 1024;
- tmpbuf = XP_ALLOC(tmpbuf_max);
- if (!tmpbuf) goto FAIL;
-
- inputend = input + inputlength;
-
- linestart = input;
- curoutput = output;
-
-
- /* Here's the strategy. We find a chunk of plainish looking text -- no
- embedded CR or LF, no "<" or "&". We feed that off to NET_ScanForURLs,
- and append the result. Then we skip to the next bit of plain text. If
- we stopped at an "&", go to the terminating ";". If we stopped at a
- "<", well, if it was a "<A>" tag, then skip to the closing "</A>".
- Otherwise, skip to the end of the tag.
- */
-
-
- lineend = linestart;
- while (linestart < inputend && lineend <= inputend) {
- switch (*lineend) {
- case '<':
- case '>':
- case '&':
- case CR:
- case LF:
- case '\0':
- if (lineend > linestart) {
- int length = lineend - linestart;
- if (length * 3 > tmpbuf_max) {
- tmpbuf_max = length * 3 + 512;
- XP_FREE(tmpbuf);
- tmpbuf = XP_ALLOC(tmpbuf_max);
- if (!tmpbuf) goto FAIL;
- }
- if (NET_ScanForURLs(NULL, linestart, length,
- tmpbuf, tmpbuf_max, TRUE) < 0) {
- goto FAIL;
- }
- length = XP_STRLEN(tmpbuf);
- Append(&output, &output_max, &curoutput, tmpbuf, length);
- if (!output) goto FAIL;
-
- }
- linestart = lineend;
- lineend = NULL;
- if (inputend - linestart < 5) {
- /* Too little to worry about; shove the rest out. */
- lineend = inputend;
- } else {
- switch (*linestart) {
- case '<':
- if ((linestart[1] == 'a' || linestart[1] == 'A') &&
- linestart[2] == ' ') {
- lineend = strcasestr(linestart, "</a");
- if (lineend) {
- lineend = XP_STRCHR(lineend, '>');
- if (lineend) lineend++;
- }
- } else {
- lineend = XP_STRCHR(linestart, '>');
- if (lineend) lineend++;
- }
- break;
- case '&':
- lineend = XP_STRCHR(linestart, ';');
- if (lineend) lineend++;
- break;
- default:
- lineend = linestart + 1;
- break;
- }
- }
- if (!lineend) lineend = inputend;
- Append(&output, &output_max, &curoutput, linestart,
- lineend - linestart);
- if (!output) goto FAIL;
- linestart = lineend;
- break;
- default:
- lineend++;
- }
- }
- XP_FREE(tmpbuf);
- *curoutput = '\0';
- return output;
-
- FAIL:
- if (tmpbuf) XP_FREE(tmpbuf);
- if (output) XP_FREE(output);
- return NULL;
- }
-
-
- /* try to make sure that this is a fully qualified
- * email address including a host and domain
- */
- PUBLIC Bool
- NET_IsFQDNMailAddress(const char * string)
- {
- /* first make sure that an @ exists
- */
- char * at_sign = XP_STRCHR(string, '@');
-
- if(at_sign)
- {
- /* make sure it has at least one period
- */
- if(XP_STRCHR(at_sign, '.'))
- return(TRUE);
- }
-
- return(FALSE);
- }
-
- static int use_ssl_for_imap4 = -1; /* -1 if uninitialized, 0 if FALSE, 1 if TRUE. */
-
- /* fix Mac warning about missing prototype */
- MODULE_PRIVATE int PR_CALLBACK net_use_ssl_for_imap4_changed_func(const char *pref,
- void *data);
-
- MODULE_PRIVATE int PR_CALLBACK net_use_ssl_for_imap4_changed_func(const char *pref,
- void *data)
- {
- int status = PREF_NOERROR;
-
- if (!XP_STRCASECMP(pref,"mail.imap.server_ssl")) {
- XP_Bool new_val;
-
- status = PREF_GetBoolPref("mail.imap.server_ssl", &new_val);
- use_ssl_for_imap4 = (int)new_val;
- }
- return status;
- }
-
-
- /* returns true if the URL is a secure URL address
- */
- PUBLIC Bool
- NET_IsURLSecure(char * address)
- {
- int type = NET_URL_Type (address);
-
- TRACEMSG(("NET_IsURLSecure called, type: %d", type));
-
- if(type == SECURE_HTTP_TYPE_URL
- || type == INTERNAL_IMAGE_TYPE_URL
- || type == SECURE_LDAP_TYPE_URL)
- return(TRUE);
-
- if(!strncasecomp(address, "/mc-icons/", 10) ||
- !strncasecomp(address, "/ns-icons/", 10))
- return(TRUE);
-
- if(!strncasecomp(address, "internal-external-reconnect:", 28))
- return(TRUE);
-
- if(!strcasecomp(address, "internal-external-plugin"))
- return(TRUE);
-
- if(!strncasecomp(address, "snews:", 6))
- return TRUE;
-
- /*
- * IMAP URLs begin with "mailbox://" unlike POP URLs which begin
- * with "mailbox:".
- */
- if(!strncasecomp(address, "mailbox://", 10)) {
- if (use_ssl_for_imap4 < 0) { /* If uninitialized. */
- XP_Bool new_val;
- int status = PREF_GetBoolPref("mail.imap.server_ssl", &new_val);
-
- if (status == PREF_NOERROR) {
- use_ssl_for_imap4 = (int)new_val;
- PREF_RegisterCallback("mail.imap.server_ssl",
- net_use_ssl_for_imap4_changed_func, NULL);
- }
- else {
- return FALSE;
- }
- }
- return (Bool)use_ssl_for_imap4;
- }
-
-
- TRACEMSG(("NET_IsURLSecure: URL NOT SECURE"));
-
- return(FALSE);
- }
-
- /* escapes all '<', '>' and '&' characters in a string
- * returns a string that must be freed
- */
- PUBLIC char *
- NET_EscapeHTML(const char * string)
- {
- char *rv = (char *) XP_ALLOC(XP_STRLEN(string)*4 + 1); /* The +1 is for
- the trailing
- null! */
- char *ptr = rv;
-
- if(rv)
- {
- for(; *string != '\0'; string++)
- {
- if(*string == '<')
- {
- *ptr++ = '&';
- *ptr++ = 'l';
- *ptr++ = 't';
- *ptr++ = ';';
- }
- else if(*string == '>')
- {
- *ptr++ = '&';
- *ptr++ = 'g';
- *ptr++ = 't';
- *ptr++ = ';';
- }
- else if(*string == '&')
- {
- *ptr++ = '&';
- *ptr++ = 'a';
- *ptr++ = 'm';
- *ptr++ = 'p';
- *ptr++ = ';';
- }
- else
- {
- *ptr++ = *string;
- }
- }
- *ptr = '\0';
- }
-
- return(rv);
- }
-
-
- PUBLIC char *
- NET_SpaceToPlus(char * string)
- {
-
- char * ptr = string;
-
- if(!ptr)
- return(NULL);
-
- for(; *ptr != '\0'; ptr++)
- if(*ptr == ' ')
- *ptr = '+';
-
- return(string);
- }
-
-
- /* returns true if the functions thinks the string contains
- * HTML
- */
- PUBLIC Bool
- NET_ContainsHTML(char * string, int32 length)
- {
- char * ptr = string;
- register int32 count=length;
-
- /* restrict searching to first K to limit false positives */
- if(count > 1024)
- count = 1024;
-
- /* if the string begins with "#!" or "%!" then it's a script of some kind,
- and it doesn't matter how many HTML tags that program references in its
- source -- it ain't HTML. This false match happened all the time with,
- for example, CGI scripts written in sh or perl that emit HTML. */
- if (count > 2 &&
- (string[0] == '#' || string[0] == '%') &&
- string[1] == '!')
- return FALSE;
-
- /* If it begins with a mailbox delimiter, it's not HTML. */
- if (count > 5 &&
- (!XP_STRNCMP(string, "From ", 5) ||
- !XP_STRNCMP(string, ">From ", 6)))
- return FALSE;
-
- for(; count > 0; ptr++, count--)
- if(*ptr == '<')
- {
- if(count > 3 && !strncasecomp(ptr+1, "HTML", 4))
- return(TRUE);
-
- if(count > 4 && !strncasecomp(ptr+1, "TITLE", 5))
- return(TRUE);
-
- if(count > 3 && !strncasecomp(ptr+1, "FRAMESET", 8))
- return(TRUE);
-
- if(count > 2 &&
- toupper(*(ptr+1)) == 'H'
- && isdigit(*(ptr+2)) && *(ptr+3) == '>')
- return(TRUE);
- }
-
- return(FALSE);
- }
-
- /* take a Layout generated LO_FormSubmitData_struct
- * and use it to add post data to the URL Structure
- * generated by CreateURLStruct
- *
- * DOES NOT Generate the URL Struct, it must be created prior to
- * calling this function
- *
- * returns 0 on failure and 1 on success
- */
-
- PUBLIC int
- NET_AddLOSubmitDataToURLStruct(LO_FormSubmitData * sub_data,
- URL_Struct * url_struct)
- {
-
- int32 i;
- int32 total_size;
- char *end, *tmp_ptr;
- char *encoding;
- char *target;
- char **name_array;
- char **value_array;
- uint8 *type_array;
- uint8 *encoding_array;
- char *esc_string;
- int32 len = 0;
-
- if(!sub_data || !url_struct)
- return(0);
-
- if(sub_data->method == FORM_METHOD_GET)
- url_struct->method = URL_GET_METHOD;
- else
- url_struct->method = URL_POST_METHOD;
- if (!strncasecomp(url_struct->address, "mailto:", 7)) {
- url_struct->mailto_post = TRUE;
- }
-
- /* free any previous url_struct->post_data
- */
- FREEIF(url_struct->post_data);
-
- PA_LOCK(name_array, char**, sub_data->name_array);
- PA_LOCK(value_array, char**, sub_data->value_array);
- PA_LOCK(type_array, uint8*, sub_data->type_array);
- PA_LOCK(encoding_array, uint8*, sub_data->encoding_array);
- PA_LOCK(encoding, char*, sub_data->encoding);
-
- /* free any previous target
- */
- FREEIF(url_struct->window_target);
- PA_LOCK(target, char*, sub_data->window_target);
- if (target == NULL)
- url_struct->window_target = NULL;
- else
- url_struct->window_target = XP_STRDUP (target);
-
- FREEIF (url_struct->post_headers);
-
- /* If we're posting to mailto, then generate the full complement
- of mail headers; and allow the url to specify additional headers
- as well. */
- #ifdef MOZ_MAIL_NEWS
- if (!strncasecomp(url_struct->address, "mailto:", 7))
- {
- #ifdef MOZILLA_CLIENT
- int status;
- char *new_url = 0;
- char *headers = 0;
-
- status = MIME_GenerateMailtoFormPostHeaders (url_struct->address,
- url_struct->referer,
- &new_url, &headers);
- if (status < 0)
- {
- FREEIF (new_url);
- FREEIF (headers);
- return status;
- }
- XP_ASSERT (new_url);
- XP_ASSERT (headers);
- url_struct->address_modified = TRUE;
- XP_FREE (url_struct->address);
- url_struct->address = new_url;
- url_struct->post_headers = headers;
- #else
- XP_ASSERT(0);
- #endif /* MOZILLA_CLIENT */
- }
- #endif /* MOZ_MAIL_NEWS */
-
- if(encoding && !strcasecomp(encoding, "text/plain"))
- {
- char *tmpfilename;
- char buffer[512];
- XP_File fp;
-
- /* always use post for this encoding type
- */
- url_struct->method = URL_POST_METHOD;
-
- /* write all the post data to a file first
- * so that we can send really big stuff
- */
- #ifdef XP_MAC /* This should really be for all platforms but I am fixing a bug for final release */
- tmpfilename = WH_TempName (xpFileToPost, "nsform");
- if (!tmpfilename) return 0;
- fp = XP_FileOpen (tmpfilename, xpFileToPost, XP_FILE_WRITE_BIN);
- #else
- tmpfilename = WH_TempName (xpTemporary, "nsform");
- if (!tmpfilename) return 0;
- fp = XP_FileOpen (tmpfilename, xpTemporary, XP_FILE_WRITE_BIN);
- #endif
- if (!fp) {
- XP_FREE(tmpfilename);
- return 0;
- }
-
- if (url_struct->post_headers)
- {
- len = XP_FileWrite(url_struct->post_headers,
- XP_STRLEN (url_struct->post_headers),
- fp);
- XP_FREE (url_struct->post_headers);
- url_struct->post_headers = 0;
- if (len < 0)
- {
- XP_FileClose(fp);
- return 0;
- }
- }
-
- XP_STRCPY (buffer,
- "Content-type: text/plain" CRLF
- "Content-Disposition: inline; form-data" CRLF CRLF);
- len = XP_FileWrite(buffer, XP_STRLEN(buffer), fp);
-
- for(i=0; (len >= 0) && (i < sub_data->value_cnt); i++)
- {
- if(name_array[i])
- XP_FileWrite(name_array[i], XP_STRLEN(name_array[i]), fp);
- XP_FileWrite("=", 1, fp);
- if(value_array[i])
- XP_FileWrite(value_array[i], XP_STRLEN(value_array[i]), fp);
- len = XP_FileWrite(CRLF, 2, fp);
- }
- XP_FileClose(fp);
-
- StrAllocCopy(url_struct->post_data, tmpfilename);
- XP_FREE(tmpfilename);
- if (len < 0)
- return 0;
- url_struct->post_data_is_file = TRUE;
- }
- else if(encoding && !strcasecomp(encoding, "multipart/form-data"))
- {
- /* encoding using a variant of multipart/mixed
- * and add files to it as well
- */
- char *tmpfilename;
- char separator[80];
- char buffer[512];
- XP_File fp;
- int boundary_len;
- int cont_disp_len;
- NET_cinfo * ctype;
-
-
- /* always use post for this encoding type
- */
- url_struct->method = URL_POST_METHOD;
-
- /* write all the post data to a file first
- * so that we can send really big stuff
- */
- tmpfilename = WH_TempName (xpFileToPost, "nsform");
- if (!tmpfilename) return 0;
- fp = XP_FileOpen (tmpfilename, xpFileToPost, XP_FILE_WRITE_BIN);
- if (!fp) {
- XP_FREE(tmpfilename);
- return 0;
- }
-
- sprintf(separator, "---------------------------%d%d%d",
- rand(), rand(), rand());
-
- if(url_struct->post_headers)
- {
- len = XP_FileWrite(url_struct->post_headers,
- XP_STRLEN (url_struct->post_headers),
- fp);
- XP_FREE (url_struct->post_headers);
- url_struct->post_headers = 0;
- if (len < 0)
- return 0;
- }
-
- sprintf(buffer,
- "Content-type: multipart/form-data;"
- " boundary=%s" CRLF,
- separator);
- len = XP_FileWrite(buffer, XP_STRLEN(buffer), fp);
-
- #define CONTENT_DISPOSITION "Content-Disposition: form-data; name=\""
- #define PLUS_FILENAME "\"; filename=\""
- #define CONTENT_TYPE_HEADER "Content-Type: "
- #define CONTENT_ENCODING_HEADER "Content-Encoding: "
-
- /* compute the content length */
- total_size = -2; /* start at negative 2 to disregard the
- * CRLF that act as a header separator
- */
- boundary_len = XP_STRLEN(separator) + 6;
- cont_disp_len = XP_STRLEN(CONTENT_DISPOSITION);
-
- for(i=0; (len >= 0) && (i < sub_data->value_cnt); i++)
- {
- total_size += boundary_len;
-
- /* The size of the content-disposition line is hard
- * coded and must be modified any time you change
- * the sprintf in the next for loop
- */
- total_size += cont_disp_len;
- if(name_array[i])
- total_size += XP_STRLEN(name_array[i]);
- total_size += 5; /* quote plus two CRLF's */
-
- if(type_array[i] == FORM_TYPE_FILE)
- {
- XP_StatStruct stat_entry;
-
- /* in this case we are going to send an extra
- * ; filename="value_array[i]"
- */
- total_size += XP_STRLEN(PLUS_FILENAME);
- if(value_array[i])
- {
- /* only write the filename, not the whole path */
- char * slash = XP_STRRCHR(value_array[i], '/');
- if(slash)
- slash++;
- else
- slash = value_array[i];
- total_size += XP_STRLEN(slash);
-
- #ifdef XP_MAC
- if(encoding_array[i] == INPUT_TYPE_ENCODING_MACBIN)
- {
- /* add the size of the content type header */
- /* NOTE - even though MacBinary is technically an encoding type we send
- it as a content type and skip the normal routine of trying
- to determine the actual file type
- */
- total_size += sizeof(CONTENT_TYPE_HEADER)-1;
- total_size += sizeof(APPLICATION_MACBINARY)-1;
- total_size += 2; /* for the CRLF terminator */
- }
- else
- #endif /* XP_MAC */
- {
-
- /* try and determine the content-type of the file
- */
- ctype = NET_cinfo_find_type(value_array[i]);
-
- if(!ctype->is_default)
- {
- /* we have determined it's type. Add enough
- * space for it
- */
- total_size += sizeof(CONTENT_TYPE_HEADER)-1;
- total_size += XP_STRLEN(ctype->type);
- total_size += 2; /* for the CRLF terminator */
- }
- }
- }
- #ifdef XP_MAC
- if(encoding_array[i] == INPUT_TYPE_ENCODING_MACBIN)
- {
- /* figure out the size of the macbinary encoded file
- * and add it to total_size
- */
- if(value_array[i] && *value_array[i])
- if(-1 != MB_Stat (value_array[i], &stat_entry, xpFileToPost))
- total_size += stat_entry.st_size;
- }
- else
- #endif /* XP_MAC */
- {
- /* if the type is a FILE type then we
- * need to stat the file to get the size
- */
- if(value_array[i] && *value_array[i])
- if(-1 != XP_Stat (value_array[i], &stat_entry, xpFileToPost))
- total_size += stat_entry.st_size;
-
- /* if we can't stat the file just add zero */
- }
- }
- else
- {
- if(value_array[i])
- total_size += XP_STRLEN(value_array[i]);
- }
- }
- /* add the size of the last separator plus
- * two for the extra two dashes
- */
- total_size += boundary_len+2;
-
- sprintf(buffer, "Content-Length: %ld%s", total_size, CRLF);
- len = XP_FileWrite(buffer, XP_STRLEN(buffer), fp);
-
- for(i=0; (len >= 0) && (i < sub_data->value_cnt); i++)
- {
- sprintf(buffer, "%s--%s%s", CRLF, separator, CRLF);
- XP_FileWrite(buffer, XP_STRLEN(buffer), fp);
-
- /* WARNING!!! If you change the size of any of the
- * sprintf's here you must change the size
- * in the counting for loop above
- */
- XP_FileWrite(CONTENT_DISPOSITION, cont_disp_len, fp);
- if(name_array[i])
- XP_FileWrite(name_array[i], XP_STRLEN(name_array[i]), fp);
-
- if(type_array[i] == FORM_TYPE_FILE)
- {
- XP_FileWrite(PLUS_FILENAME, XP_STRLEN(PLUS_FILENAME), fp);
- if(value_array[i])
- {
- /* only write the filename, not the whole path */
- char * slash = XP_STRRCHR(value_array[i], '/');
- if(slash)
- slash++;
- else
- slash = value_array[i];
- XP_FileWrite(slash, XP_STRLEN(slash), fp);
-
- }
- }
- /* end the content disposition line */
- len = XP_FileWrite("\"" CRLF, XP_STRLEN("\"" CRLF), fp);
-
- if(type_array[i] == FORM_TYPE_FILE && value_array[i])
- {
- #ifdef XP_MAC
- if(encoding_array[i] == INPUT_TYPE_ENCODING_MACBIN)
- {
- /* add the content_type header */
- XP_FileWrite(CONTENT_TYPE_HEADER,
- XP_STRLEN(CONTENT_TYPE_HEADER),
- fp);
- XP_FileWrite(APPLICATION_MACBINARY,
- XP_STRLEN(APPLICATION_MACBINARY),
- fp);
- len = XP_FileWrite(CRLF, XP_STRLEN(CRLF), fp);
- }
- else
- #endif /* XP_MAC */
- {
- /* try and determine the content-type of the file
- */
- ctype = NET_cinfo_find_type(value_array[i]);
-
- if(!ctype->is_default)
- {
- /* we have determined it's type. Send the
- * content-type
- */
- XP_FileWrite(CONTENT_TYPE_HEADER,
- XP_STRLEN(CONTENT_TYPE_HEADER),
- fp);
- XP_FileWrite(ctype->type,
- XP_STRLEN(ctype->type),
- fp);
- len = XP_FileWrite(CRLF, XP_STRLEN(CRLF), fp);
- }
- }
- }
-
- /* end the header */
- len = XP_FileWrite(CRLF, XP_STRLEN(CRLF), fp);
-
- /* send the value of the form field */
-
- /* if the type is a FILE type, send the whole file,
- * the filename is in the value field
- */
- if(type_array[i] == FORM_TYPE_FILE)
- {
- #ifdef XP_MAC
- if(encoding_array[i] == INPUT_TYPE_ENCODING_MACBIN)
- {
- MB_FileSpec mbFile;
- int32 size;
- OSErr theErr;
-
- if (value_array[i] && *value_array[i])
- {
- theErr = MB_Open(value_array[i], &mbFile);
-
- if (theErr == noErr)
- {
- while((size = MB_Read(NET_Socket_Buffer,
- NET_Socket_Buffer_Size,
- &mbFile)) != 0)
- {
- XP_FileWrite(NET_Socket_Buffer, size, fp);
- }
- MB_Close(&mbFile);
- }
- }
- }
- else
- #endif /* XP_MAC */
- {
- XP_File ext_fp=0;
- int32 size;
-
- if(value_array[i] && *value_array[i])
- ext_fp = XP_FileOpen(value_array[i],
- xpFileToPost,
- XP_FILE_READ_BIN);
-
-
- if(ext_fp)
- {
- while((size = XP_FileRead(NET_Socket_Buffer,
- NET_Socket_Buffer_Size,
- ext_fp)) != 0)
- {
- XP_FileWrite(NET_Socket_Buffer, size, fp);
- }
- XP_FileClose(ext_fp);
- }
- }
- }
- else
- {
- if(value_array[i])
- XP_FileWrite(value_array[i], XP_STRLEN(value_array[i]), fp);
- }
- }
-
- sprintf(buffer, "%s--%s--%s", CRLF, separator, CRLF);
- XP_FileWrite(buffer, XP_STRLEN(buffer), fp);
-
- XP_FileClose(fp);
-
- StrAllocCopy(url_struct->post_data, tmpfilename);
- XP_FREE(tmpfilename);
- url_struct->post_data_is_file = TRUE;
-
- }
- else
- {
- total_size=1; /* start at one for the terminator char */
-
- /* find out how much space we need total
- *
- * and also convert all spaces to pluses at the same time
- */
- for(i=0; i<sub_data->value_cnt; i++)
- {
- total_size += NET_EscapedSize(name_array[i], URL_XPALPHAS);
- total_size += NET_EscapedSize(value_array[i], URL_XPALPHAS);
- total_size += 2; /* & = */
- }
-
- if(sub_data->method == FORM_METHOD_GET)
- {
- char *punc;
-
- if(!url_struct->address)
- return(0);
-
- /* get rid of ? or # in the url string since we are adding it
- */
- punc = XP_STRCHR(url_struct->address, '?');
- if(punc)
- *punc = '\0'; /* terminate here */
- punc = XP_STRCHR(url_struct->address, '#');
- if(punc)
- *punc = '\0'; /* terminate here */
-
- /* add the size of the url plus one for the '?'
- */
- total_size += XP_STRLEN(url_struct->address)+1;
- }
-
- url_struct->post_data = (char *) XP_ALLOC(total_size);
-
- if(!url_struct->post_data)
- {
- PA_UNLOCK(sub_data->name_array);
- PA_UNLOCK(sub_data->value_array);
- PA_UNLOCK(sub_data->type_array);
- PA_UNLOCK(sub_data->encoding);
- return(0);
- }
-
- if(sub_data->method == FORM_METHOD_GET)
- {
- end = url_struct->post_data;
- for(tmp_ptr = url_struct->address; *tmp_ptr != '\0'; tmp_ptr++)
- *end++ = *tmp_ptr;
-
- /* add the '?'
- */
- *end++ = '?';
-
- /* swap the post data and address data */
- FREE(url_struct->address);
- url_struct->address = url_struct->post_data;
- url_struct->post_data = 0;
-
- /* perform hack:
- * To be compatible with old pre-form
- * indexes, other web browsers had a hack
- * wherein if a form was being submitted,
- * and its method was get, and it
- * had only one name/value pair, and the
- * name of that pair was "isindex", then
- * it would create the query url
- *
- * URL?value instead of URL?name=value
- */
- if(sub_data->value_cnt == 1 && !strcasecomp(name_array[0], "isindex"))
- {
- if(value_array && value_array[0])
- XP_STRCPY(end, NET_Escape(value_array[0], URL_XPALPHAS));
- else
- *end = '\0';
- PA_UNLOCK(sub_data->name_array);
- PA_UNLOCK(sub_data->value_array);
- PA_UNLOCK(sub_data->type_array);
- PA_UNLOCK(sub_data->encoding);
- return(1);
- }
-
- /* the end ptr is still set to the correct address!
- */
-
- }
- else
- {
- StrAllocCat(url_struct->post_headers,
- "Content-type: application/x-www-form-urlencoded" CRLF);
-
- if(!url_struct->post_headers)
- {
- FREE_AND_CLEAR(url_struct->post_data);
- PA_UNLOCK(sub_data->name_array);
- PA_UNLOCK(sub_data->value_array);
- PA_UNLOCK(sub_data->type_array);
- PA_UNLOCK(sub_data->encoding);
- return(0);
- }
-
- end = url_struct->post_data;
-
- }
-
- /* build the string
- */
- for(i=0; i<sub_data->value_cnt; i++)
- {
- /* add the name
- */
- esc_string = NET_Escape(name_array[i], URL_XPALPHAS);
- if(esc_string)
- {
- for(tmp_ptr = esc_string; *tmp_ptr != '\0'; tmp_ptr++)
- *end++ = *tmp_ptr;
- XP_FREE(esc_string);
- }
-
- /* join the name and value with a '='
- */
- *end++ = '=';
-
- /* add the value
- */
- esc_string = NET_Escape(value_array[i], URL_XPALPHAS);
- if(esc_string)
- {
- for(tmp_ptr = esc_string; *tmp_ptr != '\0'; tmp_ptr++)
- *end++ = *tmp_ptr;
- XP_FREE(esc_string);
- }
-
- /* join pairs with a '&'
- * make sure there is another pair before adding
- */
- if(i+1 < sub_data->value_cnt)
- *end++ = '&';
- }
-
- /* terminate the string
- */
- *end = '\0';
-
- if(sub_data->method == FORM_METHOD_POST)
- {
- char buffer[64];
- url_struct->post_data_size = XP_STRLEN(url_struct->post_data);
- XP_SPRINTF(buffer,
- "Content-length: %ld" CRLF,
- url_struct->post_data_size);
- StrAllocCat(url_struct->post_headers, buffer);
-
- #ifdef ADD_EXTRA_CRLF_TO_POSTS
- /* munge for broken CGIs. Add an extra CRLF to the
- * post data.
- */
- BlockAllocCat(url_struct->post_data,
- url_struct->post_data_size,
- CRLF,
- 3);
- /* don't add the eol terminator */
- url_struct->post_data_size += 2;
- #endif /* ADD_EXTRA_CRLF_TO_POSTS */
-
- }
- }
-
- PA_UNLOCK(sub_data->name_array);
- PA_UNLOCK(sub_data->value_array);
- PA_UNLOCK(sub_data->type_array);
- PA_UNLOCK(sub_data->encoding);
-
- return(1); /* success */
- }
-
- PUBLIC int
- NET_AddCoordinatesToURLStruct(URL_Struct * url_struct, int32 x_coord, int32 y_coord)
- {
-
- if(url_struct->address)
- {
- char buffer[32];
-
- XP_SPRINTF(buffer, "?%ld,%ld", x_coord, y_coord);
-
- /* get rid of ? or # in the url string since we are adding it
- */
- #undef STRIP_SEARCH_DATA_FROM_ISMAP_URLS
- #ifdef STRIP_SEARCH_DATA_FROM_ISMAP_URLS
- {
- char *punc;
- punc = XP_STRCHR(url_struct->address, '?');
- if(punc)
- *punc = '\0'; /* terminate here */
- punc = XP_STRCHR(url_struct->address, '#');
- if(punc)
- *punc = '\0'; /* terminate here */
- }
- #endif /* STRIP_SEARCH_DATA_FROM_ISMAP_URLS */
-
- StrAllocCat(url_struct->address, buffer);
- }
-
- return(1); /* success */
- }
-
- /* FREE_AND_CLEAR will free a pointer if it is non-zero and
- * then set it to zero
- */
- MODULE_PRIVATE void
- NET_f_a_c (char **pointer)
- {
- if(*pointer) {
- XP_FREE(*pointer);
- *pointer = 0;
- }
- }
-
- /* recognizes URLs and their types. Returns 0 (zero) if
- * it is unrecognized.
- */
- PUBLIC int
- NET_URL_Type (CONST char *URL)
- {
- /* Protect from SEGV */
- if (!URL || (URL && *URL == '\0'))
- return(0);
-
- switch(*URL) {
- case 'a':
- case 'A':
- if(!strncasecomp(URL,"about:security", 14))
- return(SECURITY_TYPE_URL);
- else if(!strncasecomp(URL,"about:",6))
- return(ABOUT_TYPE_URL);
- else if(!strncasecomp(URL,"addbook:",8))
- return(ADDRESS_BOOK_TYPE_URL);
- else if (!strncasecomp(URL, "addbook-ldap", 12)) /*no colon includes addbook-ldaps:*/
- return(ADDRESS_BOOK_LDAP_TYPE_URL);
- break;
-
- case 'd':
- case 'D':
- if(!strncasecomp(URL,"data:",5))
- return(DATA_TYPE_URL);
- break;
-
- case 'c':
- case 'C':
- if(!strncasecomp(URL,"castanet:",9))
- return(0);
- break;
-
- case 'f':
- case 'F':
- if(!strncasecomp(URL,"ftp:",4))
- return(FTP_TYPE_URL);
- else if(!strncasecomp(URL,"file:",5))
- return(FILE_TYPE_URL);
- break;
- case 'g':
- case 'G':
- if(!strncasecomp(URL,"gopher:",7))
- return(GOPHER_TYPE_URL);
- break;
- case 'h':
- case 'H':
- if(!strncasecomp(URL,"http:",5))
- return(HTTP_TYPE_URL);
- else if(!strncasecomp(URL,"https:",6))
- return(SECURE_HTTP_TYPE_URL);
- break;
- case 'i':
- case 'I':
- if(!strncasecomp(URL,"internal-gopher-",16))
- return(INTERNAL_IMAGE_TYPE_URL);
- else if(!strncasecomp(URL,"internal-news-",14))
- return(INTERNAL_IMAGE_TYPE_URL);
- else if(!strncasecomp(URL,"internal-edit-",14))
- return(INTERNAL_IMAGE_TYPE_URL);
- else if(!strncasecomp(URL,"internal-attachment-",20))
- return(INTERNAL_IMAGE_TYPE_URL);
- else if(!strncasecomp(URL,"internal-sa-",12))
- return(INTERNAL_IMAGE_TYPE_URL);
- else if(!strncasecomp(URL,"internal-smime-",15))
- return(INTERNAL_IMAGE_TYPE_URL);
- else if(!strncasecomp(URL,"internal-dialog-handler",23))
- return(HTML_DIALOG_HANDLER_TYPE_URL);
- else if(!strncasecomp(URL,"internal-panel-handler",22))
- return(HTML_PANEL_HANDLER_TYPE_URL);
- else if(!strncasecomp(URL,"internal-security-",18))
- return(INTERNAL_SECLIB_TYPE_URL);
- else if(!strncasecomp(URL,"internal-certldap",17))
- return(INTERNAL_CERTLDAP_TYPE_URL);
- else if(!strncasecomp(URL,"IMAP:",5))
- return(IMAP_TYPE_URL);
- break;
- case 'j':
- case 'J':
- if(!strncasecomp(URL, "javascript:",11))
- return(MOCHA_TYPE_URL);
- break;
- case 'l':
- case 'L':
- if(!strncasecomp(URL, "livescript:",11))
- return(MOCHA_TYPE_URL);
- else if (!strncasecomp(URL, "ldap:",5))
- return(LDAP_TYPE_URL);
- else if (!strncasecomp(URL, "ldaps:",6))
- return(SECURE_LDAP_TYPE_URL);
- break;
- case 'm':
- case 'M':
- if(!strncasecomp(URL,"mailto:",7))
- return(MAILTO_TYPE_URL);
- else if(!strncasecomp(URL,"mailbox:",8))
- return(MAILBOX_TYPE_URL);
- else if(!strncasecomp(URL, "mocha:",6))
- return(MOCHA_TYPE_URL);
- break;
- case 'n':
- case 'N':
- if(!strncasecomp(URL,"news:",5))
- return(NEWS_TYPE_URL);
- else if(!strncasecomp(URL,"nfs:",4))
- return(NFS_TYPE_URL);
- else if(!strncasecomp(URL, NETHELP_URL_PREFIX, sizeof(NETHELP_URL_PREFIX)-1))
- return(NETHELP_TYPE_URL);
- break;
- case 'p':
- case 'P':
- if(!strncasecomp(URL,"pop3:",5))
- return(POP3_TYPE_URL);
- break;
- case 'r':
- case 'R':
- if(!strncasecomp(URL,"rlogin:",7))
- return(RLOGIN_TYPE_URL);
- break;
- case 's':
- case 'S':
- if(!strncasecomp(URL,"snews:",6))
- return(NEWS_TYPE_URL);
- else if (!strncasecomp(URL,"search-libmsg:",14))
- return(MSG_SEARCH_TYPE_URL);
- case 't':
- case 'T':
- if(!strncasecomp(URL,"telnet:",7))
- return(TELNET_TYPE_URL);
- else if(!strncasecomp(URL,"tn3270:",7))
- return(TN3270_TYPE_URL);
- break;
- case 'u':
- case 'U':
- if(!strncasecomp(URL,"URN:",4))
- return(URN_TYPE_URL);
- break;
- case 'v':
- case 'V':
- if(!strncasecomp(URL, VIEW_SOURCE_URL_PREFIX,
- sizeof(VIEW_SOURCE_URL_PREFIX)-1))
- return(VIEW_SOURCE_TYPE_URL);
- break;
- case 'w':
- case 'W':
- if(!strncasecomp(URL,"wais:",5))
- return(WAIS_TYPE_URL);
- if(!strncasecomp(URL,"wysiwyg:",8))
- return(WYSIWYG_TYPE_URL);
- break;
- }
-
- /* no type match :( */
- return(0);
- }
-
- PUBLIC void
- NET_PlusToSpace(char *str)
- {
- for (; *str != '\0'; str++)
- if (*str == '+')
- *str = ' ';
- }
-
-
- static int
- net_buffer_output_fn ( const char *buf, int32 size, void *closure)
- {
- BufferStruct *bs = (BufferStruct *) closure;
- /* if the size greater or equal to the available buffer size
- * reallocate the buffer
- */
- XP_ASSERT (buf && bs && size > 0);
- if ( !buf || !bs || size <= 0 )
- return -1;
-
- if (size >= bs->size - bs->pos)
- {
- int32 len;
- char *newBuffer;
-
- len = (bs->size << 1) - bs->pos + size + 1; /* null terminated */
- if (bs->buffer)
- newBuffer = XP_REALLOC (bs->buffer, len);
- else
- newBuffer = XP_ALLOC(len);
- if (!newBuffer)
- return MK_OUT_OF_MEMORY;
- XP_MEMSET(newBuffer+bs->pos, 0, len-bs->pos);
- bs->size = len;
- bs->buffer = newBuffer;
- }
- XP_MEMCPY (bs->buffer+bs->pos, buf, size);
- bs->pos += size;
- return 0;
- }
-
- PRIVATE int32
- net_URNProtoLoad(ActiveEntry *ce)
- {
- char buffer[256];
-
- XP_STRCPY(buffer, XP_GetString(XP_ALERT_URN_USEHTTP));
- XP_STRNCAT(buffer, ce->URL_s->address, 150);
- buffer[255] = '\0'; /* in case strncat doesn't add one */
- FE_Alert(ce->window_id, buffer);
-
- return -1;
- }
-
- PRIVATE int32
- net_URNProtoStub(ActiveEntry *ce)
- {
- XP_ASSERT(0);
- return -1;
- }
-
- PRIVATE void
- net_URNProtoCleanupStub(void)
- {
- }
-
- /* a stub function for URN protocol converter.
- * right now we only proxy URN's
- * if URN's ever get worked on move this to another file
- */
- PUBLIC void
- NET_InitURNProtocol(void)
- {
- static NET_ProtoImpl urn_proto_impl;
-
- urn_proto_impl.init = net_URNProtoLoad;
- urn_proto_impl.process = net_URNProtoStub;
- urn_proto_impl.interrupt = net_URNProtoStub;
- urn_proto_impl.cleanup = net_URNProtoCleanupStub;
-
- NET_RegisterProtocolImplementation(&urn_proto_impl, URN_TYPE_URL);
- }
-
- PRIVATE int32
- net_NFSProtoLoad(ActiveEntry *ce)
- {
- char buffer[256];
-
- XP_STRCPY(buffer, XP_GetString(XP_ALERT_NFS_USEHTTP));
- XP_STRNCAT(buffer, ce->URL_s->address, 150);
- buffer[255] = '\0'; /* in case strncat doesn't add one */
- FE_Alert(ce->window_id, buffer);
-
- return -1;
- }
-
- PRIVATE int32
- net_NFSProtoStub(ActiveEntry *ce)
- {
- XP_ASSERT(0);
- return -1;
- }
-
- PRIVATE void
- net_NFSProtoCleanupStub(void)
- {
- }
-
- /* a stub function for NFS protocol converter.
- * right now we only proxy NFS's
- * if NFS's ever get worked on move this to another file
- */
- PUBLIC void
- NET_InitNFSProtocol(void)
- {
- static NET_ProtoImpl nfs_proto_impl;
-
- nfs_proto_impl.init = net_NFSProtoLoad;
- nfs_proto_impl.process = net_NFSProtoStub;
- nfs_proto_impl.interrupt = net_NFSProtoStub;
- nfs_proto_impl.cleanup = net_NFSProtoCleanupStub;
-
- NET_RegisterProtocolImplementation(&nfs_proto_impl, NFS_TYPE_URL);
- }
-
- PRIVATE int32
- net_WAISProtoLoad(ActiveEntry *ce)
- {
- char * alert = NET_ExplainErrorDetails(MK_NO_WAIS_PROXY);
-
- FE_Alert(ce->window_id, alert);
- FREE(alert);
-
- return -1;
- }
-
- PRIVATE int32
- net_WAISProtoStub(ActiveEntry *ce)
- {
- XP_ASSERT(0);
- return -1;
- }
-
- PRIVATE void
- net_WAISProtoCleanupStub(void)
- {
- }
-
- /* a stub function for WAIS protocol converter.
- * right now we only proxy WAIS's
- * if WAIS's ever get worked on move this to another file
- */
- PUBLIC void
- NET_InitWAISProtocol(void)
- {
- static NET_ProtoImpl wais_proto_impl;
-
- wais_proto_impl.init = net_WAISProtoLoad;
- wais_proto_impl.process = net_WAISProtoStub;
- wais_proto_impl.interrupt = net_WAISProtoStub;
- wais_proto_impl.cleanup = net_WAISProtoCleanupStub;
-
- NET_RegisterProtocolImplementation(&wais_proto_impl, WAIS_TYPE_URL);
- }
-
- #ifdef MOZ_MAIL_NEWS
- PUBLIC char *
- NET_Base64Encode (char *src, int32 srclen)
- {
- BufferStruct bs;
- MimeEncoderData *encoder_data = NULL;
-
- XP_ASSERT (src);
- if (!src)
- return NULL;
- else if (srclen == 0)
- return XP_STRDUP("");
-
- XP_MEMSET (&bs, 0, sizeof (BufferStruct));
- encoder_data = MimeB64EncoderInit(net_buffer_output_fn, (void *) &bs);
- if (!encoder_data)
- return NULL;
-
- if (MimeEncoderWrite(encoder_data, src, srclen) < 0)
- {
- MimeEncoderDestroy(encoder_data, FALSE);
- XP_FREEIF(bs.buffer);
- return NULL;
- }
-
- MimeEncoderDestroy(encoder_data, FALSE);
- /* caller must free the returned pointer to prevent
- * memory leak problem.
- */
- return bs.buffer;
- }
-
- PUBLIC char *
- NET_Base64Decode (char *src,
- int32 srclen)
- {
- BufferStruct bs;
- MimeDecoderData *decoder_data = NULL;
-
- XP_ASSERT (src);
- if (!src)
- return NULL;
- else if (srclen == 0)
- return XP_STRDUP("");
-
- XP_MEMSET (&bs, 0, sizeof (BufferStruct));
- decoder_data = MimeB64DecoderInit(net_buffer_output_fn, (void *) &bs);
- if (!decoder_data)
- return NULL;
-
- if (MimeDecoderWrite(decoder_data, src, srclen) < 0)
- {
- MimeDecoderDestroy(decoder_data, FALSE);
- XP_FREEIF(bs.buffer);
- return NULL;
- }
-
- MimeDecoderDestroy(decoder_data, FALSE);
- /* caller must free the returned pointer to prevent
- * memory leak problem.
- */
- return bs.buffer;
- }
-
- #endif /* MOZ_MAIL_NEWS */
-