Compare commits

..

2 Commits

Author SHA1 Message Date
(no author)
73de3f63a3 This commit was manufactured by cvs2svn to create tag 'LIBNET_PREMORTE'.
git-svn-id: svn://10.0.0.236/tags/LIBNET_PREMORTE@3641 18797224-902f-48f8-a5cc-f745e15eee43
1998-06-11 00:36:39 +00:00
(no author)
7af78328dc This commit was manufactured by cvs2svn to create branch 'NORMANDY_BRANCH'.
git-svn-id: svn://10.0.0.236/branches/NORMANDY_BRANCH@1267 18797224-902f-48f8-a5cc-f745e15eee43
1998-05-07 23:50:38 +00:00
136 changed files with 94246 additions and 102 deletions

View File

@@ -0,0 +1,20 @@
#
# This is a list of local files which get copied to the mozilla:dist directory
#
extcache.h
mkutils.h
mkselect.h
mkaccess.h
mkautocf.h
mkcache.h
mkformat.h
mkgeturl.h
mkhelp.h
mkstream.h
mktcp.h
mktrace.h
mkpadpac.h
mkmarimb.h
mkparse.h
mkimap4.h

202
mozilla/lib/libnet/Makefile Normal file
View File

@@ -0,0 +1,202 @@
#!gmake
#
# 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.
DEPTH = ../..
MODULE = net
LIBRARY_NAME = net
CSRCS = cvactive.c \
cvcolor.c \
cvdisk.c \
cvextcon.c \
cvproxy.c \
cvsimple.c \
cvview.c \
cvchunk.c \
extcache.c \
mkaccess.c \
mkdaturl.c \
mkformat.c \
mkfsort.c \
mkgopher.c \
mkhelp.c \
mkinit.c \
mkjscfg.c \
mkmocha.c \
mkparse.c \
mkremote.c \
mkselect.c \
mksockrw.c \
mksort.c \
mkstream.c \
mktrace.c \
mkpadpac.c \
txview.c \
jscookie.c \
cvmime.c \
cvunzip.c \
mkautocf.c \
mkcache.c \
mkconect.c \
mkcburl.c \
mkextcac.c \
mkfile.c \
mkftp.c \
mkgeturl.c \
mkhttp.c \
mkmemcac.c \
mkmessag.c \
mkutils.c \
prefetch.c \
$(NULL)
CPPSRCS = mkmarimb.cpp
REQUIRES = netcast parse js dbm nspr security htmldlgs ldap softupdt \
img util jtools layer pref java libfont lay style applet \
zlib li msg progress net
EXPORTS = extcache.h \
mkutils.h \
mkselect.h \
mkaccess.h \
mkautocf.h \
mkcache.h \
mkformat.h \
mkgeturl.h \
mkhelp.h \
mkstream.h \
mktcp.h \
mktrace.h \
mkpadpac.h \
mkmarimb.h \
mkparse.h \
$(NULL)
include $(DEPTH)/config/config.mk
ifdef MOZ_MAIL_NEWS
CSRCS += \
mkcertld.c \
imap4url.c \
mkmailbx.c \
mknews.c \
mknewsgr.c \
mkpop3.c \
mksmtp.c \
$(NULL)
CPPSRCS += mkabook.cpp \
imapbody.cpp \
imaphier.cpp \
imapearl.cpp \
mkimap4.cpp \
mkldap.cpp \
imappars.cpp \
$(NULL)
endif
ifndef NO_UNIX_ASYNC_DNS
CSRCS += unix-dns.c
endif
include $(DEPTH)/config/rules.mk
DEFINES += -DNEW_DECODERS
ifndef NO_UNIX_ASYNC_DNS
DEFINES += -DUNIX_ASYNC_DNS
endif
ifndef NO_UNIX_LDAP
INCLUDES += -I$(DIST)/include
DEFINES += -DLIBNET_LDAP
endif
#
# This converts mime.types to C source code,
# and also to an HTML table that shows what's in it.
#
MIME_TYPES = ./mime.types
MIME_TYPES_UNIX = ./mime.types-unix
MIME_TYPES_NONUNIX = ./mime.types-nonunix
AD2C = sh $(DEPTH)/cmd/xfe/ad2c
#
# Workaround for a SCO compiler bug.
#
# If mkutils.c is compiled optimized, password authorization
# always fails. Probably due to NET_UUEncode routine.
#
# We could try using GCC 2.7.x instead, since that is the first
# version that can produce SCO ELF binaries.
#
ifeq ($(OS_ARCH),SCOOS)
SCO_OPT_FIX = -O0
endif
$(OBJDIR)/mkformat.o: mkformat.c mktypes.h
$(LIBRARY): $(OBJS)
$(OBJDIR)/mkutils.o $(OBJDIR)/LITE_mkutils.o: mkutils.c
@$(MAKE_OBJDIR)
$(CC) -o $@ -c $(CFLAGS) $(SCO_OPT_FIX) $<
mktypes.h: $(MIME_TYPES) $(MIME_TYPES_UNIX) $(MIME_TYPES_NONUNIX)
rm -f $@
@echo "generating $@ from $<..." ; \
(echo '/* Generated file - do not edit! */' ; \
echo '' ; \
cat $(MIME_TYPES) | grep -v '^#' | $(AD2C) ; \
echo '' ; \
echo '#ifdef XP_UNIX' ; \
cat $(MIME_TYPES_UNIX) | grep -v '^#' | $(AD2C) ; \
echo '#else /* !XP_UNIX */' ; \
cat $(MIME_TYPES_NONUNIX) | grep -v '^#' | $(AD2C) ; \
echo '#endif /* !XP_UNIX */' ; \
) > $@
mime-types.html: $(MIME_TYPES) $(MIME_TYPES_UNIX)
rm -f $@
@echo "generating $@ from $<..." ; \
(echo '<TITLE>Netscape MIME Types</TITLE>' ; \
echo '<H1 ALIGN=CENTER>Netscape MIME Types</H1>' ; \
echo '<CENTER>' ; \
echo '<TABLE BORDER CELLSPACING=0 CELLPADDING=5>' ; \
echo '<TR><TH></TH><TH>Content Type:</TH>' ; \
echo '<TH>Extensions:</TH><TH>Description:</TH></TR>' ; \
echo '<TR></TR><TR></TR><TR></TR>' ; \
cat $(MIME_TYPES) $(MIME_TYPES_UNIX) | grep -v '^#' | \
sed 's@exts="\([^"]*\)"[ ]*[\]*@<TR><TD><TT>\1</TT></TD>@; \
s@desc="\([^"]*\)"[ ]*[\]*@<TD>\1</TD>@; \
s@enc=\([^ ]*\)[ ]*[\]*$$@<TD>encoding/\1</TD>@; \
s@type=\([^ ]*\)[ ]*[\]*$$@<TD>\1</TD>@; \
s@icon=\([^ ]*\)[ ]*[\]*$$@<TD><IMG SRC=\1></TD></TR>@'\
| sed 's/,/ /g' \
| awk '{if ( $$0 ~ /^<TR/ ) {printf "%s" , $$0} \
else {printf "%s\n" , $$0} }' \
| sed 's@\(<TR>\)\(<TD>.*</TD>\)\(<TD>.*</TD>\)\(<TD>.*</TD>\)\(<TD>.*</TD>\)\(</TR>\)$$@\1\5!\3!\2!\4\6@' \
| tr '!' '\012' \
| sed 's@<TD></TD>@<TD>\&nbsp;</TD>@' ; \
echo '</TABLE>' ; \
echo '</CENTER>' ; \
) > $@

View File

@@ -0,0 +1,24 @@
#!/usr/local/bin/tcl -f
# 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.
# This takes a date string (fairly arbitrarily formatted), and spews out
# a number suitable for pasting into the timebomb code.
foreach i $argv {
set num [convertclock $i]
puts "$num [fmtclock $num]"
}

View File

@@ -0,0 +1,137 @@
/* -*- 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.
*/
/* this little program will sequentially dump out
* every record in the database
*/
#include "extcache.h"
#include <fcntl.h>
#include <sys/stat.h>
#include <assert.h>
#ifdef _sgi
#include <sys/endian.h>
#endif /* _sgi */
/* URL methods
*/
#define URL_GET_METHOD 0
#define URL_POST_METHOD 1
#define URL_HEAD_METHOD 2
static DB *
net_OpenExtCacheFatDB(char *filename)
{
DB *rv;
HASHINFO hash_info = {
16*1024, /* bucket size */
0, /* fill factor */
0, /* number of elements */
0, /* bytes to cache */
0, /* hash function */
0}; /* byte order */
rv = dbopen(filename,
O_RDWR | O_CREAT,
0644,
DB_HASH,
&hash_info);
if(!rv)
{
printf("Could not open cache database: %s\n", filename);
exit(1);
}
return(rv);
}
int main(int argc, char **argv)
{
char url[4028];
struct stat stat_s;
net_CacheObject * cache_obj;
DB * ext_cache_database=0;
DBT key;
DBT data;
int len;
char *end;
memset(&cache_obj, 0, sizeof(net_CacheObject));
if(argc != 2)
{
printf("Usage:\n"
"%s database\n"
"\n"
"database: path and name of the database\n", argv[0]);
exit(1);
}
/* open the cache database */
ext_cache_database = net_OpenExtCacheFatDB(argv[1]);
if(!ext_cache_database)
{
perror("Could not open cache database");
exit(1);
}
while(!(ext_cache_database->seq)(ext_cache_database, &key, &data, 0))
{
if(key.size == XP_STRLEN(EXT_CACHE_NAME_STRING)
&& !XP_STRCMP(key.data, EXT_CACHE_NAME_STRING))
{
/* make sure it's a terminated string */
if(((char *)data.data)[data.size-1] == '\0')
printf("\n\nDatabase Name: %s\n", (char*)data.data);
else
printf("\n\nDatabase Name is corrupted!\n");
printf("\n--------------------------------------\n");
continue;
}
/* try and convert the db struct to a cache struct */
cache_obj = net_DBDataToCacheStruct(&data);
if(!cache_obj)
{
printf("Malformed database entry:\n");
printf("key: ");
fwrite(key.data, 1, key.size, stdout);
printf("\ndata: ");
fwrite(data.data, 1, data.size, stdout);
printf("\n");
printf("--------------------------------------\n");
continue;
}
/* the URL is 8 bytes into the key struct
*/
printf("URL: %s\n",(char*)key.data+8);
printf("file: %s\n", cache_obj->filename);
printf("is_relative_path: %s\n", cache_obj->is_relative_path ? "TRUE" : "FALSE");
printf("content_type: %s\n", cache_obj->content_type);
printf("content_length: %d\n", cache_obj->content_length);
printf("last_modified: %s\n", ctime(&cache_obj->last_modified));
printf("--------------------------------------\n");
}
}

1459
mozilla/lib/libnet/crawler.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,179 @@
/* -*- 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.
*/
/*** crawler.h ****************************************************/
/* description: html crawler */
/********************************************************************
The crawler scans html pages and the links in those pages to a specified
depth in a breadth first manner, optionally caching them in an external cache.
Items are crawled sequentially - an item must finish being crawled or cached
before the next item is crawled. Multiple instances of the crawler may be running
at the same time.
Depth = 1 means that only the initial page, and any images and resources that
it contains, are cached.
Depth = n means that the crawler will crawl to n levels deep. Assuming the
maximum cache size is sufficient, the crawler will cache images and resources
for each page it encounters. Normally, resources are cached after all the pages
for a given level have been processed, but some resources are considered "required",
meaning they will be cached immediately after the page containing them has been
processed. An example of a "required" resource is a stylesheet.
The crawler obeys the robots.txt directives on a site, which may allow or deny access
to specific urls or directories. The robots.txt file is by convention at the top level
of a site.
The type of links that are crawled are determined in pagescan.c.
The parsing code is in htmparse.c
The robots.txt parser is in robotxt.c
$Revision: 3.1 $
$Date: 1998-03-28 03:31:25 $
*********************************************************************/
#ifndef crawler_h___
#define crawler_h___
#include "ntypes.h" /* for MWContext */
#include "prtypes.h" /* for PRBool */
#include "net.h" /* for ExtCacheDBInfo, URL_Struct */
/* Error codes */
typedef PRUint16 CRAWL_Error;
#define CRAWL_CACHE_FULL ((CRAWL_Error)0x0001)
#define CRAWL_NO_MEMORY ((CRAWL_Error)0x0002)
#define CRAWL_SERVER_ERR ((CRAWL_Error)0x0004)
#define CRAWL_INTERRUPTED ((CRAWL_Error)0x0008)
/* these error codes indicate if and how the cache has been updated and are only
set if CRAWL_MakeCrawler was called with manageCache set to true. Note that replaced
links may not have been reported as such if the server does not provide a last
modified date.
*/
#define CRAWL_NEW_LINK ((CRAWL_Error)0x0010)
#define CRAWL_REPLACED_LINK ((CRAWL_Error)0x0020)
#define CRAWL_REMOVED_LINK ((CRAWL_Error)0x0040)
/* Most of the APIs require a reference to CRAWL_Crawler, which is created by CRAWL_MakeCrawler. */
typedef struct _CRAWL_CrawlerStruct *CRAWL_Crawler;
/*
* Typedef for a callback executed when an item has been processed.
*/
typedef void
(PR_CALLBACK *CRAWL_PostProcessItemFn)(CRAWL_Crawler crawler, URL_Struct *url_s, PRBool isCached, void *data);
/*
* Typedef for a callback executed when the crawler is done.
*/
typedef void
(PR_CALLBACK *CRAWL_ExitFn)(CRAWL_Crawler crawler, void *data);
/****************************************************************************************/
/* public API */
/****************************************************************************************/
NSPR_BEGIN_EXTERN_C
/*
Creates a crawler which may be used for one crawling request. Subsequent requests
to crawl urls should use a separate crawler instance. Returns NULL if not enough
memory is available, or the depth is less than 1.
Parameters:
context - needed by netlib (the crawler does not check this parameter)
siteName - url of the site
stayInSite - whether to restrict crawling to the site named.
manageCache - whether to maintain a local file describing the cache contents.
If true, the crawler uses the file to remove dangling links from the cache
the next time it is invoked with the same cache. This is not guaranteed to
work correctly if another crawling instance uses the same cache simultaneously.
cache - the external cache. This may be NULL if the crawled items do not need
to be put in an external cache.
postProcessItemFn - a function which is called after each item has been handled
by netlib. This may be NULL.
postProcessItemData - this data is supplied as a parameter to the postProcessItemFn
and is opaque to the crawler. This may be NULL.
exitFn - a function which is called when the crawler is done or has terminated
prematurely (because the cache is full, or no memory is available). This may be NULL.
exitData - this data is supplied as a parameter to the exitFn and is opaque to
the crawler. This may be NULL.
*/
PR_EXTERN(CRAWL_Crawler)
CRAWL_MakeCrawler(MWContext *context,
char *siteName,
uint8 depth,
PRBool stayInSite,
PRBool manageCache,
ExtCacheDBInfo *cache,
CRAWL_PostProcessItemFn postProcessItemFn,
void *postProcessItemData,
CRAWL_ExitFn exitFn,
void *exitData);
/*
Destroys the crawler and all memory associated with it. The crawler instance should not be
used after calling this function.
*/
PR_EXTERN(void)
CRAWL_DestroyCrawler(CRAWL_Crawler crawler);
/*
Starts crawling from the url. If its content type is text/html, links may be traversed. This function
returns as soon as the first network request is issued.
*/
PR_EXTERN(void)
CRAWL_StartCrawler(CRAWL_Crawler crawler, char *url);
/*
Stops crawling at the next link. This function returns immediately and cannot fail.
*/
PR_EXTERN(void)
CRAWL_StopCrawler(CRAWL_Crawler crawler);
/*
Returns the crawler error code. This function returns immediately and cannot fail.
*/
PR_EXTERN(CRAWL_Error)
CRAWL_GetError(CRAWL_Crawler crawler);
/*
Returns true if the crawler has stopped, which is the case before and after crawling. Returns
immediately and cannot fail.
*/
PR_EXTERN(PRBool)
CRAWL_IsStopped(CRAWL_Crawler crawler);
NSPR_END_EXTERN_C
/*
Stream function for crawling resources. Resources are not parsed, but the crawler checks the
content length to see if the cache would be exceeded.
*/
PUBLIC NET_StreamClass*
CRAWL_CrawlerResourceConverter(int format_out,
void *data_object,
URL_Struct *URL_s,
MWContext *window_id);
#endif /* crawler_h___ */

View File

@@ -0,0 +1,482 @@
/* -*- 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.
*/
#include "mkutils.h"
#include "cvactive.h"
#include "mkgeturl.h"
#include "mkstream.h"
#include "glhist.h"
#include "xp.h"
#include "merrors.h"
extern int MK_OUT_OF_MEMORY;
typedef struct _DataObject {
int state;
NET_StreamClass *next_stream;
char *prev_buffer;
int32 prev_buffer_len;
MWContext *window_id;
int format_out;
URL_Struct *URL_s;
XP_Bool signal_at_end_of_multipart;
} DataObject;
#define NORMAL_S 1
#define FOUND_BOUNDARY_S 2
#define MAX_MIME_LINE 200
/* parse a mime/multipart stream. The boundary is already
* known and we start off in the content of the original
* message/822 body.
*
* buffer data up to the size of the passed in data length
* for efficiency of the upstream module.
*/
PRIVATE int net_MultipleDocumentWrite (NET_StreamClass *stream, CONST char* s, int32 l)
{
int32 i=0;
int32 line_length=1;
int rv=0;
char *cp;
char *line;
char *push_buffer=NULL;
int32 push_buffer_size=0;
XP_Bool all_done=FALSE;
DataObject *obj=stream->data_object;
BlockAllocCat(obj->prev_buffer, obj->prev_buffer_len, s, l);
obj->prev_buffer_len += l;
if(!obj->prev_buffer)
return(MK_OUT_OF_MEMORY);
line = obj->prev_buffer;
/* try and find a line
*/
for(cp=obj->prev_buffer; i < obj->prev_buffer_len; cp++, i++, line_length++)
{
if(*cp == '\n')
{
switch(obj->state)
{
case NORMAL_S:
{
char *cp2 = line;
int blength = XP_STRLEN(obj->URL_s->boundary);
/* look for boundary. We can rest assured that these
XP_STRNCMP() calls are safe, because we know that the
valid portion of the string starting at cp2 has a
newline in it (at *cp), and we know that boundary
strings never have newlines in them. */
if((!XP_STRNCMP(cp2, "--",2) &&
!XP_STRNCMP(cp2+2,
obj->URL_s->boundary,
blength))
|| (!XP_STRNCMP(cp2,
obj->URL_s->boundary,
blength)))
{
TRACEMSG(("Found boundary: %s", obj->URL_s->boundary));
obj->state = FOUND_BOUNDARY_S;
if(obj->next_stream)
{
if(push_buffer)
{
/* strip the last newline before the
* boundary
*/
push_buffer_size--;
/* if there is a CR as well as a LF
* strip that too
*/
if(push_buffer_size > 0 && push_buffer[push_buffer_size-1] == CR)
push_buffer_size--;
rv = (*obj->next_stream->put_block)
(obj->next_stream,
push_buffer,
push_buffer_size);
FREE(push_buffer);
push_buffer = NULL;
push_buffer_size = 0;
}
TRACEMSG(("Completeing an open stream"));
/* if this stream is not the last one, set a flag
before completion to let completion do special stuff */
XP_ASSERT(cp2 + blength <= cp);
/* Because the above XP_STRCMP calls succeeded.
Because this is true, we know the first call
to XP_STRNCMP below is always safe, but we
need to check lengths before we can be sure
the other call is safe. */
if( (cp2 + blength + 2 < cp &&
!XP_STRNCMP(cp2+2+blength, "--",2))
|| !XP_STRNCMP(cp2+blength, "--",2))
{
/* very last boundary */
obj->next_stream->is_multipart = FALSE;
/* set the all_done flag when
* we have found the final boundary
*/
all_done = TRUE;
}
else
{
obj->next_stream->is_multipart = TRUE;
}
/* complete the last stream
*/
(*obj->next_stream->complete)
(obj->next_stream);
FREE(obj->next_stream);
obj->next_stream = NULL;
}
/* move the line ptr up to new data */
line = cp+1;
line_length=1; /* reset */
if(all_done && obj->signal_at_end_of_multipart)
return(MK_MULTIPART_MESSAGE_COMPLETED);
break;
}
else
{
TRACEMSG(("Pushing line (actually buffering)"));
/* didn't find the boundary
*/
if(obj->next_stream)
{
BlockAllocCat(push_buffer, push_buffer_size,
line, line_length);
push_buffer_size += line_length;
if(!push_buffer)
return(MK_OUT_OF_MEMORY);
}
/* move the line ptr up to new data */
line = cp+1;
line_length=0; /* reset */
}
break;
}
case FOUND_BOUNDARY_S:
XP_ASSERT(*cp == '\n'); /* from the 'if' above */
/* terminate at the newline.
* now 'line' points to a valid NULL terminated C string
*/
*cp = '\0';
TRACEMSG(("Parsing header: >%s<", line));
/* parse mime headers
* stop when a blank line is encountered
*/
if(*line == '\0' || *line == '\r')
{
int format_out;
obj->state = NORMAL_S;
TRACEMSG(("Found end of headers"));
if (obj->URL_s->content_type == NULL)
StrAllocCopy(obj->URL_s->content_type, TEXT_PLAIN);
/* abort all existing streams. We
* have to do this to prevent the
* image lib and other things from
* continuing to load the page after
* we left.
*
* don't abort other streams if it's
* just a new inline image or if the
* stream is not going to the screen
*/
if(CLEAR_CACHE_BIT(obj->format_out) != FO_INTERNAL_IMAGE
&& (!strncasecomp(obj->URL_s->content_type,
"text", 4)
||
!strncasecomp(obj->URL_s->content_type,
"image", 4)) )
{
NET_SilentInterruptWindow(obj->window_id);
format_out = obj->format_out;
}
else
{
/* don't cache image animations... */
format_out = CLEAR_CACHE_BIT(obj->format_out);
}
/* libimg and libplugin use the fe_data to store
* urls data, so clear it only if its not them */
if( (CLEAR_CACHE_BIT(obj->format_out) != FO_INTERNAL_IMAGE)
&& (CLEAR_CACHE_BIT(obj->format_out) != FO_PLUGIN)
&& (CLEAR_CACHE_BIT(obj->format_out) != FO_BYTERANGE)
&& strncasecomp(obj->URL_s->content_type, "image", 5))
{
obj->URL_s->fe_data = NULL;
}
/* build a stream
*/
obj->next_stream = NET_StreamBuilder(format_out,
obj->URL_s,
obj->window_id);
if(!obj->next_stream)
return(MK_UNABLE_TO_CONVERT);
}
else if(!strncasecomp(line, "CONTENT-TYPE:", 13))
{
XP_STRTOK(line+13, ";"); /* terminate at ; */
StrAllocCopy(obj->URL_s->content_type,
XP_StripLine(line+13));
if(!obj->URL_s->content_type || !*obj->URL_s->content_type)
StrAllocCopy(obj->URL_s->content_type, TEXT_PLAIN);
TRACEMSG(("found new content_type: %s",
obj->URL_s->content_type));
}
else
{
/* Pass all other headers to the MIME header parser
*/
char *value = XP_STRCHR(line, ':');
if(value)
value++;
NET_ParseMimeHeader(NET_AllowForeignCookies,
obj->window_id,
obj->URL_s,
line,
value, FALSE);
}
line = cp+1;
line_length = 0;
break;
default:
assert(0);
break;
}
} /* end if */
} /* end for */
if(line_length > MAX_MIME_LINE * 2)
{
int32 new_size;
TRACEMSG(("Line too long pushing it"));
if(obj->next_stream)
{
if(push_buffer)
{
rv = (*obj->next_stream->put_block)(obj->next_stream,
push_buffer,
push_buffer_size);
rv = (*obj->next_stream->put_block)(obj->next_stream,
line,
MAX_MIME_LINE);
FREE(push_buffer);
push_buffer = 0;
push_buffer_size = 0;
}
else
{
rv = (*obj->next_stream->put_block)(obj->next_stream,
line,
MAX_MIME_LINE);
}
if(rv < 0)
return(rv);
}
/* newsize equals the old size minus the difference
* between line and the start of the old buffer and
* the MAX_MIME_LENGTH that we just wrote out
*/
new_size = obj->prev_buffer_len -
((line - obj->prev_buffer) + MAX_MIME_LINE);
XP_MEMMOVE(obj->prev_buffer, line+MAX_MIME_LINE, new_size);
obj->prev_buffer_len = new_size;
return(0);
}
if(line != obj->prev_buffer)
{
/* some part of the line has been digested, get rid of
* the part that has been used
*/
obj->prev_buffer_len -= (line - obj->prev_buffer);
XP_MEMMOVE(obj->prev_buffer, line, obj->prev_buffer_len);
}
/* if there is anything in the push buffer send it now
*/
if(push_buffer)
{
if(obj->next_stream)
{
TRACEMSG(("Pushing buffered data"));
rv = (*obj->next_stream->put_block)(obj->next_stream,
push_buffer,
push_buffer_size);
}
FREE(push_buffer);
if (rv < 0)
return rv;
}
return(0);
}
/* is the stream ready for writeing?
*/
PRIVATE unsigned int net_MultipleDocumentWriteReady (NET_StreamClass * stream)
{
DataObject *obj=stream->data_object;
if(obj->next_stream)
return((*obj->next_stream->is_write_ready)(obj->next_stream));
else
return(MAX_WRITE_READY);
}
PRIVATE void net_MultipleDocumentComplete (NET_StreamClass *stream)
{
DataObject *obj=stream->data_object;
if(obj->next_stream)
{
(*obj->next_stream->complete)(obj->next_stream);
FREE(obj->next_stream);
}
FREEIF(obj->prev_buffer);
FREE(obj);
return;
}
PRIVATE void net_MultipleDocumentAbort (NET_StreamClass *stream, int status)
{
DataObject *obj=stream->data_object;
if(obj->next_stream)
{
(*obj->next_stream->abort)(obj->next_stream, status);
FREE(obj->next_stream);
}
FREEIF(obj->prev_buffer);
FREE(obj);
return;
}
PUBLIC NET_StreamClass *
CV_MakeMultipleDocumentStream (int format_out,
void *data_object,
URL_Struct *URL_s,
MWContext *window_id)
{
DataObject* obj;
NET_StreamClass* stream;
TRACEMSG(("Setting up display stream. Have URL: %s\n", URL_s->address));
GH_UpdateGlobalHistory(URL_s);
URL_s->is_active = TRUE; /* set to disable view source */
stream = XP_NEW(NET_StreamClass);
if(stream == NULL)
return(NULL);
obj = XP_NEW(DataObject);
if (obj == NULL)
return(NULL);
XP_MEMSET(obj, 0, sizeof(DataObject));
if(CVACTIVE_SIGNAL_AT_END_OF_MULTIPART == (int) data_object)
obj->signal_at_end_of_multipart = TRUE;
stream->name = "Multiple Document";
stream->complete = (MKStreamCompleteFunc) net_MultipleDocumentComplete;
stream->abort = (MKStreamAbortFunc) net_MultipleDocumentAbort;
stream->put_block = (MKStreamWriteFunc) net_MultipleDocumentWrite;
stream->is_write_ready = (MKStreamWriteReadyFunc) net_MultipleDocumentWriteReady;
stream->data_object = obj; /* document info object */
stream->window_id = window_id;
/* don't cache these
format_out = CLEAR_CACHE_BIT(format_out);
*/
/* enable clicking since it doesnt go through the cache
* code
*/
FE_EnableClicking(window_id);
obj->next_stream = NULL;
obj->window_id = window_id;
obj->format_out = format_out;
obj->URL_s = URL_s;
obj->state = NORMAL_S;
/* make sure that we have a real boundary.
* if not fill in '--' as a boundary
*/
if(!URL_s->boundary)
StrAllocCopy(URL_s->boundary, "--");
/* overwrite the current content type with TEXT/PLAIN since
* we want that as the default content-type for
* body parts
*/
StrAllocCopy(URL_s->content_type, TEXT_PLAIN);
TRACEMSG(("Returning stream from NET_MultipleDocumentConverter\n"));
return stream;
}

View File

@@ -0,0 +1,315 @@
/* -*- 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.
*/
/* Please leave outside of ifdef for windows precompiled headers */
#include "mkutils.h"
#ifdef MOZILLA_CLIENT
#include "cvchunk.h" /* prototype */
#include "mkstream.h"
#include "mkgeturl.h"
#include "xp.h"
extern int MK_OUT_OF_MEMORY;
typedef enum {
FIND_CHUNK_SIZE,
READ_CHUNK,
STRIP_CRLF,
PARSE_FOOTER
} States;
typedef struct _DataObject {
NET_StreamClass *next_stream;
char *in_buf;
uint32 in_buf_size;
uint32 chunk_size;
uint32 amount_of_chunk_parsed;
States cur_state;
FO_Present_Types format_out;
MWContext *context;
URL_Struct *URL_s;
} DataObject;
/* unchunk the message and return MK_MULTIPART_MESSAGE_COMPLETED
* when end detected
*/
PRIVATE int net_ChunkedWrite (NET_StreamClass *stream, char* s, int32 l)
{
DataObject *obj=stream->data_object;
BlockAllocCat(obj->in_buf, obj->in_buf_size, s, l);
if(!obj->in_buf)
return MK_OUT_OF_MEMORY;
obj->in_buf_size += l;
while(obj->in_buf_size > 0)
{
if(obj->cur_state == FIND_CHUNK_SIZE)
{
char *line_feed;
char *semicolon;
char *end;
/* we don't have a current chunk size
* look for a new chunk size
*
* make sure the line has a CRLF
*/
if((line_feed = XP_STRNCHR(obj->in_buf, LF, obj->in_buf_size)) == NULL)
{
return 1; /* need more data */
}
*line_feed = '\0';
semicolon = XP_STRNCHR(obj->in_buf, ';', line_feed-obj->in_buf);
if(semicolon)
*semicolon = '\0';
end = semicolon ? semicolon : line_feed;
/* read the first integer and ignore any thing
* else on the line. Extensions are allowed
*/
obj->chunk_size = strtol(obj->in_buf, &end, 16);
/* strip everything up to the line feed */
obj->in_buf_size -= (line_feed+1) - obj->in_buf;
if(obj->in_buf_size)
XP_MEMMOVE(obj->in_buf,
line_feed+1,
obj->in_buf_size);
if(obj->chunk_size == 0)
{
/* the stream should be done now */
obj->cur_state = PARSE_FOOTER;
}
else
{
obj->cur_state = READ_CHUNK;
}
}
else if(obj->cur_state == READ_CHUNK)
{
uint32 data_size;
int32 status;
/* take as much data as we have and push it up the stream
*/
data_size = MIN(obj->in_buf_size, obj->chunk_size-obj->amount_of_chunk_parsed);
status = (obj->next_stream->put_block)(obj->next_stream,
obj->in_buf,
data_size);
if(status < 0)
return status;
/* remove the part that has been pushed */
obj->in_buf_size -= data_size;
if(obj->in_buf_size)
XP_MEMMOVE(obj->in_buf,
obj->in_buf+data_size,
obj->in_buf_size);
obj->amount_of_chunk_parsed += data_size;
if(obj->amount_of_chunk_parsed >= obj->chunk_size)
{
XP_ASSERT(obj->amount_of_chunk_parsed == obj->chunk_size);
/* reinit */
obj->amount_of_chunk_parsed = 0;
obj->cur_state = STRIP_CRLF;
}
}
else if(obj->cur_state == STRIP_CRLF)
{
if(obj->in_buf_size > 1 && obj->in_buf[0] == CR && obj->in_buf[1] == LF)
{
/* strip two bytes */
obj->in_buf_size -= 2;
if(obj->in_buf_size)
XP_MEMMOVE(obj->in_buf,
obj->in_buf+2,
obj->in_buf_size);
obj->cur_state = FIND_CHUNK_SIZE;
}
else if(obj->in_buf[0] == LF)
{
/* strip one bytes */
obj->in_buf_size -= 1;
if(obj->in_buf_size)
XP_MEMMOVE(obj->in_buf,
obj->in_buf+1,
obj->in_buf_size);
obj->cur_state = FIND_CHUNK_SIZE;
}
else
{
if(obj->in_buf_size >= 2)
{
int status;
/* a fatal parse error */
XP_ASSERT(0);
/* just spew the buf to the screen */
status = (obj->next_stream->put_block)(obj->next_stream,
obj->in_buf,
obj->in_buf_size);
if(status < 0)
return status;
/* remove the part that has been pushed */
obj->in_buf_size = 0;
}
}
}
else if(obj->cur_state == PARSE_FOOTER)
{
char *line_feed;
char *value;
/* parse until we see two CRLF's in a row */
if((line_feed = XP_STRNCHR(obj->in_buf, LF, obj->in_buf_size)) == NULL)
{
return 1; /* need more data */
}
*line_feed = '\0';
/* strip the CR */
if(line_feed != obj->in_buf && *(line_feed-1) == CR)
*(line_feed-1) = '\0';
if(*obj->in_buf == '\0')
{
/* end of parse stream */
return MK_MULTIPART_MESSAGE_COMPLETED;
}
/* names are separated from values with a colon
*/
value = XP_STRCHR(obj->in_buf, ':');
if(value)
value++;
/* otherwise parse the line as a mime header */
NET_ParseMimeHeader(obj->format_out,
obj->context,
obj->URL_s,
obj->in_buf,
value,
FALSE);
/* strip the line from the buffer */
obj->in_buf_size -= (line_feed+1) - obj->in_buf;
if(obj->in_buf_size)
XP_MEMMOVE(obj->in_buf,
line_feed+1,
obj->in_buf_size);
}
}
XP_ASSERT(obj->in_buf_size == 0);
return(1);
}
/* is the stream ready for writeing?
*/
PRIVATE unsigned int net_ChunkedWriteReady (NET_StreamClass * stream)
{
DataObject *obj=stream->data_object;
return (*obj->next_stream->is_write_ready)(obj->next_stream);
}
PRIVATE void net_ChunkedComplete (NET_StreamClass *stream)
{
DataObject *obj=stream->data_object;
(*obj->next_stream->complete)(obj->next_stream);
FREE(obj);
return;
}
PRIVATE void net_ChunkedAbort (NET_StreamClass *stream, int status)
{
DataObject *obj=stream->data_object;
(*obj->next_stream->abort)(obj->next_stream, status);
return;
}
MODULE_PRIVATE NET_StreamClass *
NET_ChunkedDecoderStream (int format_out,
void *data_obj,
URL_Struct *URL_s,
MWContext *window_id)
{
DataObject* obj;
NET_StreamClass* stream;
TRACEMSG(("Setting up display stream. Have URL: %s\n", URL_s->address));
stream = XP_NEW(NET_StreamClass);
if(stream == NULL)
return(NULL);
obj = XP_NEW_ZAP(DataObject);
if (obj == NULL)
return(NULL);
stream->name = "Chunked decoder";
stream->complete = (MKStreamCompleteFunc) net_ChunkedComplete;
stream->abort = (MKStreamAbortFunc) net_ChunkedAbort;
stream->put_block = (MKStreamWriteFunc) net_ChunkedWrite;
stream->is_write_ready = (MKStreamWriteReadyFunc) net_ChunkedWriteReady;
stream->data_object = obj; /* document info object */
stream->window_id = window_id;
/* clear the "chunked" encoding */
if(URL_s->transfer_encoding)
FREE_AND_CLEAR(URL_s->transfer_encoding);
else
FREE_AND_CLEAR(URL_s->content_encoding);
obj->next_stream = NET_StreamBuilder(format_out, URL_s, window_id);
if(!obj->next_stream)
{
XP_FREE(obj);
XP_FREE(stream);
return NULL;
}
obj->context = window_id;
obj->format_out = format_out;
obj->URL_s = URL_s;
TRACEMSG(("Returning stream from NET_ChunkedConverter\n"));
return stream;
}
#endif /* MOZILLA_CLIENT */

View File

@@ -0,0 +1,28 @@
/* -*- 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.
*/
#ifndef CVCHUNK_H
#define CVCHUNK_H
MODULE_PRIVATE NET_StreamClass *
NET_ChunkedDecoderStream (int format_out,
void *data_obj,
URL_Struct *URL_s,
MWContext *window_id);
#endif /* CVCHUNK_H */

View File

@@ -0,0 +1,592 @@
/* -*- 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.
*/
/* Please leave outside of ifdef for windows precompiled headers */
#include "mkutils.h"
#ifdef MOZILLA_CLIENT
/* take an HTML stream. Escape all the HTML and
* use <FONT color=> to color the different syntactical parts
* of the HTML stream
*/
#include "mkstream.h"
#include "mkgeturl.h"
#include "pa_parse.h"
#include "xp.h"
#include "xpgetstr.h"
#include "intl_csi.h"
#define VIEW_SOURCE_TARGET_WINDOW_NAME "%ViewSourceWindow"
typedef enum StatesEnum {
IN_CONTENT,
IN_SCRIPT,
ABOUT_TO_BEGIN_TAG,
IN_BEGIN_TAG,
IN_TAG,
BEGIN_ATTRIBUTE_VALUE,
IN_QUOTED_ATTRIBUTE_VALUE,
IN_BROKEN_QUOTED_ATTRIBUTE_VALUE,
IN_UNQUOTED_ATTRIBUTE_VALUE,
IN_COMMENT,
IN_AMPERSAND_THINGY
} StatesEnum;
#define MAXTAGLEN 15
typedef struct _DataObject {
NET_StreamClass * next_stream;
StatesEnum state;
char tag[MAXTAGLEN+1];
uint tag_index;
int tag_type;
XP_Bool in_broken_html;
} DataObject;
#define BEGIN_TAG_MARKUP "<B>"
#define END_TAG_MARKUP "</B>"
#define BEGIN_TAG_NAME_MARKUP "<FONT SIZE=+0 COLOR=\"#551A8B\">"
#define END_TAG_NAME_MARKUP "</FONT>"
#define BEGIN_ATTRIBUTE_VALUE_MARKUP "</B><FONT SIZE=+0 COLOR=\"003E98\">"
#define END_ATTRIBUTE_VALUE_MARKUP "</FONT><B>"
#define BEGIN_BROKEN_ATTRIBUTE_MARKUP "<FONT COLOR=#0000FF><BLINK>"
#define END_BROKEN_ATTRIBUTE_MARKUP "</BLINK></FONT>"
#define BEGIN_COMMENT_MARKUP "<I>"
#define END_COMMENT_MARKUP "</I>"
#define BEGIN_AMPERSAND_THINGY_MARKUP "<FONT SIZE=+0 COLOR=\"#2F4F2F\">"
#define END_AMPERSAND_THINGY_MARKUP "</FONT>"
extern int MK_CVCOLOR_SOURCE_OF;
PRIVATE char *net_BeginColorHTMLTag (DataObject *obj)
{
char *new_markup = 0;
if (obj->tag_type == P_SCRIPT)
{
StrAllocCopy(new_markup, "</XMP><PRE>");
obj->tag_type = P_UNKNOWN;
}
StrAllocCat(new_markup, BEGIN_TAG_MARKUP);
StrAllocCat(new_markup, "&lt;");
StrAllocCat(new_markup, BEGIN_TAG_NAME_MARKUP);
obj->state = ABOUT_TO_BEGIN_TAG;
return new_markup;
}
PRIVATE char *net_EndColorHTMLTag (DataObject *obj)
{
char *new_markup = 0;
if(obj->in_broken_html)
{
StrAllocCopy(new_markup, END_BROKEN_ATTRIBUTE_MARKUP);
obj->in_broken_html = FALSE;
}
StrAllocCat(new_markup, "&gt;");
StrAllocCat(new_markup, END_TAG_MARKUP);
if (obj->tag_type == P_SCRIPT)
{
StrAllocCat(new_markup, "</PRE><XMP>");
obj->state = IN_SCRIPT;
}
else
{
obj->state = IN_CONTENT;
}
return new_markup;
}
PRIVATE int net_ColorHTMLWrite (NET_StreamClass *stream, CONST char *s, int32 l)
{
int32 i;
int32 last_output_point;
char *new_markup=0;
char *tmp_markup=0;
char tiny_buf[4];
CONST char *cp;
int status;
DataObject *obj=stream->data_object;
last_output_point = 0;
for(i = 0, cp = s; i < l; i++, cp++)
{
switch(obj->state)
{
case IN_CONTENT:
/* do nothing until you find a '<' "<!--" or '&' */
if(*cp == '<')
{
/* XXX we can miss a comment spanning a block boundary */
if(i+4 <= l && !XP_STRNCMP(cp, "<!--", 4))
{
StrAllocCopy(new_markup, BEGIN_COMMENT_MARKUP);
StrAllocCat(new_markup, "&lt;");
obj->state = IN_COMMENT;
}
else
{
new_markup = net_BeginColorHTMLTag(obj);
}
}
else if(*cp == '&')
{
StrAllocCopy(new_markup, BEGIN_AMPERSAND_THINGY_MARKUP);
StrAllocCat(new_markup, "&amp;");
obj->state = IN_AMPERSAND_THINGY;
}
break;
case IN_SCRIPT:
/* do nothing until you find '</SCRIPT>' */
if(*cp == '<')
{
/* XXX we can miss a </SCRIPT> spanning a block boundary */
if(i+8 <= l && !XP_STRNCASECMP(cp, "</SCRIPT", 8))
{
new_markup = net_BeginColorHTMLTag(obj);
}
}
break;
case ABOUT_TO_BEGIN_TAG:
/* we have seen the first '<'
* once we see a non-whitespace character
* we will be in the tag identifier
*/
if(*cp == '>')
{
StrAllocCopy(new_markup, END_TAG_NAME_MARKUP);
tmp_markup = net_EndColorHTMLTag(obj);
StrAllocCat(new_markup, tmp_markup);
FREE_AND_CLEAR(tmp_markup);
}
else if(!XP_IS_SPACE(*cp))
{
obj->state = IN_BEGIN_TAG;
obj->tag_index = 0;
obj->tag[obj->tag_index++] = *cp;
if(*cp == '<')
StrAllocCopy(new_markup, "&lt;");
}
break;
case IN_BEGIN_TAG:
/* go to the IN_TAG state when we see
* the first whitespace
*/
if(XP_IS_SPACE(*cp))
{
StrAllocCopy(new_markup, END_TAG_NAME_MARKUP);
XP_SPRINTF(tiny_buf, "%c", *cp);
StrAllocCat(new_markup, tiny_buf);
obj->state = IN_TAG;
obj->tag[obj->tag_index] = '\0';
obj->tag_type = pa_tokenize_tag(obj->tag);
}
else if(*cp == '>')
{
StrAllocCopy(new_markup, END_TAG_NAME_MARKUP);
tmp_markup = net_EndColorHTMLTag(obj);
StrAllocCat(new_markup, tmp_markup);
FREE_AND_CLEAR(tmp_markup);
}
else if(*cp == '<')
{
/* protect ourselves from markup */
if(!obj->in_broken_html)
{
obj->in_broken_html = TRUE;
StrAllocCopy(new_markup, BEGIN_BROKEN_ATTRIBUTE_MARKUP);
StrAllocCat(new_markup, "&lt;");
}
else
{
StrAllocCopy(new_markup, "&lt;");
}
}
else
{
if (obj->tag_index < MAXTAGLEN)
obj->tag[obj->tag_index++] = *cp;
}
break;
case IN_TAG:
/* do nothing until you find a opening '=' or end '>' */
if(*cp == '=')
{
StrAllocCopy(new_markup, "=");
StrAllocCat(new_markup, BEGIN_ATTRIBUTE_VALUE_MARKUP);
obj->state = BEGIN_ATTRIBUTE_VALUE;
}
else if(*cp == '>')
{
new_markup = net_EndColorHTMLTag(obj);
}
else if(*cp == '<')
{
/* protect ourselves from markup */
StrAllocCopy(new_markup, "&lt;");
}
break;
case BEGIN_ATTRIBUTE_VALUE:
/* when we reach the first non-whitespace
* we will enter the UNQUOTED or the QUOTED
* ATTRIBUTE state
*/
if(!XP_IS_SPACE(*cp))
{
if(*cp == '"')
{
obj->state = IN_QUOTED_ATTRIBUTE_VALUE;
/* no need to jump to the quoted attr handler
* since this char can't be a dangerous char
*/
}
else
{
obj->state = IN_UNQUOTED_ATTRIBUTE_VALUE;
/* need to jump to the unquoted attr handler
* since this char can be a dangerous character
*/
goto unquoted_attribute_jump_point;
}
}
else if(*cp == '>')
{
StrAllocCopy(new_markup, END_ATTRIBUTE_VALUE_MARKUP);
tmp_markup = net_EndColorHTMLTag(obj);
StrAllocCat(new_markup, tmp_markup);
FREE_AND_CLEAR(tmp_markup);
}
else if(*cp == '<')
{
/* protect ourselves from markup */
StrAllocCopy(new_markup, "&lt;");
}
break;
case IN_UNQUOTED_ATTRIBUTE_VALUE:
unquoted_attribute_jump_point:
/* do nothing until you find a whitespace */
if(XP_IS_SPACE(*cp))
{
StrAllocCopy(new_markup, END_ATTRIBUTE_VALUE_MARKUP);
XP_SPRINTF(tiny_buf, "%c", *cp);
StrAllocCat(new_markup, tiny_buf);
obj->state = IN_TAG;
}
else if(*cp == '>')
{
StrAllocCopy(new_markup, END_ATTRIBUTE_VALUE_MARKUP);
tmp_markup = net_EndColorHTMLTag(obj);
StrAllocCat(new_markup, tmp_markup);
FREE_AND_CLEAR(tmp_markup);
}
else if(*cp == '<')
{
/* protect ourselves from markup */
StrAllocCopy(new_markup, "&lt;");
}
else if(*cp == '&')
{
/* protect ourselves from markup */
StrAllocCopy(new_markup, "&amp;");
}
break;
case IN_QUOTED_ATTRIBUTE_VALUE:
/* do nothing until you find a closing '"' */
if(*cp == '\"')
{
if(obj->in_broken_html)
{
StrAllocCopy(new_markup, END_BROKEN_ATTRIBUTE_MARKUP);
obj->in_broken_html = FALSE;
}
StrAllocCat(new_markup, "\"");
StrAllocCat(new_markup, END_ATTRIBUTE_VALUE_MARKUP);
obj->state = IN_TAG;
}
else if(*cp == '<')
{
/* protect ourselves from markup */
StrAllocCopy(new_markup, "&lt;");
}
else if(*cp == '&')
{
/* protect ourselves from markup */
StrAllocCopy(new_markup, "&amp;");
}
else if(*cp == '>')
{
/* probably a broken attribute value */
if(!obj->in_broken_html)
{
obj->in_broken_html = TRUE;
StrAllocCopy(new_markup, BEGIN_BROKEN_ATTRIBUTE_MARKUP);
StrAllocCat(new_markup, ">");
}
}
break;
case IN_COMMENT:
/* do nothing until you find a closing '-->' */
if(!XP_STRNCMP(cp, "-->", 3))
{
StrAllocCopy(new_markup, "&gt;");
cp += 2;
i += 2;
StrAllocCat(new_markup, END_COMMENT_MARKUP);
obj->state = IN_CONTENT;
}
else if(*cp == '<')
{
/* protect ourselves from markup */
StrAllocCopy(new_markup, "&lt;");
}
break;
case IN_AMPERSAND_THINGY:
/* do nothing until you find a ';' or space */
if(*cp == ';' || XP_IS_SPACE(*cp))
{
XP_SPRINTF(tiny_buf, "%c", *cp);
StrAllocCopy(new_markup, tiny_buf);
StrAllocCat(new_markup, END_AMPERSAND_THINGY_MARKUP);
obj->state = IN_CONTENT;
}
else if(*cp == '<')
{
/* protect ourselves from markup */
StrAllocCopy(new_markup, "&lt;");
}
break;
default:
XP_ASSERT(0);
break;
}
if(new_markup)
{
/* push all the way up to but not including *cp */
status = (*obj->next_stream->put_block)
(obj->next_stream,
&s[last_output_point],
i-last_output_point);
last_output_point = i+1;
if(status < 0)
{
FREE(new_markup);
return(status);
}
/* add new markup */
status = (*obj->next_stream->put_block)
(obj->next_stream,
new_markup, XP_STRLEN(new_markup));
if(status < 0)
{
FREE(new_markup);
return(status);
}
FREE_AND_CLEAR(new_markup);
}
}
if(last_output_point < l)
return((*obj->next_stream->put_block)(obj->next_stream,
&s[last_output_point],
(l-last_output_point)));
else
return(0);
}
/* is the stream ready for writeing?
*/
PRIVATE unsigned int net_ColorHTMLWriteReady (NET_StreamClass * stream)
{
DataObject *obj=stream->data_object;
return((*obj->next_stream->is_write_ready)(obj->next_stream));
}
PRIVATE void net_ColorHTMLComplete (NET_StreamClass *stream)
{
DataObject *obj=stream->data_object;
(*obj->next_stream->complete)(obj->next_stream);
}
PRIVATE void net_ColorHTMLAbort (NET_StreamClass *stream, int status)
{
DataObject *obj=stream->data_object;
(*obj->next_stream->abort)(obj->next_stream, status);
}
PUBLIC NET_StreamClass *
net_ColorHTMLStream (int format_out,
void *data_obj,
URL_Struct *URL_s,
MWContext *window_id)
{
DataObject* obj;
char *new_markup=0;
char *new_url=0;
char *old_url;
int status, type;
NET_StreamClass *next_stream, *new_stream;
Bool is_html_stream = FALSE;
INTL_CharSetInfo csi = LO_GetDocumentCharacterSetInfo(window_id);
INTL_CharSetInfo next_csi;
TRACEMSG(("Setting up ColorHTML stream. Have URL: %s\n", URL_s->address));
/* treat the stream as html if the closure data says
* it's HTML and it is also not a mail or news message
*/
type = NET_URL_Type(URL_s->address);
if(data_obj
&& !XP_STRCMP((char *)data_obj, TEXT_HTML)
&& type != MAILBOX_TYPE_URL
&& type != IMAP_TYPE_URL
&& type != NEWS_TYPE_URL)
is_html_stream = TRUE;
/* use a new named window */
StrAllocCopy(URL_s->window_target, VIEW_SOURCE_TARGET_WINDOW_NAME);
/* add the url address to the name so that there can be
* one view source window per url
*/
StrAllocCat(URL_s->window_target, URL_s->address);
/* zero position_tag to prevent hash lossage */
URL_s->position_tag = 0;
/* alloc a new chrome struct and stick it in the URL
* so that we can turn off the relavent stuff
*/
URL_s->window_chrome = XP_NEW(Chrome);
if(URL_s->window_chrome)
{
/* zero everything to turn off all chrome */
XP_MEMSET(URL_s->window_chrome, 0, sizeof(Chrome));
URL_s->window_chrome->type = MWContextDialog;
URL_s->window_chrome->show_scrollbar = TRUE;
URL_s->window_chrome->allow_resize = TRUE;
URL_s->window_chrome->allow_close = TRUE;
}
/* call the HTML parser */
StrAllocCopy(URL_s->content_type, INTERNAL_PARSER);
/* use the view-source: url instead */
StrAllocCopy(new_url, VIEW_SOURCE_URL_PREFIX);
StrAllocCat(new_url, URL_s->address);
old_url = URL_s->address;
URL_s->address = new_url;
format_out = FO_PRESENT;
/* open next stream */
next_stream = NET_StreamBuilder(format_out, URL_s, window_id);
if(!next_stream)
{
FREE(old_url);
return(NULL);
}
next_csi = LO_GetDocumentCharacterSetInfo(next_stream->window_id);
/* jliu: for international's reason,
set the value ASAP, so the following stream can share it */
INTL_SetCSIWinCSID(next_csi, INTL_GetCSIWinCSID(csi));
INTL_SetCSIDocCSID(next_csi, INTL_GetCSIDocCSID(csi));
#define DEF_PICS_LABEL "<META http-equiv=PICS-Label content='(PICS-1.0 \"http://home.netscape.com/default_rating\" l gen true r (s 0))'>"
/* add a PICS label */
StrAllocCopy(new_markup, DEF_PICS_LABEL);
StrAllocCat(new_markup, "<TITLE>");
StrAllocCat(new_markup, XP_GetString(MK_CVCOLOR_SOURCE_OF));
StrAllocCat(new_markup, old_url);
StrAllocCat(new_markup, "</TITLE><BODY BGCOLOR=#C0C0C0>");
if(!is_html_stream)
StrAllocCat(new_markup, "<PLAINTEXT>");
else
StrAllocCat(new_markup, "<PRE>");
FREE(old_url);
status = (*next_stream->put_block)(next_stream,
new_markup,
XP_STRLEN(new_markup));
FREE(new_markup);
if(status < 0)
{
(*next_stream->abort)(next_stream, status);
FREE(next_stream);
return(NULL);
}
if(!is_html_stream)
return(next_stream);
/* else; continue on and build up this stream module
* and attach the next stream to it
*/
new_stream = XP_NEW(NET_StreamClass);
if(new_stream == NULL)
{
(*next_stream->abort)(next_stream, status);
FREE(next_stream);
return(NULL);
}
obj = XP_NEW(DataObject);
if (obj == NULL)
{
(*next_stream->abort)(next_stream, status);
FREE(next_stream);
FREE(new_stream);
return(NULL);
}
XP_MEMSET(obj, 0, sizeof(DataObject));
obj->state = IN_CONTENT;
obj->next_stream = next_stream;
obj->tag_type = P_UNKNOWN;
new_stream->name = "HTML Colorer";
new_stream->complete = (MKStreamCompleteFunc) net_ColorHTMLComplete;
new_stream->abort = (MKStreamAbortFunc) net_ColorHTMLAbort;
new_stream->put_block = (MKStreamWriteFunc) net_ColorHTMLWrite;
new_stream->is_write_ready = (MKStreamWriteReadyFunc)
net_ColorHTMLWriteReady;
new_stream->data_object = (void *) obj; /* document info object */
new_stream->window_id = window_id;
TRACEMSG(("Returning stream from HTMLColorConverter\n"));
return new_stream;
}
#endif /* MOZILLA_CLIENT */

View File

@@ -0,0 +1,29 @@
/* -*- 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.
*/
#ifndef CVCOLOR_H
#define CVCOLOR_H
extern NET_StreamClass *
net_ColorHTMLStream (int format_out,
void *data_obj,
URL_Struct *URL_s,
MWContext *window_id);
#endif /* CVCOLOR_H */

117
mozilla/lib/libnet/cvdisk.c Normal file
View File

@@ -0,0 +1,117 @@
/* -*- 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.
*/
/* Please leave outside of ifdef for windows precompiled headers */
#include "mkutils.h"
#ifdef MOZILLA_CLIENT
#include "mkstream.h"
#include "mkgeturl.h"
#include "xp.h"
typedef struct _DataObject {
FILE * fp;
char * filename;
} DataObject;
PRIVATE int net_SaveToDiskWrite (NET_StreamClass *stream, CONST char* s, int32 l)
{
DataObject *obj=stream->data_object;
fwrite(s, 1, l, obj->fp);
return(1);
}
/* is the stream ready for writeing?
*/
PRIVATE unsigned int net_SaveToDiskWriteReady (NET_StreamClass * stream)
{
DataObject *obj=stream->data_object;
return(MAX_WRITE_READY); /* always ready for writing */
}
PRIVATE void net_SaveToDiskComplete (NET_StreamClass *stream)
{
DataObject *obj=stream->data_object;
fclose(obj->fp);
FREEIF(obj->filename);
FREE(obj);
return;
}
PRIVATE void net_SaveToDiskAbort (NET_StreamClass *stream, int status)
{
DataObject *obj=stream->data_object;
fclose(obj->fp);
if(obj->filename)
{
remove(obj->filename);
FREE(obj->filename);
}
return;
}
PUBLIC NET_StreamClass *
fe_MakeSaveAsStream (int format_out,
void *data_obj,
URL_Struct *URL_s,
MWContext *window_id)
{
DataObject* obj;
NET_StreamClass* stream;
static int count=0;
char filename[256];
FILE *fp = stdout;
TRACEMSG(("Setting up display stream. Have URL: %s\n", URL_s->address));
PR_snprintf(filename, sizeof(filename), "foo%d.unknown",count++);
fp = fopen(filename,"w");
stream = XP_NEW(NET_StreamClass);
if(stream == NULL)
return(NULL);
obj = XP_NEW(DataObject);
if (obj == NULL)
return(NULL);
stream->name = "FileWriter";
stream->complete = (MKStreamCompleteFunc) net_SaveToDiskComplete;
stream->abort = (MKStreamAbortFunc) net_SaveToDiskAbort;
stream->put_block = (MKStreamWriteFunc) net_SaveToDiskWrite;
stream->is_write_ready = (MKStreamWriteReadyFunc) net_SaveToDiskWriteReady;
stream->data_object = obj; /* document info object */
stream->window_id = window_id;
obj->fp = fp;
obj->filename = 0;
StrAllocCopy(obj->filename, filename);
TRACEMSG(("Returning stream from NET_SaveToDiskConverter\n"));
return stream;
}
#endif /* MOZILLA_CLIENT */

View File

@@ -0,0 +1,27 @@
/* -*- 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.
*/
#ifndef CVDISK_H
#define CVDISK_H
extern NET_StreamClass* fe_MakeSaveAsStream (FO_Present_Types format_out,
void *data_obj,
URL_Struct *URL_s,
MWContext *window_id);
#endif /* CVDISK_H */

View File

@@ -0,0 +1,412 @@
/* -*- 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.
*/
/* cvextcon.c --- using external Unix programs as content-encoding filters.
*/
#include "mkutils.h"
#include "mkstream.h"
#include "mkgeturl.h"
#include "xp.h"
#include "cvextcon.h"
#include "mkformat.h"
#include <fcntl.h>
#include <sys/wait.h>
#ifdef __sgi
#include <bstring.h> /* FD_ZERO uses bzero() which needs this */
/* file for its prototype. */
#endif
typedef struct _CVG_DataObject {
NET_StreamClass *next_stream; /* Where the output goes */
pid_t pid; /* process in which the filter is running */
int infd; /* for reading from the process */
int outfd; /* for writing to the process */
struct sigaction oldact; /* Old SIGCHLD handler */
} CVG_DataObject;
PRIVATE int net_ExtConverterRead (CVG_DataObject *data, Bool block_p)
{
char input_buffer [1024];
int bytes_read;
AGAIN:
while ((bytes_read = read (data->infd, input_buffer, sizeof (input_buffer)))
> 0)
{
if (data->next_stream)
{
int status = ((*data->next_stream->put_block)
(data->next_stream,
input_buffer, bytes_read));
/* abort */
if (status < 0)
return status;
}
}
/* It's necessary that we block here waiting for the process to produce
the rest of its output before we allow the `complete' method to return.
We've already set the socket to be nonblocking, and there doesn't appear
to be any way to set it to do blocking reads again, so instead, we'll
use select() to block for it. That will return when there is some input
available, and we'll read it, and (maybe) block again, repeating until
we get an EOF.
To implement this in a non-blocking way would require the input and
output sides of this to be disconnected - the output side would be as in
this file, but the input side would need to be a new stream type in
NET_ProcessNet(), at the level of http, ftp, and file streams.
*/
if (bytes_read == -1 && block_p &&
(errno == EAGAIN || errno == EWOULDBLOCK))
{
fd_set rset;
FD_ZERO (&rset);
FD_SET (data->infd, &rset);
if (select (data->infd+1, &rset, 0, 0, 0) < 0)
perror ("select");
goto AGAIN;
}
return 1;
}
PRIVATE int net_ExtConverterWrite (NET_StreamClass *stream,
CONST char* output_buffer,
int32 output_length)
{
CVG_DataObject *data = (CVG_DataObject *) stream->data_object;
while (output_length > 0)
{
int bytes_written = 0;
/* write as much as possible (until done, or the pipe is full.)
*/
while (output_length > 0 &&
(bytes_written = write (data->outfd, output_buffer,
output_length))
> 0)
{
output_buffer += bytes_written;
output_length -= bytes_written;
}
if (bytes_written == -1 && errno != EAGAIN && errno != EWOULDBLOCK)
{
perror ("write");
return -1;
}
/* Now read as much as possible (until done, or the pipe is drained.)
*/
{
int status = net_ExtConverterRead (data, FALSE);
/* abort */
if (status < 0)
return status;
}
/* Now go around the loop again, if we weren't able to write all of
the output buffer at once (because the pipe filled up.) Now that
we've read the available data from the pipe, we will presumably
be able to write to it again.
*/
}
return 1;
}
PRIVATE int net_ExtConverterWriteReady (NET_StreamClass *stream)
{
/* #### I'm not sure what the right thing to do here is. --jwz */
#if 1
return (MAX_WRITE_READY);
#else
CVG_DataObject *data = (CVG_DataObject *) stream->data_object;
if(data->next_stream)
return ((*data->next_stream->is_write_ready)
(data->next_stream));
else
return (MAX_WRITE_READY);
#endif
}
PRIVATE void
net_KillConverterProcess (CVG_DataObject *data)
{
pid_t wait_status;
/* It may not actually be necessary to kill the process here if we have
exited normally, since in that case it has already closed its stdout;
but it can't hurt.
After it dies, we have to wait() for it, or it becomes a zombie.
I'm not entirely sure that the perror() is correct - it could be that
0 is a legitimate value from waitpid() if the process had already
exited before we kill()ed it, but I'm not sure.
*/
kill (data->pid, SIGINT);
wait_status = waitpid (data->pid, 0, 0);
#ifdef DEBUG_dp
fprintf(stderr, "Restoring sigchild handler for pid %d.\n", data->pid);
#endif
/* Reset SIGCHLD signal hander before returning */
sigaction(SIGCHLD, &data->oldact, NULL);
if (wait_status != data->pid)
perror ("waitpid");
}
PRIVATE void net_ExtConverterComplete (NET_StreamClass *stream)
{
CVG_DataObject *data = (CVG_DataObject *) stream->data_object;
/* Send an EOF to the stdin of the subprocess; then wait for the rest
of its output to show up on its stdout; then close stdout, and kill
the process. */
close (data->outfd);
net_ExtConverterRead (data, TRUE);
close (data->infd);
net_KillConverterProcess (data);
/* complete the next stream */
if (data->next_stream)
{
(*data->next_stream->complete) (data->next_stream);
free (data->next_stream);
}
free (data);
}
PRIVATE void net_ExtConverterAbort (NET_StreamClass *stream, int status)
{
CVG_DataObject *data = (CVG_DataObject *) stream->data_object;
/* Close the streams and kill the process, discarding any output still
in the pipe. */
close (data->outfd);
close (data->infd);
net_KillConverterProcess (data);
/* abort the next stream */
if (data->next_stream)
{
(*data->next_stream->abort) (data->next_stream, status);
free (data->next_stream);
}
free (data);
}
PUBLIC NET_StreamClass *
NET_ExtConverterConverter (int format_out,
void *data_obj,
URL_Struct *URL_s,
MWContext *window_id)
{
CVG_DataObject* obj;
CV_ExtConverterStruct * ext_con_obj = (CV_ExtConverterStruct *) data_obj;
NET_StreamClass* stream;
struct sigaction newact;
TRACEMSG(("Setting up display stream. Have URL: %s\n", URL_s->address));
stream = XP_NEW(NET_StreamClass);
if(stream == NULL)
return(NULL);
XP_MEMSET(stream, 0, sizeof(NET_StreamClass));
obj = XP_NEW(CVG_DataObject);
if (obj == NULL)
return(NULL);
memset(obj, 0, sizeof(CVG_DataObject));
stream->name = "Filter Stream";
stream->complete = (MKStreamCompleteFunc) net_ExtConverterComplete;
stream->abort = (MKStreamAbortFunc) net_ExtConverterAbort;
stream->put_block = (MKStreamWriteFunc) net_ExtConverterWrite;
stream->is_write_ready = (MKStreamWriteReadyFunc) net_ExtConverterWriteReady;
stream->data_object = obj; /* document info object */
stream->window_id = window_id;
/* Open the next stream.
First, swap in the content-encoding or content-type of the document
as we are about to convert it, to look up the proper next converter
(and to avoid looping.) But once we have set up the stream, put the
original encoding back, so that the URL_Struct is not permanently
altered - foo.html.gz must still have content-encoding x-gzip even
though it has been decoded for display.
*/
{
char *old, *new;
if (ext_con_obj->is_encoding_converter)
{
old = URL_s->content_encoding;
new = XP_STRDUP (ext_con_obj->new_format);
if (!new) return (NULL);
URL_s->content_encoding = new;
}
else
{
old = URL_s->content_type;
new = XP_STRDUP (ext_con_obj->new_format);
if (!new) return (NULL);
URL_s->content_type = new;
}
obj->next_stream = NET_StreamBuilder (format_out, URL_s, window_id);
if (ext_con_obj->is_encoding_converter)
{
XP_FREE (URL_s->content_encoding);
URL_s->content_encoding = old;
}
else
{
XP_FREE (URL_s->content_type);
URL_s->content_type = old;
}
}
if (!obj->next_stream)
return (NULL);
/* Open two pipes, one for writing to a subprocess, and one for reading
from it (for a total of four file descriptors, I/O for us, and O/I
for the kid.)
*/
{
int infds [2];
int outfds[2];
pid_t forked;
if (pipe (infds))
{
perror ("creating input pipe");
free (stream);
free (obj);
return 0;
}
if (pipe (outfds))
{
perror ("creating output pipe");
free (stream);
free (obj);
return 0;
}
obj->infd = infds [0];
obj->outfd = outfds [1];
/* Set our side of the pipes to be nonblocking. (It's important not
to set the other side of the pipes to be nonblocking - that
decision must be left up to the process on the other end. */
#if defined(O_NONBLOCK)
# define NONBLOCK_FLAG O_NONBLOCK
#elif defined(O_NDELAY)
# define NONBLOCK_FLAG O_NDELAY
#else
ERROR!! neither O_NONBLOCK nor O_NDELAY are defined.
#endif
fcntl (obj->infd, F_SETFL, NONBLOCK_FLAG);
fcntl (obj->outfd, F_SETFL, NONBLOCK_FLAG);
#undef NONBLOCK_FLAG
obj->pid = 0;
#ifdef DEBUG_dp
fprintf(stderr, "Ignoring sigchild.\n");
#endif
/* Setup signals so that SIGCHLD is ignored as we want to do waitpid
* when the helperapp ends
*/
newact.sa_handler = SIG_DFL;
newact.sa_flags = 0;
sigfillset(&newact.sa_mask);
sigaction (SIGCHLD, &newact, &obj->oldact);
switch (forked = fork ())
{
case -1:
perror ("fork");
close (outfds[0]);
close (outfds[1]);
close (infds [0]);
close (infds [1]);
free (stream);
free (obj);
/* Reset SIGCHLD signal hander before returning */
sigaction(SIGCHLD, &obj->oldact, NULL);
return 0;
case 0:
{
/* This is the new process. exec() the filter here.
We do this with sh to get tokenization and pipelines
and all that junk.
*/
char *av[10];
int ac = 0;
av [ac++] = "/bin/sh";
av [ac++] = "-c";
av [ac++] = ext_con_obj->command;
av [ac++] = 0;
dup2 (outfds[0], 0); /* stdin */
dup2 (infds [1], 1); /* stdout */
/* dup2 (infds [1], 2); * stderr */
/* We have copied the two pipes to stdin/stdout.
We no longer need the other file descriptors hanging around.
(Actually I think we need to close these, or the other side
of the pipe doesn't see an eof when we close stdout...)
*/
close (outfds[0]);
close (outfds[1]);
close (infds [0]);
close (infds [1]);
execv (av[0], av);
/* exec() should never return. */
perror ("execv");
exit (1); /* This only exits a child fork. */
break;
}
default:
/* This is the "old" process (subproc pid is in `forked'.) */
obj->pid = forked;
/* These are the file descriptors we created for the benefit
of the child process - we don't need them in the parent. */
close (outfds[0]);
close (infds [1]);
break;
}
}
TRACEMSG(("Returning stream from NET_ExtConverterConverter\n"));
return stream;
}

View File

@@ -0,0 +1,34 @@
/* -*- 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.
*/
#ifndef CVEXTCON_H
#define CVEXTCON_H
typedef struct _CV_ExtConverterStruct {
char * command;
char * new_format;
Bool is_encoding_converter;
} CV_ExtConverterStruct;
extern NET_StreamClass *
NET_ExtConverterConverter(FO_Present_Types format_out,
void *data_obj,
URL_Struct *URL_s,
MWContext *window_id);
#endif /* CVEXTCON_H */

1052
mozilla/lib/libnet/cvmime.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,25 @@
/* -*- 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.
*/
#ifndef CVMIME_H
#define CVMIME_H
extern NET_StreamClass *
NET_MimeEncodingConverter(int, void *, URL_Struct *, MWContext *);
#endif /* CVMIME_H */

383
mozilla/lib/libnet/cvpics.c Normal file
View File

@@ -0,0 +1,383 @@
/* this set of functions parses an incoming stream of HTML and tries to find
* any PICS label within it. It doesn't do anything accept parse the pics label
* and finish
*/
#include "mkutils.h"
#include "mkstream.h"
#include "mkgeturl.h"
#include "pa_parse.h"
#include "xp.h"
#include "xpgetstr.h"
#include "layout.h"
#include "pics.h"
typedef enum StatesEnum {
IN_CONTENT,
IN_SCRIPT,
ABOUT_TO_BEGIN_TAG,
IN_BEGIN_TAG,
IN_TAG,
BEGIN_ATTRIBUTE_VALUE,
IN_QUOTED_ATTRIBUTE_VALUE,
IN_BROKEN_QUOTED_ATTRIBUTE_VALUE,
IN_UNQUOTED_ATTRIBUTE_VALUE,
IN_COMMENT,
IN_AMPERSAND_THINGY
} StatesEnum;
#define MAXTAGLEN 15
typedef struct _DataObject {
MWContext *context;
URL_Struct *URL_s;
StatesEnum state;
char tag[MAXTAGLEN+1];
uint tag_index;
int tag_type;
XP_Bool in_broken_html;
char *tag_data; /* the contents of the current tag */
} DataObject;
extern int MK_CVCOLOR_SOURCE_OF;
PRIVATE void net_BeginPICSLabelFinderTag (DataObject *obj)
{
if(obj->tag_data)
*obj->tag_data = '\0'; /* empty tag_data */
if (obj->tag_type == P_SCRIPT)
{
obj->tag_type = P_UNKNOWN;
}
obj->state = ABOUT_TO_BEGIN_TAG;
return ;
}
PRIVATE void net_EndPICSLabelFinderTag (DataObject *obj)
{
if(obj->in_broken_html)
{
obj->in_broken_html = FALSE;
}
if (obj->tag_type == P_SCRIPT)
{
obj->state = IN_SCRIPT;
}
else
{
obj->state = IN_CONTENT;
}
/* check tag_data for a META tag */
if(obj->tag_data && !strncasecomp(obj->tag_data, "META", 4))
{
PA_Tag tmp_tag;
char *name;
tmp_tag.type = P_META;
tmp_tag.data = (void*)obj->tag_data;
tmp_tag.data_len = XP_STRLEN((char*)tmp_tag.data);
name = (char *)lo_FetchParamValue(obj->context, &tmp_tag, PARAM_HTTP_EQUIV);
#define PICS_HEADER "PICS-Label"
if(name && !strcasecomp(name, PICS_HEADER))
{
char *label = (char *)lo_FetchParamValue(obj->context, &tmp_tag, PARAM_CONTENT);
if(label)
{
PICS_RatingsStruct * rs = PICS_ParsePICSLable(label);
FREE(label);
PICS_CompareToUserSettings(rs, obj->URL_s->address);
PICS_FreeRatingsStruct(rs); /* handles NULL */
}
}
FREEIF(name);
}
return;
}
PRIVATE int net_PICSLabelFinderWrite (NET_StreamClass *stream, CONST char *s, int32 l)
{
int32 i;
CONST char *cp;
DataObject *obj = (DataObject *)stream->data_object;
char tiny_buf[8];
for(i = 0, cp = s; i < l; i++, cp++)
{
switch(obj->state)
{
case IN_CONTENT:
/* do nothing until you find a '<' "<!--" or '&' */
if(*cp == '<')
{
/* XXX we can miss a comment spanning a block boundary */
if(i+4 <= l && !XP_STRNCMP(cp, "<!--", 4))
{
obj->state = IN_COMMENT;
}
else
{
net_BeginPICSLabelFinderTag(obj);
}
}
else if(*cp == '&')
{
obj->state = IN_AMPERSAND_THINGY;
}
break;
case IN_SCRIPT:
/* do nothing until you find '</SCRIPT>' */
if(*cp == '<')
{
/* XXX we can miss a </SCRIPT> spanning a block boundary */
if(i+8 <= l && !XP_STRNCASECMP(cp, "</SCRIPT", 8))
{
net_BeginPICSLabelFinderTag(obj);
}
}
break;
case ABOUT_TO_BEGIN_TAG:
/* we have seen the first '<'
* once we see a non-whitespace character
* we will be in the tag identifier
*/
if(*cp == '>')
{
net_EndPICSLabelFinderTag(obj);
}
else if(!XP_IS_SPACE(*cp))
{
/* capture all tag data */
tiny_buf[0] = *cp;
tiny_buf[1] = '\0';
StrAllocCat(obj->tag_data, tiny_buf);
obj->state = IN_BEGIN_TAG;
obj->tag_index = 0;
obj->tag[obj->tag_index++] = *cp;
}
break;
case IN_BEGIN_TAG:
/* go to the IN_TAG state when we see
* the first whitespace
*/
/* capture all tag data */
tiny_buf[0] = *cp;
tiny_buf[1] = '\0';
StrAllocCat(obj->tag_data, tiny_buf);
if(XP_IS_SPACE(*cp))
{
obj->state = IN_TAG;
obj->tag[obj->tag_index] = '\0';
obj->tag_type = pa_tokenize_tag(obj->tag);
}
else if(*cp == '>')
{
net_EndPICSLabelFinderTag(obj);
}
else if(*cp == '<')
{
/* protect ourselves from markup */
if(!obj->in_broken_html)
{
obj->in_broken_html = TRUE;
}
}
else
{
if (obj->tag_index < MAXTAGLEN)
obj->tag[obj->tag_index++] = *cp;
}
break;
case IN_TAG:
/* capture all tag data */
tiny_buf[0] = *cp;
tiny_buf[1] = '\0';
StrAllocCat(obj->tag_data, tiny_buf);
/* do nothing until you find a opening '=' or end '>' */
if(*cp == '=')
{
obj->state = BEGIN_ATTRIBUTE_VALUE;
}
else if(*cp == '>')
{
net_EndPICSLabelFinderTag(obj);
}
break;
case BEGIN_ATTRIBUTE_VALUE:
/* capture all tag data */
tiny_buf[0] = *cp;
tiny_buf[1] = '\0';
StrAllocCat(obj->tag_data, tiny_buf);
/* when we reach the first non-whitespace
* we will enter the UNQUOTED or the QUOTED
* ATTRIBUTE state
*/
if(!XP_IS_SPACE(*cp))
{
if(*cp == '"')
{
obj->state = IN_QUOTED_ATTRIBUTE_VALUE;
/* no need to jump to the quoted attr handler
* since this char can't be a dangerous char
*/
}
else
{
obj->state = IN_UNQUOTED_ATTRIBUTE_VALUE;
/* need to jump to the unquoted attr handler
* since this char can be a dangerous character
*/
goto unquoted_attribute_jump_point;
}
}
else if(*cp == '>')
{
net_EndPICSLabelFinderTag(obj);
}
break;
case IN_UNQUOTED_ATTRIBUTE_VALUE:
/* capture all tag data */
tiny_buf[0] = *cp;
tiny_buf[1] = '\0';
StrAllocCat(obj->tag_data, tiny_buf);
unquoted_attribute_jump_point:
/* do nothing until you find a whitespace */
if(XP_IS_SPACE(*cp))
{
obj->state = IN_TAG;
}
else if(*cp == '>')
{
net_EndPICSLabelFinderTag(obj);
}
break;
case IN_QUOTED_ATTRIBUTE_VALUE:
/* capture all tag data */
tiny_buf[0] = *cp;
tiny_buf[1] = '\0';
StrAllocCat(obj->tag_data, tiny_buf);
/* do nothing until you find a closing '"' */
if(*cp == '\"')
{
if(obj->in_broken_html)
{
obj->in_broken_html = FALSE;
}
obj->state = IN_TAG;
}
else if(*cp == '>')
{
/* probably a broken attribute value */
if(!obj->in_broken_html)
{
obj->in_broken_html = TRUE;
}
}
break;
case IN_COMMENT:
/* do nothing until you find a closing '-->' */
if(!XP_STRNCMP(cp, "-->", 3))
{
cp += 2;
i += 2;
obj->state = IN_CONTENT;
}
break;
case IN_AMPERSAND_THINGY:
/* do nothing until you find a ';' or space */
if(*cp == ';' || XP_IS_SPACE(*cp))
{
XP_SPRINTF(tiny_buf, "%c", *cp);
obj->state = IN_CONTENT;
}
break;
default:
XP_ASSERT(0);
break;
}
}
return(0);
}
/* is the stream ready for writeing?
*/
PRIVATE unsigned int net_PICSLabelFinderWriteReady (NET_StreamClass *stream)
{
return(MAX_WRITE_READY);
}
PRIVATE void net_PICSLabelFinderComplete (NET_StreamClass *stream)
{
}
PRIVATE void net_PICSLabelFinderAbort (NET_StreamClass *stream, int status)
{
}
PUBLIC NET_StreamClass *
net_PICSLabelFinderStream (int format_out,
void *data_obj,
URL_Struct *URL_s,
MWContext *window_id)
{
DataObject* obj;
NET_StreamClass *new_stream;
Bool is_html_stream = FALSE;
TRACEMSG(("Setting up PICSLabelFinder stream. Have URL: %s\n", URL_s->address));
new_stream = XP_NEW_ZAP(NET_StreamClass);
if(!new_stream)
return NULL;
obj = XP_NEW(DataObject);
if (obj == NULL)
{
FREE(new_stream);
return(NULL);
}
XP_MEMSET(obj, 0, sizeof(DataObject));
obj->state = IN_CONTENT;
obj->tag_type = P_UNKNOWN;
obj->context = window_id;
obj->URL_s = URL_s;
new_stream->name = "PICSLabelFinder";
new_stream->complete = (MKStreamCompleteFunc) net_PICSLabelFinderComplete;
new_stream->abort = (MKStreamAbortFunc) net_PICSLabelFinderAbort;
new_stream->put_block = (MKStreamWriteFunc) net_PICSLabelFinderWrite;
new_stream->is_write_ready = (MKStreamWriteReadyFunc)
net_PICSLabelFinderWriteReady;
new_stream->data_object = (void *) obj; /* document info object */
new_stream->window_id = window_id;
/* don't cache this URL, since the content type is wrong */
URL_s->dont_cache = TRUE;
return new_stream;
}

View File

@@ -0,0 +1,11 @@
#ifndef CVPICS_H
#define CVPICS_H
PUBLIC NET_StreamClass *
net_PICSLabelFinderStream (int format_out,
void *data_obj,
URL_Struct *URL_s,
MWContext *window_id);
#endif /* CVPICS_H */

View File

@@ -0,0 +1,131 @@
/* -*- 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.
*/
#include "mkutils.h"
#include "mkstream.h"
#include "mkgeturl.h"
#include "xp.h"
typedef struct _ProxyObj {
Bool past_first_line;
Bool definately_send_headers;
char *content_type;
char *content_encoding;
} ProxyObj;
PRIVATE int net_proxy_write (NET_StreamClass *stream, CONST char* s, int32 len)
{
ProxyObj *obj=stream->data_object;
/* send HTTP headers if not already getting an HTTP doc
*/
if(!obj->past_first_line)
{
if(obj->definately_send_headers || strncmp(s, "HTTP/", len >= 5 ? 5 : len))
{
write(1, "HTTP/1.0 200 OK\r\n",17);
write(1, "Content-type: ",14);
write(1, obj->content_type, XP_STRLEN(obj->content_type));
if(obj->content_encoding)
{
write(1, "\r\nContent-encoding: ",18);
write(1, obj->content_encoding, XP_STRLEN(obj->content_encoding));
}
write(1, "\r\nServer: MKLib proxy agent\r\n",29);
write(1, "\r\n", 2); /* finish it */
}
obj->past_first_line = TRUE;
}
write(1, s, len);
return(1);
}
PRIVATE unsigned int net_proxy_WriteReady (NET_StreamClass *stream)
{
return(MAX_WRITE_READY); /* always ready for writing */
}
PRIVATE void net_proxy_complete (NET_StreamClass *stream)
{
ProxyObj *obj=stream->data_object;
FREEIF(obj->content_type);
FREEIF(obj->content_encoding);
FREE(obj);
return;
}
PRIVATE void net_proxy_abort (NET_StreamClass *stream, int status)
{
ProxyObj *obj=stream->data_object;
FREEIF(obj->content_type);
FREEIF(obj->content_encoding);
FREE(obj);
return;
}
PUBLIC NET_StreamClass *
NET_ProxyConverter(int format_out,
void *data_obj,
URL_Struct *URL_s,
MWContext *window_id)
{
NET_StreamClass* stream;
ProxyObj * obj;
TRACEMSG(("Setting up display stream. Have URL: %s \n%s\n",
URL_s->address, URL_s->content_type));
stream = XP_NEW(NET_StreamClass);
if(stream == NULL)
return(NULL);
obj = XP_NEW(ProxyObj);
if(obj == NULL)
{
FREE(stream);
return(NULL);
}
XP_MEMSET(obj, 0, sizeof(ProxyObj));
stream->data_object = obj;
stream->name = "ProxyWriter";
stream->complete = (MKStreamCompleteFunc) net_proxy_complete;
stream->abort = (MKStreamAbortFunc) net_proxy_abort;
stream->put_block = (MKStreamWriteFunc) net_proxy_write;
stream->is_write_ready = (MKStreamWriteReadyFunc) net_proxy_WriteReady;
stream->window_id = window_id;
TRACEMSG(("Returning stream from display_converter\n"));
/* send HTTP headers if not already getting an HTTP doc
*/
if(strncasecomp(URL_s->address,"http:",5))
{
obj->definately_send_headers = TRUE;
}
StrAllocCopy(obj->content_type, URL_s->content_type);
StrAllocCopy(obj->content_encoding, URL_s->content_encoding);
return stream;
}

View File

@@ -0,0 +1,22 @@
/* -*- 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.
*/
extern NET_StreamClass* NET_ProxyConverter (FO_Present_Types format_out,
void *data_obj,
URL_Struct *URL_s,
MWContext *window_id);

View File

@@ -0,0 +1,123 @@
/* -*- 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.
*/
/**********************************************************************
cvsimple.c
By Daniel Malmer <malmer@netscape.com>
1/14/98
Simple converter that just saves the data in a buffer.
**********************************************************************/
#include "cvsimple.h"
#include "xp.h"
typedef void (*simple_complete_t)(void* bytes, int32 bytes_written);
typedef struct {
unsigned char* bytes;
int32 bytes_written;
int32 max_bytes;
simple_complete_t complete;
} NET_SimpleStreamData;
/*
* simple_complete
*/
PRIVATE void
simple_complete(NET_StreamClass *stream)
{
NET_SimpleStreamData* obj = (NET_SimpleStreamData*) stream->data_object;
if ( obj && obj->complete ) {
(obj->complete)(obj->bytes, obj->bytes_written);
}
if ( obj && obj->bytes ) XP_FREE(obj->bytes);
if ( obj ) XP_FREE(obj);
}
/*
* simple_abort
*/
PRIVATE void
simple_abort(NET_StreamClass *stream, int status)
{
NET_SimpleStreamData* obj = (NET_SimpleStreamData*) stream->data_object;
if ( obj && obj->bytes ) XP_FREE(obj->bytes);
if ( obj ) XP_FREE(obj);
}
/*
* simple_write
*/
PRIVATE int
simple_write(NET_StreamClass *stream, const char* str, int32 len)
{
NET_SimpleStreamData* obj = (NET_SimpleStreamData*) stream->data_object;
if ( obj->bytes_written + len > obj->max_bytes ) {
/* Round to nearest 1024 */
obj->max_bytes = ( ( ( (obj->max_bytes + len) >> 10) + 1) << 10);
obj->bytes = XP_REALLOC(obj->bytes, obj->max_bytes);
}
XP_MEMCPY(obj->bytes + obj->bytes_written, str, len);
obj->bytes_written+= len;
return MK_DATA_LOADED;
}
/*
* simple_write_ready
*/
PRIVATE unsigned int
simple_write_ready(NET_StreamClass *stream)
{
return MAX_WRITE_READY;
}
/*
* NET_SimpleStream
* Simple stream constructor.
*/
MODULE_PRIVATE NET_StreamClass*
NET_SimpleStream(int fmt, void* data_obj, URL_Struct* URL_s, MWContext* w)
{
NET_SimpleStreamData* obj;
if ( (obj = XP_NEW_ZAP(NET_SimpleStreamData)) == NULL ) {
return NULL;
}
obj->bytes = NULL;
obj->bytes_written = 0;
obj->max_bytes = 0;
obj->complete = (simple_complete_t) data_obj;
return NET_NewStream("SimpleStream", simple_write, simple_complete,
simple_abort, simple_write_ready, obj, w);
}

View File

@@ -0,0 +1,36 @@
/* -*- 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.
*/
/**********************************************************************
cvsimple.h
By Daniel Malmer <malmer@netscape.com>
1/14/98
Simple converter that just saves the data in a buffer.
**********************************************************************/
#ifndef __cvsimple_h
#define __cvsimple_h
#include "net.h"
MODULE_PRIVATE NET_StreamClass*
NET_SimpleStream(int fmt, void* data_obj, URL_Struct* URL_s, MWContext* w);
#endif

View File

@@ -0,0 +1,482 @@
/* -*- 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.
*/
/* Please leave outside of ifdef for windows precompiled headers */
#include "mkutils.h"
#include "cvunzip.h"
#ifdef MOZILLA_CLIENT
#include "mkstream.h"
#include "mkgeturl.h"
#include "xp.h"
#include "zlib.h"
extern int MK_OUT_OF_MEMORY;
extern int MK_BAD_GZIP_HEADER;
typedef struct _DataObject {
NET_StreamClass *next_stream;
z_stream d_stream; /* decompression stream */
unsigned char *dcomp_buf;
uint32 dcomp_buf_size;
XP_Bool is_done;
XP_Bool checking_crc_footer;
unsigned char *incoming_buf;
uint32 incoming_buf_size;
XP_Bool header_skipped;
URL_Struct *URL_s;
uint32 crc_check;
} DataObject;
#define DECOMP_BUF_SIZE NET_Socket_Buffer_Size*2
enum check_header_response {
HEADER_OK,
BAD_HEADER,
NEED_MORE_HEADER
};
static uint32 gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
/* gzip flag byte */
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
#define COMMENT 0x10 /* bit 4 set: file comment present */
#define RESERVED 0xE0 /* bits 5..7: reserved */
/* code copied from Zlib please see zlib.h for copyright statement */
/* ===========================================================================
Check the gzip header of a gz_stream opened for reading. Set the stream
mode to transparent if the gzip magic header is not present; set s->err
to Z_DATA_ERROR if the magic header is present but the rest of the header
is incorrect.
IN assertion: the stream s has already been created sucessfully;
s->stream.avail_in is zero for the first time, but may be non-zero
for concatenated .gz files.
*/
static enum check_header_response
check_header(unsigned char *header, uint32 header_length, uint32 *actual_header_size)
{
int method; /* method byte */
int flags; /* flags byte */
uInt len;
uint32 c;
uint32 orig_header_size = header_length;
/* header must be at least 10 bytes */
if(header_length < 10)
return NEED_MORE_HEADER;
/* Check the gzip magic header */
for (len = 0; len < 2; len++) {
c = (uint32) *header++;
header_length--;
if (c != gz_magic[len]) {
return BAD_HEADER;
}
}
method = *header++;
header_length--;
flags = *header++;
header_length--;
if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
return BAD_HEADER;
}
/* Discard time, xflags and OS code: */
for (len = 0; len < 6; len++)
{
header++;
header_length--;
}
/* OK we now passed the safe 10 byte boundary, we need to check from here
* on out to make sure we have enough data
*/
if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
if(header_length < 2)
return NEED_MORE_HEADER;
len = (uInt)*header++;
header_length--;
len += ((uInt)*header++)<<8;
header_length--;
/* len is garbage if EOF but the loop below will quit anyway */
if(header_length < len)
return NEED_MORE_HEADER;
while (len-- != 0)
{
header++;
header_length--;
}
}
if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
if(header_length < 1)
return NEED_MORE_HEADER;
while (*header != '\0')
{
header++;
header_length--;
if(header_length == 0)
return NEED_MORE_HEADER;
}
/* skip null byte */
header++;
header_length--;
}
if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
if(header_length < 1)
return NEED_MORE_HEADER;
while (*header != '\0')
{
header++;
header_length--;
if(header_length == 0)
return NEED_MORE_HEADER;
}
/* skip null byte */
header++;
header_length--;
}
if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
if(header_length < 2)
return NEED_MORE_HEADER;
for (len = 0; len < 2; len++)
{
header++;
header_length--;
}
}
*actual_header_size = orig_header_size - header_length;
return HEADER_OK;
}
PRIVATE int
do_end_crc_check(DataObject *obj)
{
if(obj->incoming_buf_size >= 8)
{
uint32 crc_int;
uint32 size_int;
obj->checking_crc_footer = FALSE;
obj->is_done = TRUE;
crc_int = (uint32)obj->incoming_buf[0];
crc_int += (uint32)obj->incoming_buf[1]<<8;
crc_int += (uint32)obj->incoming_buf[2]<<16;
crc_int += (uint32)obj->incoming_buf[3]<<24;
size_int = (uint32)obj->incoming_buf[4];
size_int += (uint32)obj->incoming_buf[5]<<8;
size_int += (uint32)obj->incoming_buf[6]<<16;
size_int += (uint32)obj->incoming_buf[7]<<24;
if(obj->crc_check != crc_int
|| obj->d_stream.total_out != size_int)
{
/* crc or size checksum failure */
obj->URL_s->error_msg = NET_ExplainErrorDetails(MK_BAD_GZIP_HEADER);
return MK_BAD_GZIP_HEADER;
}
return 1;
}
return 0; /* need more data */
}
PRIVATE int net_UnZipWrite (NET_StreamClass *stream, CONST char* s, int32 l)
{
int err;
uint32 prev_total_out;
uint32 new_data_total_out;
uint32 input_used_up, input_left_over;
char * tempPtr = NULL;
DataObject *obj=stream->data_object;
if(obj->is_done)
{
/* multipart gzip? */
XP_ASSERT(0);
return (1);
}
BlockAllocCat( tempPtr, obj->incoming_buf_size, s, l);
obj->incoming_buf = (unsigned char*)tempPtr;
if(!obj->incoming_buf)
return MK_OUT_OF_MEMORY;
obj->incoming_buf_size += l;
/* parse and skip the header */
if(!obj->header_skipped)
{
uint32 actual_header_size;
enum check_header_response status;
status = check_header((unsigned char *)obj->incoming_buf, obj->incoming_buf_size, &actual_header_size);
if(status == HEADER_OK)
{
/* squash the header */
obj->incoming_buf_size -= actual_header_size;
XP_MEMMOVE(obj->incoming_buf,
obj->incoming_buf+actual_header_size,
obj->incoming_buf_size);
obj->header_skipped = TRUE;
}
else if(status == BAD_HEADER)
{
obj->URL_s->error_msg = NET_ExplainErrorDetails(MK_BAD_GZIP_HEADER);
return MK_BAD_GZIP_HEADER;
}
else if(status == NEED_MORE_HEADER)
{
return 1;
}
else
{
XP_ASSERT(0);
return 1;
}
}
else if(obj->checking_crc_footer)
{
return do_end_crc_check(obj);
}
obj->d_stream.next_in = (unsigned char *)obj->incoming_buf;
obj->d_stream.avail_in = obj->incoming_buf_size;
obj->d_stream.next_out = (unsigned char *)obj->dcomp_buf;
obj->d_stream.avail_out = obj->dcomp_buf_size;
if(obj->d_stream.avail_in <= 0)
return 1; /* wait for more data */
prev_total_out = obj->d_stream.total_out;
/* need to loop to finish for small output bufs */
while(1)
{
err = inflate(&obj->d_stream, Z_NO_FLUSH);
/* the amount of new uncompressed data is: */
new_data_total_out = obj->d_stream.total_out - prev_total_out;
if(new_data_total_out > 0)
{
obj->crc_check = crc32(obj->crc_check,
obj->dcomp_buf,
new_data_total_out);
(*obj->next_stream->put_block)(obj->next_stream,
(char *) obj->dcomp_buf,
new_data_total_out);
}
obj->d_stream.avail_out = obj->dcomp_buf_size;
obj->d_stream.next_out = (unsigned char *)obj->dcomp_buf;
prev_total_out = obj->d_stream.total_out;
if(err == Z_STREAM_END)
{
obj->checking_crc_footer = TRUE;
break;
}
else if(err != Z_OK)
{
/* need to get more data on next pass
* @@@ should check for more critical errors
*/
break;
}
else if(obj->d_stream.avail_in <= 0)
{
/* need more data */
break;
}
}
/* remove the part that has already been decoding from the incoming buf */
input_left_over = obj->d_stream.avail_in;
if(input_left_over > 0)
{
input_used_up = obj->incoming_buf_size - input_left_over;
XP_MEMMOVE(obj->incoming_buf, obj->incoming_buf+input_used_up, input_left_over);
obj->incoming_buf_size = input_left_over;
}
else
{
obj->incoming_buf_size = 0;
}
if(obj->checking_crc_footer == TRUE)
{
return do_end_crc_check(obj);
}
return(1);
}
/* is the stream ready for writeing?
*/
PRIVATE unsigned int net_UnZipWriteReady (NET_StreamClass * stream)
{
DataObject *obj=stream->data_object;
return((*obj->next_stream->is_write_ready)(obj->next_stream)); /* always ready for writing */
}
PRIVATE void net_UnZipComplete (NET_StreamClass *stream)
{
DataObject *obj=stream->data_object;
int err;
(*obj->next_stream->complete)(obj->next_stream);
err = inflateEnd(&(obj->d_stream));
XP_ASSERT(err == Z_OK);
if(!obj->is_done)
{
/* we didn't complete the crc and size checks */
/* @@@ not sure what to do here yet */
XP_ASSERT(0);
}
FREE(obj->dcomp_buf);
FREE(obj);
return;
}
PRIVATE void net_UnZipAbort (NET_StreamClass *stream, int status)
{
DataObject *obj=stream->data_object;
int err;
(*obj->next_stream->abort)(obj->next_stream, status);
err = inflateEnd(&(obj->d_stream));
XP_ASSERT(err == Z_OK);
FREE(obj->dcomp_buf);
FREE(obj);
return;
}
PUBLIC NET_StreamClass *
NET_UnZipConverter (int format_out,
void *data_obj,
URL_Struct *URL_s,
MWContext *window_id)
{
DataObject* obj;
NET_StreamClass* stream;
int err;
TRACEMSG(("Setting up display stream. Have URL: %s\n", URL_s->address));
stream = XP_NEW(NET_StreamClass);
if(stream == NULL)
return(NULL);
obj = XP_NEW_ZAP(DataObject);
if (obj == NULL)
{
FREE(stream);
return(NULL);
}
stream->name = "UnZiper";
stream->complete = (MKStreamCompleteFunc) net_UnZipComplete;
stream->abort = (MKStreamAbortFunc) net_UnZipAbort;
stream->put_block = (MKStreamWriteFunc) net_UnZipWrite;
stream->is_write_ready = (MKStreamWriteReadyFunc) net_UnZipWriteReady;
stream->data_object = obj; /* document info object */
stream->window_id = window_id;
obj->dcomp_buf = XP_ALLOC(DECOMP_BUF_SIZE);
obj->dcomp_buf_size = DECOMP_BUF_SIZE;
if(!obj->dcomp_buf)
{
FREE(stream);
FREE(obj);
return NULL;
}
obj->URL_s = URL_s;
obj->d_stream.zalloc = (alloc_func)0;
obj->d_stream.zfree = (free_func)0;
obj->d_stream.opaque = (voidpf)0;
err = inflateInit2(&obj->d_stream, -15);
if(err != Z_OK)
{
FREE(stream);
FREE(obj);
return NULL;
}
/* create the next stream, but strip the compressed encoding */
FREE_AND_CLEAR(URL_s->content_encoding);
obj->next_stream = NET_StreamBuilder(format_out, URL_s, window_id);
if(!obj->next_stream)
{
inflateEnd(&obj->d_stream);
FREE(stream);
FREE(obj);
return NULL;
}
TRACEMSG(("Returning stream from NET_UnZipConverter\n"));
return stream;
}
#endif /* MOZILLA_CLIENT */

View File

@@ -0,0 +1,28 @@
/* -*- 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.
*/
#ifndef CVUNZIP_H
#define CVUNZIP_H
NET_StreamClass *
NET_UnZipConverter (int format_out,
void *data_obj,
URL_Struct *URL_s,
MWContext *window_id);
#endif /* CVUNZIP_H */

580
mozilla/lib/libnet/cvview.c Normal file
View File

@@ -0,0 +1,580 @@
/* -*- 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.
*/
/* Please leave outside of ifdef for windows precompiled headers */
#include "mkutils.h"
#ifdef MOZILLA_CLIENT
#include "mkstream.h"
#include "mkgeturl.h"
#include "xp.h"
#include "mkparse.h"
#include "cvview.h"
#include "libmime.h"
/* for XP_GetString() */
#include <xpgetstr.h>
extern int XP_CONFIRM_EXEC_UNIXCMD_ARE;
extern int XP_CONFIRM_EXEC_UNIXCMD_MAYBE;
extern int XP_ALERT_UNABLE_INVOKEVIEWER;
extern int MK_UNABLE_TO_OPEN_TMP_FILE;
typedef struct _CV_DataObject {
FILE * fp;
char * filename;
char * command;
char * url;
unsigned int stream_block_size;
int32 cur_size;
int32 tot_size;
MWContext * context;
} CV_DataObject;
/*
** build_viewer_cmd
** Build up the command for forking the external viewer.
** Argument list is the template for the command and the a set of
** (char,char*) pairs of characters to be recognized as '%' escapes
** and what they should expand to, terminated with a 0.
**
** Return value is a malloc'ed string, must be freed when command is done.
**
** Example:
** char* s=build_viewer(line_from_mailcap, 's', tmpFile, 'u', url, 0);
**
** I'm completely unsure what to do about security considerations and
** encodings. Should the URL get % encoded. What if it contains "bad"
** characters. etc. etc. etc
*/
char*
build_viewer_cmd(char *template, ...)
{
va_list args;
char *ret, *from, *to;
int len;
if (template == NULL)
return NULL;
len = strlen(template);
ret = (char*) malloc(len+1);
if (ret == NULL)
return NULL;
from = template, to = ret;
while (*from) {
if (*from != '%' || *++from == '%') {
*to++ = *from++;
} else {
/*
** We have a % escape, now look through all the arguments for
** a matching one. When one is found, substitute in the
** passed value. If none is found, the % and following character
** get swallowed.
*/
char argc;
char* argv;
va_start(args, template);
while ((argc = va_arg(args, int)) != 0) {
argv = va_arg(args, char*);
if (*from == argc) {
int off = to - ret;
int arglen = strlen(argv);
len = len + arglen - 2;
ret = (char*) realloc(ret, len + 1);
if (ret == NULL)
return NULL;
XP_STRCPY(ret + off, argv);
to = ret + off + arglen;
break;
}
}
if (*from) from++; /* skip char following % unless it was last */
va_end(args);
}
}
*to = '\0';
return ret;
}
PRIVATE int net_ExtViewWrite (NET_StreamClass *stream, CONST char* s, int32 l)
{
CV_DataObject *obj=stream->data_object;
if(obj->tot_size)
{
obj->cur_size += l;
obj->context->funcs->SetProgressBarPercent(obj->context, (obj->cur_size*100)/obj->tot_size);
}
/* TRACEMSG(("Length of string passed to display: %d\n",l));
*/
return(fwrite((char *) s, 1, l, obj->fp));
}
PRIVATE int net_ExtViewWriteReady (NET_StreamClass * stream)
{
CV_DataObject *obj=stream->data_object;
fd_set write_fds;
struct timeval timeout;
int ret;
if(obj->command)
{
return(MAX_WRITE_READY); /* never wait for files */
}
timeout.tv_sec = 0;
timeout.tv_usec = 1; /* minimum hopefully */
XP_MEMSET(&write_fds, 0, sizeof(fd_set));
FD_SET(fileno(obj->fp), &write_fds);
ret = select(fileno(obj->fp)+1, NULL, &write_fds, NULL, &timeout);
if(ret)
return(obj->stream_block_size); /* read in a max of 8000 bytes */
else
return(0);
}
PRIVATE void net_ExtViewComplete (NET_StreamClass *stream)
{
CV_DataObject *obj=stream->data_object;
obj->context->funcs->SetProgressBarPercent(obj->context, 100);
if(obj->command)
{
char *p_tmp;
char *command;
/* restrict to allowed url chars
*
*/
for(p_tmp = obj->url; *p_tmp != '\0'; p_tmp++)
if( (*p_tmp >= '0' && *p_tmp <= '9')
|| (*p_tmp >= 'A' && *p_tmp <= 'Z')
|| (*p_tmp >= 'a' && *p_tmp <= 'z')
|| (*p_tmp == '_')
|| (*p_tmp == '?')
|| (*p_tmp == '#')
|| (*p_tmp == '&')
|| (*p_tmp == '%')
|| (*p_tmp == '/')
|| (*p_tmp == ':')
|| (*p_tmp == '+')
|| (*p_tmp == '.')
|| (*p_tmp == '~')
|| (*p_tmp == '=')
|| (*p_tmp == '-'))
{
/* this is a good character. Allow it.
*/
}
else
{
*p_tmp = '\0';
break;
}
command=build_viewer_cmd(obj->command,
's', obj->filename,
'u', obj->url, 0);
fclose(obj->fp);
TRACEMSG(("Invoking: %s", command));
system(command);
FREEIF(obj->command);
}
else
{
pclose(obj->fp);
}
FREEIF(obj->filename);
FREEIF(obj->url);
FREE(obj);
return;
}
PRIVATE void net_ExtViewAbort (NET_StreamClass *stream, int status)
{
CV_DataObject *obj=stream->data_object;
obj->context->funcs->SetProgressBarPercent(obj->context, 100);
fclose(obj->fp);
if(obj->filename)
{
remove(obj->filename);
FREE(obj->filename);
}
FREEIF(obj->url);
FREEIF(obj->command);
FREE(obj);
return;
}
#ifdef XP_UNIX
extern char **fe_encoding_extensions; /* gag! */
#endif
PUBLIC NET_StreamClass *
NET_ExtViewerConverter (int format_out,
void *data_obj,
URL_Struct *URL_s,
MWContext *window_id)
{
CV_DataObject* obj;
NET_StreamClass* stream;
char *tmp_filename;
char *dot;
char *path;
CV_ExtViewStruct * view_struct = (CV_ExtViewStruct *)data_obj;
char small_buf[256];
int yes_stream=0;
/* If this URL is a mail or news attachment, use the name of that
attachment as the URL -- this is so the temp file gets the right
extension on it (some helper apps are picky about that...)
*/
path = MimeGuessURLContentName(window_id, URL_s->address);
if (!path)
path = NET_ParseURL(URL_s->address, GET_PATH_PART);
if (!path)
return 0;
TRACEMSG(("Setting up display stream. Have URL: %s\n", URL_s->address));
stream = XP_NEW(NET_StreamClass);
if(stream == NULL)
return(NULL);
memset(stream, 0, sizeof(NET_StreamClass));
obj = XP_NEW(CV_DataObject);
if (obj == NULL)
return(NULL);
memset(obj, 0, sizeof(CV_DataObject));
obj->context = window_id;
if(URL_s->content_length)
{
obj->tot_size = URL_s->content_length;
}
else
{
/* start the progress bar cyloning
*/
obj->context->funcs->SetProgressBarPercent(window_id, -1);
}
stream->name = "Execute external viewer";
stream->complete = (MKStreamCompleteFunc) net_ExtViewComplete;
stream->abort = (MKStreamAbortFunc) net_ExtViewAbort;
stream->put_block = (MKStreamWriteFunc) net_ExtViewWrite;
stream->is_write_ready = (MKStreamWriteReadyFunc) net_ExtViewWriteReady;
stream->data_object = obj; /* document info object */
stream->window_id = window_id;
#ifdef XP_UNIX
/* Some naive people may have trustingly put
application/x-sh; sh %s
application/x-csh; csh %s
in their mailcap files without realizing how dangerous that is.
Worse, it might be there and they might not realize it. So, if
we're about to execute a shell, pop up a dialog box first.
*/
{
char *prog = XP_STRDUP (view_struct->system_command);
char *s, *start, *end;
int danger = 0;
/* strip end space */
end = XP_StripLine(prog);
/* Extract the leaf name of the program: " /bin/sh -foo" ==> "sh". */
for (; *end && !XP_IS_SPACE(*end); end++)
;
*end = 0;
if ((start = XP_STRRCHR (prog, '/')))
start++;
else
start = XP_StripLine(prog); /* start at first non-white space */
/* Strip off everything after the first nonalphabetic.
This is so "perl-4.0" is compared as "perl" and
"emacs19" is compared as "emacs".
*/
for (s = start; *s; s++)
if (!isalpha (*s))
*s = 0;
/* These are things known to be shells - very bad. */
if (!XP_STRCMP (start, "ash") ||
!XP_STRCMP (start, "bash") ||
!XP_STRCMP (start, "csh") ||
!XP_STRCMP (start, "jsh") ||
!XP_STRCMP (start, "ksh") ||
!XP_STRCMP (start, "pdksh") ||
!XP_STRCMP (start, "sh") ||
!XP_STRCMP (start, "tclsh") ||
!XP_STRCMP (start, "tcsh") ||
!XP_STRCMP (start, "wish") || /* a tcl thing */
!XP_STRCMP (start, "wksh") ||
!XP_STRCMP (start, "zsh"))
danger = 2;
/* Remote shells are potentially dangerous, in the case of
"rsh somehost some-dangerous-program", but it's hard to
parse that out, since rsh could take arbitrarily complicated
args, like "rsh somehost -u something -pass8 /bin/sh %s".
And we don't want to squawk about "rsh somehost playulaw -".
So... allow rsh to possibly be a security hole.
*/
else if (!XP_STRCMP (start, "remsh") || /* remote shell */
!XP_STRCMP (start, "rksh") ||
!XP_STRCMP (start, "rsh") /* remote- or restricted- */
)
danger = 0;
/* These are things which aren't really shells, but can do the
same damage anyway since they can write files and/or execute
other programs. */
else if (!XP_STRCMP (start, "awk") ||
!XP_STRCMP (start, "e") ||
!XP_STRCMP (start, "ed") ||
!XP_STRCMP (start, "ex") ||
!XP_STRCMP (start, "gawk") ||
!XP_STRCMP (start, "m4") ||
!XP_STRCMP (start, "sed") ||
!XP_STRCMP (start, "vi") ||
!XP_STRCMP (start, "emacs") ||
!XP_STRCMP (start, "lemacs") ||
!XP_STRCMP (start, "xemacs") ||
!XP_STRCMP (start, "temacs") ||
/* Other dangerous interpreters */
!XP_STRCMP (start, "basic") ||
!XP_STRCMP (start, "expect") ||
!XP_STRCMP (start, "expectk") ||
!XP_STRCMP (start, "perl") ||
!XP_STRCMP (start, "python") ||
!XP_STRCMP (start, "rexx")
)
danger = 1;
/* Be suspicious of anything ending in "sh". */
else if (XP_STRLEN (start) > 2 &&
!XP_STRCMP (start + XP_STRLEN (start) - 2, "sh"))
danger = 1;
if (danger)
{
char msg [2048];
PR_snprintf (msg,
sizeof(msg),
(danger > 1 ? XP_GetString(XP_CONFIRM_EXEC_UNIXCMD_ARE) : XP_GetString(XP_CONFIRM_EXEC_UNIXCMD_MAYBE)),
start
);
if (!FE_Confirm (window_id, msg))
{
FREE (stream);
FREE (obj);
FREE (path);
FREE (prog);
return(NULL);
}
}
FREE (prog);
}
#endif /* XP_UNIX */
if(view_struct->stream_block_size)
{
/* asks the user if they want to stream data.
* -1 cancel
* 0 No, don't stream data, play from the file
* 1 Yes, stream the data from the network
*/
int XFE_AskStreamQuestion(MWContext * window_id); /* definition */
if (NET_URL_Type (URL_s->address) == ABOUT_TYPE_URL)
yes_stream = 1;
else
yes_stream = XFE_AskStreamQuestion(window_id);
if(yes_stream == -1)
{
FREE(stream);
FREE(obj);
FREE(path);
return(NULL);
}
}
if(yes_stream && view_struct->stream_block_size)
{
/* use popen */
obj->fp = popen(view_struct->system_command, "w");
if(!obj->fp)
{
FE_Alert(window_id, XP_GetString(XP_ALERT_UNABLE_INVOKEVIEWER));
return(NULL);
}
obj->stream_block_size = view_struct->stream_block_size;
signal(SIGPIPE, SIG_IGN);
}
else
{
dot = XP_STRRCHR(path, '.');
#ifdef XP_UNIX
/* Gag. foo.ps.gz --> tmpXXXXX.ps, not tmpXXXXX.gz. */
if (dot && fe_encoding_extensions)
{
int i = 0;
while (fe_encoding_extensions [i])
{
if (!XP_STRCMP (dot, fe_encoding_extensions [i]))
{
*dot = 0;
dot--;
while (dot > path && *dot != '.')
dot--;
if (*dot != '.')
dot = 0;
break;
}
i++;
}
}
#endif /* XP_UNIX */
tmp_filename = WH_TempName(xpTemporary, "MO");
if (!tmp_filename) {
FREEIF(stream);
FREEIF(obj);
return NULL;
}
if (dot)
{
char * p_tmp;
StrAllocCopy(obj->filename, tmp_filename);
/* restrict to ascii alphanumeric chars
*
* this fixes really bad security hole
*/
for(p_tmp = dot+1; *p_tmp != '\0'; p_tmp++)
if( (*p_tmp >= '0' && *p_tmp <= '9')
|| (*p_tmp >= 'A' && *p_tmp <= 'Z')
|| (*p_tmp >= 'a' && *p_tmp <= 'z')
|| (*p_tmp == '_')
|| (*p_tmp == '+')
|| (*p_tmp == '-'))
{
/* this is a good character. Allow it.
*/
}
else
{
*p_tmp = '\0';
break;
}
StrAllocCat(obj->filename, dot);
}
else
{
StrAllocCopy(obj->filename, tmp_filename);
}
FREE(path);
XP_FREE(tmp_filename);
obj->fp = XP_FileOpen(obj->filename, xpTemporary, XP_FILE_WRITE);
TRACEMSG(("Trying to open output file: %s\n", obj->filename));
if(!obj->fp)
{
char *s = NET_ExplainErrorDetails (MK_UNABLE_TO_OPEN_TMP_FILE,
obj->filename);
if (s)
{
FE_Alert (window_id, s);
XP_FREE (s);
}
return(NULL);
}
/* construct the command like this
*
* (( COMMAND ); rm %s )&
*/
StrAllocCopy(obj->command, "((");
/* this is a stream writable program that the user wants
* to use non streaming
*/
if(view_struct->stream_block_size)
StrAllocCat(obj->command, "cat %s | ");
StrAllocCat(obj->command, view_struct->system_command);
PR_snprintf(small_buf, sizeof(small_buf), "); rm %.200s )&", obj->filename);
StrAllocCat(obj->command, small_buf);
}
StrAllocCopy(obj->url, URL_s->address);
TRACEMSG(("Returning stream from NET_ExtViewer\n"));
return stream;
}
#endif /* MOZILLA_CLIENT */

View File

@@ -0,0 +1,32 @@
/* -*- 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.
*/
#ifndef CVVIEW_H
#define CVVIEW_H
extern NET_StreamClass* NET_ExtViewerConverter ( FO_Present_Types format_out,
void *data_obj,
URL_Struct *URL_s,
MWContext *window_id);
typedef struct _CV_ExtViewStruct {
char * system_command;
unsigned int stream_block_size;
} CV_ExtViewStruct;
#endif /* CVVIEW_H */

View File

@@ -0,0 +1,20 @@
#
# This is a list of local files which get copied to the mozilla:dist directory
#
extcache.h
mkutils.h
mkselect.h
mkaccess.h
mkautocf.h
mkcache.h
mkformat.h
mkgeturl.h
mkhelp.h
mkstream.h
mktcp.h
mktrace.h
mkpadpac.h
mkmarimb.h
mkparse.h
mkimap4.h

View File

@@ -0,0 +1,880 @@
/* -*- 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.
*/
/* Please leave outside of ifdef for window precompiled headers */
#include "mkutils.h"
#ifdef MOZILLA_CLIENT
/* Publicly released Netscape cache access routines.
*
* These routines are shared between the netscape executable
* and the programs released as a cache developers kit.
*
* Created: Lou Montulli <montulli@netscape.com>, July-95.
* Modifications/Addition: Gagan Saksena, 97
*/
#ifndef EXT_DB_ROUTINES
#include "secnav.h"
#include "sechash.h"
#endif
#include "extcache.h" /* include this for everything */
#ifdef EXT_DB_ROUTINES
#include <fcntl.h>
#include <sys/stat.h>
#include <assert.h>
typedef struct {
int32 len;
char *data;
} SECItem;
#ifdef _sgi
#include <sys/endian.h>
#endif /* _sgi */
/* URL methods
*/
#define URL_GET_METHOD 0
#define URL_POST_METHOD 1
#define URL_HEAD_METHOD 2
#endif /* DB_STORE */
MODULE_PRIVATE DBT *
net_CacheDBTDup(DBT *obj)
{
DBT * rv = XP_NEW(DBT);
if(!rv)
return(NULL);
rv->size = obj->size;
rv->data = XP_ALLOC(rv->size);
if(!rv->data)
{
FREE(rv);
return(NULL);
}
XP_MEMCPY(rv->data, obj->data, rv->size);
return(rv);
}
/* free the cache object
*/
MODULE_PRIVATE void net_freeCacheObj (net_CacheObject * cache_obj)
{
FREEIF(cache_obj->address);
FREEIF(cache_obj->post_data);
FREEIF(cache_obj->post_headers);
FREEIF(cache_obj->content_type);
FREEIF(cache_obj->charset);
FREEIF(cache_obj->content_encoding);
FREEIF(cache_obj->page_services_url);
FREEIF(cache_obj->filename);
#ifndef EXT_DB_ROUTINES
FREEIF(cache_obj->sec_info);
#endif
FREE(cache_obj);
}
/* returns true if this DBT looks like a valid
* entry. It looks at the checksum and the
* version number to see if it's valid
*/
#define MAX_VALID_DBT_SIZE 10000
MODULE_PRIVATE Bool
net_IsValidCacheDBT(DBT *obj)
{
char *cur_ptr, *max_ptr;
uint32 len;
if(!obj || obj->size < 9 || obj->size > MAX_VALID_DBT_SIZE)
return(FALSE);
cur_ptr = (char *)obj->data;
max_ptr = cur_ptr+obj->size;
/* get the total size of the struct out of
* the first field to check it
*/
COPY_INT32(&len, cur_ptr);
cur_ptr += sizeof(int32);
if(len != obj->size)
{
TRACEMSG(("Size going in is not the same as size coming out"));
return(FALSE);
}
/* get the version number of the written structure
*/
if(cur_ptr > max_ptr)
return(FALSE);
COPY_INT32(&len, cur_ptr);
cur_ptr += sizeof(int32);
if(len != CACHE_FORMAT_VERSION)
{
TRACEMSG(("Version of cache structure is wrong!: %d", len));
return(FALSE);
}
/* looks good to me... */
return(TRUE);
}
/* takes a cache object and returns a malloc'd
* (void *) suitible for passing in as a database
* data storage object
*/
MODULE_PRIVATE DBT *
net_CacheStructToDBData(net_CacheObject * old_obj)
{
int32 len;
char *cur_ptr;
void *new_obj;
int32 total_size;
DBT *rv;
rv = XP_NEW(DBT);
if(!rv)
return(NULL);
total_size = sizeof(net_CacheObject);
#define ADD_STRING_SIZE(string) \
total_size += old_obj->string ? XP_STRLEN(old_obj->string)+1 : 0
ADD_STRING_SIZE(address);
total_size += old_obj->post_data_size+1;
ADD_STRING_SIZE(post_headers);
ADD_STRING_SIZE(content_type);
ADD_STRING_SIZE(content_encoding);
ADD_STRING_SIZE(charset);
ADD_STRING_SIZE(filename);
total_size += sizeof(uint32); /* size of secinfo */
total_size += SECNAV_SSLSocketStatusLength(old_obj->sec_info);
ADD_STRING_SIZE(page_services_url);
#undef ADD_STRING_SIZE
new_obj = XP_ALLOC(total_size * sizeof(char));
if(!new_obj)
{
FREE(rv);
return NULL;
}
XP_MEMSET(new_obj, 0, total_size * sizeof(char));
/*
* order is:
* int32 size of the entire structure;
*
* int32 version of the structure format (CACHE_FORMAT_VERSION)
*
* time_t last_modified;
* time_t last_accessed;
* time_t expires;
* uint32 content_length;
* Bool is_netsite;
*
* time_t lock_date;
*
* char * filename;
* int32 filename_len;
*
* int32 security_on;
* unsigned char * sec_info;
*
* int32 method;
*
* # don't store address, or post_data stuff
* # char * address;
* # uint32 post_data_size;
* # char * post_data;
*
* char * post_headers;
* char * content_type;
* char * content_encoding;
* char * charset;
*
* Bool incomplete_file;
* uint32 total_content_length;
*
* char * page_services_url;
*
* string lengths all include null terminators
* all integer constants are stored as 4 bytes
* all booleans are stored as one byte
*/
/* VERY VERY IMPORTANT. Whenever the
* format of the record structure changes
* you must verify that the byte positions
* in extcache.h are updated
*/
#define STUFF_STRING(string) \
{ \
len = (old_obj->string ? XP_STRLEN(old_obj->string)+1 : 0); \
COPY_INT32((void *)cur_ptr, &len); \
cur_ptr = cur_ptr + sizeof(int32); \
if(len) \
XP_MEMCPY((void *)cur_ptr, old_obj->string, len); \
cur_ptr += len; \
}
#define STUFF_NUMBER(number) \
{ \
COPY_INT32((void *)cur_ptr, &old_obj->number); \
cur_ptr = cur_ptr + sizeof(int32); \
}
#define STUFF_TIMET(number) \
{ \
COPY_INT32((void *)cur_ptr, &old_obj->number); \
cur_ptr = cur_ptr + sizeof(time_t); \
}
#define STUFF_BOOL(bool_val) \
{ \
if(old_obj->bool_val) \
((char *)(cur_ptr))[0] = 1; \
else \
((char *)(cur_ptr))[0] = 0; \
cur_ptr = cur_ptr + sizeof(char); \
}
cur_ptr = (char *)new_obj;
/* put the total size of the struct into
* the first field so that we have
* a cross check against corruption
*/
COPY_INT32((void *)cur_ptr, &total_size);
cur_ptr = cur_ptr + sizeof(int32);
/* put the version number of the structure
* format that we are using
* By using a version string when writting
* we can support backwards compatibility
* in our reading code
* (use "len" as a temp variable)
*/
len = CACHE_FORMAT_VERSION;
COPY_INT32((void *)cur_ptr, &len);
cur_ptr = cur_ptr + sizeof(int32);
STUFF_TIMET(last_modified);
STUFF_TIMET(last_accessed);
STUFF_TIMET(expires);
STUFF_NUMBER(content_length);
STUFF_BOOL(is_netsite);
STUFF_TIMET(lock_date);
STUFF_STRING(filename);
STUFF_NUMBER(filename_len);
STUFF_BOOL(is_relative_path);
STUFF_NUMBER(security_on);
#ifndef EXT_DB_ROUTINES
/* save the security info */
if ( old_obj->sec_info ) {
len = SECNAV_SSLSocketStatusLength(old_obj->sec_info);
COPY_INT32((void *)cur_ptr, &len);
cur_ptr = cur_ptr + sizeof(int32);
XP_MEMCPY((void *)cur_ptr, old_obj->sec_info, len);
cur_ptr += len;
} else
#endif
{
len = 0;
COPY_INT32((void *)cur_ptr, &len);
cur_ptr = cur_ptr + sizeof(int32);
}
STUFF_NUMBER(method);
#ifdef STORE_ADDRESS_AND_POST_DATA
STUFF_STRING(address);
STUFF_NUMBER(post_data_size);
/* post_data
* this is special since it not necessarily a string
*/
if(old_obj->post_data_size)
{
XP_MEMCPY(cur_ptr, old_obj->post_data, old_obj->post_data_size+1);
cur_ptr += old_obj->post_data_size+1;
}
#endif /* STORE_ADDRESS_AND_POST_DATA */
STUFF_STRING(post_headers);
STUFF_STRING(content_type);
STUFF_STRING(content_encoding);
STUFF_STRING(charset);
STUFF_BOOL(incomplete_file);
STUFF_NUMBER(real_content_length);
STUFF_STRING(page_services_url);
#undef STUFF_STRING
#undef STUFF_NUMBER
#undef STUFF_BOOL
rv->data = new_obj;
rv->size = total_size;
return(rv);
}
/* takes a database storage object and returns a malloc'd
* cache data object. The cache object needs all of
* it's parts free'd.
*
* returns NULL on parse error
*/
MODULE_PRIVATE net_CacheObject *
net_DBDataToCacheStruct(DBT * db_obj)
{
net_CacheObject * rv = XP_NEW(net_CacheObject);
char * cur_ptr;
char * max_ptr;
uint32 len;
int32 version;
if(!rv)
return NULL;
XP_MEMSET(rv, 0, sizeof(net_CacheObject));
/* if any strings are larger than this then
* there was a serious database error
*/
#define MAX_HUGE_STRING_SIZE 10000
#define RETRIEVE_STRING(string) \
{ \
if(cur_ptr > max_ptr) \
{ \
net_freeCacheObj(rv); \
return(NULL); \
} \
COPY_INT32(&len, cur_ptr); \
cur_ptr += sizeof(int32); \
if(len) \
{ \
if(len > MAX_HUGE_STRING_SIZE) \
{ \
net_freeCacheObj(rv); \
return(NULL); \
} \
rv->string = (char*)XP_ALLOC(len); \
if(!rv->string) \
{ \
net_freeCacheObj(rv); \
return(NULL); \
} \
XP_MEMCPY(rv->string, cur_ptr, len); \
cur_ptr += len; \
} \
}
#define RETRIEVE_NUMBER(number) \
{ \
if(cur_ptr > max_ptr) \
return(rv); \
COPY_INT32(&rv->number, cur_ptr); \
cur_ptr += sizeof(int32); \
}
#define RETRIEVE_TIMET(number) \
{ \
if(cur_ptr > max_ptr) \
return(rv); \
COPY_INT32(&rv->number, cur_ptr); \
cur_ptr += sizeof(time_t); \
}
#define RETRIEVE_BOOL(bool) \
{ \
if(cur_ptr > max_ptr) \
return(rv); \
if(((char *)(cur_ptr))[0]) \
rv->bool = TRUE; \
else \
rv->bool = FALSE; \
cur_ptr += sizeof(char); \
}
cur_ptr = (char *)db_obj->data;
max_ptr = cur_ptr+db_obj->size;
/* get the total size of the struct out of
* the first field to check it
*/
COPY_INT32(&len, cur_ptr);
cur_ptr += sizeof(int32);
if(len != db_obj->size)
{
TRACEMSG(("Size going in is not the same as size coming out"));
FREE(rv);
return(NULL);
}
/* get the version number of the written structure
*/
if(cur_ptr > max_ptr)
return(rv);
COPY_INT32(&version, cur_ptr);
cur_ptr += sizeof(int32);
if(version != CACHE_FORMAT_VERSION)
{
TRACEMSG(("Version of cache structure is wrong!: %d", version));
FREE(rv);
return(NULL);
}
RETRIEVE_TIMET(last_modified);
RETRIEVE_TIMET(last_accessed);
RETRIEVE_TIMET(expires);
RETRIEVE_NUMBER(content_length);
RETRIEVE_BOOL(is_netsite);
RETRIEVE_TIMET(lock_date);
RETRIEVE_STRING(filename);
RETRIEVE_NUMBER(filename_len);
RETRIEVE_BOOL(is_relative_path);
RETRIEVE_NUMBER(security_on);
/* security info */
if(cur_ptr > max_ptr)
return(rv);
COPY_INT32(&len, cur_ptr);
cur_ptr += sizeof(int32);
if ( len == 0 ) {
rv->sec_info = NULL;
} else {
rv->sec_info = XP_ALLOC(len);
if ( rv->sec_info == NULL ) {
return(rv);
}
XP_MEMCPY(rv->sec_info, cur_ptr, len);
cur_ptr += len;
}
RETRIEVE_NUMBER(method);
#ifdef STORE_ADDRESS_AND_POST_DATA
RETRIEVE_STRING(address);
RETRIEVE_NUMBER(post_data_size);
/* post_data
* this is special since it not necessarily a string
*/
if(rv->post_data_size)
{
rv->post_data = XP_ALLOC(rv->post_data_size+1);
if(rv->post_data)
XP_MEMCPY(rv->post_data, cur_ptr, rv->post_data_size+1);
cur_ptr += rv->post_data_size+1;
}
#endif /* STORE_ADDRESS_AND_POST_DATA */
RETRIEVE_STRING(post_headers);
RETRIEVE_STRING(content_type);
RETRIEVE_STRING(content_encoding);
RETRIEVE_STRING(charset);
RETRIEVE_BOOL(incomplete_file);
RETRIEVE_NUMBER(real_content_length);
RETRIEVE_STRING(page_services_url);
#undef RETRIEVE_STRING
#undef RETRIEVE_NUMBER
#undef RETRIEVE_BOOL
return(rv);
}
#if defined(DEBUG) && defined(UNIX)
int
cache_test_me()
{
net_CacheObject test;
net_CacheObject *rv;
int32 total_size;
DBT *db_obj;
XP_MEMSET(&test, 0, sizeof(net_CacheObject));
StrAllocCopy(test.address, "test1");
db_obj = net_CacheStructToDBData(&test);
rv = net_DBDataToCacheStruct(db_obj);
printf("test1: %s\n", rv->address);
XP_MEMSET(&test, 0, sizeof(net_CacheObject));
StrAllocCopy(test.address, "test2");
StrAllocCopy(test.charset, "test2");
db_obj = net_CacheStructToDBData(&test);
rv = net_DBDataToCacheStruct(db_obj);
printf("test2: %s %s\n", rv->address, rv->charset);
XP_MEMSET(&test, 0, sizeof(net_CacheObject));
StrAllocCopy(test.address, "test3");
StrAllocCopy(test.charset, "test3");
test.content_length = 3 ;
test.method = 3 ;
test.is_netsite = 3 ;
db_obj = net_CacheStructToDBData(&test);
rv = net_DBDataToCacheStruct(db_obj);
printf("test3: %s %s %d %d %s\n",
rv->address, rv->charset,
rv->content_length, rv->method,
(rv->is_netsite == 3 ? "TRUE" : "FALSE"));
}
#endif
/* generates a key for use in the cache database
* from a CacheObject struct
*
* Key is based on the address and the post_data
*
* looks like:
* size checksum | size of address | ADDRESS | size of post data | POST DATA
*/
MODULE_PRIVATE DBT *
net_GenCacheDBKey(char *address, char *post_data, int32 post_data_size)
{
DBT *rv = XP_NEW(DBT);
char *hash;
char *data_ptr;
int32 str_len;
int32 size;
#define MD5_HASH_SIZE 16 /* always 16 due to md5 hash type */
if(!rv)
return(NULL);
if(!address)
{
XP_ASSERT(0);
rv->size = 0;
return(rv);
}
hash = XP_STRCHR(address, '#');
/* don't include '#' in a key */
if(hash)
*hash = '\0';
str_len = XP_STRLEN(address)+1;
size = sizeof(int32); /* for check sum */
size += sizeof(int32); /* for size of address */
size += str_len; /* for address string */
size += sizeof(int32); /* for size of post_data */
if(post_data_size)
size += MD5_HASH_SIZE;
rv->size = size;
rv->data = XP_ALLOC(size);
if(!rv->data)
{
FREE(rv);
return NULL;
}
data_ptr = (char *) rv->data;
/* put in the checksum size */
COPY_INT32(data_ptr, &size);
data_ptr = data_ptr + sizeof(int32);
/* put in the size of the address string */
COPY_INT32(data_ptr, &str_len);
data_ptr = data_ptr + sizeof(int32);
/* put in the address string data */
XP_MEMCPY(data_ptr, address, str_len);
data_ptr = data_ptr + str_len;
/* set the address back to it's original form */
if(hash)
*hash = '#';
/* put in the size of the post data */
if(post_data_size)
{
int32 size_of_md5 = MD5_HASH_SIZE;
unsigned char post_data_hash[MD5_HASH_SIZE];
MD5_HashBuf(post_data_hash, (unsigned char*)post_data, post_data_size);
COPY_INT32(data_ptr, &size_of_md5);
data_ptr = data_ptr + sizeof(int32);
/* put in the post data if there is any */
XP_MEMCPY(data_ptr, post_data_hash, sizeof(post_data_hash));
}
else
{
COPY_INT32(data_ptr, &post_data_size);
data_ptr = data_ptr + sizeof(int32);
}
return(rv);
}
/* returns a static string that contains the
* URL->address of the key
*
* returns NULL on error
*/
MODULE_PRIVATE char *
net_GetAddressFromCacheKey(DBT *key)
{
uint32 size;
char *data;
/* check for minimum size */
if(key->size < 10)
return(NULL);
/* validate size checksum */
data = (char *)key->data;
COPY_INT32(&size, data);
data += sizeof(int32);
if(size != key->size)
return(NULL);
/* get size of address string */
COPY_INT32(&size, data);
data += sizeof(int32);
/* make sure it's a valid c string */
if(data[size] != '\0')
return(NULL);
/* it's valid return it */
return(data);
}
/* checks a date within a DBT struct so
* that we don't have to convert it into a CacheObject
*
* This works because of the fixed length record format
* of the first part of the specific DBT format I'm
* using
*
* returns 0 on error
*/
MODULE_PRIVATE time_t
net_GetTimeInCacheDBT(DBT *data, int byte_position)
{
time_t date;
char *ptr = (char *)data->data;
if(data->size < byte_position+sizeof(time_t))
return(0);
if(!net_IsValidCacheDBT(data))
return(0);
COPY_INT32(&date, ptr+byte_position);
/* TRACEMSG(("Got date from cache DBT: %d", date)); */
return(date);
}
/* Sets a date within a DBT struct so
* that we don't have to convert it into a CacheObject
*
* This works because of the fixed length record format
* of the first part of the specific DBT format I'm
* using
*
* returns 0 on error
*/
MODULE_PRIVATE void
net_SetTimeInCacheDBT(DBT *data, int byte_position, time_t date)
{
char *ptr = (char *)data->data;
if(data->size < byte_position+sizeof(time_t))
return;
if(!net_IsValidCacheDBT(data))
return;
COPY_INT32(ptr+byte_position, &date);
return;
}
/* Gets the filename within a cache DBT struct so
* that we don't have to convert it into a CacheObject
*
* This works because of the fixed length record format
* of the first part of the specific DBT format I'm
* using
*
* returns NULL on error
*/
#define MAX_FILE_SIZE 2048
MODULE_PRIVATE char *
net_GetFilenameInCacheDBT(DBT *data)
{
int32 size;
char *rv;
char *ptr = (char*)data->data;
if(data->size < FILENAME_BYTE_POSITION)
return(NULL);
if(!net_IsValidCacheDBT(data))
return(0);
COPY_INT32(&size, ptr+FILENAME_SIZE_BYTE_POSITION);
if(data->size < FILENAME_BYTE_POSITION+size
|| size > MAX_FILE_SIZE)
return(NULL);
rv = (char *)XP_ALLOC(size);
if(!rv)
return(NULL);
XP_MEMCPY(rv, ptr+FILENAME_BYTE_POSITION, size);
TRACEMSG(("Got filename: %s from DBT", rv));
return(rv);
}
/* Gets a int32 within a DBT struct so
* that we don't have to convert it into a CacheObject
*
* This works because of the fixed length record format
* of the first part of the specific DBT format I'm
* using
*
* returns 0 on error
*/
MODULE_PRIVATE time_t
net_GetInt32InCacheDBT(DBT *data, int byte_position)
{
int32 num;
char *ptr = (char *)data->data;
if(!net_IsValidCacheDBT(data))
return(0);
if(data->size < byte_position+sizeof(time_t))
return(0);
COPY_INT32(&num, ptr+byte_position);
/* TRACEMSG(("Got int32 from cache DBT: %d", num)); */
return(num);
}
MODULE_PRIVATE void
net_FreeCacheDBTdata(DBT *stuff)
{
if(stuff)
{
FREE(stuff->data);
FREE(stuff);
}
}
/* takes a database storage object and returns an un-malloc'd
* cache data object. The structure returned has pointers
* directly into the database memory and are only valid
* until the next call to any database function
*
* do not free anything returned by this structure
*/
MODULE_PRIVATE net_CacheObject *
net_Fast_DBDataToCacheStruct(DBT *obj)
{
static net_CacheObject *rv=0;
/* free any previous one */
if(rv)
net_freeCacheObj(rv);
rv = net_DBDataToCacheStruct(obj);
return(rv);
}
#endif /* MOZILLA_CLIENT */

View File

@@ -0,0 +1,273 @@
/* -*- 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.
*/
#ifndef EXT_CACHE_H
#define EXT_CACHE_H
#ifndef EXT_DB_ROUTINES
#include "mcom_db.h"
#endif
#ifdef EXT_DB_ROUTINES
#define Bool char
#define uint32 unsigned int
#define int32 int
#define XP_NEW(structure) ((structure *) malloc(sizeof(structure)))
#define XP_ALLOC (void *) malloc
#define XP_MEMCPY memcpy
#define XP_MEMSET memset
#define TRACEMSG(x) printf x
#define FREEIF(x) do { if(x) free(x); } while(0)
#define FREE free
#define XP_STRLEN strlen
#define XP_STRCHR strchr
#define XP_STRCMP strcmp
#define XP_ASSERT assert
#define MODULE_PRIVATE
#define PRIVATE static
#define TRUE !0
#define FALSE 0
#include <stdio.h>
#include <string.h>
#include <db.h>
#endif
#ifndef EXT_DB_ROUTINES
#include "mkutils.h"
#ifndef NSPR20
#include "prosdep.h" /* for IS_LITTLE_ENDIAN / IS_BIG_ENDIAN */
#else
#include "prtypes.h"
#endif
#endif /* EXT_DB_ROUTINES */
#if !defined(IS_LITTLE_ENDIAN) && !defined(IS_BIG_ENDIAN)
ERROR! Must have a byte order
#endif
#ifdef IS_LITTLE_ENDIAN
#define COPY_INT32(_a,_b) XP_MEMCPY(_a, _b, sizeof(int32));
#else
#define COPY_INT32(_a,_b) /* swap */ \
do { \
((char *)(_a))[0] = ((char *)(_b))[3]; \
((char *)(_a))[1] = ((char *)(_b))[2]; \
((char *)(_a))[2] = ((char *)(_b))[1]; \
((char *)(_a))[3] = ((char *)(_b))[0]; \
} while(0)
#endif
#define EXT_CACHE_NAME_STRING "INT_ExternalCacheNameString"
/* Internal WARNING!! Some slots of this structure
* are shared with URL_Struct and
* History_entry. If you add a slot, decide whether it needs to be shared
* as well.
*/
typedef struct _net_CacheObject {
time_t last_modified;
time_t last_accessed;
time_t expires;
Bool is_netsite;
uint32 content_length;
char * filename; /* cache file name */
int32 filename_len; /* optimization */
Bool is_relative_path; /* is the path relative? */
/* Security information */
int32 security_on; /* is security on? */
unsigned char *sec_info;
time_t lock_date; /* the file is locked if this
* is non-zero. The date
* represents the time the
* lock was put in place.
* Locks are only valid for
* one session
*/
int32 method;
char * address;
uint32 post_data_size;
char * post_data;
char * post_headers;
char * content_type;
char * content_encoding;
char * charset;
Bool incomplete_file; /* means that the whole
* file is not there.
* This can only be true
* if the server supports byteranges
*/
uint32 real_content_length; /* the whole content length
* i.e. the server size of a truncated
* client file
*/
char * page_services_url;
char * etag; /* HTTP/1.1 Etag */
} net_CacheObject;
/* this is the version number of the cache database entry.
* It should be incremented in integer ingrements up
* to MAXINT32
*/
#define CACHE_FORMAT_VERSION 5
/* these defines specify the exact byte position
* of the first 4 elements in the DBT data struct
* Change these if you change the order of entry into
* the DBT
*/
#define LAST_MODIFIED_BYTE_POSITION \
sizeof(int32)+sizeof(int32)
#define LAST_ACCESSED_BYTE_POSITION \
sizeof(int32)+sizeof(int32)+sizeof(time_t)
#define EXPIRES_BYTE_POSITION \
sizeof(int32)+sizeof(int32)+sizeof(time_t)+sizeof(time_t)
#define CONTENT_LENGTH_BYTE_POSITION \
sizeof(int32)+sizeof(int32)+sizeof(time_t)+sizeof(time_t) \
+sizeof(time_t)
#define IS_NETSITE_BYTE_POSITION \
sizeof(int32)+sizeof(int32)+sizeof(time_t)+sizeof(time_t) \
+sizeof(time_t)+sizeof(int32)
#define LOCK_DATE_BYTE_POSITION \
sizeof(int32)+sizeof(int32)+sizeof(time_t)+sizeof(time_t) \
+sizeof(time_t)+sizeof(int32)+sizeof(char)
#define FILENAME_SIZE_BYTE_POSITION \
sizeof(int32)+sizeof(int32)+sizeof(time_t)+sizeof(time_t) \
+sizeof(time_t)+sizeof(uint32)+sizeof(char)+sizeof(time_t)
#define FILENAME_BYTE_POSITION \
sizeof(int32)+sizeof(int32)+sizeof(time_t)+sizeof(time_t) \
+sizeof(time_t)+sizeof(uint32)+sizeof(char)+sizeof(time_t) \
+sizeof(int32)
/* generates a key for use in the cache database
* from a CacheObject struct
*
* Key is based on the address and the post_data
*/
extern DBT *
net_GenCacheDBKey(char *address, char *post_data, int32 post_data_size);
/* returns a static string that contains the
* URL->address of the key
*
* returns NULL on error
*/
extern char *
net_GetAddressFromCacheKey(DBT *key);
/* allocs and copies a new DBT from an existing DBT
*/
extern DBT * net_CacheDBTDup(DBT *obj);
/* free the cache object
*/
extern void net_freeCacheObj (net_CacheObject * cache_obj);
/* takes a cache object and returns a malloc'd
* (void *) suitible for passing in as a database
* data storage object
*/
extern DBT * net_CacheStructToDBData(net_CacheObject * old_obj);
/* takes a database storage object and returns a malloc'd
* cache data object. The cache object needs all of
* it's parts free'd.
*
* returns NULL on parse error
*/
extern net_CacheObject * net_DBDataToCacheStruct(DBT * db_obj);
/* checks a date within a DBT struct so
* that we don't have to convert it into a CacheObject
*
* This works because of the fixed length record format
* of the first part of the specific DBT format I'm
* using
*
* returns 0 on error
*/
extern time_t net_GetTimeInCacheDBT(DBT *data, int byte_position);
/* Sets a date within a DBT struct so
* that we don't have to convert it into a CacheObject
*
* This works because of the fixed length record format
* of the first part of the specific DBT format I'm
* using
*
* returns 0 on error
*/
extern void net_SetTimeInCacheDBT(DBT *data, int byte_position, time_t date);
/* Gets the filename within a cache DBT struct so
* that we don't have to convert it into a CacheObject
*
* This works because of the fixed length record format
* of the first part of the specific DBT format I'm
* using
*
* returns NULL on error
*/
extern char * net_GetFilenameInCacheDBT(DBT *data);
/* Gets a int32 within a DBT struct so
* that we don't have to convert it into a CacheObject
*
* This works because of the fixed length record format
* of the first part of the specific DBT format I'm
* using
*
* returns 0 on error
*/
extern time_t net_GetInt32InCacheDBT(DBT *data, int byte_position);
/* free's a DBT struct
*/
extern void net_FreeCacheDBTdata(DBT *stuff);
/* stores a cache object in the DBM database
*/
extern void net_ExtCacheStore(DB *database, net_CacheObject * obj);
/* takes a database storage object and returns an un-malloc'd
* cache data object. The structure returned has pointers
* directly into the database memory and are only valid
* until the next call to any database function
*
* do not free anything returned by this structure
*/
extern net_CacheObject * net_Fast_DBDataToCacheStruct(DBT *obj);
/* returns true if this DBT looks like a valid
* entry. It looks at the checksum and the
* version number to see if it's valid
*/
extern Bool net_IsValidCacheDBT(DBT *obj);
#endif /* EXT_CACHE_H */

View File

@@ -0,0 +1,510 @@
/* -*- 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.
*/
/*** htmparse.c ***************************************************/
/* description: html parser */
/********************************************************************
$Revision: 3.1 $
$Date: 1998-03-28 03:31:31 $
*********************************************************************/
#include "xp.h"
#include "xp_str.h"
#include "htmparse.h"
#include "prtypes.h"
#include "pa_tags.h"
#include "pa_parse.h" /* for pa_tokenize_tag */
#include "prmem.h"
#if 0
#include "prio.h" /* for test only */
#include <stdio.h> /* for test only */
#endif
typedef char ParseState;
/* states of the parser */
#define PS_START 0 /* starting state */
#define PS_BETWEEN_TAGS 1 /* characters not enclosed by < > */
#define PS_TAG_NAME 2
#define PS_EMPTY_TAG 3
#define PS_CLOSE_BRACKET 4
#define PS_ATTRIBUTE 5
#define PS_EQUALS 6
#define PS_VALUE 7
#define PS_START_COMMENT 8
#define PS_END_COMMENT 9
typedef struct _CRAWL_TagStruc {
char *name;
intn token;
char **attributeNames;
char **attributeValues; /* max length of html attribute is 1024 chars */
uint16 sizeNames;
uint16 numNames;
uint16 sizeValues;
uint16 numValues;
PRBool emptyTagp;
PRBool endTagp;
} CRAWL_TagStruc;
/* maintains state of parser */
typedef struct _CRAWL_ParseObjStruc {
ParseState state;
CRAWL_Tag tag;
char *data;
uint16 dataLen;
uint16 dataSize;
char *str;
uint16 strLen;
uint16 strSize;
char prev1;
char prev2;
char inQuote; /* current quote character. when not in quote, value is '\0' */
PRBool inComment; /* we don't support comment nesting anymore */
PRBool inScript; /* inside <SCRIPT> and </SCRIPT> */
PRBool skipWhitespace;
PRBool isRDF;
} CRAWL_ParseObjStruc;
/* prototypes */
static CRAWL_Tag crawl_makeTag();
static void crawl_recycleTag(CRAWL_Tag tag);
static void crawl_destroyTag(CRAWL_Tag tag);
static void crawl_recycleParseObj(CRAWL_ParseObj obj);
int crawl_appendString(char **str, uint16 *len, uint16 *size, char c);
int crawl_appendStringList(char ***list_p, uint16 *len, uint16 *size, char *str);
/* accessors */
PR_IMPLEMENT(CRAWL_Tag) CRAWL_GetTagParsed(CRAWL_ParseObj obj) {
if (obj->data != NULL) return NULL;
else return obj->tag;
}
PR_IMPLEMENT(char*) CRAWL_GetDataParsed(CRAWL_ParseObj obj) {
if (obj->data != NULL) return obj->data;
else return NULL;
}
PR_IMPLEMENT(char*) CRAWL_GetTagName(CRAWL_Tag tag) {
return tag->name;
}
PR_IMPLEMENT(intn) CRAWL_GetTagToken(CRAWL_Tag tag) {
return tag->token;
}
PR_IMPLEMENT(PRBool) CRAWL_IsEmptyTag(CRAWL_Tag tag) {
return tag->emptyTagp;
}
PR_IMPLEMENT(PRBool) CRAWL_IsEndTag(CRAWL_Tag tag) {
return tag->endTagp;
}
PR_IMPLEMENT(uint16) CRAWL_GetNumberOfAttributes(CRAWL_Tag tag) {
return tag->numNames;
}
PR_IMPLEMENT(char*) CRAWL_GetNthAttributeName(CRAWL_Tag tag, uint16 n) {
return *(tag->attributeNames + n);
}
PR_IMPLEMENT(char*) CRAWL_GetNthAttributeValue(CRAWL_Tag tag, uint16 n) {
return *(tag->attributeValues + n);
}
PR_IMPLEMENT(char*) CRAWL_GetAttributeValue(CRAWL_Tag tag, char *attributeName) {
int count = 0;
while (count < tag->numNames) {
if (XP_STRCASECMP(attributeName, *(tag->attributeNames + count)) == 0)
return *(tag->attributeValues + count);
count++;
}
return NULL;
}
static CRAWL_Tag crawl_makeTag() {
CRAWL_Tag tag = PR_NEWZAP(CRAWL_TagStruc);
if (tag == NULL) return NULL;
tag->sizeNames = tag->sizeValues = 4;
tag->attributeNames = (char**)PR_MALLOC(sizeof(char*) * tag->sizeNames);
if (tag->attributeNames == NULL) return NULL;
tag->attributeValues = (char**)PR_MALLOC(sizeof(char*) * tag->sizeValues);
if (tag->attributeValues == NULL) return NULL;
return tag;
}
static void crawl_recycleTag(CRAWL_Tag tag) {
int count;
if (tag->name != NULL) PR_Free(tag->name);
tag->name = NULL;
for (count = 0; count < tag->numNames; count++) {
PR_Free(*(tag->attributeNames + count));
}
tag->numNames = 0;
for (count = 0; count < tag->numValues; count++) {
PR_Free(*(tag->attributeValues + count));
}
tag->numValues = 0;
tag->emptyTagp = PR_FALSE;
tag->endTagp = PR_FALSE;
}
static void crawl_destroyTag(CRAWL_Tag tag) {
crawl_recycleTag(tag);
if (tag->attributeNames != NULL) PR_Free(tag->attributeNames);
if (tag->attributeValues != NULL) PR_Free(tag->attributeValues);
PR_Free(tag);
}
static void crawl_recycleParseObj(CRAWL_ParseObj obj) {
crawl_recycleTag(obj->tag);
if (obj->data != NULL) PR_Free(obj->data);
obj->data = NULL;
obj->dataLen = obj->dataSize = 0;
}
PR_IMPLEMENT(CRAWL_ParseObj) CRAWL_MakeParseObj() {
CRAWL_ParseObj obj = PR_NEWZAP(CRAWL_ParseObjStruc);
if (obj == NULL) return NULL;
obj->tag = crawl_makeTag();
if (obj->tag == NULL) {
PR_Free(obj);
return NULL;
}
return obj;
}
PR_IMPLEMENT(void) CRAWL_DestroyParseObj(CRAWL_ParseObj obj) {
crawl_destroyTag(obj->tag);
if (obj->data != NULL) PR_Free(obj->data);
obj->data = NULL;
obj->dataLen = obj->dataSize = 0;
if (obj->str != NULL) PR_Free(obj->str);
obj->str = NULL;
obj->strLen = obj->strSize = 0;
PR_Free(obj);
}
#define STRING_EXPANSION_INCREMENT 16
/* returns 0 if no error, -1 if no memory */
int crawl_appendString(char **str, uint16 *len, uint16 *size, char c) {
if (*len == *size) {
char *newName = (char*)PR_MALLOC(*size + STRING_EXPANSION_INCREMENT);
char *old = *str;
if (newName == NULL) return -1;
XP_MEMCPY(newName, *str, *size);
*str = newName;
if (old != NULL) PR_Free(old);
*size += STRING_EXPANSION_INCREMENT;
}
*(*str + *len) = c;
++(*len);
return 0;
}
#define STRINGLIST_EXPANSION_INCREMENT 8
/* returns 0 if no error, -1 if no memory */
int crawl_appendStringList(char ***list_p, uint16 *len, uint16 *size, char *str) {
char **list = *list_p;
if (*len == *size) {
char **newList = (char**)PR_MALLOC(sizeof(char*) * (*size + STRINGLIST_EXPANSION_INCREMENT));
char **old = list;
if (newList == NULL) return -1;
XP_MEMCPY(newList, list, (sizeof(char*) * (*size)));
list = newList;
if (old != NULL) PR_Free(old);
*size += STRINGLIST_EXPANSION_INCREMENT;
}
*(list + *len) = str;
++(*len);
*list_p = list;
return 0;
}
/* returns index to last character of buffer parsed */
PR_IMPLEMENT(int) CRAWL_ParserPut(CRAWL_ParseObj obj, char *str, uint32 len, CRAWL_ParseFunc func, void *data) {
uint32 n = 0; /* where we are in the buffer */
uint32 lastn = 0; /* position the last time in the loop */
char c;
while (n < len) {
if (lastn < n) { /* we advanced a character */
obj->prev1 = obj->prev2;
obj->prev2 = c;
}
lastn = n;
c = *(str + n);
if (obj->inComment) {
/* if we're in a comment, ignore everything until we detect end of comment */
if ((obj->prev1 == '-') && (obj->prev2 == '-') && (c == '>')) obj->inComment = PR_FALSE;
n++;
} else if (obj->skipWhitespace) {
if ((c == ' ') || (c == '\n') || (c == '\r')) {
n++;
} else obj->skipWhitespace = PR_FALSE;
} else {
PRBool endOfString = PR_FALSE;
switch (obj->state) {
case PS_START:
/* PS_START - expecting open bracket or character data */
if (c == '<') {
obj->state = PS_TAG_NAME;
n++;
} else {
obj->state = PS_BETWEEN_TAGS;
}
break;
case PS_BETWEEN_TAGS:
/* PS_BETWEEN_TAGS - expecting open bracket (terminating character data) or more character data */
if (obj->inQuote == c) {
obj->inQuote = '\0'; /* close quote */
} else if ((c == '"') || (obj->inScript && (c == '\''))) { /* start a quote, only double quotes significant in between tags */
obj->inQuote = c;
}
/* open bracket not in quoted section indicates end of data */
if ((obj->inQuote == '\0') && (c == '<')) {
obj->state = PS_START;
if (crawl_appendString(&obj->data, &obj->dataLen, &obj->dataSize, '\0') != 0) /* null terminate string */
return CRAWL_PARSE_OUT_OF_MEMORY;
if (func(obj, PR_FALSE, data) == PARSE_STOP) return CRAWL_PARSE_TERMINATE;
crawl_recycleParseObj(obj);
} else {
if (crawl_appendString(&obj->data, &obj->dataLen, &obj->dataSize, c) != 0)
return CRAWL_PARSE_OUT_OF_MEMORY;
n++;
}
break;
case PS_TAG_NAME:
/* PS_TAG_NAME - terminated by space, \r, \n, >, / */
if ((c == '"') || (c == '\'')) return CRAWL_PARSE_ERROR; /* error - these are not allowed in tagname */
else if (c == ' ') {
/* Note: Both mozilla and XML don't allow any spaces between < and tagname.
Need to check for zero-length tagname.
*/
if (obj->str == NULL) return CRAWL_PARSE_ERROR; /* obj->str is the buffer we're working on */
endOfString = PR_TRUE;
obj->state = PS_ATTRIBUTE;
obj->skipWhitespace = PR_TRUE;
n++;
} else if (c == '/') {
if (obj->tag->name == NULL) obj->tag->endTagp = PR_TRUE; /* indicates end tag if no tag name read yet */
else if (obj->isRDF) { /* otherwise its an empty tag (RDF only) */
endOfString = PR_TRUE;
obj->tag->emptyTagp = PR_TRUE;
obj->state = PS_CLOSE_BRACKET;
} else return CRAWL_PARSE_ERROR;
n++;
} else if (c == '>') {
endOfString = PR_TRUE;
obj->state = PS_CLOSE_BRACKET;
} else if ((c != '\r') && (c != '\n')) {
if (crawl_appendString(&obj->str, &obj->strLen, &obj->strSize, c) != 0)
return CRAWL_PARSE_OUT_OF_MEMORY;
n++;
} else {
endOfString = PR_TRUE;
obj->state = PS_ATTRIBUTE; /* note - mozilla allows newline after tag name */
obj->skipWhitespace = PR_TRUE;
n++;
}
if (endOfString) {
if (crawl_appendString(&obj->str, &obj->strLen, &obj->strSize, '\0') != 0) /* null terminate string */
return CRAWL_PARSE_OUT_OF_MEMORY;
if (strcmp(obj->str, "!--") == 0) { /* html comment */
obj->inComment = PR_TRUE;
obj->state = PS_START;
} else {
obj->tag->name = obj->str;
obj->tag->token = pa_tokenize_tag(obj->str);
}
obj->str = NULL;
obj->strLen = obj->strSize = 0;
endOfString = PR_FALSE;
}
break;
case PS_CLOSE_BRACKET:
/* PS_CLOSE_BRACKET - expecting a close bracket, anything else is an error */
if (c == '>') {
if (!obj->isRDF && (obj->tag->token == P_SCRIPT)) {
/* we're inside a script tag (not RDF) */
if (obj->tag->endTagp) obj->inScript = PR_FALSE;
else obj->inScript = PR_TRUE;
}
if (func(obj, PR_TRUE, data) == PARSE_STOP) return CRAWL_PARSE_TERMINATE;
crawl_recycleParseObj(obj);
obj->state = PS_START;
n++;
} else return CRAWL_PARSE_ERROR; /* error */
break;
case PS_ATTRIBUTE:
/* PS_ATTRIBUTE - expecting an attribute name, or / (RDF only) or > indicating no more attributes */
/* accept attributes without values, such as <tag attr1 attr2=val2>
or <tag attr2=val2 attr1>
*/
if (obj->inQuote == c) {
obj->inQuote = '\0'; /* close quote */
} else if (((c == '"') || (c == '\'')) && (obj->inQuote == '\0')) {
/* start a quote if none is already in effect */
obj->inQuote = c;
}
if (obj->inQuote == '\0') {
if ((((c == '/') && obj->isRDF) || (c == '>')) && (obj->str == NULL)) {
obj->state = PS_CLOSE_BRACKET;
} else if ((c == ' ') || (c == '=') || (c == '\n') || (c == '\r') || ((c == '/') && obj->isRDF) || (c == '>')) {
if (crawl_appendString(&obj->str, &obj->strLen, &obj->strSize, '\0') != 0) /* null terminate string */
return CRAWL_PARSE_OUT_OF_MEMORY;
if (crawl_appendStringList(&obj->tag->attributeNames, &obj->tag->numNames, &obj->tag->sizeNames, obj->str) != 0)
return CRAWL_PARSE_OUT_OF_MEMORY;
obj->str = NULL;
obj->strLen = obj->strSize = 0;
obj->state = PS_EQUALS; /* if non-null attribute name */
} else {
if (crawl_appendString(&obj->str, &obj->strLen, &obj->strSize, c) != 0)
return CRAWL_PARSE_OUT_OF_MEMORY;
n++;
}
} else {
if (crawl_appendString(&obj->str, &obj->strLen, &obj->strSize, c) != 0)
return CRAWL_PARSE_OUT_OF_MEMORY;
n++;
}
break;
case PS_EQUALS:
if ((c == ' ') || (c == '\n') || (c == '\r')) {
obj->skipWhitespace = PR_TRUE;
n++;
} else if (c == '=') {
obj->skipWhitespace = PR_TRUE;
obj->state = PS_VALUE;
n++;
} else { /* no value for the attribute - error in RDF? */
if (crawl_appendString(&obj->str, &obj->strLen, &obj->strSize, '\0') != 0) /* null terminate string */
return CRAWL_PARSE_OUT_OF_MEMORY;
if (crawl_appendStringList(&obj->tag->attributeValues, &obj->tag->numValues, &obj->tag->sizeValues, obj->str) != 0)
return CRAWL_PARSE_OUT_OF_MEMORY;
obj->str = NULL;
obj->strLen = obj->strSize = 0;
obj->state = PS_ATTRIBUTE;
}
break;
case PS_VALUE:
/* expecting a value, or space, / (RDF only), or > indicating end of value. */
{
PRBool include = PR_TRUE; /* whether the current character should be included in value */
if (obj->inQuote == c) {
obj->inQuote = '\0'; /* close quote */
include = PR_FALSE;
} else if (((c == '"') || (c == '\'')) && (obj->inQuote == '\0')) {
/* start a quote if none is already in effect */
obj->inQuote = c;
include = PR_FALSE;
}
if (obj->inQuote == '\0') {
if ((c == '/') && obj->isRDF) {
endOfString = PR_TRUE;
obj->state = PS_CLOSE_BRACKET;
n++;
} else if (c == '>') {
endOfString = PR_TRUE;
obj->state = PS_CLOSE_BRACKET;
} else if ((c == ' ') || (c == '\r') || (c == '\n')) {
endOfString = PR_TRUE;
obj->skipWhitespace = PR_TRUE;
obj->state = PS_ATTRIBUTE; /* if non-null value name */
n++;
} else if (include) {
if (crawl_appendString(&obj->str, &obj->strLen, &obj->strSize, c) != 0)
return CRAWL_PARSE_OUT_OF_MEMORY;
n++;
} else n++;
} else if (include) {
if (crawl_appendString(&obj->str, &obj->strLen, &obj->strSize, c) != 0)
return CRAWL_PARSE_OUT_OF_MEMORY;
n++;
} else n++;
if (endOfString) {
if (crawl_appendString(&obj->str, &obj->strLen, &obj->strSize, '\0') != 0) /* null terminate string */
return CRAWL_PARSE_OUT_OF_MEMORY;
if (crawl_appendStringList(&obj->tag->attributeValues, &obj->tag->numValues, &obj->tag->sizeValues, obj->str) != 0)
return CRAWL_PARSE_OUT_OF_MEMORY;
obj->str = NULL;
obj->strLen = obj->strSize = 0;
endOfString = PR_FALSE;
}
break;
}
default:
break;
}
}
}
return CRAWL_PARSE_NO_ERROR;
}
#if 0
void printParseObj(CRAWL_ParseObj obj, PRBool isTag, void *data) {
if (isTag) {
CRAWL_Tag tag = CRAWL_GetTagParsed(obj);
if (CRAWL_IsEndTag(tag)) {
printf("</%s>\n", CRAWL_GetTagName(tag));
} else {
uint16 i;
printf("<%s", CRAWL_GetTagName(tag));
for (i = 0; i < CRAWL_GetNumberOfAttributes(tag); i++) {
printf(" %s=\"%s\"", CRAWL_GetNthAttributeName(tag, i), CRAWL_GetNthAttributeValue(tag, i));
}
if (CRAWL_IsEmptyTag(tag)) printf("/>\n");
else printf(">\n");
}
} else printf(">>>>>%s<<<<<\n", CRAWL_GetDataParsed(obj));
}
void parseLocalFile (char *url) {
PRFileDesc *fp;
int32 len;
char *path;
static char buf[512]; /* xxx alloc */
CRAWL_ParseObj parse;
/* XXX need to unescape URL */
path=&url[8];
fp = PR_Open(path, PR_RDONLY, 0644); /* WR_ONLY|PR_TRUNCATE */
if(fp == NULL)
{
/* abortRDFParse(file); */
return;
}
parse = CRAWL_MakeParseObj();
while((len=PR_Read(fp, buf, 512))>0) {
int result;
result = CRAWL_ParserPut(parse, buf, len, printParseObj, NULL);
if (result == len) printf("************NO ERRORS************\n");
else printf("************PARSING ERROR************\n");
}
PR_Close(fp);
CRAWL_DestroyParseObj(parse);
/* finishRDFParse(file); */
return;
}
#endif

View File

@@ -0,0 +1,155 @@
/* -*- 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.
*/
/*** htmparse.h ***************************************************/
/* description: html parser */
/********************************************************************
The client calls CRAWL_ParserPut, and gets called back with
a function whose prototype is described by CRAWL_ParseFunc. The
parser calls this function whenever a begin or end tag, or run of
character data has been scanned, and does not build a tree.
$Revision: 3.1 $
$Date: 1998-03-28 03:31:31 $
*********************************************************************/
#ifndef htmparse_h___
#define htmparse_h___
#include "prtypes.h"
/* return values from CRAWL_ParserPut */
#define CRAWL_PARSE_NO_ERROR 0 /* no error */
#define CRAWL_PARSE_ERROR 1 /* syntax error */
#define CRAWL_PARSE_TERMINATE 2 /* don't continue to parse */
#define CRAWL_PARSE_OUT_OF_MEMORY 3 /* out of memory */
/* return values for CRAWL_ParseFunc callback function */
#define PARSE_GET_NEXT_TOKEN 0
#define PARSE_STOP 1
#define PARSE_OUT_OF_MEMORY 2
typedef struct _CRAWL_TagStruc *CRAWL_Tag;
/*
The client of this API creates a reference to this with CRAWL_MakeParseObj and provides it as
a parameter to CRAWL_ParserPut. It is passed as a parameter to the CRAWL_ParseFunc function and
the parsed data may be extracted from it through the API. It should be considered opaque data.
*/
typedef struct _CRAWL_ParseObjStruc *CRAWL_ParseObj;
/*
Typedef for a parse callback. The memory in CRAWL_ParseObj is reused across successive calls.
*/
typedef int
(PR_CALLBACK *CRAWL_ParseFunc)(CRAWL_ParseObj obj, PRBool isTag, void *data);
/****************************************************************************************/
/* public API */
/****************************************************************************************/
NSPR_BEGIN_EXTERN_C
/*
Returns the tag parsed
*/
PR_EXTERN(CRAWL_Tag)
CRAWL_GetTagParsed(CRAWL_ParseObj obj);
/*
Returns the character data between tags
*/
PR_EXTERN(char*)
CRAWL_GetDataParsed(CRAWL_ParseObj obj);
/*
Returns the tag name
*/
PR_EXTERN(char*)
CRAWL_GetTagName(CRAWL_Tag tag);
/*
Returns the libparse tag code as defined in pa_tags.h
*/
PR_EXTERN(intn)
CRAWL_GetTagToken(CRAWL_Tag tag);
/*
a tag of the form <tagname /> Empty tags are recognized only if the page has been designated as
containing RDF (the API doesn't support this yet)
*/
PR_EXTERN(PRBool)
CRAWL_IsEmptyTag(CRAWL_Tag tag);
/*
A tag of the form </tagname>.
*/
PR_EXTERN(PRBool)
CRAWL_IsEndTag(CRAWL_Tag tag);
/*
Returns the tag attribute given a name
*/
PR_EXTERN(char*)
CRAWL_GetAttributeValue(CRAWL_Tag tag, char *attributeName);
/*
Returns the number of attributes for the tag.
*/
PR_EXTERN(uint16)
CRAWL_GetNumberOfAttributes(CRAWL_Tag tag);
/*
Returns the nth attribute of the tag.
*/
PR_EXTERN(char*)
CRAWL_GetNthAttributeName(CRAWL_Tag tag, uint16 n);
/*
Returns the nth attribute value of the tag.
*/
PR_EXTERN(char*)
CRAWL_GetNthAttributeValue(CRAWL_Tag tag, uint16 n);
/*
Creates a new CRAWL_ParseObj suitable for passing to CRAWL_ParserPut.
Returns NULL if out of memory.
*/
PR_EXTERN(CRAWL_ParseObj)
CRAWL_MakeParseObj();
/*
Destroys the CRAWL_ParseObj and all associated memory
*/
PR_EXTERN(void)
CRAWL_DestroyParseObj(CRAWL_ParseObj obj);
/*
Parse characters in buffer and call func when an element (tag or data) has been
scanned. Returns an error code. The same CRAWL_ParseObj must be provided for successive
puts in the same buffer. It is up to the caller to create and destroy the CRAWL_ParseObj.
*/
PR_EXTERN(int)
CRAWL_ParserPut(CRAWL_ParseObj obj, char *str, uint32 len, CRAWL_ParseFunc func, void *data);
NSPR_END_EXTERN_C
#endif /* htmparse_h___ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,658 @@
/* -*- 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.
*/
#include "mkutils.h"
#ifndef __imap__
#include "imap.h"
#endif
#ifndef _MCOM_H_
#include "xp_mcom.h"
#endif
/* 45678901234567890123456789012345678901234567890123456789012345678901234567890
*/
char useme;
static char *createStartOfIMAPurl(const char *imapHost, int additionalSize)
{
static const char *formatString = "IMAP://%s?";
char *returnString = XP_ALLOC(XP_STRLEN(formatString) + XP_STRLEN(imapHost) + additionalSize);
if (returnString)
sprintf(returnString, formatString, imapHost);
return returnString;
}
/* Selecting a mailbox */
/* imap4://HOST>select>MAILBOXPATH */
char *CreateImapMailboxSelectUrl(const char *imapHost,
const char *mailbox,
char hierarchySeparator,
const char *undoDeleteIdentifierList)
{
static const char *formatString = "select>%c%s>%s";
/* 22 enough for huge index string */
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) +
XP_STRLEN(mailbox) +
(undoDeleteIdentifierList ? XP_STRLEN(undoDeleteIdentifierList) : 1) +
22);
if (returnString)
sprintf(returnString + XP_STRLEN(returnString),
formatString,
hierarchySeparator,
mailbox,
undoDeleteIdentifierList ? undoDeleteIdentifierList : "");
return returnString;
}
/* lite select, used to verify UIDVALIDITY while going on/offline */
char *CreateImapMailboxLITESelectUrl(const char *imapHost,
const char *mailbox,
char hierarchySeparator)
{
static const char *formatString = "liteselect>%c%s";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(mailbox));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString),
formatString,
hierarchySeparator,
mailbox);
return returnString;
}
/* expunge, used in traditional imap delete model */
char *CreateImapMailboxExpungeUrl(const char *imapHost,
const char *mailbox,
char hierarchySeparator)
{
static const char *formatString = "expunge>%c%s";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(mailbox));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString),
formatString,
hierarchySeparator,
mailbox);
return returnString;
}
/* Creating a mailbox */
/* imap4://HOST>create>MAILBOXPATH */
char *CreateImapMailboxCreateUrl(const char *imapHost, const char *mailbox,char hierarchySeparator)
{
static const char *formatString = "create>%c%s";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(mailbox));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString, hierarchySeparator, mailbox);
return returnString;
}
/* discover the mailboxes of this account */
char *CreateImapAllMailboxDiscoveryUrl(const char *imapHost)
{
static const char *formatString = "discoverallboxes";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString);
return returnString;
}
/* discover the mailboxes of this account, and the subscribed mailboxes */
char *CreateImapAllAndSubscribedMailboxDiscoveryUrl(const char *imapHost)
{
static const char *formatString = "discoverallandsubscribedboxes";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString);
return returnString;
}
/* discover the children of this mailbox */
char *CreateImapChildDiscoveryUrl(const char *imapHost, const char *mailbox,char hierarchySeparator)
{
static const char *formatString = "discoverchildren>%c%s";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(mailbox));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString, hierarchySeparator, mailbox);
return returnString;
}
/* discover the n-th level deep children of this mailbox */
char *CreateImapLevelChildDiscoveryUrl(const char *imapHost, const char *mailbox,char hierarchySeparator, int n)
{
static const char *formatString = "discoverlevelchildren>%d>%c%s";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(mailbox));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString, n, hierarchySeparator, mailbox);
return returnString;
}
/* deleting a mailbox */
/* imap4://HOST>delete>MAILBOXPATH */
char *CreateImapMailboxDeleteUrl(const char *imapHost, const char *mailbox, char hierarchySeparator)
{
static const char *formatString = "delete>%c%s";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(mailbox));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString, hierarchySeparator, mailbox);
return returnString;
}
/* renaming a mailbox */
/* imap4://HOST>rename>OLDNAME>NEWNAME */
char *CreateImapMailboxRenameLeafUrl(const char *imapHost,
const char *oldBoxPathName,
char hierarchySeparator,
const char *newBoxLeafName)
{
static const char *formatString = "rename>%c%s>%c%s";
char *returnString = NULL;
/* figure out the new mailbox name */
char *slash;
char *newPath = XP_ALLOC(XP_STRLEN(oldBoxPathName) + XP_STRLEN(newBoxLeafName) + 1);
if (newPath)
{
XP_STRCPY (newPath, oldBoxPathName);
slash = XP_STRRCHR (newPath, '/');
if (slash)
slash++;
else
slash = newPath; /* renaming a 1st level box */
XP_STRCPY (slash, newBoxLeafName);
returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(oldBoxPathName) + XP_STRLEN(newPath));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString, hierarchySeparator, oldBoxPathName, hierarchySeparator, newPath);
XP_FREE( newPath);
}
return returnString;
}
/* renaming a mailbox, moving hierarchy */
/* imap4://HOST>movefolderhierarchy>OLDNAME>NEWNAME */
/* oldBoxPathName is the old name of the child folder */
/* destinationBoxPathName is the name of the new parent */
char *CreateImapMailboxMoveFolderHierarchyUrl(const char *imapHost,
const char *oldBoxPathName,
char oldHierarchySeparator,
const char *newBoxPathName,
char newHierarchySeparator)
{
static const char *formatString = "movefolderhierarchy>%c%s>%c%s";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(oldBoxPathName) + XP_STRLEN(newBoxPathName));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString, oldHierarchySeparator, oldBoxPathName, newHierarchySeparator, newBoxPathName);
return returnString;
}
/* listing available mailboxes */
/* imap4://HOST>list>referenceName>MAILBOXPATH */
/* MAILBOXPATH can contain wildcard */
/* **** jefft -- I am using this url to detect whether an mailbox
exists on the Imap sever
*/
char *CreateImapListUrl(const char *imapHost,
const char *mailbox,
const char hierarchySeparator)
{
static const char *formatString = "list>%c%s";
char *returnString = createStartOfIMAPurl(imapHost,
XP_STRLEN(formatString) +
XP_STRLEN(mailbox) + 1);
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString,
hierarchySeparator, mailbox);
return returnString;
}
/* biff */
char *CreateImapBiffUrl(const char *imapHost,
const char *mailbox,
char hierarchySeparator,
uint32 uidHighWater)
{
static const char *formatString = "biff>%c%s>%ld";
/* 22 enough for huge uid string */
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) +
XP_STRLEN(mailbox) + 22);
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString, hierarchySeparator, mailbox, (long)uidHighWater);
return returnString;
}
static const char *sequenceString = "SEQUENCE";
static const char *uidString = "UID";
/* fetching RFC822 messages */
/* imap4://HOST>fetch><UID/SEQUENCE>>MAILBOXPATH>x */
/* 'x' is the message UID or sequence number list */
/* will set the 'SEEN' flag */
char *CreateImapMessageFetchUrl(const char *imapHost,
const char *mailbox,
char hierarchySeparator,
const char *messageIdentifierList,
XP_Bool messageIdsAreUID)
{
static const char *formatString = "fetch>%s>%c%s>%s";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(sequenceString) + XP_STRLEN(mailbox) + XP_STRLEN(messageIdentifierList));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString, messageIdsAreUID ? uidString : sequenceString, hierarchySeparator, mailbox, messageIdentifierList);
return returnString;
}
/* fetching the headers of RFC822 messages */
/* imap4://HOST>header><UID/SEQUENCE>>MAILBOXPATH>x */
/* 'x' is the message UID or sequence number list */
/* will not affect the 'SEEN' flag */
char *CreateImapMessageHeaderUrl(const char *imapHost,
const char *mailbox,
char hierarchySeparator,
const char *messageIdentifierList,
XP_Bool messageIdsAreUID)
{
static const char *formatString = "header>%s>%c%s>%s";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(sequenceString) + XP_STRLEN(mailbox) + XP_STRLEN(messageIdentifierList));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString, messageIdsAreUID ? uidString : sequenceString, hierarchySeparator, mailbox, messageIdentifierList);
return returnString;
}
/* search an online mailbox */
/* imap4://HOST>search><UID/SEQUENCE>>MAILBOXPATH>SEARCHSTRING */
/* 'x' is the message sequence number list */
char *CreateImapSearchUrl(const char *imapHost,
const char *mailbox,
char hierarchySeparator,
const char *searchString,
XP_Bool messageIdsAreUID)
{
static const char *formatString = "search>%s>%c%s>%s";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(sequenceString) + XP_STRLEN(mailbox) + XP_STRLEN(searchString));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString, messageIdsAreUID ? uidString : sequenceString, hierarchySeparator, mailbox, searchString);
return returnString;
}
/* delete messages */
/* imap4://HOST>deletemsg><UID/SEQUENCE>>MAILBOXPATH>x */
/* 'x' is the message UID or sequence number list */
char *CreateImapDeleteMessageUrl(const char *imapHost,
const char *mailbox,
char hierarchySeparator,
const char *messageIds,
XP_Bool idsAreUids)
{
static const char *formatString = "deletemsg>%s>%c%s>%s";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(sequenceString) + XP_STRLEN(mailbox) + XP_STRLEN(messageIds));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString, idsAreUids ? uidString : sequenceString, hierarchySeparator, mailbox, messageIds);
return returnString;
}
/* delete all messages */
/* imap4://HOST>deleteallmsgs>MAILBOXPATH */
char *CreateImapDeleteAllMessagesUrl(const char *imapHost,
const char *mailbox,
char hierarchySeparator)
{
static const char *formatString = "deleteallmsgs>%c%s";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(mailbox));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString, hierarchySeparator, mailbox);
return returnString;
}
/* store +flags url */
/* imap4://HOST>store+flags><UID/SEQUENCE>>MAILBOXPATH>x>f */
/* 'x' is the message UID or sequence number list */
/* 'f' is the byte of flags */
char *CreateImapAddMessageFlagsUrl(const char *imapHost,
const char *mailbox,
char hierarchySeparator,
const char *messageIds,
imapMessageFlagsType flags,
XP_Bool idsAreUids)
{
static const char *formatString = "addmsgflags>%s>%c%s>%s>%d";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(sequenceString) + XP_STRLEN(mailbox) + XP_STRLEN(messageIds) + 10);
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString, idsAreUids ? uidString : sequenceString, hierarchySeparator, mailbox, messageIds, (int) flags);
return returnString;
}
/* store -flags url */
/* imap4://HOST>store-flags><UID/SEQUENCE>>MAILBOXPATH>x>f */
/* 'x' is the message UID or sequence number list */
/* 'f' is the byte of flags */
char *CreateImapSubtractMessageFlagsUrl(const char *imapHost,
const char *mailbox,
char hierarchySeparator,
const char *messageIds,
imapMessageFlagsType flags,
XP_Bool idsAreUids)
{
static const char *formatString = "subtractmsgflags>%s>%c%s>%s>%d";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(sequenceString) + XP_STRLEN(mailbox) + XP_STRLEN(messageIds) + 10);
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString, idsAreUids ? uidString : sequenceString, hierarchySeparator, mailbox, messageIds, (int) flags);
return returnString;
}
/* set flags url, make the flags match */
char *CreateImapSetMessageFlagsUrl(const char *imapHost,
const char *mailbox,
char hierarchySeparator,
const char *messageIds,
imapMessageFlagsType flags,
XP_Bool idsAreUids)
{
static const char *formatString = "setmsgflags>%s>%c%s>%s>%d";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(sequenceString) + XP_STRLEN(mailbox) + XP_STRLEN(messageIds) + 10);
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString, idsAreUids ? uidString : sequenceString, hierarchySeparator, mailbox, messageIds, (int) flags);
return returnString;
}
/* copy messages from one online box to another */
/* imap4://HOST>onlineCopy><UID/SEQUENCE>>SOURCEMAILBOXPATH>x>
DESTINATIONMAILBOXPATH */
/* 'x' is the message UID or sequence number list */
char *CreateImapOnlineCopyUrl(const char *imapHost,
const char *sourceMailbox,
char sourceHierarchySeparator,
const char *messageIds,
const char *destinationMailbox,
char destinationHierarchySeparator,
XP_Bool idsAreUids,
XP_Bool isMove)
{
static const char *formatString = "%s>%s>%c%s>%s>%c%s";
static const char *moveString = "onlinemove";
static const char *copyString = "onlinecopy";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(moveString) + XP_STRLEN(sequenceString) + XP_STRLEN(sourceMailbox) + XP_STRLEN(messageIds) + XP_STRLEN(destinationMailbox));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString,
isMove ? moveString : copyString,
idsAreUids ? uidString : sequenceString,
sourceHierarchySeparator, sourceMailbox,
messageIds,
destinationHierarchySeparator, destinationMailbox);
return returnString;
}
/* copy messages from one online box to another */
/* imap4://HOST>onlineCopy><UID/SEQUENCE>>SOURCEMAILBOXPATH>x>
DESTINATIONMAILBOXPATH */
/* 'x' is the message UID or sequence number list */
char *CreateImapOnToOfflineCopyUrl(const char *imapHost,
const char *sourceMailbox,
char sourceHierarchySeparator,
const char *messageIds,
const char *destinationMailbox,
XP_Bool idsAreUids,
XP_Bool isMove)
{
static const char *formatString = "%s>%s>%c%s>%s>%c%s";
static const char *moveString = "onlinetoofflinemove";
static const char *copyString = "onlinetoofflinecopy";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(moveString) + XP_STRLEN(sequenceString) + XP_STRLEN(sourceMailbox) + XP_STRLEN(messageIds) + XP_STRLEN(destinationMailbox));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString,
isMove ? moveString : copyString,
idsAreUids ? uidString : sequenceString,
sourceHierarchySeparator, sourceMailbox,
messageIds,
kOnlineHierarchySeparatorUnknown, destinationMailbox);
return returnString;
}
/* copy messages from an offline box to an online box */
/* imap4://HOST>offtoonCopy>SOURCEMAILBOXPATH>x>
DESTINATIONMAILBOXPATH */
/* 'x' is the size of the message to upload */
char *CreateImapOffToOnlineCopyUrl(const char *imapHost,
const char *destinationMailbox,
char destinationHierarchySeparator)
{
static const char *formatString = "offlinetoonlinecopy>%c%s";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(destinationMailbox));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString, destinationHierarchySeparator, destinationMailbox);
return returnString;
}
/* get mail account rul */
/* imap4://HOST>NETSCAPE */
char *CreateImapManageMailAccountUrl(const char *imapHost)
{
static const char *formatString = "netscape";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + 1);
StrAllocCat(returnString, formatString);;
return returnString;
}
/* append message from file url */
/* imap4://HOST>appendmsgfromfile>DESTINATIONMAILBOXPATH */
char *CreateImapAppendMessageFromFileUrl(const char *imapHost,
const char *destinationMailboxPath,
const char hierarchySeparator,
XP_Bool isDraft)
{
const char *formatString = isDraft ? "appenddraftfromfile>%c%s" :
"appendmsgfromfile>%c%s";
char *returnString =
createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) +
XP_STRLEN(destinationMailboxPath));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString,
hierarchySeparator, destinationMailboxPath);
return returnString;
}
/* Subscribe to a mailbox on the given IMAP host */
char *CreateIMAPSubscribeMailboxURL(const char *imapHost, const char *mailboxName)
{
/* we don't need the hierarchy delimiter, so just use slash ("/") */
static const char *formatString = "subscribe>/%s";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(mailboxName));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString, mailboxName);
return returnString;
}
/* Unsubscribe from a mailbox on the given IMAP host */
char *CreateIMAPUnsubscribeMailboxURL(const char *imapHost, const char *mailboxName)
{
/* we don't need the hierarchy delimiter, so just use slash ("/") */
static const char *formatString = "unsubscribe>/%s";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(mailboxName));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString, mailboxName);
return returnString;
}
/* Refresh the ACL for a folder on the given IMAP host */
char *CreateIMAPRefreshACLForFolderURL(const char *imapHost, const char *mailboxName)
{
/* we don't need the hierarchy delimiter, so just use slash ("/") */
static const char *formatString = "refreshacl>/%s";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(mailboxName));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString, mailboxName);
return returnString;
}
/* Refresh the ACL for all folders on the given IMAP host */
char *CreateIMAPRefreshACLForAllFoldersURL(const char *imapHost)
{
/* we don't need the hierarchy delimiter, so just use slash ("/") */
static const char *formatString = "refreshallacls>/";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString);
return returnString;
}
/* Auto-Upgrade to IMAP subscription */
char *CreateIMAPUpgradeToSubscriptionURL(const char *imapHost, XP_Bool subscribeToAll)
{
static char *formatString = "upgradetosubscription>/";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString));
if (subscribeToAll)
formatString[XP_STRLEN(formatString)-1] = '.';
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString);
return returnString;
}
/* do a status command on a folder on the given IMAP host */
char *CreateIMAPStatusFolderURL(const char *imapHost, const char *mailboxName, char hierarchySeparator)
{
static const char *formatString = "folderstatus>%c%s";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(mailboxName));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString),
formatString,
hierarchySeparator,
mailboxName);
return returnString;
}
/* Refresh the admin url for a folder on the given IMAP host */
char *CreateIMAPRefreshFolderURLs(const char *imapHost, const char *mailboxName)
{
/* we don't need the hierarchy delimiter, so just use slash ("/") */
static const char *formatString = "refreshfolderurls>/%s";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(mailboxName));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString, mailboxName);
return returnString;
}
/* Force the reload of all parts of the message given in url */
char *IMAP_CreateReloadAllPartsUrl(const char *url)
{
char *returnUrl = PR_smprintf("%s&allparts", url);
return returnUrl;
}
/* Explicitly LIST a given mailbox, and refresh its flags in the folder list */
char *CreateIMAPListFolderURL(const char *imapHost, const char *mailboxName)
{
/* we don't need the hierarchy delimiter, so just use slash ("/") */
static const char *formatString = "listfolder>/%s";
char *returnString = createStartOfIMAPurl(imapHost, XP_STRLEN(formatString) + XP_STRLEN(mailboxName));
if (returnString)
sprintf(returnString + XP_STRLEN(returnString), formatString, mailboxName);
return returnString;
}

View File

@@ -0,0 +1,157 @@
/* -*- 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.
*/
/* this file defines the syntax of the imap4 url's and offers functions
that create url strings. If the functions do not offer enough
functionality then let kevin know before you starting creating strings
from scratch. */
#ifndef IMAP4URL_H
#define IMAP4URL_H
#include "xp_mcom.h"
/* 45678901234567890123456789012345678901234567890123456789012345678901234567890
*/
XP_BEGIN_PROTOS
/* need mailbox status urls to get the number of message and the
number of unread messages */
/* Creating a mailbox */
/* imap4://HOST?create?MAILBOXPATH */
char *CreateImapMailboxCreateUrl(const char *imapHost, const char *mailbox);
/* deleting a mailbox */
/* imap4://HOST?delete?MAILBOXPATH */
char *CreateImapMailboxDeleteUrl(const char *imapHost, const char *mailbox);
/* renaming a mailbox */
/* imap4://HOST?rename?OLDNAME?NEWNAME */
char *CreateImapMailboxRenameUrl(const char *imapHost,
const char *oldBoxName,
const char *newBoxName);
/* listing available mailboxes */
/* imap4://HOST?list */
char *CreateImapListUrl(const char *imapHost);
/* fetching RFC822 messages */
/* imap4://HOST?fetch?<UID/SEQUENCE>?MAILBOXPATH?x */
/* 'x' is the message UID or sequence number list */
/* will set the 'SEEN' flag */
char *CreateImapMessageFetchUrl(const char *imapHost,
const char *mailbox,
const char *messageIdentifierList,
XP_Bool messageIdsAreUID);
/* fetching the headers of RFC822 messages */
/* imap4://HOST?header?<UID/SEQUENCE>?MAILBOXPATH?x */
/* 'x' is the message UID or sequence number list */
/* will not affect the 'SEEN' flag */
char *CreateImapMessageHeaderUrl(const char *imapHost,
const char *mailbox,
const char *messageIdentifierList,
XP_Bool messageIdsAreUID);
/* dump headers url. Notify the front end when the mailbox is selected and
when each message line is dumped */
char *CreateImapMessageHeaderDumpUrl(const char *imapHost,
const char *mailbox);
/* search an online mailbox */
/* imap4://HOST?search?<UID/SEQUENCE>?MAILBOXPATH?SEARCHSTRING */
/* 'x' is the message sequence number list */
char *CreateImapSearchUrl(const char *imapHost,
const char *mailbox,
const char *searchString,
XP_Bool messageIdsAreUID);
/* delete messages */
/* imap4://HOST?deletemsg?<UID/SEQUENCE>?MAILBOXPATH?x */
/* 'x' is the message UID or sequence number list */
char *CreateImapDeleteMessageUrl(const char *imapHost,
const char *mailbox,
const char *messageIds,
XP_Bool idsAreUids);
/* mark messages as read */
/* imap4://HOST?markread?<UID/SEQUENCE>?MAILBOXPATH?x */
/* 'x' is the message UID or sequence number list */
char *CreateImapMarkMessageReadUrl(const char *imapHost,
const char *mailbox,
const char *messageIds,
XP_Bool idsAreUids);
/* mark messages as unread */
/* imap4://HOST?markunread?<UID/SEQUENCE>?MAILBOXPATH?x */
/* 'x' is the message UID or sequence number list */
char *CreateImapMarkMessageUnReadUrl(const char *imapHost,
const char *mailbox,
const char *messageIds,
XP_Bool idsAreUids);
/* copy messages from one online box to another */
/* imap4://HOST?onlineCopy?<UID/SEQUENCE>?
SOURCEMAILBOXPATH?x?DESTINATIONMAILBOXPATH */
/* 'x' is the message UID or sequence number list */
char *CreateImapOnlineCopyUrl(const char *imapHost,
const char *sourceMailbox,
const char *messageIds,
const char *destinationMailbox,
XP_Bool idsAreUids);
#if DOTHISSTUFFLATER
/* copy a message from an online box to an offline box */
/* imap4://HOST?ontooffCopy?SOURCEMAILBOXPATH?number=x?
DESTINATIONMAILBOXPATH */
/* 'x' is the message sequence number */
char *CreateImapOnToOfflineCopyUrl(const char *imapHost,
const char *sourceOnlineMailbox,
int32 messageSequenceNumber,
const char *destinationOfflineMailbox);
/* copy a message from an offline box to an online box */
/* imap4://HOST?offtoonCopy?SOURCEMAILBOXPATH?number=x?
DESTINATIONMAILBOXPATH */
/* 'x' is the message sequence number */
char *CreateImapOffToOnlineCopyUrl(const char *imapHost,
const char *sourceOnlineMailbox,
int32 messageSequenceNumber,
const char *destinationOfflineMailbox);
/* get mail account rul */
/* imap4://HOST?NETSCAPE */
char *CreateImapManageMailAccountUrl(const char *imapHost);
/* append message from file url */
/* imap4://HOST?appendmsgfromfile>DESTINATIONMAILBOXPATH */
char *CreateImapAppendMessageFromFileUrl(const char *imapHost,
const char *destinationMailboxPath,
const char hierarchySeparator,
XP_Bool isDraft);
#endif
XP_END_PROTOS
#endif /* IMAP4URL_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,364 @@
/* -*- 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.
*/
/*
TIMAPBodyShell and associated classes
*/
#ifndef IMAPBODY_H
#define IMAPBODY_H
#include "imap.h"
#include "xp_list.h"
typedef enum _TIMAPBodypartType {
IMAP_BODY_MESSAGE_RFC822,
IMAP_BODY_MESSAGE_HEADER,
IMAP_BODY_LEAF,
IMAP_BODY_MULTIPART
} TIMAPBodypartType;
class TIMAPGenericParser;
class TNavigatorImapConnection;
class TIMAPBodyShell;
class XPPtrArray;
class TIMAPBodypartMessage;
typedef struct xp_HashTable *XP_HashTable;
class TIMAPBodypart : public TIMAPGenericParser
{
public:
// Construction
static TIMAPBodypart *CreatePart(TIMAPBodyShell *shell, char *partNum, const char *buf, TIMAPBodypart *parentPart);
virtual XP_Bool GetIsValid() { return m_isValid; }
virtual void SetIsValid(XP_Bool valid);
virtual TIMAPBodypartType GetType() = 0;
// Generation
virtual int32 Generate(XP_Bool /*stream*/, XP_Bool /* prefetch */) { return -1; } // Generates an HTML representation of this part. Returns content length generated, -1 if failed.
virtual void AdoptPartDataBuffer(char *buf); // Adopts storage for part data buffer. If NULL, sets isValid to FALSE.
virtual void AdoptHeaderDataBuffer(char *buf); // Adopts storage for header data buffer. If NULL, sets isValid to FALSE.
virtual XP_Bool ShouldFetchInline() { return TRUE; } // returns TRUE if this part should be fetched inline for generation.
virtual XP_Bool PreflightCheckAllInline() { return TRUE; }
virtual XP_Bool ShouldExplicitlyFetchInline();
virtual XP_Bool ShouldExplicitlyNotFetchInline();
protected: // If stream is FALSE, simply returns the content length that will be generated
virtual int32 GeneratePart(XP_Bool stream, XP_Bool prefetch); // the body of the part itself
virtual int32 GenerateMIMEHeader(XP_Bool stream, XP_Bool prefetch); // the MIME headers of the part
virtual int32 GenerateBoundary(XP_Bool stream, XP_Bool prefetch, XP_Bool lastBoundary); // Generates the MIME boundary wrapper for this part.
// lastBoundary indicates whether or not this should be the boundary for the
// final MIME part of the multipart message.
virtual int32 GenerateEmptyFilling(XP_Bool stream, XP_Bool prefetch); // Generates (possibly empty) filling for a part that won't be filled in inline.
// Part Numbers / Hierarchy
public:
virtual int GetPartNumber() { return m_partNumber; } // Returns the part number on this hierarchy level
virtual char *GetPartNumberString() { return m_partNumberString; }
virtual TIMAPBodypart *FindPartWithNumber(const char *partNum); // Returns the part object with the given number
virtual TIMAPBodypart *GetParentPart() { return m_parentPart; } // Returns the parent of this part.
// We will define a part of type message/rfc822 to be the
// parent of its body and header.
// A multipart is a parent of its child parts.
// All other leafs do not have children.
// Other / Helpers
public:
virtual ~TIMAPBodypart();
virtual XP_Bool GetNextLineForParser(char **nextLine);
virtual XP_Bool ContinueParse(); // overrides the parser, but calls it anyway
virtual TIMAPBodypartMessage *GetTIMAPBodypartMessage() { return NULL; }
protected:
virtual void QueuePrefetchMIMEHeader();
//virtual void PrefetchMIMEHeader(); // Initiates a prefetch for the MIME header of this part.
virtual XP_Bool ParseIntoObjects() = 0; // Parses buffer and fills in both this and any children with associated objects
// Returns TRUE if it produced a valid Shell
// Must be overridden in the concerte derived class
const char *GetBodyType() { return m_bodyType; }
const char *GetBodySubType() { return m_bodySubType; }
TIMAPBodypart(TIMAPBodyShell *shell, char *partNumber, const char *buf, TIMAPBodypart *parentPart);
protected:
TIMAPBodyShell *m_shell; // points back to the shell
XP_Bool m_isValid; // If this part is valid.
int m_partNumber; // part number on this hierarchy level
char *m_partNumberString; // string representation of this part's full-hierarchy number. Define 0 to be the top-level message
char *m_partData; // data for this part. NULL if not filled in yet.
char *m_headerData; // data for this part's MIME header. NULL if not filled in yet.
char *m_boundaryData; // MIME boundary for this part
int32 m_partLength;
int32 m_contentLength; // Total content length which will be Generate()'d. -1 if not filled in yet.
char *m_responseBuffer; // The buffer for this object
TIMAPBodypart *m_parentPart; // Parent of this part
// Fields - Filled in from parsed BODYSTRUCTURE response (as well as others)
char *m_contentType; // constructed from m_bodyType and m_bodySubType
char *m_bodyType;
char *m_bodySubType;
char *m_bodyID;
char *m_bodyDescription;
char *m_bodyEncoding;
// we ignore extension data for now
};
// Message headers
// A special type of TIMAPBodypart
// These may be headers for the top-level message,
// or any body part of type message/rfc822.
class TIMAPMessageHeaders : public TIMAPBodypart
{
public:
TIMAPMessageHeaders(TIMAPBodyShell *shell, char *partNum, TIMAPBodypart *parentPart);
virtual TIMAPBodypartType GetType();
virtual int32 Generate(XP_Bool stream, XP_Bool prefetch); // Generates an HTML representation of this part. Returns content length generated, -1 if failed.
virtual XP_Bool ShouldFetchInline();
virtual void QueuePrefetchMessageHeaders();
protected:
virtual XP_Bool ParseIntoObjects(); // Parses m_responseBuffer and fills in m_partList with associated objects
// Returns TRUE if it produced a valid Shell
};
class TIMAPBodypartMultipart : public TIMAPBodypart
{
public:
TIMAPBodypartMultipart(TIMAPBodyShell *shell, char *partNum, const char *buf, TIMAPBodypart *parentPart);
virtual TIMAPBodypartType GetType();
virtual ~TIMAPBodypartMultipart();
virtual XP_Bool ShouldFetchInline();
virtual XP_Bool PreflightCheckAllInline();
virtual int32 Generate(XP_Bool stream, XP_Bool prefetch); // Generates an HTML representation of this part. Returns content length generated, -1 if failed.
virtual TIMAPBodypart *FindPartWithNumber(const char *partNum); // Returns the part object with the given number
protected:
virtual XP_Bool ParseIntoObjects();
protected:
XPPtrArray *m_partList; // An ordered list of top-level body parts for this shell
};
// The name "leaf" is somewhat misleading, since a part of type message/rfc822 is technically
// a leaf, even though it can contain other parts within it.
class TIMAPBodypartLeaf : public TIMAPBodypart
{
public:
TIMAPBodypartLeaf(TIMAPBodyShell *shell, char *partNum, const char *buf, TIMAPBodypart *parentPart);
virtual TIMAPBodypartType GetType();
virtual int32 Generate(XP_Bool stream, XP_Bool prefetch); // Generates an HTML representation of this part. Returns content length generated, -1 if failed.
virtual XP_Bool ShouldFetchInline(); // returns TRUE if this part should be fetched inline for generation.
virtual XP_Bool PreflightCheckAllInline();
protected:
virtual XP_Bool ParseIntoObjects();
};
class TIMAPBodypartMessage : public TIMAPBodypartLeaf
{
public:
TIMAPBodypartMessage(TIMAPBodyShell *shell, char *partNum, const char *buf, TIMAPBodypart *parentPart, XP_Bool topLevelMessage);
virtual TIMAPBodypartType GetType();
virtual ~TIMAPBodypartMessage();
virtual int32 Generate(XP_Bool stream, XP_Bool prefetch);
virtual XP_Bool ShouldFetchInline();
virtual XP_Bool PreflightCheckAllInline();
virtual TIMAPBodypart *FindPartWithNumber(const char *partNum); // Returns the part object with the given number
void AdoptMessageHeaders(char *headers); // Fills in buffer (and adopts storage) for header object
// partNum specifies the message part number to which the
// headers correspond. NULL indicates the top-level message
virtual TIMAPBodypartMessage *GetTIMAPBodypartMessage() { return this; }
virtual XP_Bool GetIsTopLevelMessage() { return m_topLevelMessage; }
protected:
virtual XP_Bool ParseIntoObjects();
protected:
TIMAPMessageHeaders *m_headers; // Every body shell should have headers
TIMAPBodypart *m_body;
XP_Bool m_topLevelMessage; // Whether or not this is the top-level message
};
class TIMAPMessagePartIDArray;
// We will refer to a Body "Shell" as a hierarchical object representation of a parsed BODYSTRUCTURE
// response. A shell contains representations of Shell "Parts." A Body Shell can undergo essentially
// two operations: Construction and Generation.
// Shell Construction occurs by parsing a BODYSTRUCTURE response into empty Parts.
// Shell Generation generates a "MIME Shell" of the message and streams it to libmime for
// display. The MIME Shell has selected (inline) parts filled in, and leaves all others
// for on-demand retrieval through explicit part fetches.
class TIMAPBodyShell
{
public:
// Construction
TIMAPBodyShell(TNavigatorImapConnection *connection, const char *bs, uint32 UID, const char *folderName); // Constructor takes in a buffer containing an IMAP
// bodystructure response from the server, with the associated
// tag/command/etc. stripped off.
// That is, it takes in something of the form:
// (("TEXT" "PLAIN" ..... ))
virtual ~TIMAPBodyShell();
void SetConnection(TNavigatorImapConnection *con) { m_connection = con; } // To be used after a shell is uncached
virtual XP_Bool GetIsValid() { return m_isValid; }
virtual void SetIsValid(XP_Bool valid);
// Prefetch
void AddPrefetchToQueue(TIMAP4BlockingConnection::eFetchFields, const char *partNum); // Adds a message body part to the queue to be prefetched
// in a single, pipelined command
void FlushPrefetchQueue(); // Runs a single pipelined command which fetches all of the
// elements in the prefetch queue
void AdoptMessageHeaders(char *headers, const char *partNum); // Fills in buffer (and adopts storage) for header object
// partNum specifies the message part number to which the
// headers correspond. NULL indicates the top-level message
void AdoptMimeHeader(const char *partNum, char *mimeHeader); // Fills in buffer (and adopts storage) for MIME headers in appropriate object.
// If object can't be found, sets isValid to FALSE.
// Generation
virtual int32 Generate(char *partNum); // Streams out an HTML representation of this IMAP message, going along and
// fetching parts it thinks it needs, and leaving empty shells for the parts
// it doesn't.
// Returns number of bytes generated, or -1 if invalid.
// If partNum is not NULL, then this works to generates a MIME part that hasn't been downloaded yet
// and leaves out all other parts. By default, to generate a normal message, partNum should be NULL.
XP_Bool GetShowAttachmentsInline(); // Returns TRUE if the user has the pref "Show Attachments Inline" set.
// Returns FALSE if the setting is "Show Attachments as Links"
XP_Bool PreflightCheckAllInline(); // Returns TRUE if all parts are inline, FALSE otherwise. Does not generate anything.
// Helpers
TNavigatorImapConnection *GetConnection() { return m_connection; }
XP_Bool GetPseudoInterrupted();
XP_Bool DeathSignalReceived();
const char *GetUID() { return m_UID; }
const char *GetFolderName() { return m_folderName; }
char *GetGeneratingPart() { return m_generatingPart; }
XP_Bool IsBeingGenerated() { return m_isBeingGenerated; } // Returns TRUE if this is in the process of being
// generated, so we don't re-enter
XP_Bool IsShellCached() { return m_cached; }
void SetIsCached(XP_Bool isCached) { m_cached = isCached; }
XP_Bool GetGeneratingWholeMessage() { return m_generatingWholeMessage; }
protected:
TIMAPBodypartMessage *m_message;
TIMAPMessagePartIDArray *m_prefetchQueue; // array of pipelined part prefetches. Ok, so it's not really a queue.
XP_Bool m_isValid;
TNavigatorImapConnection *m_connection; // Connection, for filling in parts
char *m_UID; // UID of this message
char *m_folderName; // folder that contains this message
char *m_generatingPart; // If a specific part is being generated, this is it. Otherwise, NULL.
XP_Bool m_isBeingGenerated; // TRUE if this body shell is in the process of being generated
XP_Bool m_showAttachmentsInline;
XP_Bool m_gotAttachmentPref;
XP_Bool m_cached; // Whether or not this shell is cached
XP_Bool m_generatingWholeMessage; // whether or not we are generating the whole (non-MPOD) message
// Set to FALSE if we are generating by parts
};
// This class caches shells, so we don't have to always go and re-fetch them.
// This does not cache any of the filled-in inline parts; those are cached individually
// in the libnet memory cache. (ugh, how will we do that?)
// Since we'll only be retrieving shells for messages over a given size, and since the
// shells themselves won't be very large, this cache will not grow very big (relatively)
// and should handle most common usage scenarios.
// A body cache is associated with a given host, spanning folders.
// It should pay attention to UIDVALIDITY.
class TIMAPBodyShellCache
{
public:
static TIMAPBodyShellCache *Create();
virtual ~TIMAPBodyShellCache();
XP_Bool AddShellToCache(TIMAPBodyShell *shell); // Adds shell to cache, possibly ejecting
// another entry based on scheme in EjectEntry().
TIMAPBodyShell *FindShellForUID(const char *UID, const char *mailboxName); // Looks up a shell in the cache given the message's UID.
TIMAPBodyShell *FindShellForUID(uint32 UID, const char *mailboxName); // Looks up a shell in the cache given the message's UID.
// Returns the shell if found, NULL if not found.
protected:
TIMAPBodyShellCache();
XP_Bool EjectEntry(); // Chooses an entry to eject; deletes that entry; and ejects it from the cache,
// clearing up a new space. Returns TRUE if it found an entry to eject, FALSE otherwise.
uint32 GetSize() { return m_shellList->GetSize(); }
uint32 GetMaxSize() { return 20; }
protected:
XPPtrArray *m_shellList; // For maintenance
XP_HashTable m_shellHash; // For quick lookup based on UID
};
// MessagePartID and MessagePartIDArray are used for pipelining prefetches.
class TIMAPMessagePartID
{
public:
TIMAPMessagePartID(TIMAP4BlockingConnection::eFetchFields fields, const char *partNumberString);
TIMAP4BlockingConnection::eFetchFields GetFields() { return m_fields; }
const char *GetPartNumberString() { return m_partNumberString; }
protected:
const char *m_partNumberString;
TIMAP4BlockingConnection::eFetchFields m_fields;
};
class TIMAPMessagePartIDArray : public XPPtrArray {
public:
TIMAPMessagePartIDArray();
~TIMAPMessagePartIDArray();
void RemoveAndFreeAll();
int GetNumParts() {return GetSize();}
TIMAPMessagePartID *GetPart(int i)
{
XP_ASSERT(i >= 0 && i < GetSize());
return (TIMAPMessagePartID *) GetAt(i);
}
};
#endif // IMAPBODY_H

View File

@@ -0,0 +1,677 @@
/* -*- 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.
*/
#include "mkutils.h"
#include "imap.h"
#include "imap4pvt.h"
#define ISHEX(c) ( ((c) >= '0' && (c) <= '9') || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F') )
#define NONHEX(c) (!ISHEX(c))
extern "C" char * escape_unescaped_percents(const char *incomingURL);
extern "C"
{
char * escape_unescaped_percents(const char *incomingURL)
{
const char *inC;
char *outC;
char *result = (char *) XP_ALLOC(XP_STRLEN(incomingURL)*3+1);
if (result)
{
for(inC = incomingURL, outC = result; *inC != '\0'; inC++)
{
if (*inC == '%')
{
// Check if either of the next two characters are non-hex.
if ( !*(inC+1) || NONHEX(*(inC+1)) || !*(inC+2) || NONHEX(*(inC+2)) )
{
// Hex characters don't follow, escape the
// percent char
*outC++ = '%'; *outC++ = '2'; *outC++ = '5';
}
else
{
// Hex characters follow, so assume the percent
// is escaping something else
*outC++ = *inC;
}
}
else
*outC++ = *inC;
}
*outC = '\0';
}
return result;
}
}
// member functions of the TIMAPUrl class
TIMAPUrl::TIMAPUrl(const char *url_string, XP_Bool internal)
: fHostSubString(nil),
fUrlidSubString(nil),
fSourceCanonicalFolderPathSubString(nil),
fDestinationCanonicalFolderPathSubString(nil),
fSearchCriteriaString(nil),
fListOfMessageIds(nil),
fTokenPlaceHolder(nil),
fFlags(0),
fIdsAreUids(FALSE),
fIMAPstate(kAuthenticatedStateURL),
fUrlType(kTest),
fValidURL(FALSE),
fMimePartSelectorDetected(FALSE),
fInternal(internal),
fDiscoveryDepth(0)
{
fOnlineSubDirSeparator = '/'; // initial guess
fUrlString = escape_unescaped_percents(url_string); // this duplicates url_string
fUrlString = NET_UnEscape(fUrlString); // ### mwelch - Put spaces and '>'s back in.
Parse();
}
TIMAPUrl::~TIMAPUrl()
{
FREEIF( fUrlString);
}
void TIMAPUrl::ParseFolderPath(char **resultingCanonicalPath)
{
*resultingCanonicalPath = fTokenPlaceHolder ? XP_STRTOK_R(nil, IMAP_URL_TOKEN_SEPARATOR, &fTokenPlaceHolder) : (char *)NULL;
if (!*resultingCanonicalPath)
{
fValidURL = FALSE;
return;
}
// The delimiter will be set for a given URL, but will not be statically available
// from an arbitrary URL. It is the creator's responsibility to fill in the correct
// delimiter from the folder's namespace when creating the URL.
char dirSeparator = *(*resultingCanonicalPath)++;
if (dirSeparator != kOnlineHierarchySeparatorUnknown)
SetOnlineSubDirSeparator( dirSeparator);
// if dirSeparator == kOnlineHierarchySeparatorUnknown, then this must be a create
// of a top level imap box. If there is an online subdir, we will automatically
// use its separator. If there is not an online subdir, we don't need a separator.
/*
// I don't think we want to do any of this anymore (for 5.0).
const char *hostDir = TIMAPHostInfo::GetPersonalOrDefaultOnlineSubDirForHost(GetUrlHost());
if (!hostDir)
{
// couldn't find the host in our list
fValidURL = FALSE;
return;
}
int lengthOfImapSubDirString = XP_STRLEN(hostDir);
if (*resultingCanonicalPath &&
((lengthOfImapSubDirString + XP_STRLEN("INBOX")) == XP_STRLEN(*resultingCanonicalPath)) &&
!XP_STRCASECMP("INBOX", *resultingCanonicalPath + lengthOfImapSubDirString))
{
// this is the inbox
*resultingCanonicalPath = "INBOX";
}
*/
}
void TIMAPUrl::ParseSearchCriteriaString()
{
fSearchCriteriaString = fTokenPlaceHolder ? XP_STRTOK_R(nil, IMAP_URL_TOKEN_SEPARATOR, &fTokenPlaceHolder) : (char *)NULL;
if (!fSearchCriteriaString)
fValidURL = FALSE;
}
void TIMAPUrl::ParseChildDiscoveryDepth()
{
char *discoveryDepth = fTokenPlaceHolder ? XP_STRTOK_R(nil, IMAP_URL_TOKEN_SEPARATOR, &fTokenPlaceHolder) : (char *)NULL;
if (!discoveryDepth)
{
fValidURL = FALSE;
fDiscoveryDepth = 0;
return;
}
fDiscoveryDepth = atoi(discoveryDepth);
}
void TIMAPUrl::ParseUidChoice()
{
char *uidChoiceString = fTokenPlaceHolder ? XP_STRTOK_R(nil, IMAP_URL_TOKEN_SEPARATOR, &fTokenPlaceHolder) : (char *)NULL;
if (!uidChoiceString)
fValidURL = FALSE;
else
fIdsAreUids = XP_STRCMP(uidChoiceString, "UID") == 0;
}
void TIMAPUrl::ParseMsgFlags()
{
char *flagsPtr = fTokenPlaceHolder ? XP_STRTOK_R(nil, IMAP_URL_TOKEN_SEPARATOR, &fTokenPlaceHolder) : (char *)NULL;
if (flagsPtr)
{
// the url is encodes the flags byte as ascii
int intFlags = atoi(flagsPtr);
fFlags = (imapMessageFlagsType) intFlags; // cast here
}
else
fFlags = 0;
}
void TIMAPUrl::ParseListofMessageIds()
{
fListOfMessageIds = fTokenPlaceHolder ? XP_STRTOK_R(nil, IMAP_URL_TOKEN_SEPARATOR, &fTokenPlaceHolder) : (char *)NULL;
if (!fListOfMessageIds)
fValidURL = FALSE;
else
{
fMimePartSelectorDetected = XP_STRSTR(fListOfMessageIds, "&part=") != 0;
}
}
void TIMAPUrl::Parse()
{
fValidURL = TRUE; // hope for the best
// first token separator is a "?" so others can grab the host
char *urlStartToken = XP_STRTOK_R(fUrlString, "?", &fTokenPlaceHolder);
if (!XP_STRNCASECMP(urlStartToken, "IMAP://",7) )
{
fHostSubString = urlStartToken + 7;
fUrlidSubString = fTokenPlaceHolder ? XP_STRTOK_R(nil, IMAP_URL_TOKEN_SEPARATOR, &fTokenPlaceHolder) : (char *)NULL;
if (!fUrlidSubString)
{
fValidURL = FALSE;
return;
}
if (!XP_STRCASECMP(fUrlidSubString, "fetch"))
{
fIMAPstate = kSelectedStateURL;
fUrlType = kMsgFetch;
ParseUidChoice();
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
ParseListofMessageIds();
}
else if (fInternal)
{
if (!XP_STRCASECMP(fUrlidSubString, "header"))
{
fIMAPstate = kSelectedStateURL;
fUrlType = kMsgHeader;
ParseUidChoice();
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
ParseListofMessageIds();
}
else if (!XP_STRCASECMP(fUrlidSubString, "deletemsg"))
{
fIMAPstate = kSelectedStateURL;
fUrlType = kDeleteMsg;
ParseUidChoice();
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
ParseListofMessageIds();
}
else if (!XP_STRCASECMP(fUrlidSubString, "deleteallmsgs"))
{
fIMAPstate = kSelectedStateURL;
fUrlType = kDeleteAllMsgs;
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
}
else if (!XP_STRCASECMP(fUrlidSubString, "addmsgflags"))
{
fIMAPstate = kSelectedStateURL;
fUrlType = kAddMsgFlags;
ParseUidChoice();
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
ParseListofMessageIds();
ParseMsgFlags();
}
else if (!XP_STRCASECMP(fUrlidSubString, "subtractmsgflags"))
{
fIMAPstate = kSelectedStateURL;
fUrlType = kSubtractMsgFlags;
ParseUidChoice();
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
ParseListofMessageIds();
ParseMsgFlags();
}
else if (!XP_STRCASECMP(fUrlidSubString, "setmsgflags"))
{
fIMAPstate = kSelectedStateURL;
fUrlType = kSetMsgFlags;
ParseUidChoice();
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
ParseListofMessageIds();
ParseMsgFlags();
}
else if (!XP_STRCASECMP(fUrlidSubString, "onlinecopy"))
{
fIMAPstate = kSelectedStateURL;
fUrlType = kOnlineCopy;
ParseUidChoice();
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
ParseListofMessageIds();
ParseFolderPath(&fDestinationCanonicalFolderPathSubString);
}
else if (!XP_STRCASECMP(fUrlidSubString, "onlinemove"))
{
fIMAPstate = kSelectedStateURL;
fUrlType = kOnlineMove;
ParseUidChoice();
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
ParseListofMessageIds();
ParseFolderPath(&fDestinationCanonicalFolderPathSubString);
}
else if (!XP_STRCASECMP(fUrlidSubString, "onlinetoofflinecopy"))
{
fIMAPstate = kSelectedStateURL;
fUrlType = kOnlineToOfflineCopy;
ParseUidChoice();
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
ParseListofMessageIds();
ParseFolderPath(&fDestinationCanonicalFolderPathSubString);
}
else if (!XP_STRCASECMP(fUrlidSubString, "onlinetoofflinemove"))
{
fIMAPstate = kSelectedStateURL;
fUrlType = kOnlineToOfflineMove;
ParseUidChoice();
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
ParseListofMessageIds();
ParseFolderPath(&fDestinationCanonicalFolderPathSubString);
}
else if (!XP_STRCASECMP(fUrlidSubString, "offlinetoonlinecopy"))
{
fIMAPstate = kAuthenticatedStateURL;
fUrlType = kOfflineToOnlineMove;
ParseFolderPath(&fDestinationCanonicalFolderPathSubString);
}
else if (!XP_STRCASECMP(fUrlidSubString, "search"))
{
fIMAPstate = kSelectedStateURL;
fUrlType = kSearch;
ParseUidChoice();
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
ParseSearchCriteriaString();
}
else if (!XP_STRCASECMP(fUrlidSubString, "test"))
{
fIMAPstate = kAuthenticatedStateURL;
fUrlType = kTest;
}
else if (!XP_STRCASECMP(fUrlidSubString, "select"))
{
fIMAPstate = kSelectedStateURL;
fUrlType = kSelectFolder;
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
if (fTokenPlaceHolder && *fTokenPlaceHolder)
ParseListofMessageIds();
else
fListOfMessageIds = "";
}
else if (!XP_STRCASECMP(fUrlidSubString, "liteselect"))
{
fIMAPstate = kSelectedStateURL;
fUrlType = kLiteSelectFolder;
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
}
else if (!XP_STRCASECMP(fUrlidSubString, "expunge"))
{
fIMAPstate = kSelectedStateURL;
fUrlType = kExpungeFolder;
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
fListOfMessageIds = ""; // no ids to UNDO
}
else if (!XP_STRCASECMP(fUrlidSubString, "create"))
{
fIMAPstate = kAuthenticatedStateURL;
fUrlType = kCreateFolder;
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
}
else if (!XP_STRCASECMP(fUrlidSubString, "discoverchildren"))
{
fIMAPstate = kAuthenticatedStateURL;
fUrlType = kDiscoverChildrenUrl;
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
}
else if (!XP_STRCASECMP(fUrlidSubString, "discoverlevelchildren"))
{
fIMAPstate = kAuthenticatedStateURL;
fUrlType = kDiscoverLevelChildrenUrl;
ParseChildDiscoveryDepth();
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
}
else if (!XP_STRCASECMP(fUrlidSubString, "discoverallboxes"))
{
fIMAPstate = kAuthenticatedStateURL;
fUrlType = kDiscoverAllBoxesUrl;
}
else if (!XP_STRCASECMP(fUrlidSubString, "discoverallandsubscribedboxes"))
{
fIMAPstate = kAuthenticatedStateURL;
fUrlType = kDiscoverAllAndSubscribedBoxesUrl;
}
else if (!XP_STRCASECMP(fUrlidSubString, "delete"))
{
fIMAPstate = kAuthenticatedStateURL;
fUrlType = kDeleteFolder;
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
}
else if (!XP_STRCASECMP(fUrlidSubString, "rename"))
{
fIMAPstate = kAuthenticatedStateURL;
fUrlType = kRenameFolder;
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
ParseFolderPath(&fDestinationCanonicalFolderPathSubString);
}
else if (!XP_STRCASECMP(fUrlidSubString, "movefolderhierarchy"))
{
fIMAPstate = kAuthenticatedStateURL;
fUrlType = kMoveFolderHierarchy;
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
if (fTokenPlaceHolder && *fTokenPlaceHolder) // handle promote to root
ParseFolderPath(&fDestinationCanonicalFolderPathSubString);
}
else if (!XP_STRCASECMP(fUrlidSubString, "list"))
{
fIMAPstate = kAuthenticatedStateURL;
fUrlType = kLsubFolders;
ParseFolderPath(&fDestinationCanonicalFolderPathSubString);
}
else if (!XP_STRCASECMP(fUrlidSubString, "biff"))
{
fIMAPstate = kSelectedStateURL;
fUrlType = kBiff;
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
ParseListofMessageIds();
}
else if (!XP_STRCASECMP(fUrlidSubString, "netscape"))
{
fIMAPstate = kAuthenticatedStateURL;
fUrlType = kGetMailAccountUrl;
}
else if (!XP_STRCASECMP(fUrlidSubString, "appendmsgfromfile"))
{
fIMAPstate = kAuthenticatedStateURL;
fUrlType = kAppendMsgFromFile;
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
}
else if (!XP_STRCASECMP(fUrlidSubString, "appenddraftfromfile"))
{
fIMAPstate = kSelectedStateURL;
fUrlType = kAppendMsgFromFile;
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
}
else if (!XP_STRCASECMP(fUrlidSubString, "subscribe"))
{
fIMAPstate = kAuthenticatedStateURL;
fUrlType = kSubscribe;
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
}
else if (!XP_STRCASECMP(fUrlidSubString, "unsubscribe"))
{
fIMAPstate = kAuthenticatedStateURL;
fUrlType = kUnsubscribe;
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
}
else if (!XP_STRCASECMP(fUrlidSubString, "refreshacl"))
{
fIMAPstate = kAuthenticatedStateURL;
fUrlType = kRefreshACL;
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
}
else if (!XP_STRCASECMP(fUrlidSubString, "refreshfolderurls"))
{
fIMAPstate = kAuthenticatedStateURL;
fUrlType = kRefreshFolderUrls;
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
}
else if (!XP_STRCASECMP(fUrlidSubString, "refreshallacls"))
{
fIMAPstate = kAuthenticatedStateURL;
fUrlType = kRefreshAllACLs;
}
else if (!XP_STRCASECMP(fUrlidSubString, "listfolder"))
{
fIMAPstate = kAuthenticatedStateURL;
fUrlType = kListFolder;
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
}
else if (!XP_STRCASECMP(fUrlidSubString, "upgradetosubscription"))
{
fIMAPstate = kAuthenticatedStateURL;
fUrlType = kUpgradeToSubscription;
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
}
else if (!XP_STRCASECMP(fUrlidSubString, "folderstatus"))
{
fIMAPstate = kAuthenticatedStateURL;
fUrlType = kFolderStatus;
ParseFolderPath(&fSourceCanonicalFolderPathSubString);
}
else
fValidURL = FALSE;
}
else fValidURL = FALSE;
}
else
fValidURL = FALSE;
}
TIMAPUrl::EUrlIMAPstate TIMAPUrl::GetUrlIMAPstate()
{
return fIMAPstate;
}
TIMAPUrl::EIMAPurlType TIMAPUrl::GetIMAPurlType()
{
return fUrlType;
}
char *TIMAPUrl::CreateCanonicalSourceFolderPathString()
{
return XP_STRDUP(fSourceCanonicalFolderPathSubString ? fSourceCanonicalFolderPathSubString : "");
}
char *TIMAPUrl::CreateCanonicalDestinationFolderPathString()
{
return XP_STRDUP(fDestinationCanonicalFolderPathSubString);
}
char *TIMAPUrl::CreateServerSourceFolderPathString()
{
return AllocateServerPath(fSourceCanonicalFolderPathSubString);
}
char *TIMAPUrl::CreateServerDestinationFolderPathString()
{
// its possible for the destination folder path to be the root
if (!fDestinationCanonicalFolderPathSubString)
return XP_STRDUP("");
else
return AllocateServerPath(fDestinationCanonicalFolderPathSubString);
}
char *TIMAPUrl::CreateSearchCriteriaString()
{
return XP_STRDUP(fSearchCriteriaString);
}
char *TIMAPUrl::CreateListOfMessageIdsString()
{
char *returnIdString = XP_STRDUP(fListOfMessageIds);
if (returnIdString)
{
// mime may have glommed a "&part=" for a part download
// we return the entire message and let mime extract
// the part. Pop and news work this way also.
// this algorithm truncates the "&part" string.
char *currentChar = returnIdString;
while (*currentChar && (*currentChar != '&'))
currentChar++;
if (*currentChar == '&')
*currentChar = 0;
// we should also strip off anything after "/;section="
// since that can specify an IMAP MIME part
char *wherepart = XP_STRSTR(returnIdString, "/;section=");
if (wherepart)
*wherepart = 0;
}
return returnIdString;
}
char *TIMAPUrl::GetIMAPPartToFetch()
{
char *wherepart = NULL, *rv = NULL;
if (fListOfMessageIds && (wherepart = XP_STRSTR(fListOfMessageIds, "/;section=")) != NULL)
{
wherepart += 10; // XP_STRLEN("/;section=")
if (wherepart)
{
char *wherelibmimepart = XP_STRSTR(wherepart, "&part=");
int len = XP_STRLEN(fListOfMessageIds), numCharsToCopy = 0;
if (wherelibmimepart)
numCharsToCopy = (wherelibmimepart - wherepart);
else
numCharsToCopy = XP_STRLEN(fListOfMessageIds) - (wherepart - fListOfMessageIds);
if (numCharsToCopy)
{
rv = (char *) XP_ALLOC(sizeof(char) * (numCharsToCopy + 1));
if (rv)
XP_STRNCPY_SAFE(rv, wherepart, numCharsToCopy + 1); // appends a \0
}
}
}
return rv;
}
imapMessageFlagsType TIMAPUrl::GetMsgFlags() // kAddMsgFlags or kSubtractMsgFlags only
{
return fFlags;
}
XP_Bool TIMAPUrl::ValidIMAPUrl()
{
return fValidURL;
}
XP_Bool TIMAPUrl::MessageIdsAreUids()
{
return fIdsAreUids;
}
char *TIMAPUrl::AllocateServerPath(const char *canonicalPath)
{
XP_ASSERT(GetOnlineSubDirSeparator() != kOnlineHierarchySeparatorUnknown);
return ReplaceCharsInCopiedString(canonicalPath, '/', GetOnlineSubDirSeparator());
}
char *TIMAPUrl::AllocateCanonicalPath(const char *serverPath)
{
char *canonicalPath = ReplaceCharsInCopiedString(serverPath, GetOnlineSubDirSeparator() , '/');
// eat any escape characters for escaped dir separators
if (canonicalPath)
{
char *currentEscapeSequence = XP_STRSTR(canonicalPath, "\\/");
while (currentEscapeSequence)
{
XP_STRCPY(currentEscapeSequence, currentEscapeSequence+1);
currentEscapeSequence = XP_STRSTR(currentEscapeSequence+1, "\\/");
}
}
return canonicalPath;
}
char *TIMAPUrl::ReplaceCharsInCopiedString(const char *stringToCopy, char oldChar, char newChar)
{
char oldCharString[2];
*oldCharString = oldChar;
*(oldCharString+1) = 0;
char *translatedString = XP_STRDUP(stringToCopy);
char *currentSeparator = strstr(translatedString, oldCharString);
while(currentSeparator)
{
*currentSeparator = newChar;
currentSeparator = strstr(currentSeparator+1, oldCharString);
}
return translatedString;
}
void TIMAPUrl::SetOnlineSubDirSeparator(char onlineDirSeparator)
{
fOnlineSubDirSeparator = onlineDirSeparator;
}
char TIMAPUrl::GetOnlineSubDirSeparator()
{
return fOnlineSubDirSeparator;
}
XP_Bool TIMAPUrl::GetShouldSubscribeToAll()
{
return (GetOnlineSubDirSeparator() == '.');
}
#if 0
// According to the comment in imap.h, where the prototype lives and has been commented out,
// this is obsolete. So let's get rid of the "no prototype" warning.
extern "C" {
void
IMAP_SetNamespacesFromPrefs(const char *hostName, char *personalPrefix, char *publicPrefixes, char *otherUsersPrefixes)
{
TIMAPHostInfo::ClearPrefsNamespacesForHost(hostName);
if (XP_STRCMP(personalPrefix,""))
{
TIMAPNamespace *ns = new TIMAPNamespace(kPersonalNamespace, personalPrefix, '/', TRUE);
if (ns)
TIMAPHostInfo::AddNewNamespaceForHost(hostName, ns);
}
if (XP_STRCMP(publicPrefixes,""))
{
TIMAPNamespace *ns = new TIMAPNamespace(kPublicNamespace, publicPrefixes, '/', TRUE);
if (ns)
TIMAPHostInfo::AddNewNamespaceForHost(hostName, ns);
}
if (XP_STRCMP(otherUsersPrefixes,""))
{
TIMAPNamespace *ns = new TIMAPNamespace(kOtherUsersNamespace, otherUsersPrefixes, '/', TRUE);
if (ns)
TIMAPHostInfo::AddNewNamespaceForHost(hostName, ns);
}
}
} // extern "C"
#endif // 0

View File

@@ -0,0 +1,203 @@
/* -*- 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.
*/
#include "mkutils.h"
#include "imaphier.h"
#include "imap4pvt.h"
#include "imap.h"
ImapHierarchyMover::ImapHierarchyMover(
const char *destinationNodeName,
const char *sourceNodeName,
TNavigatorImapConnection &connection)
: fIMAPConnection(connection)
{
fDestinationNodeName = XP_STRDUP(destinationNodeName);
fSourceNodeName = XP_STRDUP(sourceNodeName);
fMailboxHierarchy = XP_ListNew();
}
ImapHierarchyMover::~ImapHierarchyMover()
{
// this is a leak, delete the structs
if (fMailboxHierarchy)
XP_ListDestroy(fMailboxHierarchy);
FREEIF(fDestinationNodeName);
FREEIF(fSourceNodeName);
}
void ImapHierarchyMover::AddToHierarchy(const char *nodeName)
{
int stringLength = XP_STRLEN(nodeName);
char *nodeTokens = new char [stringLength + 2]; // end the string in double null so AddToSubTree
XP_STRCPY(nodeTokens, nodeName); // will work
*(nodeTokens + stringLength) = 0;
*(nodeTokens + stringLength+1) = 0;
AddToSubTree(nodeTokens, nodeName, fMailboxHierarchy);
delete nodeTokens;
}
void ImapHierarchyMover::AddToSubTree(char *nodeTokens, const char *nodeName, XP_List *subTree)
{
char *positionOfNodeTokens = XP_STRSTR(nodeName, nodeTokens);
// make sure we find the last one
char *currentPositionOfNodeTokens = positionOfNodeTokens;
while (currentPositionOfNodeTokens && strlen(nodeTokens))
{
currentPositionOfNodeTokens = XP_STRSTR(currentPositionOfNodeTokens + 1, nodeTokens);
if (currentPositionOfNodeTokens)
positionOfNodeTokens = currentPositionOfNodeTokens;
}
char *placeHolderInTokenString = nil;
char *currentNodeToken = XP_STRTOK_R(nodeTokens, "/",&placeHolderInTokenString);
if (currentNodeToken)
{
// find the current node, if it exists
HierarchyNode *currentNode = NULL;
int numberOfNodes = XP_ListCount(subTree);
XP_Bool nodeFound = FALSE;
while (numberOfNodes && !nodeFound)
{
currentNode = (HierarchyNode *) XP_ListGetObjectNum(subTree, numberOfNodes--);
nodeFound = XP_STRCMP(currentNode->fNodeToken, currentNodeToken) == 0;
}
if (!nodeFound)
{
// create the node
currentNode = (HierarchyNode *) XP_ALLOC(sizeof(HierarchyNode));
if (currentNode)
{
currentNode->fPresentName = XP_STRDUP(nodeName);
// less the remaining tokens
*(currentNode->fPresentName + (positionOfNodeTokens-nodeName) + XP_STRLEN(currentNodeToken)) = 0;
currentNode->fNodeToken = XP_STRDUP(currentNodeToken);
currentNode->fSubFolders = XP_ListNew();
XP_ListAddObjectToEnd(subTree, currentNode);
}
}
// recurse!
char *subNodeTokens = nodeTokens + XP_STRLEN(currentNodeToken) + 1; // +1 see note in AddToHierarchy
AddToSubTree(subNodeTokens, nodeName, currentNode->fSubFolders);
}
}
// depth first, post process unsubscribe and delete everything including and below source node name
void ImapHierarchyMover::DestroyOldFolderTree(XP_List *subTree)
{
int numberOfNodesAtThisLevel = XP_ListCount(subTree);
for (int nodeIndex=numberOfNodesAtThisLevel; nodeIndex > 0; nodeIndex--)
{
HierarchyNode *currentNode = (HierarchyNode *) XP_ListGetObjectNum(subTree, nodeIndex);
DestroyOldFolderTree(currentNode->fSubFolders);
if (fIMAPConnection.GetServerStateParser().LastCommandSuccessful() &&
XP_STRSTR(currentNode->fPresentName, fSourceNodeName))
{
fIMAPConnection.Unsubscribe(currentNode->fPresentName);
if (fIMAPConnection.GetServerStateParser().LastCommandSuccessful())
fIMAPConnection.DeleteMailbox(currentNode->fPresentName);
}
}
}
// depth first, pre-process create, subscribe, and fill with messages
void ImapHierarchyMover::CreateNewFolderTree(const char *destinationNodeName, XP_List *subTree)
{
int numberOfNodesAtThisLevel = XP_ListCount(subTree);
for (int nodeIndex=1; nodeIndex <= numberOfNodesAtThisLevel; nodeIndex++)
{
HierarchyNode *currentNode = (HierarchyNode *) XP_ListGetObjectNum(subTree, nodeIndex);
if (!XP_STRSTR(fSourceNodeName, currentNode->fPresentName) ||
!XP_STRCMP(fSourceNodeName, currentNode->fPresentName)) // if we are not yet at the node name, don't rename
{
char *newNodeName = (char *) XP_ALLOC(XP_STRLEN(destinationNodeName) +
XP_STRLEN(currentNode->fNodeToken) + 2);
XP_STRCPY(newNodeName, destinationNodeName);
XP_STRCAT(newNodeName, "/");
XP_STRCAT(newNodeName, currentNode->fNodeToken);
fIMAPConnection.CreateMailbox(newNodeName);
if (fIMAPConnection.GetServerStateParser().LastCommandSuccessful())
{
fIMAPConnection.Subscribe(newNodeName);
if (fIMAPConnection.GetServerStateParser().LastCommandSuccessful())
{
// close the current folder if one is selected
if (fIMAPConnection.GetServerStateParser().GetIMAPstate() ==
TImapServerState::kFolderSelected)
fIMAPConnection.Close();
// select the old folder
fIMAPConnection.SelectMailbox(currentNode->fPresentName);
if (fIMAPConnection.GetServerStateParser().LastCommandSuccessful())
{
// copy its entire contents to the destination
int numOfMsgs = fIMAPConnection.GetServerStateParser().NumberOfMessages();
if (numOfMsgs)
{
char msgList[100]; // enough for trillions?
sprintf(msgList, "1:%d", numOfMsgs);
fIMAPConnection.Copy(msgList, newNodeName, FALSE); // not uids
}
if (fIMAPConnection.GetServerStateParser().LastCommandSuccessful())
fIMAPConnection.Close();
}
}
}
// recurse to my children
if (fIMAPConnection.GetServerStateParser().LastCommandSuccessful())
CreateNewFolderTree(newNodeName, currentNode->fSubFolders);
FREEIF( newNodeName);
}
else
CreateNewFolderTree(destinationNodeName, currentNode->fSubFolders);
}
}
int ImapHierarchyMover::DoMove()
{
int returnValue = 0;
CreateNewFolderTree(fDestinationNodeName, fMailboxHierarchy);
if (fIMAPConnection.GetServerStateParser().LastCommandSuccessful())
{
DestroyOldFolderTree(fMailboxHierarchy);
if (!fIMAPConnection.GetServerStateParser().LastCommandSuccessful())
returnValue = -1;
}
else
returnValue = -1;
return returnValue;
}

View File

@@ -0,0 +1,55 @@
/* -*- 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.
*/
#ifndef IMAPHIER
#define IMAPHIER
#include "xp_list.h"
class TNavigatorImapConnection;
struct HierarchyNode {
char *fPresentName;
char *fNodeToken; // leaf name of node
XP_List *fSubFolders;
};
class ImapHierarchyMover {
public:
ImapHierarchyMover(const char *destinationNodeName,
const char *sourceNodeName,
TNavigatorImapConnection &connection);
virtual ~ImapHierarchyMover();
virtual void AddToHierarchy(const char *nodeName);
virtual int DoMove();
protected:
virtual void AddToSubTree(char *nodeTokens, const char *nodeName, XP_List *subTree);
virtual void CreateNewFolderTree(const char *destinationNodeName, XP_List *subTree);
virtual void DestroyOldFolderTree(XP_List *subTree);
private:
XP_List *fMailboxHierarchy;
TNavigatorImapConnection &fIMAPConnection;
char *fDestinationNodeName;
char *fSourceNodeName;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,303 @@
/* -*- 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.
*/
#include "mkutils.h" /* LF */
#include <time.h>
#include "jsautocf.h"
#include "xp_mem.h" /* XP_NEW_ZAP() */
#ifndef XP_MAC
#include <sys/types.h>
#endif
#include "libi18n.h"
#include "mkstream.h"
#include "mkgeturl.h"
#include "cvextcon.h"
#include "mkformat.h"
/* acharya: This file is obsolete and not used in this file.
#include "il.h"
*/
#include "mime.h"
#include "cvactive.h"
#include "gui.h"
#include "msgcom.h"
#include "xp_reg.h"
#if defined(XP_UNIX) || defined(XP_WIN32)
#include "prnetdb.h"
#else
#define PRHostEnt struct hostent
#endif
/*
* Private object for the proxy config loader stream.
*
*
*/
typedef struct _JSACF_Object {
MWContext * context;
int flag;
} JSACF_Object;
/*
* A struct for holding queued state.
*
* The state is saved when NET_GetURL() is called for the first time,
* and the Javascript autoconfig retrieve has to be started (and finished)
* before the first actual document can be loaded.
*
* A pre-exit function for the Javascript autoconfig URL restarts the
* original URL retrieve by calling NET_GetURL() again with the
* same parameters.
*
*/
typedef struct _JSACF_QueuedState {
URL_Struct * URL_s;
FO_Present_Types output_format;
MWContext * window_id;
Net_GetUrlExitFunc* exit_routine;
} JSACF_QueuedState;
PRIVATE Bool jsacf_loading = FALSE;
PRIVATE Bool jsacf_ok = FALSE;
PRIVATE char * jsacf_url = NULL;
PRIVATE char * jsacf_src_buf = NULL;
PRIVATE int jsacf_src_len = 0;
/*
* Saves out the proxy autoconfig file to disk, in case the server
* is down the next time.
*
* Returns 0 on success, -1 on failure.
*
*/
PRIVATE int jsacf_save_config(void)
{
XP_File fp;
int32 len = 0;
// TODO: jonm
if(!(fp = XP_FileOpen("", xpProxyConfig, XP_FILE_WRITE)))
return -1;
len = XP_FileWrite(jsacf_src_buf, jsacf_src_len, fp);
XP_FileClose(fp);
if (len != jsacf_src_len)
return -1;
return 0;
}
/*
* Reads the proxy autoconfig file from disk.
* This is called if the config server is not responding.
*
* returns 0 on success -1 on failure.
*
*/
PRIVATE int jsacf_read_config(void)
{
XP_StatStruct st;
XP_File fp;
if (XP_Stat("", &st, xpProxyConfig) == -1)
return -1;
if (!(fp = XP_FileOpen("", xpProxyConfig, XP_FILE_READ)))
return -1;
jsacf_src_len = st.st_size;
jsacf_src_buf = (char *)XP_ALLOC(jsacf_src_len + 1);
if (!jsacf_src_buf) {
XP_FileClose(fp);
jsacf_src_len = 0;
return -1;
}
if ((jsacf_src_len = XP_FileRead(jsacf_src_buf, jsacf_src_len, fp)) > 0)
{
jsacf_src_buf[jsacf_src_len] = '\0';
}
else
{
XP_FREE(jsacf_src_buf);
jsacf_src_buf = NULL;
jsacf_src_len = 0;
}
XP_FileClose(fp);
return 0;
}
/*
* Private stream object methods for receiving the proxy autoconfig
* file.
*
*
*/
PRIVATE int jsacf_write(NET_StreamClass *stream, CONST char *buf, int32 len)
{
JSACF_Object *obj=stream->data_object;
if (len > 0) {
if (!jsacf_src_buf)
jsacf_src_buf = (char*)XP_ALLOC(len + 1);
else
jsacf_src_buf = (char*)XP_REALLOC(jsacf_src_buf,
jsacf_src_len + len + 1);
if (!jsacf_src_buf) { /* Out of memory */
jsacf_src_len = 0;
return MK_DATA_LOADED;
}
XP_MEMCPY(jsacf_src_buf + jsacf_src_len, buf, len);
jsacf_src_len += len;
jsacf_src_buf[jsacf_src_len] = '\0';
}
return MK_DATA_LOADED;
}
PRIVATE unsigned int jsacf_write_ready(NET_StreamClass *stream)
{
return MAX_WRITE_READY;
}
extern int PREF_EvaluateJSBuffer(char * js_buffer, size_t length);
PRIVATE void jsacf_complete(NET_StreamClass *stream)
{
JSACF_Object *obj=stream->data_object;
int err = PREF_EvaluateJSBuffer(jsacf_src_buf,jsacf_src_len);
if (jsacf_src_buf) XP_FREE(jsacf_src_buf);
}
PRIVATE void jsacf_abort(NET_StreamClass *stream, int status)
{
JSACF_Object *obj=stream->data_object;
jsacf_loading = FALSE;
// FE_Alert(obj->context, CONFIG_LOAD_ABORTED);
XP_FREE(obj);
}
/*
* A stream constructor function for application/x-ns-proxy-autoconfig.
*
*
*
*/
MODULE_PRIVATE NET_StreamClass *
NET_JavaScriptAutoConfig(int fmt, void *data_obj, URL_Struct *URL_s, MWContext *w)
{
JSACF_Object *obj;
NET_StreamClass *stream;
#ifdef LATER
if (!jsacf_loading) {
/*
* The Navigator didn't start this config retrieve
* intentionally. Discarding the config.
*/
alert2(w, CONFIG_BLAST_WARNING, URL_s->address);
return NULL;
}
else {
NET_Progress(w, XP_GetString( XP_RECEIVING_PROXY_AUTOCFG ) );
}
#endif
if (jsacf_src_buf) {
XP_FREE(jsacf_src_buf);
jsacf_src_buf = NULL;
jsacf_src_len = 0;
}
if (!(stream = XP_NEW_ZAP(NET_StreamClass)))
return NULL;
if (!(obj = XP_NEW_ZAP(JSACF_Object))) {
XP_FREE(stream);
return NULL;
}
obj->context = w;
stream->data_object = obj;
stream->name = "JavaScriptAutoConfigLoader";
stream->complete = (MKStreamCompleteFunc) jsacf_complete;
stream->abort = (MKStreamAbortFunc) jsacf_abort;
stream->put_block = (MKStreamWriteFunc) jsacf_write;
stream->is_write_ready = (MKStreamWriteReadyFunc)jsacf_write_ready;
stream->window_id = w;
return stream;
}
void jsacf_exit_routine(URL_Struct *URL_s, int status, MWContext *window_id)
{}
PRIVATE void
simple_exit(URL_Struct *URL_s, int status, MWContext *window_id)
{
if(status != MK_CHANGING_CONTEXT)
NET_FreeURLStruct(URL_s);
}
/*
* Called by mkgeturl.c to originally retrieve, and re-retrieve
* the javascript autoconfig file.
*
* autoconfig_url is the URL pointing to the autoconfig.
*
*/
MODULE_PRIVATE int NET_LoadJavaScriptConfig(char *autoconf_url,MWContext *window_id)
{
URL_Struct *my_url_s = NULL;
if (!autoconf_url)
return -1;
StrAllocCopy(jsacf_url, autoconf_url);
my_url_s = NET_CreateURLStruct(autoconf_url, NET_SUPER_RELOAD);
/* Alert the proxy autoconfig module that config is coming */
jsacf_loading = TRUE;
return NET_GetURL(my_url_s, FO_CACHE_AND_JAVASCRIPT_CONFIG, window_id, simple_exit);
//return FE_GetURL(window_id, my_url_s);
}
/*
* Returns a pointer to a NULL-terminted buffer which contains
* the text of the proxy autoconfig file.
*
*
*/
PUBLIC char * NET_GetJavaScriptConfigSource(void)
{
return jsacf_src_buf;
}

View File

@@ -0,0 +1,41 @@
/* -*- 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.
*/
/*
* jsautocf.h: JavaScript auto-config parser and evaluator
*/
#ifndef MK_JAVASCRIPT_AUTO_CONFIG
#define MK_JAVASCRIPT_AUTO_CONFIG
#include "xp_mcom.h"
#include "xp.h"
/*
* A stream constructor function for application/x-ns-javascript-autoconfig.
*
*
*
*/
MODULE_PRIVATE NET_StreamClass *
NET_JavaScriptAutoConfig(int fmt, void *data_obj, URL_Struct *URL_s, MWContext *w);
MODULE_PRIVATE int NET_LoadJavaScriptConfig(char *autoconf_url,MWContext *window_id);
#endif /* ! MK_JAVASCRIPT_AUTO_CONFIG */

View File

@@ -0,0 +1,604 @@
/* -*- Mode: C++; tab-width: 8; 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.
*/
/*
jscookie.c -- javascript reflection of cookies for filters.
Created: Frederick G.M. Roeber <roeber@netscape.com>, 12-Jul-97.
Adopted: Judson Valeski, 1997.
Large chunks of this were stolen from jsmsg.c.
*/
#include "mkutils.h"
#include "mkutils.h"
#include "mkparse.h"
#include "mkaccess.h"
#include "prefapi.h"
#include "jsapi.h"
#include "xp_core.h"
#include "xp_mcom.h"
#include "jscookie.h"
#include "ds.h"
#include "htmldlgs.h"
#include "xpgetstr.h"
extern int MK_ACCESS_JAVASCRIPT_COOKIE_FILTER;
static JSObject *filter_obj = NULL;
static JSContext *filter_context = NULL;
static JSBool error_reporter_installed = JS_FALSE;
static JSErrorReporter previous_error_reporter;
/* tells us when we should recompile the file. */
static JSBool need_compile = JS_TRUE;
/* This is the private instance data associated with a cookie */
typedef struct JSCookieData {
JSContext *js_context;
JSObject *js_object;
JSCFCookieData *data;
PRPackedBool property_changed, rejected, accepted, ask, decision_made;
} JSCookieData;
/* The properties of a cookie that we reflect */
enum cookie_slot {
COOKIE_PATH = -1,
COOKIE_DOMAIN = -2,
COOKIE_NAME = -3,
COOKIE_VALUE = -4,
COOKIE_EXPIRES = -5,
COOKIE_URL = -6,
COOKIE_IS_SECURE = -7,
COOKIE_IS_DOMAIN = -8,
COOKIE_PROMPT_PREF = -9,
COOKIE_PREF = -10
};
/*
* Should more of these be readonly? What does it mean for a cookie
* to de secure? -chouck
*/
static JSPropertySpec cookie_props[] = {
{ "path", COOKIE_PATH, JSPROP_ENUMERATE },
{ "domain", COOKIE_DOMAIN, JSPROP_ENUMERATE },
{ "name", COOKIE_NAME, JSPROP_ENUMERATE },
{ "value", COOKIE_VALUE, JSPROP_ENUMERATE },
{ "expires", COOKIE_EXPIRES, JSPROP_ENUMERATE },
{ "url", COOKIE_URL, JSPROP_ENUMERATE|JSPROP_READONLY },
{ "isSecure", COOKIE_IS_SECURE, JSPROP_ENUMERATE },
{ "isDomain", COOKIE_IS_DOMAIN, JSPROP_ENUMERATE },
{ "prompt", COOKIE_PROMPT_PREF, JSPROP_ENUMERATE|JSPROP_READONLY },
{ "preference", COOKIE_PREF, JSPROP_ENUMERATE|JSPROP_READONLY },
{ 0 }
};
PR_STATIC_CALLBACK(JSBool)
cookie_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
JSCookieData *data;
JSString *str;
jsint slot;
data = (JSCookieData *)JS_GetPrivate(cx, obj);
if (!data)
return JS_TRUE;
if (!JSVAL_IS_INT(id))
return JS_TRUE;
slot = JSVAL_TO_INT(id);
switch (slot) {
case COOKIE_PATH:
str = JS_NewStringCopyZ(cx, (const char *)data->data->path_from_header);
if( (JSString *)0 == str )
return JS_FALSE;
*vp = STRING_TO_JSVAL(str);
break;
case COOKIE_DOMAIN:
str = JS_NewStringCopyZ(cx, (const char *)data->data->host_from_header);
if( (JSString *)0 == str )
return JS_FALSE;
*vp = STRING_TO_JSVAL(str);
break;
case COOKIE_NAME:
str = JS_NewStringCopyZ(cx, (const char *)data->data->name_from_header);
if( (JSString *)0 == str )
return JS_FALSE;
*vp = STRING_TO_JSVAL(str);
break;
case COOKIE_VALUE:
str = JS_NewStringCopyZ(cx, (const char *)data->data->cookie_from_header);
if( (JSString *)0 == str )
return JS_FALSE;
*vp = STRING_TO_JSVAL(str);
break;
case COOKIE_EXPIRES:
*vp = INT_TO_JSVAL(data->data->expires);
break;
case COOKIE_URL:
str = JS_NewStringCopyZ(cx, (const char *)data->data->url);
if( (JSString *)0 == str )
return JS_FALSE;
*vp = STRING_TO_JSVAL(str);
break;
case COOKIE_IS_SECURE:
*vp = BOOLEAN_TO_JSVAL(data->data->secure);
break;
case COOKIE_IS_DOMAIN:
*vp = BOOLEAN_TO_JSVAL(data->data->domain);
break;
case COOKIE_PROMPT_PREF:
*vp = BOOLEAN_TO_JSVAL(data->data->prompt);
break;
case COOKIE_PREF:
*vp = INT_TO_JSVAL(data->data->preference);
break;
}
return JS_TRUE;
}
PR_STATIC_CALLBACK(JSBool)
cookie_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
JSCookieData *data;
jsint slot;
PRInt32 i;
JSBool b;
data = (JSCookieData *)JS_GetPrivate(cx, obj);
if (!data)
return JS_TRUE;
if (!JSVAL_IS_INT(id))
return JS_TRUE;
slot = JSVAL_TO_INT(id);
if (slot == COOKIE_PATH) {
data->data->path_from_header = JS_GetStringBytes(JSVAL_TO_STRING(*vp));
}
else if (slot == COOKIE_DOMAIN) {
data->data->host_from_header = JS_GetStringBytes(JSVAL_TO_STRING(*vp));
}
else if (slot == COOKIE_NAME) {
data->data->name_from_header = JS_GetStringBytes(JSVAL_TO_STRING(*vp));
}
else if (slot == COOKIE_VALUE) {
data->data->cookie_from_header = JS_GetStringBytes(JSVAL_TO_STRING(*vp));
}
else if (slot == COOKIE_EXPIRES) {
if( !JS_ValueToInt32(cx, *vp, (long *)&i) )
return JS_FALSE;
data->data->expires = i;
}
else if (slot == COOKIE_IS_SECURE) {
if( !JS_ValueToBoolean(cx, *vp, &b) )
return JS_FALSE;
data->data->secure = b;
}
else if (slot == COOKIE_IS_DOMAIN) {
if( !JS_ValueToBoolean(cx, *vp, &b) )
return JS_FALSE;
data->data->domain = b;
}
data->property_changed = TRUE;
return JS_TRUE;
}
PR_STATIC_CALLBACK(void)
cookie_finalize(JSContext *cx, JSObject *obj)
{
JSCookieData *cookie;
cookie = JS_GetPrivate(cx, obj);
FREEIF(cookie);
}
/* So we can possibly add functions "global" to filters... */
static JSClass global_class = {
"CookieFilters", 0 /* no private data */,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
};
static JSClass js_cookie_class = {
"Cookie", JSCLASS_HAS_PRIVATE,
JS_PropertyStub, JS_PropertyStub, cookie_getProperty, cookie_setProperty,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, cookie_finalize
};
/* cookie.accept() -- mark it okay */
PR_STATIC_CALLBACK(JSBool)
cookie_accept(JSContext *cx, JSObject *obj, uint argc, jsval *argv, jsval * rval)
{
JSCookieData *data;
if (!(data = (JSCookieData*)JS_GetInstancePrivate(cx, obj, &js_cookie_class, argv)))
return JS_FALSE;
data->accepted = TRUE;
data->rejected = FALSE;
data->ask = FALSE;
data->decision_made = TRUE;
return JS_TRUE;
}
/* cookie.reject() -- reject it out of hand */
PR_STATIC_CALLBACK(JSBool)
cookie_reject(JSContext *cx, JSObject *obj, uint argc, jsval *argv, jsval * rval)
{
JSCookieData *data;
if (!(data = (JSCookieData*)JS_GetInstancePrivate(cx, obj, &js_cookie_class, argv)))
return JS_FALSE;
data->accepted = FALSE;
data->rejected = TRUE;
data->ask = FALSE;
data->decision_made = TRUE;
return JS_TRUE;
}
/* cookie.ask() -- ask the luser, even if that pref is off */
PR_STATIC_CALLBACK(JSBool)
cookie_ask(JSContext *cx, JSObject *obj, uint argc, jsval *argv, jsval * rval)
{
JSCookieData *data;
if (!(data = (JSCookieData*)JS_GetInstancePrivate(cx, obj, &js_cookie_class, argv)))
return JS_FALSE;
data->accepted = FALSE;
data->rejected = FALSE;
data->ask = TRUE;
data->decision_made = TRUE;
return JS_TRUE;
}
/* cookie.confirm() -- pop up a confirmation box */
PR_STATIC_CALLBACK(JSBool)
cookie_confirm(JSContext *cx, JSObject *obj, uint argc, jsval *argv, jsval * rval)
{
JSCookieData *data;
JSString *str;
char *msg = (char *)0;
Bool result;
MWContext * context = XP_FindSomeContext();
if (argc < 1 || !context)
return JS_FALSE;
if (!(data = (JSCookieData*)JS_GetInstancePrivate(cx, obj, &js_cookie_class, argv)))
return JS_FALSE;
str = JS_ValueToString(cx, argv[0]);
if (!str)
return JS_FALSE;
StrAllocCopy(msg, XP_GetString(MK_ACCESS_JAVASCRIPT_COOKIE_FILTER));
StrAllocCat(msg, JS_GetStringBytes(str));
if (!msg)
return JS_FALSE;
result = FE_Confirm(context, msg);
FREEIF(msg);
*rval = BOOLEAN_TO_JSVAL(result);
return JS_TRUE;
}
#if DEBUG
/* trace() -- outputs spew to stderr. Actually, this (or something like it
that perhaps outputs to the same file that the rest of the filter logging code
writes to) would probably be very useful in the normal course of writing filters. */
PR_STATIC_CALLBACK(JSBool)
cookie_filter_trace(JSContext *cx, JSObject * obj, uint argc, jsval *argv, jsval * rval)
{
if (argc > 0)
{
JSString *str;
const char *trace_str;
if (!(str = JS_ValueToString(cx, argv[0])))
return JS_FALSE;
trace_str = JS_GetStringBytes(str);
if (*trace_str != '\0')
{
fprintf (stderr, "cookie filter trace: %s\n", trace_str);
}
return JS_TRUE;
}
return JS_FALSE;
}
#endif
static JSFunctionSpec cookie_methods[] = {
{ "accept", cookie_accept, 0 },
{ "reject", cookie_reject, 0 },
{ "ask", cookie_ask, 0 },
{ "confirm", cookie_confirm, 1 },
{ 0 }
};
static JSFunctionSpec filter_methods[] = {
#ifdef DEBUG
{ "trace", cookie_filter_trace, 1 },
#endif
{ 0 }
};
PRIVATE void
destroyJSCookieFilterStuff(void)
{
filter_obj = NULL;
}
/*
* This function used to take an MWContext and store it as the private data
* of the filter object. That is a no-no since the filter_obj is going to
* be around until the end of time but there is no guarentee that the
* context won't get free'd out from under us. The solution is to not
* hold onto any particular context but just call XP_FindSomeContext() or
* some derivative of it when we need to.
*/
PRIVATE JSContext *
initializeJSCookieFilterStuff()
{
/* Only bother initializing once */
if (filter_obj)
return filter_context;
/* If we can't get the mozilla-thread global context just bail */
PREF_GetConfigContext(&filter_context);
if (!filter_context)
return NULL;
/* create our "global" object. We make the message object a child of this */
filter_obj = JS_NewObject(filter_context, &global_class, NULL, NULL);
/* MLM - don't do JS_InitStandardClasses() twice */
if (!filter_obj
|| !JS_DefineFunctions(filter_context, filter_obj, filter_methods))
{
destroyJSCookieFilterStuff();
return NULL;
}
return filter_context;
}
PRIVATE JSObject *
newCookieObject(void)
{
JSObject *rv;
JSCookieData *cookie_data;
rv = JS_DefineObject(filter_context, filter_obj,
"cookie", &js_cookie_class,
NULL, JSPROP_ENUMERATE);
if( (JSObject *)0 == rv )
return (JSObject *)0;
cookie_data = XP_NEW_ZAP(JSCookieData);
if( (JSCookieData *)0 == cookie_data )
return (JSObject *)0;
if( !JS_SetPrivate(filter_context, rv, cookie_data)
|| !JS_DefineProperties(filter_context, rv, cookie_props)
|| !JS_DefineFunctions(filter_context, rv, cookie_methods)) {
return (JSObject *)0;
}
return rv;
}
PR_STATIC_CALLBACK(void)
jscookie_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
{
char *msg = NULL;
MWContext *context;
context = XP_FindSomeContext();
if(!context || !report)
return;
/*XXX: i18n-ise this */
msg = PR_sprintf_append(NULL,
"JavaScript Cookie Filter Error:\n"
"You will be prompted manually to accept or reject this cookie.\n"
"Filename: %s\n"
"Line #: %u\n"
"%s\n"
"%.*s\n",
report->filename,
report->lineno,
report->linebuf,
(int)(report->tokenptr - report->linebuf) + 1,
"^"
);
if (!msg)
return;
FE_Alert(context, msg);
XP_FREE(msg);
return;
}
PRIVATE JSBool
compileJSCookieFilters(void)
{
static time_t m_time = 0; /* the last modification time of filters.js */
static JSBool ret_val = JS_FALSE;
char *filename;
XP_File fp;
XP_StatStruct stats;
if (!need_compile)
return ret_val;
filename = WH_FileName("", xpJSCookieFilters);
XP_Trace("+Filename for script filter is %s\n", filename);
/* If we can't get to the file, get the hell outa dodge. */
if(XP_Stat(filename, &stats, xpJSCookieFilters))
return ret_val;
if (stats.st_mtime > m_time || need_compile)
{
long fileLength;
char *buffer;
jsval rval;
m_time = stats.st_mtime;
fileLength = stats.st_size;
if (fileLength <= 1)
{
ret_val = JS_FALSE;
return ret_val;
}
if( !(fp = XP_FileOpen(filename, xpJSCookieFilters, "r")) ) {
ret_val = JS_FALSE;
return ret_val;
}
buffer = (char*)malloc(fileLength);
if (!buffer) {
XP_FileClose(fp);
ret_val = JS_FALSE;
return ret_val;
}
fileLength = XP_FileRead(buffer, fileLength, fp);
XP_FileClose(fp);
XP_Trace("+Compiling filters.js...\n");
ret_val = JS_EvaluateScript(filter_context, filter_obj, buffer, fileLength,
filename, 1, &rval);
XP_Trace("+Done.\n");
XP_FREE(buffer);
need_compile = JS_FALSE;
}
return ret_val;
}
PUBLIC JSCFResult
JSCF_Execute(
MWContext *mwcontext,
const char *script_name,
JSCFCookieData *data,
Bool *data_changed
)
{
jsval result;
jsval filter_arg; /* we will this in with the message object we create. */
JSObject *cookie_obj;
JSCookieData *cookie_data;
if (!script_name)
return JSCF_error;
/* initialize the filter stuff, and bomb out early if it fails */
if (!initializeJSCookieFilterStuff())
return JSCF_error;
/*
* try loading (reloading if necessary) the filter file before bothering
* to create any JS-objects
*/
if (!compileJSCookieFilters())
return JSCF_error;
if (!error_reporter_installed)
{
error_reporter_installed = JS_TRUE;
previous_error_reporter = JS_SetErrorReporter(filter_context,
jscookie_ErrorReporter);
}
cookie_obj = newCookieObject();
if( (JSObject *)0 == cookie_obj )
return JSCF_error;
cookie_data = (JSCookieData *)JS_GetPrivate(filter_context, cookie_obj);
cookie_data->js_context = filter_context;
cookie_data->js_object = cookie_obj;
cookie_data->data = data;
cookie_data->property_changed = FALSE;
cookie_data->rejected = FALSE;
cookie_data->accepted = FALSE;
cookie_data->decision_made = FALSE;
filter_arg = OBJECT_TO_JSVAL(cookie_obj);
JS_CallFunctionName(filter_context, filter_obj, script_name, 1,
&filter_arg, &result);
*data_changed = cookie_data->property_changed;
if( cookie_data->decision_made ) {
if( cookie_data->rejected )
return JSCF_reject;
else if( cookie_data->accepted )
return JSCF_accept;
else if( cookie_data->ask )
return JSCF_ask;
}
return JSCF_whatever;
}
PUBLIC void
JSCF_Cleanup(void)
{
TRACEMSG(("+Cleaning up JS Cookie Filters"));
need_compile = JS_TRUE;
if (filter_context)
{
if (error_reporter_installed)
{
error_reporter_installed = JS_FALSE;
JS_SetErrorReporter(filter_context, previous_error_reporter);
}
JS_GC(filter_context);
destroyJSCookieFilterStuff();
}
}

View File

@@ -0,0 +1,62 @@
/* -*- 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.
*/
/*
jscookie.h -- javascript reflection of cookies for filters.
Created: Frederick G.M. Roeber <roeber@netscape.com>, 12-Jul-97.
Adopted: Judson Valeski, 1997
*/
#ifndef _JSCOOKIE_H_
#define _JSCOOKIE_H_
typedef enum {
JSCF_accept,
JSCF_reject,
JSCF_ask,
JSCF_whatever,
JSCF_error
}
JSCFResult;
typedef struct {
char *path_from_header;
char *host_from_header;
char *name_from_header;
char *cookie_from_header;
time_t expires;
char *url;
Bool secure;
Bool domain;
Bool prompt; /* the preference */
NET_CookieBehaviorEnum preference;
}
JSCFCookieData;
extern JSCFResult JSCF_Execute(
MWContext *mwcontext,
const char *script_name,
JSCFCookieData *data,
Bool *data_changed
);
/* runs the garbage collector on the filter context. Probably a good
idea to call on completion of NET_GetURL or something. */
extern void JSCF_Cleanup(void);
#endif /* _JSCOOKIE_H_ */

View File

@@ -0,0 +1,292 @@
#--Netscape Communications Corporation MIME Information
# Do not delete the above line. It is used to identify the file type.
# 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.
# This file defines all of the default file extensions recognised by Netscape.
# See also mime.types-unix and mime.types-nonunix for some platform-specific
# stuff.
# If you add a new non-"text/" type to this file, and it's primarily a
# line-based textual type, you may also want to update the list of
# application-types-that-are-really-textual in mime_type_requires_b64_p()
# in libmsg/compose.c, so that docs of that type don't always get base64
# encoded when mailed.
####################################################################
# Text
####################################################################
exts="txt,text" type=text/plain \
desc="Plain Text" icon=internal-gopher-text
exts="html,htm" type=text/html \
desc="Hypertext Markup Language" icon=internal-gopher-text
exts="xml" type=text/xml \
desc="Extensible Markup Language" icon=internal-gopher-text
exts="rtf" type=application/rtf \
desc="Rich Text Format" icon=internal-gopher-text
# note: text/richtext is *not the same format*
exts="pdf" type=application/pdf \
desc="Portable Document Format" icon=internal-gopher-text
exts="tex" type=application/x-tex \
desc="TeX Document" icon=internal-gopher-text
exts="latex" type=application/x-latex \
desc="LaTeX Document" icon=internal-gopher-text
exts="dvi" type=application/x-dvi \
desc="TeX DVI Data" icon=internal-gopher-text
exts="texi,texinfo" type=application/x-texinfo \
desc="GNU TeXinfo Document" icon=internal-gopher-text
exts="vcf" type=text/x-vcard \
desc="VCard" icon=internal-gopher-unknown
####################################################################
# Images
####################################################################
exts="gif" type=image/gif \
desc="GIF Image" icon=internal-gopher-image
exts="jpeg,jpg,jpe,jfif,pjpeg,pjp" type=image/jpeg \
desc="JPEG Image" icon=internal-gopher-image
exts="tiff,tif" type=image/tiff \
desc="TIFF Image" icon=internal-gopher-image
exts="ras" type=image/x-cmu-raster \
desc="CMU Raster Image" icon=internal-gopher-image
exts="xbm" type=image/x-xbitmap \
desc="X Bitmap" icon=internal-gopher-image
# note: have also seen "image/x-bitmap"
exts="xpm" type=image/x-xpixmap \
desc="X Pixmap" icon=internal-gopher-image
# note: have also seen "image/x-xpm"
exts="xwd" type=image/x-xwindowdump \
desc="X Window Dump Image" icon=internal-gopher-image
# note: have also seen "image/x-xwd"
exts="pnm" type=image/x-portable-anymap \
desc="PBM Image" icon=internal-gopher-image
exts="pbm" type=image/x-portable-bitmap \
desc="PBM Image" icon=internal-gopher-image
exts="pgm" type=image/x-portable-graymap \
desc="PGM Image" icon=internal-gopher-image
exts="ppm" type=image/x-portable-pixmap \
desc="PPM Image" icon=internal-gopher-image
# note: have also seen "image/x-pbm", "image/x-pgm", "image/x-ppm".
exts="rgb" type=image/x-rgb \
desc="RGB Image" icon=internal-gopher-image
exts="bmp" type=image/x-MS-bmp \
desc="Windows Bitmap" icon=internal-gopher-image
exts="pcd" type=image/x-photo-cd \
desc="PhotoCD Image" icon=internal-gopher-image
exts="png" type=image/x-png \
desc="PNG Image" icon=internal-gopher-image
exts="ief" type=image/ief \
desc="" icon=internal-gopher-image
# What is "ief"?
exts="fif" type=application/fractals \
desc="Fractal Image Format" icon=internal-gopher-image
####################################################################
# Audio
####################################################################
exts="au,snd" type=audio/basic \
desc="ULAW Audio" icon=internal-gopher-sound
exts="aif,aiff,aifc" type=audio/x-aiff \
desc="AIFF Audio" icon=internal-gopher-sound
exts="wav" type=audio/x-wav \
desc="WAV Audio" icon=internal-gopher-sound
exts="mp2,mpa,abs,mpega" type=audio/x-mpeg \
desc="MPEG Audio" icon=internal-gopher-sound
exts="ra,ram" type=audio/x-pn-realaudio \
desc="RealAudio" icon=internal-gopher-sound
####################################################################
# Video
####################################################################
exts="mpeg,mpg,mpe,mpv,vbs,mpegv" type=video/mpeg \
desc="MPEG Video" icon=internal-gopher-movie
exts="mpv2,mp2v" type=video/x-mpeg2 \
desc="MPEG2 Video" icon=internal-gopher-movie
exts="qt,mov,moov" type=video/quicktime \
desc="Quicktime Video" icon=internal-gopher-movie
exts="avi" type=video/x-msvideo \
desc="Microsoft Video" icon=internal-gopher-movie
####################################################################
# Archives
####################################################################
exts="hqx" type=application/mac-binhex40 \
desc="Macintosh BinHex Archive" icon=internal-gopher-binary
# note: have also seen "application/x-macbinhex40"
exts="sit" type=application/x-stuffit \
desc="Macintosh StuffIt Archive" icon=internal-gopher-binary
exts="zip" type=application/x-zip-compressed \
desc="Zip Compressed Data" icon=internal-gopher-binary
exts="shar" type=application/x-shar \
desc="Unix Shell Archive" icon=internal-gopher-unknown
exts="tar" type=application/x-tar \
desc="Unix Tape Archive" icon=internal-gopher-binary
exts="gtar" type=application/x-gtar \
desc="GNU Tape Archive" icon=internal-gopher-binary
exts="cpio" type=application/x-cpio \
desc="Unix CPIO Archive" icon=internal-gopher-binary
# note: have also seen "application/x-sv4cpio"
# and "application/x-bcpio" for ".bcpio" files -- what's that?
# and "application/x-sv4crc" for ".sv4crc" -- what's that?
exts="jar" type=application/java-archive \
desc="Java Archive" icon=internal-gopher-binary
####################################################################
# Programs
####################################################################
exts="exe,bin" type=application/octet-stream \
desc="Binary Executable" icon=internal-gopher-binary
exts="ai,eps,ps" type=application/postscript \
desc="Postscript Document" icon=internal-gopher-text
exts="csh" type=application/x-csh \
desc="C Shell Program" icon=internal-gopher-unknown
exts="sh" type=application/x-sh \
desc="Bourne Shell Program" icon=internal-gopher-unknown
exts="tcl" type=application/x-tcl \
desc="TCL Program" icon=internal-gopher-unknown
exts="pl" type=application/x-perl \
desc="Perl Program" icon=internal-gopher-unknown
exts="js,mocha" type=application/x-javascript \
desc="JavaScript Program" icon=internal-gopher-unknown
exts="pac" type=application/x-ns-proxy-autoconfig \
desc="Proxy Auto-Config" icon=internal-gopher-unknown
exts="jsc" type=application/x-javascript-config \
desc="JavaScript Config" icon=internal-gopher-unknown
exts="p7m,p7c" type=application/x-pkcs7-mime \
desc="PKCS7 Encrypted Data" icon=internal-gopher-binary
exts="p7s" type=application/x-pkcs7-signature \
desc="PKCS7 Signature" icon=internal-gopher-binary
exts="enc" type=application/pre-encrypted \
desc="Pre-encrypted Data" icon=internal-gopher-binary
exts="crl" type=application/x-pkcs7-crl \
desc="Certificate Revocation List" icon=internal-gopher-binary
exts="ckl" type=application/x-fortezza-ckl \
desc="Compromised Key List" icon=internal-gopher-binary
# This is too ambiguous an extension. Those losers.
#exts="src" type=application/x-wais-source \
#desc="WAIS Source" icon=internal-gopher-unknown
####################################################################
# Encodings
####################################################################
exts="uu,uue" enc=x-uuencode \
desc="UUEncoded Data" icon=internal-gopher-binary
####################################################################
# Documents
####################################################################
exts="doc,dot" type=application/msword \
desc="Microsoft Word Document" icon=internal-gopher-text
exts="xls,xlt,xlm,xld,xla,xlc,xlw,xll" type=application/vnd.ms-excel \
desc="Microsoft Excel Worksheet" icon=internal-gopher-text
exts="mdb,mda,mde" type=application/vnd.ms-access \
desc="Microsoft Access Database" icon=internal-gopher-text
exts="ppt,pot,ppa,pps,pwz" type=application/vnd.ms-powerpoint \
desc="Microsoft PowerPoint Show" icon=internal-gopher-text
exts="scd,sch,sc2" type=application/vnd.ms-schedule \
desc="Microsoft Schedule+ Application" icon=internal-gopher-text
exts="lwp,sam" type=application/vnd.lotus-wordpro \
desc="Lotus WordPro Document" icon=internal-gopher-text
exts="123,wk4,wk3,wk1" type=application/vnd.lotus-1-2-3 \
desc="Lotus 123 Document" icon=internal-gopher-text
exts="apr,vew" type=application/vnd.lotus-approach \
desc="Lotus Approach Document" icon=internal-gopher-text
exts="prz,pre" type=application/vnd.lotus-freelance \
desc="Lotus Freelance Document" icon=internal-gopher-text
exts="or3,or2,org" type=application/vnd.lotus-organizer \
desc="Lotus Organizer Document" icon=internal-gopher-text
exts="scm" type=application/vnd.lotus-screencam \
desc="Lotus ScreenCam Movie" icon=internal-gopher-text
exts="wpd,wp6" type=application/wordperfect5.1 \
desc="WordPerfect Document" icon=internal-gopher-text

View File

@@ -0,0 +1,30 @@
#--Netscape Communications Corporation MIME Information
# Do not delete the above line. It is used to identify the file type.
# 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.
# This file defines all of the default file extensions recognised by Netscape
# on non-Unix platforms. See also mime.types and mime.types-unix.
####################################################################
# Archives
####################################################################
exts="Z" type=application/x-compress \
desc="Compressed Data" icon=internal-gopher-binary
exts="gz" enc=x-gzip \
desc="GNU Zip Compressed Data" icon=internal-gopher-binary

View File

@@ -0,0 +1,56 @@
#--Netscape Communications Corporation MIME Information
# Do not delete the above line. It is used to identify the file type.
# 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.
# This file defines all of the default file extensions recognised by Netscape
# on Unix platforms. See also mime.types and mime.types-nonunix.
####################################################################
# Text
####################################################################
exts="t,tr,roff" type=application/x-troff \
desc="TROFF Document" icon=internal-gopher-text
exts="me" type=application/x-troff-me \
desc="TROFF Document" icon=internal-gopher-text
exts="ms" type=application/x-troff-ms \
desc="TROFF Document" icon=internal-gopher-text
exts="man" type=application/x-troff-man \
desc="Unix Manual Page" icon=internal-gopher-text
####################################################################
# Video
####################################################################
exts="movie" type=video/x-sgi-movie \
desc="SGI Video" icon=internal-gopher-movie
####################################################################
# Encodings
####################################################################
exts="Z" enc=x-compress \
desc="Compressed Data" icon=internal-gopher-binary
exts="gz" enc=x-gzip \
desc="GNU Zip Compressed Data" icon=internal-gopher-binary

View File

@@ -0,0 +1,85 @@
/* -*- 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.
*/
//
// mkabook.cpp -- Handles "addbook:" " URLs for core Navigator, without
// requiring libmsg. mkabook is intended for adding
// to the address-book.
//
//
#include "mkutils.h"
#include "xp.h"
#include "xp_str.h"
#include "mkgeturl.h"
#include "mkabook.h"
#include "addrbook.h"
//
// Callbacks from NET_GetURL
//
extern "C" int32 net_AddressBookLoad (ActiveEntry *ce)
{
char * url = ce->URL_s->address;
char * path = NET_ParseURL(url, GET_PATH_PART);
char * search = NET_ParseURL(url, GET_SEARCH_PART);
if (!XP_STRNCASECMP(path,"add",3)) {
if (!XP_STRNCASECMP (search, "?vcard=", 7)) {
ABook* addressbook = FE_GetAddressBook(NULL);
if (addressbook)
AB_ImportFromVcardURL(addressbook, ce->window_id, NET_UnEscape(search+7));
}
}
return -1;
}
extern "C" int32 net_ProcessAddressBook (ActiveEntry *ce)
{
XP_ASSERT(0);
return -1;
}
extern "C" int32 net_InterruptAddressBook (ActiveEntry * ce)
{
XP_ASSERT(0);
return -1;
}
extern "C" void
net_CleanupAddressBook(void)
{
}
MODULE_PRIVATE void
NET_InitAddressBookProtocol(void)
{
static NET_ProtoImpl abook_proto_impl;
abook_proto_impl.init = net_AddressBookLoad;
abook_proto_impl.process = net_ProcessAddressBook;
abook_proto_impl.interrupt = net_InterruptAddressBook;
abook_proto_impl.cleanup = net_CleanupAddressBook;
NET_RegisterProtocolImplementation(&abook_proto_impl, ADDRESS_BOOK_TYPE_URL);
}

View File

@@ -0,0 +1,27 @@
/* -*- 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.
*/
#ifndef MKABOOK_H
#define MKABOOK_H
XP_BEGIN_PROTOS
void NET_InitAddressBookProtocol(void);
XP_END_PROTOS
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,131 @@
/* -*- 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.
*/
#ifndef MKACCESS_H
#define MKACCESS_H
#ifndef MKGETURL_H
#include "mkgeturl.h"
#endif
/* returns TRUE if authorization is required
*/
extern Bool NET_AuthorizationRequired(char * address);
/* returns false if the user wishes to cancel authorization
* and TRUE if the user wants to continue with a new authorization
* string
*/
extern Bool NET_AskForAuthString(MWContext * context,
URL_Struct *URL_s,
char * authenticate,
char * prot_template,
Bool already_sent_auth);
/* returns a authorization string if one is required, otherwise
* returns NULL
*/
extern char * NET_BuildAuthString(MWContext * context, URL_Struct *URL_s);
/* removes all authorization structs from the auth list */
extern void
NET_RemoveAllAuthorizations();
/* removes all cookies structs from the cookie list */
extern void
NET_RemoveAllCookies();
/* returns TRUE if authorization is required
*/
extern char *
NET_GetCookie(MWContext * context, char * address);
extern void
NET_SetCookieString(MWContext * context,
char * cur_url,
char * set_cookie_header);
/* wrapper of NET_SetCookieString for netlib use. We need outformat and url_struct to determine
* whether we're dealing with inline cookies */
extern void
NET_SetCookieStringFromHttp(FO_Present_Types outputFormat,
URL_Struct * URL_s,
MWContext * context,
char * cur_url,
char * set_cookie_header);
/* saves out the HTTP cookies to disk
*
* on entry pass in the name of the file to save
*
* returns 0 on success -1 on failure.
*
*/
extern int NET_SaveCookies(char * filename);
/* reads HTTP cookies from disk
*
* on entry pass in the name of the file to read
*
* returns 0 on success -1 on failure.
*
*/
extern int NET_ReadCookies(char * filename);
/*
* Builds the Proxy-authorization string
*/
extern char *
NET_BuildProxyAuthString(MWContext * context,
URL_Struct * url_s,
char * proxy_addr);
/*
* Returns FALSE if the user wishes to cancel proxy authorization
* and TRUE if the user wants to continue with a new authorization
* string.
*/
PUBLIC XP_Bool
NET_AskForProxyAuth(MWContext * context,
char * proxy_addr,
char * pauth_params,
XP_Bool already_sent_auth);
/*
* Figure out better of two {WWW,Proxy}-Authenticate headers;
* SimpleMD5 is better than Basic. Uses the order of AuthType
* enum values.
*
*/
extern XP_Bool
net_IsBetterAuth(char *new_auth, char *old_auth);
/* create an HTML stream and push a bunch of HTML about cookies */
extern void
NET_DisplayCookieInfoAsHTML(ActiveEntry * cur_entry);
MODULE_PRIVATE int PR_CALLBACK
NET_CookieBehaviorPrefChanged(const char * newpref, void * data);
MODULE_PRIVATE int PR_CALLBACK
NET_CookieWarningPrefChanged(const char * newpref, void * data);
MODULE_PRIVATE int PR_CALLBACK
NET_CookieScriptPrefChanged(const char * newpref, void * data);
#endif /* MKACCESS_H */

View File

@@ -0,0 +1,293 @@
/* -*- 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.
*/
#include "mkutils.h"
#include "mkgeturl.h"
#include <stdio.h>
#include <ctype.h>
#include <stdarg.h>
PUBLIC Bool
FE_SecurityDialog(MWContext * context, int message)
{
switch(message)
{
case SD_INSECURE_POST_FROM_SECURE_DOC:
case SD_INSECURE_POST_FROM_INSECURE_DOC:
case SD_ENTERING_SECURE_SPACE:
case SD_LEAVING_SECURE_SPACE:
case SD_INSECURE_DOCS_WITHIN_SECURE_DOCS_NOT_SHOWN:
case SD_REDIRECTION_TO_INSECURE_DOC:
case SD_REDIRECTION_TO_SECURE_SITE:
printf("Security message: %d", message);
}
}
void
TESTFE_AllConnectionsComplete(MWContext * context)
{
}
void
TESTFE_EnableClicking(MWContext * context)
{
}
void
XFE_SetProgressBarPercent(MWContext * context, int percent)
{
}
PUBLIC const char *
FE_UsersMailAddress(void)
{
return("montulli@netscape.com");
}
PUBLIC const char *
FE_UsersFullName(void)
{
return(NULL);
}
extern void sample_exit_routine(URL_Struct *URL_s,int status,MWContext *window_id);
PUBLIC void
FE_EditMailMessage (MWContext *context,
const char * to_address,
const char * subject,
const char * newsgroups,
const char * references,
const char * news_url)
{
#if 0
URL_Struct * URL_s;
char buffer[356];
XP_SPRINTF(buffer, "mailto:%.256s", to_address);
URL_s = NET_CreateURLStruct(buffer, FALSE);
StrAllocCopy(URL_s->post_headers,"Subject: This is a test\r\nX-URL: http://bogus\r\n");
StrAllocCopy(URL_s->post_data,"This is a test, this is only a test\n");
URL_s->method = URL_POST_METHOD;
NET_GetURL(URL_s, FO_CACHE_AND_PRESENT, (MWContext *)0 ,sample_exit_routine);
return;
#endif
}
PUBLIC void
FE_ConnectToRemoteHost(MWContext * window_id, int url_type, char * hostname, char * port, char * username)
{
}
extern NET_StreamClass *
IL_NewStream (int format_out,
void *data_obj,
URL_Struct *URL_s,
MWContext *context)
{
return(NULL);
}
fe_MakeViewSourceStream (int format_out,
void *data_obj,
URL_Struct *URL_s,
MWContext *context)
{
return(NULL);
}
fe_MakeMailToStream (int format_out,
void *data_obj,
URL_Struct *URL_s,
MWContext *context)
{
return(NULL);
}
fe_MakePPMStream (int format_out,
void *data_obj,
URL_Struct *URL_s,
MWContext *context)
{
return(NULL);
}
Bool
TESTFE_ShowAllNewsArticles(MWContext * window_id)
{
return(FALSE);
}
intn
LO_Format(void * data_object, PA_Tag *tag, intn status)
{
return(0);
}
void
XP_Trace (const char* message, ...)
{
int actualLen;
static char xp_Buffer[2048];
va_list stack;
va_start (stack, message);
actualLen = vsprintf (xp_Buffer, message, stack);
va_end (stack);
fwrite(xp_Buffer, 1, strlen(xp_Buffer), stderr);
fprintf (stderr, "\n");
}
PUBLIC int32 FE_GetContextID(MWContext * window_id)
{
return((int) window_id);
}
PUBLIC int TESTFE_FileSortMethod(MWContext * window_id)
{
return(SORT_BY_NAME);
}
PUBLIC Bool TESTFE_UseFancyNewsgroupListing (MWContext * window_id)
{
return(TRUE);
}
PUBLIC Bool TESTFE_UseFancyFTP(MWContext * window_id)
{
return(1);
}
PUBLIC int TESTFE_CheckForInterrupt(void * window_id)
{
/* check check check check and check again */
return(0);
}
PUBLIC void TESTFE_Spinner (MWContext * window_id)
{
/* big wheel keep on rolling. Proud Mary keep on.... */
}
PUBLIC void TESTFE_Alert (MWContext * window_id, CONST char * mess)
{
TRACEMSG(("WWW Alert: %s\n", mess));
}
PUBLIC void TESTFE_Progress (MWContext * window_id, CONST char * mess)
{
TRACEMSG((" %s ...\n", mess));
}
PUBLIC void TESTFE_GraphProgressInit (MWContext * window_id, URL_Struct *url, int32 total_length)
{
TRACEMSG((" GraphInit: %s is %d long...\n", url->address, total_length));
}
PUBLIC void TESTFE_GraphProgressDestroy (MWContext * window_id, URL_Struct *url, int32 bytes_transferred, int32 total_length)
{
TRACEMSG((" GraphDestroy: %s is %d long...\n", url->address, total_length));
}
PUBLIC void TESTFE_GraphProgress (MWContext * window_id, URL_Struct *url, int32 cur_length, int32 length_delta, int32 total_length)
{
TRACEMSG((" GraphProgress: %d of %d ...\n", cur_length, total_length));
}
PUBLIC Bool TESTFE_Confirm (MWContext * window_id, CONST char * mess)
{
char Reply[4];
char *URep;
fprintf(stderr, "WWW: %s (y/n) ", mess);
fgets(Reply, 4, stdin); /* get reply, max 3 characters */
URep=Reply;
while (*URep) {
if (*URep == '\n') {
*URep = (char)0; /* Overwrite newline */
break;
}
*URep=toupper(*URep);
URep++; /* This was previously embedded in the TOUPPER */
/* call an it became evaluated twice because */
}
if ((XP_STRCMP(Reply,"YES")==0) || (XP_STRCMP(Reply,"Y")==0))
return(YES);
else
return(NO);
}
/* Prompt for answer and get text back
*/
PUBLIC char * TESTFE_Prompt (MWContext * window_id, CONST char * mess, CONST char * deflt)
{
char temp[512];
char * t_string = 0;
fprintf(stderr, "Prompt: %s", mess);
if (deflt) fprintf(stderr, " (RETURN for [%s]) ", deflt);
fgets(temp, 200, stdin);
temp[XP_STRLEN(temp)-1] = (char)0; /* Overwrite newline */
StrAllocCopy(t_string, *temp ? temp : deflt);
return t_string;
}
/* Prompt for password without echoing the reply
*/
PUBLIC char * TESTFE_PromptPassword (MWContext * window_id, CONST char * mess)
{
char *result = NULL;
char pw[80];
printf("%s",mess ? mess : "Type your password:");
scanf("%s",pw);
StrAllocCopy(result, pw);
return result;
}
PUBLIC void TESTFE_PromptUsernameAndPassword (MWContext * window_id,
CONST char * mess,
char ** username,
char ** password)
{
if (mess)
fprintf(stderr, "WWW: %s\n", mess);
*username = TESTFE_Prompt(window_id, "Username: ", *username);
*password = TESTFE_PromptPassword(window_id, "Password: ");
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,98 @@
/* -*- 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.
*/
/* mkautocf.h: Proxy auto-config parser and evaluator
* Ari Luotonen */
#ifndef MK_PROXY_AUTO_CONFIG
#define MK_PROXY_AUTO_CONFIG
#include "xp_mcom.h"
#include "xp.h"
/*
* Called by netlib to get a single string of "host:port" format,
* given the XP_List containing opaque proxy config objects.
*
* This function will return an address to a proxy that is (to its
* knowledge) up and running. Netlib can later inform this module
* using the function pacf_proxy_is_down() that a proxy is down
* and should not be called for a few minutes.
*
* Returns FALSE if everything has failed, and an error should be
* displayed to the user.
*
* Returns TRUE if there is hope.
* If *ret is NULL, a direct connection should be attempted.
* If *ret is not null, it is the proxy address to use.
*
*/
MODULE_PRIVATE Bool
pacf_get_proxy_addr(MWContext *context, char *list,
char ** ret_proxy_addr,
u_long * ret_socks_addr,
short * ret_socks_port);
MODULE_PRIVATE char *pacf_find_proxies_for_url(MWContext *context,
URL_Struct *URL_s);
/*
* A stream constructor function for application/x-ns-proxy-autoconfig.
*
*
*
*/
MODULE_PRIVATE NET_StreamClass *
NET_ProxyAutoConfig(int fmt, void *data_obj, URL_Struct *URL_s, MWContext *w);
/*
* Called by mkgeturl.c to originally retrieve, and re-retrieve
* the proxy autoconfig file.
*
* autoconfig_url is the URL pointing to the autoconfig.
*
* The rest of the parameters are what was passed to NET_GetURL(),
* and when the autoconfig load finishes NET_GetURL() will be called
* with those exact same parameters.
*
* This is because the proxy config is loaded when NET_GetURL() is
* called for the very first time, and the actual request must be put
* on hold when the proxy config is being loaded.
*
* When called from the explicit proxy config RE-load function
* NET_ReloadProxyConfig, the four last parameters are all zero,
* and no request gets restarted.
*
*/
MODULE_PRIVATE int NET_LoadProxyConfig(char *autoconf_url,
URL_Struct *URL_s,
FO_Present_Types output_format,
MWContext *window_id,
Net_GetUrlExitFunc *exit_routine);
/*
* NET_GetNoProxyFailover
* Returns TRUE if we're not allowing proxy failover.
*/
MODULE_PRIVATE Bool NET_GetNoProxyFailover(void);
#endif /* ! MK_PROXY_AUTO_CONFIG */

3430
mozilla/lib/libnet/mkcache.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,69 @@
/* -*- 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.
*/
#ifndef MKCACHE_H
#define MKCACHE_H
#include "mkgeturl.h"
#ifndef EXT_CACHE_H
#include "extcache.h"
#endif
XP_BEGIN_PROTOS
extern void NET_CleanupCache (char * filename);
extern int NET_FindURLInCache(URL_Struct * URL_s, MWContext *ctxt);
extern void NET_RefreshCacheFileExpiration(URL_Struct * URL_s);
/* read the Cache File allocation table.
*/
extern void NET_ReadCacheFAT(char * cachefatfile, Bool stat_files);
/* remove a URL from the cache
*/
extern void NET_RemoveURLFromCache(URL_Struct *URL_s);
/* create an HTML stream and push a bunch of HTML about
* the cache
*/
extern void NET_DisplayCacheInfoAsHTML(ActiveEntry * cur_entry);
/* trace variable for cache testing */
extern XP_Bool NET_CacheTraceOn;
/* public accessor function for netcaster */
extern Bool NET_CacheStore(net_CacheObject *cacheObject, URL_Struct *url_s, Bool accept_partial_files);
/* return TRUE if the URL is in the cache and
* is a partial cache file
*/
extern Bool NET_IsPartialCacheFile(URL_Struct *URL_s);
/* encapsulated access to the first object in cache_database */
extern int NET_FirstCacheObject(DBT *key, DBT *data);
/* encapsulated access to the next object in the cache_database */
extern int NET_NextCacheObject(DBT *key, DBT *data);
/* Max size for displaying in the cache browser */
extern int32 NET_GetMaxDiskCacheSize();
XP_END_PROTOS
#endif /* MKCACHE_H */

View File

@@ -0,0 +1,125 @@
/* -*- 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.
*/
#include "xp.h"
#include "mkgeturl.h"
#include "netcburl.h"
#include "secrng.h" /* For RNG_GenerateGlobalRandomBytes */
typedef struct _NET_CallbackURLData {
int id;
char* match;
NET_CallbackURLFunc func;
void* closure;
struct _NET_CallbackURLData* next;
} NET_CallbackURLData;
static NET_CallbackURLData* First = NULL;
static int Counter = 1;
char*
NET_CallbackURLCreate(NET_CallbackURLFunc func, void* closure) {
unsigned char rand_buf[13];
char* result = NULL;
NET_CallbackURLData* tmp;
NET_CallbackURLFree(func, closure);
tmp = XP_NEW(NET_CallbackURLData);
if (!tmp) return NULL;
tmp->id = Counter++;
RNG_GenerateGlobalRandomBytes((void *) rand_buf, 12);
tmp->match =
PR_smprintf("%02X%02X%02X%02X"
"%02X%02X%02X%02X"
"%02X%02X%02X%02X",
rand_buf[0], rand_buf[1], rand_buf[2], rand_buf[3],
rand_buf[4], rand_buf[5], rand_buf[6], rand_buf[7],
rand_buf[8], rand_buf[9], rand_buf[10], rand_buf[11]);
if (tmp->match) {
result = PR_smprintf("internal-callback-handler:%d/%s",
tmp->id, tmp->match);
}
if (result == NULL) {
if (tmp->match) XP_FREE(tmp->match);
XP_FREE(tmp);
return NULL;
}
tmp->next = First;
First = tmp;
tmp->func = func;
tmp->closure = closure;
return result;
}
int
NET_CallbackURLFree(NET_CallbackURLFunc func, void* closure) {
NET_CallbackURLData** tmp;
NET_CallbackURLData* t;
for (tmp = &First ; *tmp ; tmp = &((*tmp)->next)) {
t = *tmp;
if (t->func == func && t->closure == closure) {
*tmp = t->next;
XP_FREE(t->match);
XP_FREE(t);
return 0;
}
}
return -1;
}
int NET_LoadCallbackURL (ActiveEntry* ce)
{
char* url = ce->URL_s->address;
char* path;
char* match;
int id;
NET_CallbackURLData* tmp;
path = NET_ParseURL(url, GET_PATH_PART);
if (path == NULL) return -1;
id = XP_ATOI(path);
match = XP_STRCHR(path, '/');
if (match) match++;
else match = "";
for (tmp = First ; tmp ; tmp = tmp->next) {
if (id == tmp->id && XP_STRCMP(match, tmp->match) == 0) {
(*tmp->func)(tmp->closure, url);
break;
}
}
XP_FREE(path);
return -1;
}
int NET_ProcessCallbackURL(ActiveEntry* ce)
{
return -1; /* Should never get here */
}
int NET_InterruptCallbackURL(ActiveEntry* ce)
{
return -1; /* Should never get here */
}

View File

@@ -0,0 +1,131 @@
/* -*- 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.
*/
#include "mkutils.h"
#include "mkgeturl.h"
#include "net.h"
#include "secnav.h"
#include "ldap.h"
#include "certldap.h"
#include "mkcertld.h"
PRIVATE int32
net_CertLdapLoad(ActiveEntry *ce)
{
int err = 0;
CertLdapConnData *connData;
connData = SECNAV_CertLdapLoad(ce->URL_s);
ce->con_data = connData;
if ( connData == NULL ) {
err = -1;
}
if ( err ) {
ce->status = err;
} else {
#ifdef NSPR20_DISABLED /* need to convert to PRFileDesc */
ce->socket = connData->fd;
#endif
XP_ASSERT(0);
#ifdef XP_UNIX
NET_SetConnectSelect(ce->window_id, ce->socket);
NET_TotalNumberOfOpenConnections++;
#else
NET_SetCallNetlibAllTheTime(ce->window_id, "mkcertld");
#endif
}
return(err);
}
PRIVATE int32
net_ProcessCertLdap(ActiveEntry *ce)
{
int err;
CertLdapConnData *connData;
connData = (CertLdapConnData *)ce->con_data;
#ifdef XP_UNIX
NET_ClearConnectSelect(ce->window_id, connData->fd);
NET_SetReadSelect(ce->window_id, connData->fd);
#endif
err = SECNAV_CertLdapProcess(connData);
if ( err ) {
if ( err == 1 ) {
/* done */
ce->status = 0;
err = -1;
} else {
ce->status = err;
}
#ifdef XP_UNIX
NET_ClearReadSelect(ce->window_id, connData->fd);
NET_TotalNumberOfOpenConnections--;
#else
NET_ClearCallNetlibAllTheTime(ce->window_id, "mkcertld");
#endif
}
return(err);
}
PRIVATE int32
net_InterruptCertLdap(ActiveEntry *ce)
{
int err;
CertLdapConnData *connData;
connData = (CertLdapConnData *)ce->con_data;
err = SECNAV_CertLdapInterrupt(connData);
ce->status = MK_INTERRUPTED;
#ifdef XP_UNIX
NET_ClearReadSelect(ce->window_id, connData->fd);
NET_TotalNumberOfOpenConnections--;
#else
NET_ClearCallNetlibAllTheTime(ce->window_id, "mkcertld");
#endif
return(err);
}
PRIVATE void
net_CleanupCertLdap(void)
{
}
MODULE_PRIVATE void
NET_InitCertLdapProtocol(void)
{
static NET_ProtoImpl certldap_proto_impl;
certldap_proto_impl.init = net_CertLdapLoad;
certldap_proto_impl.process = net_ProcessCertLdap;
certldap_proto_impl.interrupt = net_InterruptCertLdap;
certldap_proto_impl.cleanup = net_CleanupCertLdap;
NET_RegisterProtocolImplementation(&certldap_proto_impl, INTERNAL_CERTLDAP_TYPE_URL);
}

View File

@@ -0,0 +1,32 @@
/* -*- 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.
*/
#ifndef _MKCERTLD_H_
#define _MKCERTLD_H_
/*
* mkcertld.h - api to cert ldap protocol code
*
* $Id: mkcertld.h,v 3.1 1998-03-28 03:31:36 ltabb Exp $
*/
XP_BEGIN_PROTOS
void NET_InitCertLdapProtocol(void);
XP_END_PROTOS
#endif /* _MKCERTLD_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,156 @@
/* -*- 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.
*/
#include "mkutils.h"
#include "mkgeturl.h"
#include "cvmime.h"
#include "mkdaturl.h"
extern int MK_OUT_OF_MEMORY;
extern int MK_MALFORMED_URL_ERROR;
/* format of the DATA: URL
*
* data:[CONTENT-TYPE][;base64],DATA
*/
PRIVATE int32
net_DataURLLoad (ActiveEntry * ce)
{
char *data_buffer;
XP_Bool is_base64 = FALSE;
NET_StreamClass *stream;
char *comma;
ce->protocol = DATA_TYPE_URL;
/* we need a buffer equal to or smaller than the size of the URL
*/
data_buffer = (char *)XP_ALLOC(XP_STRLEN(ce->URL_s->address)+1);
if(!data_buffer)
return(MK_OUT_OF_MEMORY);
/* determine the content type */
/* find the first comma */
comma = XP_STRCHR(ce->URL_s->address, ',');
/* if no comma abort */
if(!comma)
{
ce->URL_s->error_msg = NET_ExplainErrorDetails(MK_MALFORMED_URL_ERROR, ce->URL_s->address);
return(MK_MALFORMED_URL_ERROR);
}
/* fill in default content type */
StrAllocCopy(ce->URL_s->content_type, TEXT_PLAIN);
/* check for a content type */
if(comma != ce->URL_s->address + XP_STRLEN("data:"))
{
*comma = '\0';
XP_STRCPY(data_buffer, ce->URL_s->address + XP_STRLEN("data:"));
*comma = ',';
/* check for base 64 encoding */
if(strcasestr(data_buffer, "base64"))
is_base64 = TRUE;
/* parse the rest as a content-type */
NET_ParseContentTypeHeader(ce->window_id, data_buffer, ce->URL_s, FALSE);
}
if(is_base64)
{
stream = NET_MimeEncodingConverter(ce->format_out, ENCODING_BASE64, ce->URL_s, ce->window_id);
}
else
{
/* open the outgoing stream
*/
stream = NET_StreamBuilder(ce->format_out, ce->URL_s, ce->window_id);
}
if(!stream)
{
ce->URL_s->error_msg = NET_ExplainErrorDetails(MK_UNABLE_TO_CONVERT);
ce->status = MK_UNABLE_TO_CONVERT;
return (ce->status);
}
/* @@@@ bug: ignore is_write_ready */
/* copy the data part of the URL into a scratch buffer */
XP_STRCPY(data_buffer, comma+1);
ce->status = (*stream->put_block)(stream,
data_buffer,
XP_STRLEN(data_buffer));
if(ce->status < 0)
{
(*stream->abort)(stream, ce->status);
return (ce->status);
}
(*stream->complete)(stream);
ce->status = MK_DATA_LOADED;
return(-1); /* all done */
}
/* called repeatedly from NET_ProcessNet to push all the
* data up the stream
*/
PRIVATE int32
net_ProcessDataURL (ActiveEntry * cur_entry)
{
XP_ASSERT(0);
return(-1);
}
/* called by functions in mkgeturl to interrupt the loading of
* an object. (Usually a user interrupt)
*/
PRIVATE int32
net_InterruptDataURL (ActiveEntry * cur_entry)
{
XP_ASSERT(0);
return(-1);
}
PRIVATE void
net_CleanupDataURL(void)
{
}
MODULE_PRIVATE void
NET_InitDataURLProtocol(void)
{
static NET_ProtoImpl dataurl_proto_impl;
dataurl_proto_impl.init = net_DataURLLoad;
dataurl_proto_impl.process = net_ProcessDataURL;
dataurl_proto_impl.interrupt = net_InterruptDataURL;
dataurl_proto_impl.cleanup = net_CleanupDataURL;
NET_RegisterProtocolImplementation(&dataurl_proto_impl, DATA_TYPE_URL);
}

View File

@@ -0,0 +1,24 @@
/* -*- 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.
*/
#ifndef MKDATURL_H
#define MKDATURL_H
extern void NET_InitDataURLProtocol(void);
#endif /* MKDATURL_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,40 @@
/* -*- 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.
*/
#ifndef MKEXTCACHE_H
#define MKEXTCACHE_H
/* lookup routine
*
* builds a key and looks for it in
* the database. Returns an access
* method and sets a filename in the
* URL struct if found
*/
extern int NET_FindURLInExtCache(URL_Struct * URL_s, MWContext *ctxt);
extern void
NET_OpenExtCacheFAT(MWContext *ctxt, char * cache_name, char * instructions);
extern void
CACHE_CloseAllOpenSARCache();
extern void
CACHE_OpenAllSARCache();
#endif /* MKEXTCACHE_H */

1830
mozilla/lib/libnet/mkfile.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,34 @@
/* -*- 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.
*/
#ifndef MKFILE_H
#define MKFILE_H
#include "mkfsort.h"
extern void NET_InitFileProtocol(void);
extern int
NET_PrintDirectory(SortStruct **sort_base, NET_StreamClass * stream, char * path, URL_Struct *URL_s);
extern NET_StreamClass *
net_CloneWysiwygLocalFile(MWContext *window_id, URL_Struct *URL_s,
uint32 nbytes, const char * wysiwyg_url,
const char * base_href);
#endif /* MKFILE_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,98 @@
/* -*- 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.
*/
/*
* cinfo.h: Content Information for a file, i.e. its type, etc.
*
* See cinfo.c for dependency information.
*
* Rob McCool
*/
#ifndef MKFORMAT_H
#define MKFORMAT_H
#ifndef MKSTREAM_H
#include "mkstream.h"
#endif /* MKSTREAM_H */
/* ------------------------------ Constants ------------------------------- */
/*
* This will be the first string in the file, followed by x.x version
* where x is an integer.
*
* If this magic string is not found, cinfo_merge will try to parse
* the file as a NCSA httpd mime.types file.
*/
#define MCC_MT_MAGIC "#--MCOM MIME Information"
#define MCC_MT_MAGIC_LEN 24
#define NCC_MT_MAGIC "#--Netscape Communications Corporation MIME Information"
#define NCC_MT_MAGIC_LEN 40 /* Don't bother to check it all */
/* The character which separates extensions with cinfo_find */
#define CINFO_SEPARATOR '.'
/* The maximum length of a line in this file */
#define CINFO_MAX_LEN 1024
/* The hash function for the database. Hashed on extension. */
#include <ctype.h>
#define CINFO_HASH(s) (isalpha(s[0]) ? tolower(s[0]) - 'a' : 26)
/* The hash table size for that function */
#define CINFO_HASHSIZE 27
/* ------------------------------ Structures ------------------------------ */
/* see ../include/net.h for the NET_cinfo struct */
/* ------------------------------ Prototypes ------------------------------ */
/*
* cinfo_find finds any content information for the given uri. The file name
* is the string following the last / in the uri. Multiple extensions are
* separated by CINFO_SEPARATOR. You may pass in a filename instead of uri.
*
* Returns a newly allocated cinfo structure with the information it
* finds. The elements of this structure are coming right out of the types
* database and so if you change it or want to keep it around for long you
* should strdup it. You should free only the structure itself when finished
* with it.
*
* If there is no information for any one of the extensions it
* finds, it will ignore that extension. If it cannot find information for
* any of the extensions, it will return NULL.
*/
extern NET_cinfo *NET_cinfo_find(char *uri);
extern NET_cinfo *NET_cinfo_find_type(char *uri);
extern NET_cinfo *NET_cinfo_find_enc (char *uri);
/*
* cinfo_lookup finds the information about the given content-type, and
* returns a cinfo structure so you can look up description and icon.
*/
NET_cinfo *NET_cinfo_lookup(char *type);
#endif /* MKFORMAT_H */

View File

@@ -0,0 +1,153 @@
/* -*- 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.
*/
/*
*
* routines to sort an array of file objects
* uses qsort alg
*
* Designed and implemented by Lou Montulli '94
*/
#include "mkutils.h"
#include "mkfsort.h"
#include "mkgeturl.h"
#ifdef PROFILE
#pragma profile on
#endif
PRIVATE int net_file_sort_method = SORT_BY_NAME;
/* print a text string in place of the NET_FileEntryInfo special_type int */
PUBLIC char *
NET_PrintFileType(int special_type)
{
switch(special_type)
{
case NET_FILE_TYPE:
return("FILE");
case NET_DIRECTORY:
return("DIRECTORY");
case NET_SYM_LINK:
return("SYMBOLIC-LINK");
case NET_SYM_LINK_TO_DIR:
return("SYM-DIRECTORY");
case NET_SYM_LINK_TO_FILE:
return("SYM-FILE");
default:
XP_ASSERT(0);
return("FILE");
}
}
PRIVATE void
NET_SetFileSortMethod(int method)
{
net_file_sort_method = method;
}
MODULE_PRIVATE void NET_FreeEntryInfoStruct(NET_FileEntryInfo *entry_info)
{
if(entry_info)
{
FREEIF(entry_info->filename);
/* free the struct */
XP_FREE(entry_info);
}
}
MODULE_PRIVATE NET_FileEntryInfo * NET_CreateFileEntryInfoStruct (void)
{
NET_FileEntryInfo * new_entry = XP_NEW(NET_FileEntryInfo);
if(!new_entry)
return(NULL);
XP_MEMSET(new_entry, 0, sizeof(NET_FileEntryInfo));
new_entry->permissions = -1;
return(new_entry);
}
/* This function is used as a comparer function for the Qsort routine.
* It uses a function FE_FileSortMethod() to determine the
* field to sort on.
*
*/
PRIVATE int
NET_CompareFileEntryInfoStructs (const void *ent2, const void *ent1)
{
int status;
const NET_FileEntryInfo *entry1 = *(NET_FileEntryInfo **) ent1;
const NET_FileEntryInfo *entry2 = *(NET_FileEntryInfo **) ent2;
if(!entry1 || !entry2)
return(-1);
switch(net_file_sort_method)
{
case SORT_BY_SIZE:
/* both equal or both 0 */
if(entry1->size == entry2->size)
return(XP_STRCMP(entry2->filename, entry1->filename));
else
if(entry1->size > entry2->size)
return(-1);
else
return(1);
/* break; NOT NEEDED */
case SORT_BY_TYPE:
if(entry1->cinfo && entry1->cinfo->desc &&
entry2->cinfo && entry2->cinfo->desc)
{
status = XP_STRCMP(entry1->cinfo->desc, entry2->cinfo->desc);
if(status)
return(status);
/* else fall to filename comparison */
}
return (XP_STRCMP(entry2->filename, entry1->filename));
/* break; NOT NEEDED */
case SORT_BY_DATE:
if(entry1->date == entry2->date)
return(XP_STRCMP(entry2->filename, entry1->filename));
else
if(entry1->size > entry2->size)
return(-1);
else
return(1);
/* break; NOT NEEDED */
case SORT_BY_NAME:
default:
return (XP_STRCMP(entry2->filename, entry1->filename));
}
}
/* sort the files
*/
MODULE_PRIVATE void
NET_DoFileSort(SortStruct * sort_list)
{
NET_DoSort(sort_list, NET_CompareFileEntryInfoStructs);
}
#ifdef PROFILE
#pragma profile off
#endif

View File

@@ -0,0 +1,35 @@
/* -*- 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.
*/
#ifndef MKFSORT_H
#define MKFSORT_H
#include "mksort.h"
#include <time.h>
#ifdef XP_UNIX
#include <sys/types.h>
#endif /* XP_UNIX */
extern void NET_FreeEntryInfoStruct(NET_FileEntryInfo *entry_info);
extern NET_FileEntryInfo * NET_CreateFileEntryInfoStruct (void);
extern int NET_CompareEntryInfoStructs (void *ent1, void *ent2);
extern void NET_DoFileSort (SortStruct * sort_list);
#endif /* MKFSORT_H */

4729
mozilla/lib/libnet/mkftp.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,26 @@
/* -*- 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.
*/
#ifndef MKFTP_H
#define MKFTP_H
#include "mkgeturl.h"
extern void NET_InitFTPProtocol(void);
#endif /* HTFTP_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,130 @@
/* -*- 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.
*/
#ifndef MKGETURL_H
#define MKGETURL_H
#include "mkutils.h"
#include "xp.h"
#include "mktcp.h"
#include "nslocks.h"
/* fix Mac warnings about missing prototypes */
MODULE_PRIVATE int PR_CALLBACK
NET_PrefChangedFunc(const char *pref, void *data);
/* Debugging routine prints an URL (and string "header")
*/
XP_BEGIN_PROTOS
#ifdef DEBUG
extern void TraceURL (URL_Struct *url, char *header);
#else
#define TraceURL(U,M)
#endif /* DEBUG */
XP_END_PROTOS
/* forward declared; see below */
typedef struct _NET_ProtoImpl NET_ProtoImpl;
/* structure for maintaining multiple active data transfers
*/
typedef struct _ActiveEntry {
URL_Struct *URL_s; /* the URL data */
int status; /* current status */
int32 bytes_received; /* number of bytes received so far */
PRFileDesc *socket; /* data sock */
PRFileDesc *con_sock; /* socket waiting for connection */
Bool local_file; /* are we reading a local file */
Bool memory_file; /* are we reading from memory? */
int protocol; /* protocol used for transfer */
NET_ProtoImpl *proto_impl; /* handle to protocol implemenation */
void *con_data; /* data about the transfer connection and status */
/* routine to call when finished */
Net_GetUrlExitFunc *exit_routine;
MWContext * window_id; /* a unique window id */
FO_Present_Types format_out; /* the output format */
NET_StreamClass * save_stream; /* used for cacheing of partial docs
* The file code opens this stream
* and writes part of the file down it.
* Then the stream is saved
* and the rest is loaded from the
* network
*/
Bool busy;
char * proxy_conf; /* Proxy autoconfig string */
char * proxy_addr; /* Proxy address in host:port format */
u_long socks_host; /* SOCKS host IP address */
short socks_port; /* SOCKS port number */
} ActiveEntry;
/* typedefs of protocol implementation functions
*
* All these currently take an ActiveEntry Struct but
* should probably be abstracted out considerably more
*/
typedef int32 NET_ProtoInitFunc(ActiveEntry *ce);
typedef int32 NET_ProtoProcessFunc(ActiveEntry *ce);
typedef int32 NET_ProtoInterruptFunc(ActiveEntry *ce);
typedef int32 NET_ProtoCleanupFunc(void);
/* a structure to hold the registered implementation of
* a protocol converter
*/
struct _NET_ProtoImpl {
int32 (*init) (ActiveEntry *ce);
int32 (*process) (ActiveEntry *ce);
int32 (*interrupt) (ActiveEntry *ce);
void (*cleanup) (void); /* note that cleanup can be called more
* than once, when we need to shut down
* connections or free up memory
*/
};
XP_BEGIN_PROTOS
extern int NET_TotalNumberOfOpenConnections;
extern int NET_MaxNumberOfOpenConnections;
extern CacheUseEnum NET_CacheUseMethod;
extern time_t NET_StartupTime; /* time we began the program */
extern XP_Bool NET_ProxyAcLoaded;
/*
* Silently Interrupts all transfers in progress that have the same
* window id as the one passed in.
*/
extern int NET_SilentInterruptWindow(MWContext * window_id);
/* cause prefs to be read or updated */
extern void NET_SetupPrefs(const char * prefChanged);
extern NET_ProxyStyle NET_GetProxyStyle(void);
extern const char * net_GetPACUrl(void);
extern void net_SetPACUrl(char *u);
/* return a proxy server host and port to the caller or NULL
*/
extern char * NET_FindProxyHostForUrl(int urltype, char *urladdress);
/* registers a protocol impelementation for a particular url_type
* see NET_URL_Type() for types
*/
extern void NET_RegisterProtocolImplementation(NET_ProtoImpl *impl, int for_url_type);
XP_END_PROTOS
#endif /* not MKGetURL_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,25 @@
/* -*- 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.
*/
#ifndef MKGOPHER_H
#define MKGOPHER_H
extern void NET_InitGopherProtocol(void);
#endif /* MKGOPHER_H */

1022
mozilla/lib/libnet/mkhelp.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,58 @@
/* -*- 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.
*/
#ifndef MKHELP_H
#define MKHELP_H
/* EA: Help Begin */
/* The following structure stores the URL of the current help topic and project
file of a help window. Because this information is accessed by a javascript
context sometime after the URL is delivered to the window, we needed a persistent
way in which the data would remain associated with a given window, and,
despite a great desire to not muck around with the MWContext, that was the
only thing that was in scope at the time. Lou Montoulli suggested using
fields that are part of the URL_struct, such as the fe_data and Chrome
fields, but these were not in scope at the time that the Javascript calls
were being evaluated. */
typedef struct HelpInfoStruct_ {
char *topicURL;
char *projectURL;
} HelpInfoStruct;
#define HELP_INFO_PTR(MW_CTX) ((HelpInfoStruct *) (MW_CTX).pHelpInfo)
/* Called by netlib to parse a nethelp URL. ParseNetHelpURL alters the
URL struct passed in to point to the location of the help project file
specified by the nethelp URL. */
extern int
NET_ParseNetHelpURL(URL_Struct *URL_s);
/* stream converter to parse an HTML help mapping file
* and load the url associated with the id
*/
extern NET_StreamClass *
NET_HTMLHelpMapToURL(int format_out,
void *data_object,
URL_Struct *URL_s,
MWContext *window_id);
#endif /* MKHELP_H */

3772
mozilla/lib/libnet/mkhttp.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,35 @@
/* -*- 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.
*/
#ifndef MKHTTP_H
#define MKHTTP_H
#ifndef MKGETURL_H
#include "MKGetURL.h"
#endif /* MKGETURL_H */
#define DEF_HTTP_PORT 80
#define DEF_HTTPS_PORT 443
extern void
NET_SetSendRefererHeader(Bool b);
extern void
NET_InitHTTPProtocol(void);
#endif /* MKHTTP_H */

10495
mozilla/lib/libnet/mkimap4.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,45 @@
/* -*- 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.
*/
#ifndef MKIMAP4_H
#define MKIMAP4_H
#include "mkgeturl.h"
XP_BEGIN_PROTOS
extern int32 NET_IMAP4Load (ActiveEntry *ce);
/* NET_ProcessIMAP4 will control the state machine that
* loads messages from a imap4 server
*
* returns negative if the transfer is finished or error'd out
*
* returns zero or more if the transfer needs to be continued.
*/
extern int32 NET_ProcessIMAP4 (ActiveEntry *ce);
/* abort the connection in progress
*/
MODULE_PRIVATE int32 NET_InterruptIMAP4(ActiveEntry * ce);
extern void NET_InitIMAP4Protocol(void);
XP_END_PROTOS
#endif /* MKIMAP4_H */

779
mozilla/lib/libnet/mkinit.c Normal file
View File

@@ -0,0 +1,779 @@
/* -*- 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.
*/
/*
* register all neccessary
* stream converters
*/
/* Please leave outside of ifdef for window's precompiled headers. */
#include "mkutils.h"
#ifdef MOZILLA_CLIENT
#ifdef XP_UNIX /* this whole module is ifdef'd UNIX */
#include "mkstream.h"
#include "mkformat.h"
#include "net.h"
#include "cvview.h"
#include "cvdisk.h"
#include "cvproxy.h"
#include "cvextcon.h"
#include "txview.h"
#include "xlate.h"
#include "libi18n.h" /* For character code set conversion stream */
#include "cvactive.h"
#include "pa_parse.h"
#include "np.h"
#include "il_strm.h" /* Image Library stream converters. */
/* The master database of mail cap info (link list) */
PRIVATE XP_List *NET_mcMasterList = 0; /* May want to save out this info */
PUBLIC void
NET_mdataFree(NET_mdataStruct *md)
{
FREEIF(md->contenttype);
FREEIF(md->command);
FREEIF(md->testcommand);
FREEIF(md->label);
FREEIF(md->printcommand);
FREEIF(md->src_string);
FREEIF(md->xmode);
FREE(md);
md = NULL;
}
/* File is a directory ?*/
PRIVATE Bool
net_isDir(char *name)
{
XP_StatStruct st;
if (!name || !*name) return (FALSE);
if (!stat (name, &st) && S_ISDIR(st.st_mode))
return (TRUE);
else
return (FALSE);
}
PUBLIC void
NET_CleanupMailCapList(char* filename)
{
NET_mdataStruct *mdata;
FILE *fp = NULL;
XP_List *modifiedList = NULL;
if ( !NET_mcMasterList ) return;
if ( filename && *filename )
{
/* Invalid filename, then don't write */
if ( net_isDir(filename) )
return;
fp = fopen(filename, "w");
if ( !fp ) return;
modifiedList = XP_ListNew();
while ((mdata=(NET_mdataStruct *)XP_ListRemoveEndObject(NET_mcMasterList)))
{
if (mdata->is_local )
{
if ( mdata->src_string && *mdata->src_string)
{
fputs(mdata->src_string, fp);
if ( mdata->src_string[strlen(mdata->src_string)-1] != '\n' )
fputs("\n", fp);
}
else mdata->src_string = 0;
NET_mdataFree(mdata);
}
else if (mdata->is_modified)
XP_ListAddObject(modifiedList, mdata);
else
{
NET_mdataFree(mdata);
}
}
while ((mdata=(NET_mdataStruct *)XP_ListRemoveEndObject(modifiedList)))
{
if ( mdata->src_string && *mdata->src_string)
{
fputs(mdata->src_string, fp);
if ( mdata->src_string[strlen(mdata->src_string)-1] != '\n' )
fputs("\n", fp);
}
else mdata->src_string = 0;
NET_mdataFree(mdata);
}
fclose(fp);
}
else
{
while ((mdata = (NET_mdataStruct *)XP_ListRemoveEndObject(NET_mcMasterList)))
{
NET_mdataFree(mdata);
}
}
XP_ListDestroy(NET_mcMasterList);
NET_mcMasterList = 0;
}
/* register all your converters
*
* YOU MUST register a "*" converter for
* EVERY format out type, this acts as a default
* and prevents a "Could not convert error"
*/
PUBLIC void
NET_RegisterConverters (char * personal_file, char * global_file)
{
NET_CleanupMailCapList(NULL);
NET_mcMasterList = XP_ListNew();
NET_RegisterMIMEDecoders ();
NET_RegisterExternalViewerCommand (IMAGE_WILDCARD, "xv %s", 0);
NET_RegisterExternalViewerCommand ("audio/ulaw", "playulaw", 2000);
#ifdef NOT /* NO default audio */
#ifdef __sun
NET_RegisterExternalViewerCommand (AUDIO_BASIC, "cat > /dev/audio", 2000);
#else
NET_RegisterExternalViewerCommand (AUDIO_BASIC, "playulaw", 2000);
#endif /* __sgi */
#endif /* NOT */
NET_RegisterExternalViewerCommand (VIDEO_MPEG,
/* throw away stderr and stdout, since
mpeg_play is so darn noisy. */
"mpeg_play %s >/dev/null 2>&1", 0);
NET_RegisterExternalViewerCommand ("image/x-xwd", "xwud", 2000);
/* global file must come first!!!!!!!!!!!!!!
*/
if (global_file)
NET_ProcessMailcapFile (global_file, FALSE);
if (personal_file)
NET_ProcessMailcapFile (personal_file, TRUE);
}
/*
* before you modify this,
* make darn sure you want to deviuate from the standard bellcore mailcap
* handling!! *this means you Garrett!!*"
*
* Code borrowed from:
*
* Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore)
*
* Permission to use, copy, modify, and distribute this material
* for any purpose and without fee is hereby granted, provided
* that the above copyright notice and this permission notice
* appear in all copies, and that the name of Bellcore not be
* used in advertising or publicity pertaining to this
* material without the specific, prior written permission
* of an authorized representative of Bellcore. BELLCORE
* MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY
* OF THIS MATERIAL FOR ANY PURPOSE. IT IS PROVIDED "AS IS",
* WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
*/
/*
* Metamail -- A tool to help diverse mail readers
* cope with diverse multimedia mail formats.
*
* Author: Nathaniel S. Borenstein, Bellcore
*
*/
struct MailcapEntry {
char *contenttype;
char *command;
char *testcommand;
int needsterminal;
int copiousoutput;
int needtofree;
char *label;
char *printcommand;
int32 stream_buffer_size;
char *xmode;
};
#define LINE_BUF_SIZE 2048
#define TMPFILE_NAME_SIZE 127
PRIVATE char *GetCommand (char *s, char **t)
{
char *s2;
int quoted = 0;
s2 = (char *) XP_ALLOC(XP_STRLEN(s)*2 + 3); /* absolute max, if all % signs */
if(!s2)
return(NULL);
*s2 = 0;
*t = s2;
while (s && *s)
{
if (quoted)
{
if (*s == '%')
*s2++ = '%';
*s2++ = *s++;
quoted = 0;
}
else
{
if (*s == ';')
{
break; /* finish the string below */
}
if (*s == '\\')
{
quoted = 1;
++s;
}
else
{
*s2++ = *s++;
}
}
}
/* look at the last character of the command and make sure it doesn't have
* a '&'
*/
if( s2 > *t && *(s2-1) == '&')
s2--; /* kill the ampersand */
*s2 = 0; /* terminate string */
if(*s)
return(s+1);
else
return(s);
}
/* Trims leading and trailing space in the input string while converting
* it to all lower case.
*
* WARNING: Modified input string.
*/
PRIVATE char *Cleanse (char *s)
{
char *tmp, *news, *tmpnews;
news = s;
/* strip leading white space */
while (*s && XP_IS_SPACE(*s)) ++s;
/* put in lower case */
for (tmpnews=news, tmp=s; *tmp; tmpnews++, ++tmp) {
*tmpnews = tolower ((unsigned char)*tmp);
}
*tmpnews = '\0';
/* strip trailing white space */
while (*--tmpnews && XP_IS_SPACE(*tmpnews)) *tmpnews = 0;
return(news);
}
PRIVATE void BuildCommand (char *Buf, char *controlstring, char *TmpFileName)
{
char *from, *to;
int prefixed = 0;
for (from=controlstring, to=Buf; *from != '\0'; from++)
{
if (prefixed)
{
prefixed = 0;
switch(*from)
{
case '%':
*to++ = '%';
break;
case 'n':
case 'F':
fprintf(stderr, "metamail: Bad mailcap \"test\" clause: %s\n", controlstring);
case 's':
if (TmpFileName)
{
XP_STRCPY(to, TmpFileName);
to += XP_STRLEN(TmpFileName);
}
break;
default:
fprintf(stderr,
"%s: Ignoring unsupported format code in mailcap file: %%%c\n",
XP_AppName, *from);
break;
}
}
else if (*from == '%')
{
prefixed = 1;
}
else
{
*to++ = *from;
}
}
*to = 0;
}
static void
net_register_new_converter(char *contenttype, char *command, char *xmode,
int buffer_size)
{
/* xmode takes priority over command */
if (xmode && !XP_STRCASECMP(xmode, NET_COMMAND_NETSCAPE))
{
if ( !XP_STRCASECMP(contenttype, TEXT_HTML) )
NET_RegisterContentTypeConverter (TEXT_HTML, FO_PRESENT,
NULL, INTL_ConvCharCode);
else if (!XP_STRCASECMP(contenttype, TEXT_MDL))
NET_RegisterContentTypeConverter (TEXT_MDL, FO_PRESENT,
NULL, INTL_ConvCharCode);
else if (!XP_STRCASECMP(contenttype, TEXT_PLAIN))
NET_RegisterContentTypeConverter (TEXT_PLAIN, FO_PRESENT,
NULL, NET_PlainTextConverter);
else if (!XP_STRCASECMP(contenttype, IMAGE_GIF))
NET_RegisterContentTypeConverter (IMAGE_GIF,
FO_PRESENT,NULL, IL_ViewStream);
else if (!XP_STRCASECMP(contenttype, IMAGE_XBM) ||
!XP_STRCASECMP(contenttype, IMAGE_XBM2) ||
!XP_STRCASECMP(contenttype, IMAGE_XBM3))
NET_RegisterContentTypeConverter (IMAGE_XBM,
FO_PRESENT,NULL, IL_ViewStream);
else if (!XP_STRCASECMP(contenttype, IMAGE_JPG) ||
!XP_STRCASECMP(contenttype, IMAGE_PJPG))
NET_RegisterContentTypeConverter (IMAGE_JPG,
FO_PRESENT,NULL, IL_ViewStream);
else if (!XP_STRCASECMP(contenttype, IMAGE_PNG))
NET_RegisterContentTypeConverter (IMAGE_PNG,
FO_PRESENT,NULL, IL_ViewStream);
else if (!XP_STRCASECMP(contenttype,
APPLICATION_NS_PROXY_AUTOCONFIG))
NET_RegisterContentTypeConverter(
APPLICATION_NS_PROXY_AUTOCONFIG,
FO_PRESENT,
(void *)0, NET_ProxyAutoConfig);
else if (!XP_STRCASECMP(contenttype,
APPLICATION_NS_JAVASCRIPT_AUTOCONFIG))
NET_RegisterContentTypeConverter(
APPLICATION_NS_JAVASCRIPT_AUTOCONFIG,
FO_PRESENT,
(void *)0, NET_ProxyAutoConfig);
else
{
fprintf(stderr,
"%s: Ignoring unsupported netscape contenttype in user mailcap file.\n", XP_AppName);
}
}
else if (xmode && !strncasecmp(xmode, NET_COMMAND_PLUGIN,
strlen(NET_COMMAND_PLUGIN)))
{
char *pluginName = xmode + strlen(NET_COMMAND_PLUGIN);
/* For plugins enable the plugin for this mimetype */
NPL_EnablePlugin(contenttype, pluginName, TRUE);
}
else if (xmode &&
(!XP_STRCASECMP(xmode, NET_COMMAND_SAVE_TO_DISK) ||
!XP_STRCASECMP(xmode, NET_COMMAND_SAVE_BY_NETSCAPE)))
NET_RegisterContentTypeConverter(contenttype,
FO_PRESENT,
NULL, fe_MakeSaveAsStream );
else if (xmode && !XP_STRCASECMP(xmode, NET_COMMAND_UNKNOWN))
NET_RegisterContentTypeConverter(contenttype,
FO_PRESENT,
NULL, fe_MakeSaveAsStream );
else if (xmode && !XP_STRCASECMP(xmode,NET_COMMAND_DELETED))
{
/* Do nothing */
}
else if (command && *command )/* It's an external application then */
{
/* register the command
*
* but only if it isn't text/html
*/
if(strcasecomp(contenttype, TEXT_HTML) &&
strcasecomp(contenttype, MESSAGE_RFC822) &&
strcasecomp(contenttype, MESSAGE_NEWS))
NET_RegisterExternalViewerCommand(contenttype, command, buffer_size);
}
}
PRIVATE int PassesTest (struct MailcapEntry *mc)
{
int result;
char *cmd, TmpFileName[TMPFILE_NAME_SIZE];
if (!mc->testcommand) return(1);
tmpnam(TmpFileName);
cmd = (char *)XP_ALLOC(1024);
if (!cmd)
return(0);
BuildCommand(cmd, mc->testcommand, TmpFileName);
TRACEMSG(("Executing test command: %s\n", cmd));
result = system(cmd);
free(cmd);
remove(TmpFileName);
if(result)
TRACEMSG(("[HTInit] Test failed!\n"));
else
TRACEMSG(("[HTInit] Test passed!\n"));
return(result==0);
}
PRIVATE int ProcessMailcapEntry (FILE *fp, struct MailcapEntry *mc,
char** src_string, Bool is_local)
{
NET_cdataStruct *tmp_cd = NULL;
NET_cdataStruct *cd = NULL;
NET_mdataStruct *md = NULL;
int unprocessed_entryalloc = 1023, len;
char *unprocessed_entry, *s, *t, *buffer;
char *arg, *eq;
char *command=0;
buffer = (char *) XP_ALLOC(LINE_BUF_SIZE);
if (!buffer)
return 0;
unprocessed_entry = (char *) XP_ALLOC(1 + unprocessed_entryalloc);
if (!unprocessed_entry)
{
free(buffer);
return 0;
}
*unprocessed_entry = '\0';
while (fgets(buffer, LINE_BUF_SIZE, fp))
{
if ( !*src_string )
StrAllocCopy(*src_string, buffer );
else
*src_string = XP_AppendStr(*src_string, buffer);
if (buffer[0] == '#')
continue;
len = XP_STRLEN(buffer);
if (len == 0)
continue;
if (buffer[len-1] == '\n')
buffer[--len] = 0;
if ((len + XP_STRLEN(unprocessed_entry)) > unprocessed_entryalloc)
{
unprocessed_entryalloc += 1024;
unprocessed_entry = (char *) XP_REALLOC(unprocessed_entry, unprocessed_entryalloc+1);
TRACEMSG(("Growing input line in mkinit"));
if (!unprocessed_entry)
{
TRACEMSG(("ERROR! Growing input line in mkinit"));
return 0;
}
}
if (len > 0 && buffer[len-1] == '\\')
{
buffer[len-1] = 0;
XP_STRCAT(unprocessed_entry, buffer);
}
else
{
XP_STRCAT(unprocessed_entry, buffer);
break;
}
}
for (s=unprocessed_entry; *s && XP_IS_SPACE(*s); ++s)
; /* NULL BODY */
if (!*s)
{
/* totally blank entry -- quietly ignore */
free(unprocessed_entry);
free(buffer);
return(0);
}
s = XP_STRCHR(unprocessed_entry, ';');
if (s == NULL)
{
fprintf(stderr, "%s: Ignoring invalid mailcap entry: %s\n",
XP_AppName, unprocessed_entry);
free(unprocessed_entry);
free(buffer);
XP_FREE(*src_string);
*src_string = 0;
return(0);
}
*s++ = 0;
mc->needsterminal = 0;
mc->copiousoutput = 0;
mc->needtofree = 1;
mc->testcommand = 0;
mc->label = NULL;
mc->printcommand = NULL;
mc->contenttype = 0; /* init */
mc->xmode = 0;
mc->stream_buffer_size = 0;
StrAllocCopy(mc->contenttype, unprocessed_entry); /* copy */
if (!mc->contenttype)
{
free(buffer);
TRACEMSG(("mailcap: no content-type"));
return 0;
}
s = GetCommand(s, &mc->command);
while (s && *s != '\0')
{
arg = s;
eq = XP_STRCHR(arg, '=');
if (eq)
*eq++ = 0;
else
eq = arg;
t = GetCommand(eq, &command);
if (arg && *arg)
{
arg = Cleanse(arg);
if ( eq && !XP_STRCMP(arg, NET_MOZILLA_FLAGS))
{
/* xmode is case sensitive. That is why we dont Cleanse it. */
mc->xmode = command;
command = 0;
}
else {
command = Cleanse(command);
if (eq && !XP_STRCMP(arg, "test"))
{
mc->testcommand = command;
command = 0;
TRACEMSG(("mailcap: found testcommand:%s\n",mc->testcommand));
}
else if (eq && !XP_STRCMP(arg, "description"))
{
mc->label = command;
command = 0;
}
else if (eq && !XP_STRCMP(arg, "label"))
{
mc->label = command; /* bogus old name for description */
command = 0;
}
else if (eq && !XP_STRCMP(arg, "stream-buffer-size"))
{
mc->stream_buffer_size = atol(command);
TRACEMSG(("mailcap: found stream-buffer-size:%d\n",mc->stream_buffer_size));
FREEIF(command);
command = 0;
}
else
FREEIF(command);
}
}
else if (command && *command) FREEIF(command);
s = t;
}
free(unprocessed_entry);
/* Copy over the mail cap entry so that it can saved into data base */
if (mc)
{
md = NET_mdataCreate();
if ( !md ) return (-1);
StrAllocCopy(md->contenttype, mc->contenttype);
StrAllocCopy(md->command, mc->command);
StrAllocCopy(md->testcommand, mc->testcommand);
StrAllocCopy(md->label, mc->label);
StrAllocCopy(md->printcommand, mc->printcommand);
md->stream_buffer_size = mc->stream_buffer_size;
if (is_local && *src_string && **src_string)
StrAllocCopy(md->src_string, *src_string); /* copy buffer */
StrAllocCopy(md->xmode, mc->xmode);
md->is_local = is_local;
XP_FREE(*src_string);
*src_string = 0;
}
if (PassesTest(mc))
{
TRACEMSG(("mailcap: Setting up conversion %s : %s\n", mc->contenttype,
mc->command));
net_register_new_converter(XP_StripLine(mc->contenttype),
mc->command, mc->xmode,
mc->stream_buffer_size);
if (md)
md->test_succeed = TRUE;
}
/* Add to the database */
if (md)
{
NET_mdataStruct *old_md = NULL;
if ( !(old_md = NET_mdataExist(md)))
NET_mdataAdd(md);
else
{
NET_mdataRemove(old_md);
NET_mdataAdd(md);
}
cd = NET_cdataCreate();
cd->ci.type = 0;
cd->is_external = 1;
cd->is_local = 0; /* This is internal; only for user to view */
StrAllocCopy(cd->ci.type, md->contenttype );
/* Does not exist add this contenttype to mime content list */
if ( !(tmp_cd = NET_cdataExist(cd) ) )
NET_cdataAdd(cd);
else /* Already Exist, so we don't need to add it again. Then, free it now */
NET_cdataRemove(cd);
}
free(buffer);
FREEIF(mc->contenttype);
FREEIF(mc->command);
FREEIF(mc->testcommand);
FREEIF(mc->label);
FREEIF(mc->xmode);
return(1);
}
/* reads a mailcap file and adds entries to the
* external viewers converter list
*/
PUBLIC int
NET_ProcessMailcapFile (char *file, Bool is_local)
{
struct MailcapEntry mc;
FILE *fp;
char *src_string = 0;
TRACEMSG(("Loading types config file '%s'\n", file));
if ( !net_isDir(file) )
{
fp = fopen(file, "r");
while (fp && !feof(fp))
{
ProcessMailcapEntry(fp, &mc, &src_string, is_local);
}
if (fp) fclose(fp);
}
return(-1);
}
PUBLIC XP_List *
mailcap_MasterListPointer(void)
{
return (NET_mcMasterList);
}
PUBLIC NET_mdataStruct *
NET_mdataCreate(void)
{
NET_mdataStruct *md = XP_NEW(NET_mdataStruct);
if(!md)
return(NULL);
memset(md, 0, sizeof(NET_mdataStruct));
return md;
}
PUBLIC void
NET_mdataAdd(NET_mdataStruct *md)
{
XP_ListAddObject(NET_mcMasterList, md);
}
PUBLIC void
NET_mdataRemove(NET_mdataStruct *md)
{
XP_ListRemoveObject(NET_mcMasterList, md);
NET_mdataFree(md);
}
PUBLIC NET_mdataStruct*
NET_mdataExist(NET_mdataStruct *old_md )
{
NET_mdataStruct *found_md = NULL;
NET_mdataStruct *md = NULL;
XP_List *infoList;
infoList = mailcap_MasterListPointer();
if ( !infoList )
return found_md;
while ((md= (NET_mdataStruct *)XP_ListNextObject(infoList)))
{
if ( old_md->contenttype &&
md->contenttype &&
!strcasecomp(old_md->contenttype, md->contenttype))
{
/* found matching type */
found_md = md;
break;
}
}
return found_md;
}
#endif /* XP_UNIX */
#endif /* MOZILLA_CLIENT */

View File

@@ -0,0 +1,54 @@
/* -*- 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.
*/
#include "mkjscfg.h"
#include "cvsimple.h"
#include "prefapi.h"
/*
* jsc_complete
*/
PRIVATE void
jsc_complete(void* bytes, int32 num_bytes)
{
#ifdef DEBUG_malmer
extern FILE* real_stderr;
fwrite(bytes, sizeof(char), num_bytes, real_stderr);
#endif
if ( bytes ) {
PREF_EvaluateConfigScript(bytes, num_bytes, NULL, TRUE, TRUE);
} else {
/* If failover is ok, read the local cached config */
}
/* Need to hash and save to disk here */
}
/*
* NET_JavascriptConfig
*/
MODULE_PRIVATE NET_StreamClass*
NET_JavascriptConfig(int fmt, void* data_obj, URL_Struct* URL_s, MWContext* w)
{
return NET_SimpleStream(fmt, (void*) jsc_complete, URL_s, w);
}

View File

@@ -0,0 +1,28 @@
/* -*- 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.
*/
/* By Daniel Malmer <malmer@netscape.com> */
#ifndef __mkjscfg_h
#define __mkjscfg_h
#include "net.h"
MODULE_PRIVATE NET_StreamClass*
NET_JavascriptConfig(int fmt, void* data_obj, URL_Struct* URL_s, MWContext* w);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,28 @@
/* -*- 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.
*/
#ifndef MKLDAP_H
#define MKLDAP_H
XP_BEGIN_PROTOS
void NET_InitLDAPProtocol(void);
XP_END_PROTOS
#endif

View File

@@ -0,0 +1,854 @@
/* -*- 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.
*/
/*
* state machine to handle mailbox URL
*/
#include "mkutils.h"
#include "mkgeturl.h"
#include "mktcp.h"
#include "mkparse.h"
#include "mkmailbx.h"
#include "msgcom.h"
#include "msgnet.h"
#include "msg_srch.h"
#include "libmime.h"
#include "merrors.h"
#include "mkimap4.h"
/* for XP_GetString() */
#include "xpgetstr.h"
extern int XP_MAIL_READING_FOLDER;
extern int XP_MAIL_READING_MESSAGE;
extern int XP_COMPRESSING_FOLDER;
extern int XP_MAIL_DELIVERING_QUEUED_MESSAGES;
extern int XP_READING_MESSAGE_DONE;
extern int XP_MAIL_READING_FOLDER_DONE;
extern int XP_MAIL_COMPRESSING_FOLDER_DONE;
extern int XP_MAIL_DELIVERING_QUEUED_MESSAGES_DONE;
extern int XP_MAIL_SEARCHING;
extern int MK_OUT_OF_MEMORY;
/* definitions of states for the state machine design
*/
typedef enum _MailboxStates {
MAILBOX_OPEN_FOLDER,
MAILBOX_FINISH_OPEN_FOLDER,
MAILBOX_OPEN_MESSAGE,
MAILBOX_OPEN_STREAM,
MAILBOX_READ_MESSAGE,
MAILBOX_COMPRESS_FOLDER,
MAILBOX_FINISH_COMPRESS_FOLDER,
MAILBOX_BACKGROUND,
MAILBOX_DELIVER_QUEUED,
MAILBOX_FINISH_DELIVER_QUEUED,
MAILBOX_DONE,
MAILBOX_ERROR_DONE,
MAILBOX_FREE,
MAILBOX_COPY_MESSAGES,
MAILBOX_FINISH_COPY_MESSAGES
} MailboxStates;
/* structure to hold data pertaining to the active state of
* a transfer in progress.
*
*/
typedef struct _MailboxConData {
MSG_Pane *pane;
int next_state; /* the next state or action to be taken */
int initial_state; /* why we are here */
Bool pause_for_read; /* Pause now for next read? */
void *folder_ptr;
void *msg_ptr;
void *compress_folder_ptr;
void *deliver_queued_ptr;
void *mailbox_search_ptr;
char *folder_name;
char *msg_id;
int32 msgnum; /* -1 if none specified. */
NET_StreamClass *stream;
XP_Bool destroy_graph_progress; /* do we need to destroy
* graph progress? */
int32 original_content_length; /* the content length at the time of
* calling graph progress */
char *input_buffer;
int32 input_buffer_size;
} MailboxConData;
#define COMPLETE_STREAM (*cd->stream->complete)(cd->stream)
#define ABORT_STREAM(s) (*cd->stream->abort)(cd->stream, s)
#define PUT_STREAM(buf, size) (*cd->stream->put_block) \
(cd->stream, buf, size)
/* forward decl */
PRIVATE int32 net_ProcessMailbox (ActiveEntry *ce);
PRIVATE int32
net_MailboxLoad (ActiveEntry * ce)
{
/* get memory for Connection Data */
MailboxConData * cd;
char *path;
char *search;
char *part;
char *wholeUrl;
/* temp, until imap urls have their own identifier */
if (!XP_STRNCASECMP(ce->URL_s->address, "mailbox://", 10) )
return NET_IMAP4Load(ce);
if (XP_STRCASECMP(ce->URL_s->address, "mailbox:displayattachments") == 0) {
MIME_DisplayAttachmentPane(ce->window_id);
return -1;
}
cd = XP_NEW(MailboxConData);
path = NET_ParseURL(ce->URL_s->address, GET_PATH_PART);
search = NET_ParseURL(ce->URL_s->address, GET_SEARCH_PART);
part = search;
ce->con_data = cd;
if(!ce->con_data)
{
ce->URL_s->error_msg = NET_ExplainErrorDetails(MK_OUT_OF_MEMORY);
ce->status = MK_OUT_OF_MEMORY;
return (ce->status);
}
/* init */
XP_MEMSET(cd, 0, sizeof(MailboxConData));
cd->msgnum = -1;
wholeUrl = XP_STRDUP(ce->URL_s->address);
#ifndef XP_MAC /* #### Giant Evil Mac Pathname Hack */
NET_UnEscape (path);
NET_UnEscape (wholeUrl);
#endif /* !XP_MAC */
cd->pane = ce->URL_s->msg_pane;
if (!cd->pane)
{
#ifdef DEBUG_phil
XP_Trace ("NET_MailboxLoad: url->msg_pane NULL for URL: %s\n", ce->URL_s->address);
#endif
/* If we're displaying a message, there'll be a '?' in the url */
if (XP_STRCHR(wholeUrl, '?'))
{
if (XP_STRSTR(wholeUrl, "?compress-folder") || XP_STRSTR(wholeUrl, "?deliver-queued"))
cd->pane = MSG_FindPane(ce->window_id, MSG_FOLDERPANE); /* ###phil tar to the tarpit */
else
{
/* find a pane, just to get back to the MSG_Master */
MSG_Pane *someRandomPane = MSG_FindPane (ce->window_id, MSG_ANYPANE);
if (someRandomPane)
{
cd->pane = MSG_FindPaneFromUrl(someRandomPane, wholeUrl, MSG_MESSAGEPANE);
/*
** jrm and dmb, 97/02/06: temporary fix, because we MUST have a thread pane
** in order for certain operations to succeed. The macintosh UI can
** forward from the thread pane, with no message pane available, and this
** routine was setting cd->pane to a folderpane, which is a kind of
** pane that really doesn't work. The permanent fix will be to change the
** behavior of MSG_FindPane.
*/
if (!cd->pane)
cd->pane = MSG_FindPaneFromUrl(someRandomPane, wholeUrl, MSG_THREADPANE);
}
}
}
else
cd->pane = MSG_FindPane(ce->window_id, MSG_FOLDERPANE);
if (cd->pane == NULL)
{
/* find a pane, just to get back to the MSG_Master */
MSG_Pane *someRandomPane = MSG_FindPane (ce->window_id, MSG_ANYPANE);
if (someRandomPane)
cd->pane = MSG_FindPaneFromUrl (someRandomPane, wholeUrl, MSG_MESSAGEPANE);
}
/* ###dmb so there! This whole FindPane stuff is too adhoc. */
if (cd->pane == NULL)
cd->pane = MSG_FindPane(ce->window_id, MSG_FOLDERPANE);
/* km! I agree! */
if (cd->pane == NULL)
cd->pane = MSG_FindPane(ce->window_id, MSG_THREADPANE);
/* ###whs this isn't really true the way things are set up. */
/* XP_ASSERT(cd->pane && MSG_GetContext(cd->pane) == ce->window_id); */
}
if (cd->pane == NULL)
{
FREEIF(wholeUrl);
return -1; /* ### */
}
if (XP_STRCASECMP(wholeUrl, "mailbox:copymessages") == 0)
cd->next_state = MAILBOX_COPY_MESSAGES;
else
{
cd->folder_name = path;
cd->next_state = MAILBOX_OPEN_FOLDER;
}
if (part && *part == '?') part++;
while (part) {
char* amp = XP_STRCHR(part, '&');
if (amp) *amp++ = '\0';
if (XP_STRNCMP(part, "id=", 3) == 0) {
cd->msg_id = XP_STRDUP (NET_UnEscape (part+3));
} else if (XP_STRNCMP(part, "number=", 7) == 0) {
cd->msgnum = atol(part + 7);
if (cd->msgnum == 0 && part[7] != '0') cd->msgnum = -1;
} else if (XP_STRNCMP(part, "uidl=", 5) == 0) {
/* ### Vile hack time. If a UIDL was specified, then tell libmsg about
it, giving it a chance to arrange so that when this URL is all done,
MSG_GetNewMail gets called. */
MSG_PrepareToIncUIDL(cd->pane, ce->URL_s, NET_UnEscape(part + 5));
} else if (ce->URL_s->internal_url &&
XP_STRNCMP(part, "compress-folder", 15) == 0) {
cd->next_state = MAILBOX_COMPRESS_FOLDER;
} else if (ce->URL_s->internal_url &&
XP_STRNCMP(part, "deliver-queued", 14) == 0) {
cd->next_state = MAILBOX_DELIVER_QUEUED;
} else if (ce->URL_s->internal_url &&
XP_STRNCMP(part, "background", 10) == 0) {
cd->next_state = MAILBOX_BACKGROUND;
}
part = amp;
}
FREEIF(search);
FREEIF(wholeUrl);
cd->initial_state = cd->next_state;
/* don't cache mailbox url's */
ce->format_out = CLEAR_CACHE_BIT(ce->format_out);
ce->local_file = TRUE;
ce->socket = NULL;
NET_SetCallNetlibAllTheTime(ce->window_id, "mkmailbx");
return(net_ProcessMailbox(ce));
}
/* This doesn't actually generate HTML - but it is our hook into the
message display code, so that we can get some values out of it
after the headers-to-be-displayed have been parsed.
*/
static char *
mail_generate_html_header_fn (const char *dest, void *closure,
MimeHeaders *headers)
{
ActiveEntry *ce = (ActiveEntry *) closure;
MailboxConData * cd = (MailboxConData *)ce->con_data;
MSG_ActivateReplyOptions (cd->pane, headers);
return 0;
}
static char *
mail_generate_html_footer_fn (const char *dest, void *closure,
MimeHeaders *headers)
{
ActiveEntry *cur_entry = (ActiveEntry *) closure;
MailboxConData * cd = (MailboxConData *)cur_entry->con_data;
char *uidl = (headers
? MimeHeaders_get(headers, HEADER_X_UIDL, FALSE, FALSE)
: 0);
if (uidl)
{
XP_FREE(uidl);
return MSG_GeneratePartialMessageBlurb (cd->pane,
cur_entry->URL_s,
closure, headers);
}
return 0;
}
static char *
mail_generate_reference_url_fn (const char *dest, void *closure,
MimeHeaders *headers)
{
ActiveEntry *cur_entry = (ActiveEntry *) closure;
char *addr = cur_entry->URL_s->address;
char *search = (addr ? XP_STRCHR (addr, '?') : 0);
char *id2;
char *new_dest;
char *result;
if (!dest || !*dest) return 0;
id2 = XP_STRDUP (dest);
if (!id2) return 0;
if (id2[XP_STRLEN (id2)-1] == '>')
id2[XP_STRLEN (id2)-1] = 0;
if (id2[0] == '<')
new_dest = NET_Escape (id2+1, URL_PATH);
else
new_dest = NET_Escape (id2, URL_PATH);
FREEIF (id2);
result = (char *) XP_ALLOC ((search ? search - addr : 0) +
(new_dest ? XP_STRLEN (new_dest) : 0) +
40);
if (result && new_dest)
{
if (search)
{
XP_MEMCPY (result, addr, search - addr);
result[search - addr] = 0;
}
else if (addr)
XP_STRCPY (result, addr);
else
*result = 0;
XP_STRCAT (result, "?id=");
XP_STRCAT (result, new_dest);
if (search && XP_STRSTR (search, "&headers=all"))
XP_STRCAT (result, "&headers=all");
}
FREEIF (new_dest);
return result;
}
static int
net_make_mail_msg_stream (ActiveEntry *ce)
{
MailboxConData * cd = (MailboxConData *)ce->con_data;
StrAllocCopy(ce->URL_s->content_type, MESSAGE_RFC822);
if (ce->format_out == FO_PRESENT || ce->format_out == FO_CACHE_AND_PRESENT)
{
MimeDisplayOptions *opt = XP_NEW (MimeDisplayOptions);
if (!opt) return MK_OUT_OF_MEMORY;
XP_MEMSET (opt, 0, sizeof(*opt));
opt->generate_reference_url_fn = mail_generate_reference_url_fn;
opt->generate_header_html_fn = 0;
opt->generate_post_header_html_fn = mail_generate_html_header_fn;
opt->generate_footer_html_fn = mail_generate_html_footer_fn;
opt->html_closure = ce;
ce->URL_s->fe_data = opt;
}
cd->stream = NET_StreamBuilder(ce->format_out, ce->URL_s, ce->window_id);
if (!cd->stream)
return MK_UNABLE_TO_CONVERT;
else
return 0;
}
/*
* returns negative if the transfer is finished or error'd out
*
* returns zero or more if the transfer needs to be continued.
*/
PRIVATE int32
net_ProcessMailbox (ActiveEntry *ce)
{
MailboxConData * cd = (MailboxConData *)ce->con_data;
/* temp, until imap urls have their own identifier */
if ((!XP_STRNCASECMP(ce->URL_s->address, "mailbox://", 10) ) ||
(!XP_STRNCASECMP(ce->URL_s->address, "view-source:mailbox://",22)))
return NET_ProcessIMAP4(ce);
cd->pause_for_read = FALSE; /* already paused; reset */
while(!cd->pause_for_read)
{
#ifdef DEBUG_username
XP_Trace("NET_ProcessMailbox: at top of loop, state %d, status %d", cd->next_state, ce->status);
#endif
switch(cd->next_state) {
case MAILBOX_OPEN_FOLDER:
if (!ce->URL_s->load_background) {
char *fmt = XP_GetString( XP_MAIL_READING_FOLDER );
char *folder = cd->folder_name;
char *s = XP_STRRCHR (folder, '/');
if (s)
folder = s+1;
s = (char *) XP_ALLOC(XP_STRLEN(fmt) + XP_STRLEN(folder) + 20);
if (s)
{
XP_SPRINTF (s, fmt, folder);
NET_Progress(ce->window_id, s);
XP_FREE(s);
}
}
ce->status = MSG_BeginOpenFolderSock(cd->pane,
cd->folder_name,
cd->msg_id,
cd->msgnum,
&cd->folder_ptr);
if(ce->status == MK_CONNECTED)
{
#ifdef DEBUG_username
XP_Trace ("NET_ProcessMailBox: next state is MAILBOX_OPEN_MESSAGE");
#endif
cd->next_state = MAILBOX_OPEN_MESSAGE;
}
else if(ce->status > -1)
{
#ifdef DEBUG_username
XP_Trace ("NET_ProcessMailBox: next state is MAILBOX_FINISH_OPEN_FOLDER");
#endif
cd->pause_for_read = TRUE;
cd->next_state = MAILBOX_FINISH_OPEN_FOLDER;
}
#ifdef DEBUG_username
XP_Trace ("NET_ProcessMailBox: MAILBOX_OPEN_FOLDER got error %d", ce->status);
#endif
break;
case MAILBOX_FINISH_OPEN_FOLDER:
ce->status = MSG_FinishOpenFolderSock(cd->pane,
cd->folder_name,
cd->msg_id,
cd->msgnum,
&cd->folder_ptr);
if(ce->status == MK_CONNECTED)
{
cd->next_state = MAILBOX_OPEN_MESSAGE;
}
else
{
cd->pause_for_read = TRUE;
}
break;
case MAILBOX_OPEN_MESSAGE:
if(cd->msg_id == NULL && cd->msgnum < 0)
{
/* only open the message if we are actuall
* asking for a message
*/
cd->next_state = MAILBOX_DONE;
}
else
{
if (!ce->URL_s->load_background)
NET_Progress(ce->window_id,
XP_GetString( XP_MAIL_READING_MESSAGE ) );
ce->status = MSG_OpenMessageSock(cd->pane,
cd->folder_name,
cd->msg_id,
cd->msgnum,
cd->folder_ptr,
&cd->msg_ptr,
&ce->URL_s->content_length);
cd->next_state = MAILBOX_OPEN_STREAM;
}
break;
case MAILBOX_OPEN_STREAM:
{
ce->status = net_make_mail_msg_stream (ce);
if (ce->status < 0)
{
ce->URL_s->error_msg = NET_ExplainErrorDetails(ce->status);
return(ce->status);
}
else
{
XP_ASSERT (cd->stream);
cd->next_state = MAILBOX_READ_MESSAGE;
}
if (!ce->URL_s->load_background) {
FE_GraphProgressInit(ce->window_id, ce->URL_s,
ce->URL_s->content_length);
cd->destroy_graph_progress = TRUE;
}
cd->original_content_length = ce->URL_s->content_length;
}
break;
case MAILBOX_READ_MESSAGE:
{
int32 read_size;
cd->pause_for_read = TRUE;
read_size = (*cd->stream->is_write_ready)
(cd->stream);
if (cd->input_buffer == NULL) {
cd->input_buffer_size = 10240;
#ifdef DEBUG_ricardob
cd->input_buffer_size *= 2;
#endif
while (cd->input_buffer == NULL) {
cd->input_buffer =
(char*) XP_ALLOC(cd->input_buffer_size);
if (!cd->input_buffer) {
cd->input_buffer_size /= 2;
if (cd->input_buffer_size < 512) {
ce->status = MK_OUT_OF_MEMORY;
break;
}
}
}
if (cd->input_buffer == NULL) break;
}
if(!read_size)
{
return(0); /* wait until we are ready to write */
}
else
{
read_size = MIN(read_size, cd->input_buffer_size);
}
ce->status = MSG_ReadMessageSock(cd->pane,
cd->folder_name,
cd->msg_ptr,
cd->msg_id,
cd->msgnum,
cd->input_buffer,
read_size);
if(ce->status > 0)
{
ce->bytes_received += ce->status;
if (!ce->URL_s->load_background)
FE_GraphProgress(ce->window_id, ce->URL_s,
ce->bytes_received, ce->status,
ce->URL_s->content_length);
ce->status = PUT_STREAM(cd->input_buffer, ce->status);
}
else if(ce->status == 0)
cd->next_state = MAILBOX_DONE;
}
break;
case MAILBOX_COMPRESS_FOLDER:
if ((cd->initial_state == MAILBOX_COMPRESS_FOLDER) &&
(!ce->URL_s->load_background)) {
char *fmt= XP_GetString( XP_COMPRESSING_FOLDER );
char *folder = cd->folder_name;
char *s = XP_STRRCHR (folder, '/');
if (s)
folder = s+1;
s = (char *)XP_ALLOC (XP_STRLEN(fmt) + XP_STRLEN(folder) + 20);
if (s)
{
XP_SPRINTF (s, fmt, folder);
NET_Progress(ce->window_id, s);
XP_FREE(s);
}
}
ce->status = MSG_BeginCompressFolder(cd->pane, ce->URL_s,
cd->folder_name,
&cd->compress_folder_ptr);
if (ce->status == MK_CONNECTED) {
cd->next_state = MAILBOX_DONE;
} else {
cd->pause_for_read = TRUE;
cd->next_state = MAILBOX_FINISH_COMPRESS_FOLDER;
}
break;
case MAILBOX_FINISH_COMPRESS_FOLDER:
ce->status = MSG_FinishCompressFolder(cd->pane, ce->URL_s,
cd->folder_name,
cd->compress_folder_ptr);
if (ce->status == MK_CONNECTED) {
cd->next_state = MAILBOX_DONE;
} else {
cd->pause_for_read = TRUE;
}
break;
case MAILBOX_BACKGROUND:
ce->status = MSG_ProcessBackground(ce->URL_s);
if (ce->status == MK_CONNECTED) {
cd->next_state = MAILBOX_DONE;
} else {
cd->pause_for_read = TRUE;
}
break;
case MAILBOX_DELIVER_QUEUED:
if (!ce->URL_s->load_background)
NET_Progress(ce->window_id,
XP_GetString( XP_MAIL_DELIVERING_QUEUED_MESSAGES ) );
ce->status = MSG_BeginDeliverQueued(cd->pane, ce->URL_s,
&cd->deliver_queued_ptr);
if (ce->status == MK_CONNECTED) {
cd->next_state = MAILBOX_DONE;
} else {
cd->pause_for_read = TRUE;
cd->next_state = MAILBOX_FINISH_DELIVER_QUEUED;
}
break;
case MAILBOX_FINISH_DELIVER_QUEUED:
ce->status = MSG_FinishDeliverQueued(cd->pane, ce->URL_s,
cd->deliver_queued_ptr);
if (ce->status == MK_CONNECTED) {
cd->next_state = MAILBOX_DONE;
} else {
cd->pause_for_read = TRUE;
}
break;
case MAILBOX_COPY_MESSAGES:
ce->status = MSG_BeginCopyingMessages(ce->window_id);
if (ce->status == MK_CONNECTED)
cd->next_state = MAILBOX_DONE;
else
{
cd->pause_for_read = TRUE;
cd->next_state = MAILBOX_FINISH_COPY_MESSAGES;
}
break;
case MAILBOX_FINISH_COPY_MESSAGES:
ce->status = MSG_FinishCopyingMessages(ce->window_id);
if (ce->status == MK_CONNECTED)
cd->next_state = MAILBOX_DONE;
else
cd->pause_for_read = TRUE;
break;
case MAILBOX_DONE:
if(cd->stream)
{
COMPLETE_STREAM;
FREE(cd->stream);
}
cd->next_state = MAILBOX_FREE;
break;
case MAILBOX_ERROR_DONE:
if(cd->stream)
{
ABORT_STREAM(ce->status);
FREE(cd->stream);
}
cd->next_state = MAILBOX_FREE;
if (ce->status < -1 && !ce->URL_s->error_msg)
ce->URL_s->error_msg = NET_ExplainErrorDetails(ce->status);
break;
case MAILBOX_FREE:
NET_ClearCallNetlibAllTheTime(ce->window_id, "mkmailbx");
if (cd->input_buffer) {
XP_FREE(cd->input_buffer);
cd->input_buffer = NULL;
}
if(cd->destroy_graph_progress)
FE_GraphProgressDestroy(ce->window_id,
ce->URL_s,
cd->original_content_length,
ce->bytes_received);
if(cd->msg_ptr)
{
MSG_CloseMessageSock(cd->pane, cd->folder_name,
cd->msg_id, cd->msgnum, cd->msg_ptr);
cd->msg_ptr = NULL;
if (!ce->URL_s->load_background)
NET_Progress(ce->window_id,
XP_GetString( XP_READING_MESSAGE_DONE ) );
}
if(cd->folder_ptr)
{
MSG_CloseFolderSock(cd->pane, cd->folder_name,
cd->msg_id, cd->msgnum, cd->folder_ptr);
if ((cd->msg_id == NULL && cd->msgnum < 0) &&
(!ce->URL_s->load_background))
/* If we read a message, don't hide the previous message
with this one. */
NET_Progress(ce->window_id,
XP_GetString( XP_MAIL_READING_FOLDER_DONE ) );
}
if(cd->compress_folder_ptr)
{
MSG_CloseCompressFolderSock(cd->pane, ce->URL_s,
cd->compress_folder_ptr);
cd->compress_folder_ptr = NULL;
if ((cd->initial_state == MAILBOX_COMPRESS_FOLDER) &&
(!ce->URL_s->load_background))
NET_Progress(ce->window_id,
XP_GetString( XP_MAIL_COMPRESSING_FOLDER_DONE ) );
}
if(cd->deliver_queued_ptr)
{
MSG_CloseDeliverQueuedSock(cd->pane, ce->URL_s,
cd->deliver_queued_ptr);
cd->deliver_queued_ptr = NULL;
if (!ce->URL_s->load_background)
NET_Progress(ce->window_id,
XP_GetString( XP_MAIL_DELIVERING_QUEUED_MESSAGES_DONE ) );
}
FREEIF(cd->folder_name);
FREEIF(cd->msg_id);
FREE(cd);
return(-1); /* final end */
default: /* should never happen !!! */
TRACEMSG(("MAILBOX: BAD STATE!"));
XP_ASSERT(0);
cd->next_state = MAILBOX_ERROR_DONE;
break;
}
/* check for errors during load and call error
* state if found
*/
if(ce->status < 0 && cd->next_state != MAILBOX_FREE)
{
cd->next_state = MAILBOX_ERROR_DONE;
/* don't exit! loop around again and do the free case */
cd->pause_for_read = FALSE;
}
} /* while(!cd->pause_for_read) */
#ifdef DEBUG_username
XP_Trace ("Leaving NET_ProcessMailbox with status %d", ce->status);
#endif
return(ce->status);
}
/* abort the connection in progress
*/
PRIVATE int32
net_InterruptMailbox(ActiveEntry * ce)
{
MailboxConData * cd = (MailboxConData *)ce->con_data;
/* temp until imap urls have their own identifier */
if (!XP_STRNCASECMP(ce->URL_s->address, "mailbox://", 10) )
return NET_InterruptIMAP4(ce);
cd->next_state = MAILBOX_ERROR_DONE;
ce->status = MK_INTERRUPTED;
return(net_ProcessMailbox(ce));
}
/* Free any memory that might be used in caching etc.
*/
PRIVATE void
net_CleanupMailbox(void)
{
/* nothing so far needs freeing */
return;
}
MODULE_PRIVATE void
NET_InitMailboxProtocol(void)
{
static NET_ProtoImpl mailbox_proto_impl;
mailbox_proto_impl.init = net_MailboxLoad;
mailbox_proto_impl.process = net_ProcessMailbox;
mailbox_proto_impl.interrupt = net_InterruptMailbox;
mailbox_proto_impl.cleanup = net_CleanupMailbox;
NET_RegisterProtocolImplementation(&mailbox_proto_impl, MAILBOX_TYPE_URL);
}
/* Since each search may be composed of multiple distinct URLs to
* process, use a "search:" URL as a meta-URL which schedules the
* subparts for processing
*/
PRIVATE int32
net_ProcessMsgSearch (ActiveEntry *ce)
{
/* MailboxConData *cd = (MailboxConData *) ce->con_data;*/
int retVal = MSG_ProcessSearch (ce->window_id);
ce->status = 0;
if (0 != retVal)
{
/* stop this crazy thing */
NET_ClearCallNetlibAllTheTime(ce->window_id, "mkmailbx");
}
return retVal;
}
PRIVATE int32
net_MsgSearchLoad (ActiveEntry *ce)
{
/* don't cache search urls */
ce->format_out = CLEAR_CACHE_BIT(ce->format_out);
ce->local_file = TRUE;
ce->socket = NULL;
NET_SetCallNetlibAllTheTime(ce->window_id, "mkmailbx");
return 0;
}
PRIVATE int32
net_InterruptMsgSearch (ActiveEntry *ce)
{
return MSG_InterruptSearch (ce->window_id);
}
/* Free any memory that might be used in caching etc.
*/
PRIVATE void
net_CleanupMsgSearch(void)
{
/* nothing so far needs freeing */
return;
}
MODULE_PRIVATE void
NET_InitMsgSearchProtocol(void)
{
static NET_ProtoImpl msgsearch_proto_impl;
msgsearch_proto_impl.init = net_MsgSearchLoad;
msgsearch_proto_impl.process = net_ProcessMsgSearch;
msgsearch_proto_impl.interrupt = net_InterruptMsgSearch;
msgsearch_proto_impl.cleanup = net_CleanupMsgSearch;
NET_RegisterProtocolImplementation(&msgsearch_proto_impl, MSG_SEARCH_TYPE_URL);
}

View File

@@ -0,0 +1,26 @@
/* -*- 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.
*/
#ifndef MK_MAILBX_H
#define MK_MAILBX_H
extern void NET_InitMailboxProtocol(void);
extern void NET_InitMsgSearchProtocol(void);
#endif /* MK_MAILBX_H */

View File

@@ -0,0 +1,52 @@
/* -*- 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.
*/
// mkmarimb.cpp -- Handles "castanet:" URLs for core Navigator, without
// requiring libmsg.
//
#include "mkutils.h"
#include "mkgeturl.h"
#include "mkmarimb.h"
#include "xpgetstr.h"
#include "net.h"
#include "xp_str.h"
#include "client.h"
/* a stub */
MODULE_PRIVATE void
NET_InitMarimbaProtocol(void)
{
return;
}
/* this is a stub converter
*/
PUBLIC NET_StreamClass *
NET_DoMarimbaApplication(int format_out,
void *data_obj,
URL_Struct *url_struct,
MWContext *context)
{
return(NULL);
}

View File

@@ -0,0 +1,47 @@
/* -*- 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.
*/
#ifndef MKMARIMBA_H
#define MKMARIMBA_H
XP_BEGIN_PROTOS
extern void NET_InitMarimbaProtocol(void);
/* MIME Stuff */
typedef struct _NET_AppMarimbaStruct {
MWContext *context;
int32 content_length;
int32 bytes_read;
int32 bytes_alloc;
char *channelData;
} NET_ApplicationMarimbaStruct;
NET_StreamClass * NET_DoMarimbaApplication(int format_out,
void *data_obj,
URL_Struct *url_struct,
MWContext *context);
XP_END_PROTOS
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,71 @@
/* -*- 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.
*/
#ifndef MK_MEMORY_CACHE_H
/* A pointer to this struct is passed as the converter_obj argument to
* NET_MemCacheConverter.
*/
typedef struct net_MemCacheConverterObject {
NET_StreamClass *next_stream;
XP_Bool dont_hold_URL_s;
} net_MemCacheConverterObject;
extern NET_StreamClass *
NET_MemCacheConverter (FO_Present_Types format_out,
void *converter_obj,
URL_Struct *URL_s,
MWContext *window_id);
extern int
NET_FindURLInMemCache(URL_Struct * URL_s, MWContext *ctxt);
extern void
NET_InitMemCacProtocol(void);
/* remove a URL from the memory cache
*/
extern void
NET_RemoveURLFromMemCache(URL_Struct *URL_s);
/* create an HTML stream and push a bunch of HTML about
* the memory cache
*/
extern void
NET_DisplayMemCacheInfoAsHTML(ActiveEntry * cur_entry);
/* set or unset a lock on a memory cache object
*/
extern void
NET_ChangeMemCacheLock(URL_Struct *URL_s, Bool set);
/* Create a wysiwyg cache converter to a copy of the current entry for URL_s.
*/
extern NET_StreamClass *
net_CloneWysiwygMemCacheEntry(MWContext *window_id, URL_Struct *URL_s,
uint32 nbytes, const char * wysiwyg_url,
const char * base_href);
/* return the first cache object in memory */
extern net_CacheObject *
NET_FirstMemCacheObject(XP_List* list_ptr);
/* return the next cache object in memory */
extern net_CacheObject *
NET_NextMemCacheObject(XP_List* list_ptr);
#endif /* MK_MEMORY_CACHE_H */

View File

@@ -0,0 +1,204 @@
/* -*- 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.
*/
#include "mkutils.h"
#include "mktcp.h"
#include "gui.h"
#include "merrors.h"
#include "xpgetstr.h"
/*
* hack alert: this file contains a switch statement with a gazillion cases,
* so I'd prefer to use enums instead of extern ints in this case -- erik
*/
#define WANT_ENUM_STRING_IDS
#include "allxpstr.h"
#ifndef XP_UNIX
#include <stdarg.h>
#endif /* !XP_UNIX */
/*
* This function takes an error code and associated error data
* and creates a string containing a textual description of
* what the error is and why it happened.
*
* The returned string is allocated and thus should be freed
* once it has been used.
*/
PUBLIC char *
NET_ExplainErrorDetails (int code, ...)
{
va_list args;
char *msg = 0;
int sub_error;
va_start (args, code);
if (IS_SSL_ERROR(code) || IS_SEC_ERROR(code)) {
const char *s = XP_GetString(code);
msg = (s ? XP_STRDUP(s) : 0);
}
if (!msg)
switch(code) {
case MK_INTERRUPTED:
case MK_USE_FTP_INSTEAD:
case MK_USE_COPY_FROM_CACHE:
case MK_MAILTO_NOT_READY:
case MK_UNABLE_TO_LOGIN:
case MK_UNABLE_TO_CONVERT:
case MK_IMAGE_LOSSAGE: /* image library generic error */
case MK_ERROR_SENDING_DATA_COMMAND:
case MK_OFFLINE:
msg = NULL;
break;
case MK_REDIRECT_ATTEMPT_NOT_ALLOWED:
case MK_SERVER_TIMEOUT:
case MK_CONNECTION_TIMED_OUT:
case MK_OUT_OF_MEMORY:
case MK_TIMEBOMB_URL_PROHIBIT:
case MK_TIMEBOMB_MESSAGE:
case MK_RELATIVE_TIMEBOMB_MESSAGE:
case MK_NO_WAIS_PROXY:
case MK_CREATING_NEWSRC_FILE:
case MK_NNTP_SERVER_NOT_CONFIGURED:
case MK_NNTP_NEWSGROUP_SCAN_ERROR:
case MK_ZERO_LENGTH_FILE:
case MK_BAD_CONNECT:
case MK_UNABLE_TO_USE_PASV_FTP:
case MK_UNABLE_TO_CHANGE_FTP_MODE:
case MK_UNABLE_TO_FTP_CWD:
case MK_UNABLE_TO_SEND_PORT_COMMAND:
case MK_UNABLE_TO_ACCEPT_SOCKET:
case MK_UNABLE_TO_CONNECT2:
case MK_BAD_NNTP_CONNECTION:
case MK_NNTP_SERVER_ERROR:
case MK_SERVER_DISCONNECTED:
case MK_NEWS_ITEM_UNAVAILABLE:
case MK_UNABLE_TO_OPEN_NEWSRC:
case MK_COULD_NOT_LOGIN_TO_SMTP_SERVER:
case MK_MSG_NO_SMTP_HOST:
case MK_COULD_NOT_GET_USERS_MAIL_ADDRESS:
case MK_UNABLE_TO_CONNECT_TO_PROXY:
case MK_UNABLE_TO_LOCATE_PROXY:
case MK_DISK_FULL:
case MK_PRINT_LOSSAGE:
case MK_SECURE_NEWS_PROXY_ERROR:
case MK_SIGNATURE_TOO_LONG:
case MK_SIGNATURE_TOO_WIDE:
case MK_POP3_SERVER_ERROR:
case MK_POP3_USERNAME_UNDEFINED:
case MK_POP3_PASSWORD_UNDEFINED:
case MK_POP3_USERNAME_FAILURE:
case MK_POP3_PASSWORD_FAILURE:
case MK_POP3_NO_MESSAGES:
case MK_POP3_LIST_FAILURE:
case MK_POP3_LAST_FAILURE:
case MK_POP3_RETR_FAILURE:
case MK_POP3_DELE_FAILURE:
case MK_POP3_OUT_OF_DISK_SPACE:
case MK_POP3_MESSAGE_WRITE_ERROR:
case MK_MIME_NO_SENDER:
case MK_MIME_NO_RECIPIENTS:
case MK_MIME_NO_SUBJECT:
case MK_MIME_ERROR_WRITING_FILE:
case MK_MIME_MULTIPART_BLURB:
case MK_MSG_CANT_COPY_TO_SAME_FOLDER:
case MK_MSG_CANT_COPY_TO_QUEUE_FOLDER:
case MK_MSG_CANT_COPY_TO_QUEUE_FOLDER_OLD:
case MK_MSG_CANT_COPY_TO_DRAFTS_FOLDER:
case MK_MSG_CANT_CREATE_FOLDER:
case MK_MSG_FOLDER_ALREADY_EXISTS:
case MK_MSG_FOLDER_NOT_EMPTY:
case MK_MSG_CANT_DELETE_FOLDER:
case MK_MSG_CANT_CREATE_INBOX:
case MK_MSG_CANT_CREATE_MAIL_DIR:
case MK_MSG_NO_POP_HOST:
case MK_MSG_MESSAGE_CANCELLED:
case MK_MSG_FOLDER_UNREADABLE:
case MK_MSG_FOLDER_SUMMARY_UNREADABLE:
case MK_MSG_TMP_FOLDER_UNWRITABLE:
case MK_MSG_ID_NOT_IN_FOLDER:
case MK_MSG_NEWSRC_UNPARSABLE:
case MK_MSG_NO_RETURN_ADDRESS:
case MK_MSG_ERROR_WRITING_NEWSRC:
case MK_MSG_ERROR_WRITING_MAIL_FOLDER:
case MK_MSG_SEARCH_FAILED:
case MK_MSG_FOLDER_BUSY:
msg = XP_STRDUP(XP_GetString(code));
break;
case MK_TCP_READ_ERROR:
case MK_TCP_WRITE_ERROR:
case MK_UNABLE_TO_CREATE_SOCKET:
case MK_UNABLE_TO_CONNECT:
case MK_HTTP_TYPE_CONFLICT:
case MK_TCP_ERROR:
sub_error = va_arg(args, int);
if (IS_SSL_ERROR(sub_error) || IS_SEC_ERROR(sub_error)) {
/*
* For SSL/SEC errors, use the message without a wrapper.
*/
msg = XP_STRDUP(XP_GetString(sub_error));
} else if (code == MK_UNABLE_TO_CONNECT &&
(sub_error == XP_ERRNO_EINVAL
|| sub_error == XP_ERRNO_EADDRINUSE)) {
/*
* With unable-to-connect errors, some errno values/strings
* are not more helpful, so just use a plain message for these.
*/
msg = XP_STRDUP(XP_GetString(MK_UNABLE_TO_CONNECT2));
} else {
msg = PR_smprintf(XP_GetString(code), XP_GetString(sub_error));
}
break;
case MK_MALFORMED_URL_ERROR:
case MK_COULD_NOT_PUT_FILE:
case MK_UNABLE_TO_LOCATE_FILE:
case MK_NNTP_AUTH_FAILED:
case MK_UNABLE_TO_LOCATE_HOST:
case MK_UNABLE_TO_LOCATE_SOCKS_HOST:
case MK_UNABLE_TO_OPEN_FILE:
case MK_UNABLE_TO_OPEN_TMP_FILE:
case MK_CONNECTION_REFUSED:
case MK_NNTP_ERROR_MESSAGE:
case MK_MSG_COULDNT_OPEN_FCC_FILE:
case MK_TIMEBOMB_WARNING_MESSAGE:
case MK_RELATIVE_TIMEBOMB_WARNING_MESSAGE:
case MK_ERROR_SENDING_FROM_COMMAND:
case MK_ERROR_SENDING_RCPT_COMMAND:
case MK_ERROR_SENDING_MESSAGE:
case MK_SMTP_SERVER_ERROR:
msg = PR_vsmprintf(XP_GetString(code), args);
break;
case -1:
default:
msg = PR_smprintf(XP_GetString(MK_COMMUNICATIONS_ERROR), code);
break;
}
va_end (args);
TRACEMSG(("NET_ExplainErrorDetails generated: %s", msg ? msg : "(none)"));
return(msg);
}

View File

@@ -0,0 +1,749 @@
/* -*- 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.
*/
/* Please leave at the top for windows precompiled headers */
#include "mkutils.h"
#include <stddef.h>
#include <memory.h>
#include <time.h>
#include "net.h"
#include "xp.h"
#include "libmocha.h"
#include "mkgeturl.h"
#include "mkmocha.h"
#include "libevent.h"
#include "fe_proto.h"
#include "pa_tags.h" /* included via -I../libparse */
#include "libi18n.h" /* unicode */
#include "layout.h" /* for lo_ContextToCell only */
extern char lm_unknown_origin_str[];
extern int MK_OUT_OF_MEMORY;
extern int MK_MALFORMED_URL_ERROR;
typedef struct {
char * buffer;
size_t offset;
size_t length;
MWContext * context;
char * content_type;
int16 char_set;
} MochaStream;
typedef struct {
int32 ref_count;
ActiveEntry * active_entry;
PRPackedBool is_valid;
PRPackedBool eval_what;
PRPackedBool single_shot;
PRPackedBool polling;
char * str;
size_t len;
MWContext * context;
int status;
char * wysiwyg_url;
char * base_href;
NET_StreamClass * stream;
} MochaConData;
#define HOLD_CON_DATA(con_data) ((con_data)->ref_count++)
#define DROP_CON_DATA(con_data) { \
if (--(con_data)->ref_count == 0) \
free_con_data(con_data); \
}
static void
free_con_data(MochaConData * con_data)
{
XP_FREEIF(con_data->str);
XP_FREEIF(con_data->wysiwyg_url);
XP_FREEIF(con_data->base_href);
XP_FREE(con_data);
}
#define START_POLLING(ae, con_data) { \
(con_data)->polling = TRUE; \
NET_SetCallNetlibAllTheTime((ae)->window_id, "mkmocha"); \
}
#define STOP_POLLING(ae, con_data) { \
NET_ClearCallNetlibAllTheTime((ae)->window_id, "mkmocha"); \
(con_data)->polling = FALSE; \
}
/* forward decl */
PRIVATE int32 net_ProcessMocha(ActiveEntry * ae);
/*
* Add the new bits to our buffer
*/
PRIVATE int
mocha_process(NET_StreamClass *stream, const char *str, int32 len)
{
MochaStream * mocha_stream = (MochaStream *) stream->data_object;
mocha_stream->length += len;
if (!mocha_stream->buffer) {
mocha_stream->buffer = (char *)XP_ALLOC(mocha_stream->length);
}
else {
mocha_stream->buffer = (char *)XP_REALLOC(mocha_stream->buffer,
mocha_stream->length);
}
if (!mocha_stream->buffer) {
return MK_OUT_OF_MEMORY;
}
memcpy(mocha_stream->buffer + mocha_stream->offset, str, len);
mocha_stream->offset += len;
return len;
}
PRIVATE unsigned int
mocha_ready(NET_StreamClass *stream)
{
return MAX_WRITE_READY; /* always ready for writing */
}
/*
* All of the processing for this needs to be done in the mocha thread
*/
PRIVATE void
mocha_complete(NET_StreamClass *stream)
{
void * data;
JSBool isUnicode = JS_FALSE;
MochaStream * mocha_stream = (MochaStream *) stream->data_object;
if (mocha_stream->char_set != CS_DEFAULT) {
uint32 len;
INTL_Unicode * unicode;
/* find out how many unicode characters we'll end up with */
len = INTL_TextToUnicodeLen(mocha_stream->char_set,
(unsigned char *) mocha_stream->buffer,
mocha_stream->length);
unicode = XP_ALLOC(sizeof(INTL_Unicode) * len);
if (!unicode)
return;
/* do the conversion */
mocha_stream->length = INTL_TextToUnicode(mocha_stream->char_set,
(unsigned char *) mocha_stream->buffer,
mocha_stream->length,
unicode,
len);
data = unicode;
isUnicode = JS_TRUE;
XP_FREE(mocha_stream->buffer);
mocha_stream->buffer = NULL;
}
else {
data = mocha_stream->buffer;
}
/* this will grab ownership of data */
ET_MochaStreamComplete(mocha_stream->context, data,
mocha_stream->length,
mocha_stream->content_type,
isUnicode);
XP_FREEIF(mocha_stream->content_type);
XP_FREE(mocha_stream);
}
PRIVATE void
mocha_abort(NET_StreamClass *stream, int status)
{
MochaStream * mocha_stream = (MochaStream *) stream->data_object;
ET_MochaStreamAbort(mocha_stream->context, status);
XP_FREE(mocha_stream->buffer);
XP_FREEIF(mocha_stream->content_type);
XP_FREE(mocha_stream);
}
int16
net_check_for_charset(URL_Struct *url_struct)
{
int i, max;
char *key, *value;
static char charset[] = "charset=";
int len = XP_STRLEN(charset);
max = url_struct->all_headers.empty_index;
for (i = 0; i < max; i++) {
key = url_struct->all_headers.key[i];
/* keep looking until we find the content type one */
if (XP_STRCASECMP(key, "Content-type"))
continue;
value = url_struct->all_headers.value[i];
/* don't bother unless this is a JS file to begin with */
if (!strcasestr(value, APPLICATION_JAVASCRIPT))
return CS_DEFAULT;
value = XP_STRTOK(value, ";");
while (value) {
value = XP_StripLine(value);
if (!strncasecomp(value, charset, len)) {
value += len;
value = XP_StripLine(value);
return (INTL_CharSetNameToID(value));
}
/* move to next arg */
value = XP_STRTOK(NULL, ";");
}
/* found content-type but no charset */
return CS_DEFAULT;
}
/* didn't find content-type */
return CS_DEFAULT;
}
static char *
getOriginFromURLStruct(MWContext *context, URL_Struct *url_struct)
{
char *referer;
/*
* Look in url_struct->origin_url for this javascript: URL's
* original referrer.
*
* In the basis case, a javascript: or *.js URL targets a context
* from a (the same, or not) context loaded with a non-javascript URL.
* The referring document's URL is in url_struct->referer and we
* duplicate it as origin_url. If we find a non-null origin_url
* later, we know by induction where it came from.
*/
referer = url_struct->origin_url;
if (referer == NULL) {
/*
* url_struct->referer (sic) tells the URL of the page in
* which a javascript: or *.js link or form was clicked or submitted.
* If it's non-null, but the context is a frame cell that's
* being (re-)created for this load, don't use referer as the
* decoder's source URL for the evaluation, because the FE has
* arbitrarily set it to the top frameset's URL. Instead, use
* the immediate parent frameset context's wysiwyg URL to get
* the origin of the generator (or the parent's address URL if
* not wysiwyg).
*
* If referer is null, the user typed this javascript: URL or
* its frameset's URL directly into the Location toolbar.
*/
referer = url_struct->referer;
if (referer) {
lo_GridRec *grid = NULL;
if (context->is_grid_cell &&
!lo_ContextToCell(context, FALSE, &grid)) {
/*
* Context is a frame being (re)created: veto referer.
* The javascript: or *.js URL can't be a LAYER SRC= URL in a
* frame because the frame's cell must point to its
* context by the time the first tag (even LAYER) is
* processed by layout.
*/
referer = NULL;
}
}
if (!referer) {
History_entry *he;
if (context->grid_parent) {
/*
* If grid parent, use its history entry to get the
* wysiwyg or real URL, which tells the subject origin
* of (any code in it that may have generated) this
* javascript: or *.js URL open. If no grid parent, this must
* be a javascript: or *.js URL that was typed directly into
* Location.
*/
context = context->grid_parent;
}
he = SHIST_GetCurrent(&context->hist);
if (!he) {
referer = lm_unknown_origin_str;
} else {
referer = he->wysiwyg_url;
if (!referer)
referer = he->address;
}
}
}
XP_ASSERT(referer);
referer = XP_STRDUP(referer);
if (!referer) {
return NULL;
}
url_struct->origin_url = referer;
return referer;
}
NET_StreamClass *
NET_CreateMochaConverter(FO_Present_Types format_out,
void *data_object,
URL_Struct *url_struct,
MWContext *context)
{
MochaStream * mocha_stream;
NET_StreamClass *stream;
char *origin;
mocha_stream = (MochaStream *) XP_NEW_ZAP(MochaStream);
if (!mocha_stream)
return NULL;
mocha_stream->context = context;
mocha_stream->content_type = XP_STRDUP(url_struct->content_type);
mocha_stream->char_set = net_check_for_charset(url_struct);
/* Get the origin from the URL struct. We don't have to free origin
* here because url_struct->origin_url owns it.
*/
origin = getOriginFromURLStruct(context, url_struct);
if (origin == NULL)
return NULL;
if (NET_URL_Type(url_struct->address) == FILE_TYPE_URL &&
NET_URL_Type(origin) != FILE_TYPE_URL)
{
/*
* Don't allow loading a file: URL from a non-file URL to
* prevent privacy attacks against the local machine from
* web pages.
*/
return NULL;
}
stream = NET_NewStream("mocha", mocha_process, mocha_complete,
mocha_abort, mocha_ready, mocha_stream,
context);
return stream;
}
PRIVATE void
mk_mocha_eval_exit_fn(void * data, char * str, size_t len, char * wysiwyg_url,
char * base_href, Bool valid)
{
MochaConData * con_data = (MochaConData *) data;
if (!valid) {
con_data->status = MK_MALFORMED_URL_ERROR;
con_data->is_valid = TRUE;
return;
}
if (str == NULL) {
con_data->status = MK_DATA_LOADED;
con_data->is_valid = TRUE;
return;
}
con_data->base_href = base_href;
con_data->wysiwyg_url = wysiwyg_url;
con_data->str = str;
con_data->len = len;
con_data->is_valid = TRUE;
}
/*
* Handle both 'mocha:<stuff>' urls and the mocha type-in widget
*/
MODULE_PRIVATE int32
net_MochaLoad(ActiveEntry *ae)
{
MWContext *context;
URL_Struct *url_struct;
char *what;
Bool eval_what, single_shot;
MochaConData * con_data;
context = ae->window_id;
url_struct = ae->URL_s;
what = XP_STRCHR(url_struct->address, ':');
XP_ASSERT(what);
what++;
eval_what = FALSE;
single_shot = (*what != '?');
if (single_shot) {
/* Don't use an existing Mocha output window's stream. */
if (*what == '\0') {
/* Generate two grid cells, one for output and one for input. */
what = PR_smprintf("<frameset rows=\"75%%,25%%\">\n"
"<frame name=MochaOutput src=about:blank>\n"
"<frame name=MochaInput src=%.*s#input>\n"
"</frameset>",
what - url_struct->address,
url_struct->address);
} else if (!XP_STRCMP(what, "#input")) {
/* The input cell contains a form with one magic isindex field. */
what = PR_smprintf("<b>%.*s typein</b>\n"
"<form action=%.*s target=MochaOutput"
" onsubmit='this.isindex.focus()'>\n"
"<input name=isindex size=60>\n"
"</form>",
what - url_struct->address - 1,
url_struct->address,
what - url_struct->address,
url_struct->address);
url_struct->internal_url = TRUE;
} else {
eval_what = TRUE;
}
} else {
/* Use the Mocha output window if it exists. */
url_struct->auto_scroll = 1000;
/* Skip the leading question-mark and clean up the string. */
what++;
NET_PlusToSpace(what);
NET_UnEscape(what);
eval_what = TRUE;
}
/* something got hosed. bail */
if (!what) {
ae->status = MK_OUT_OF_MEMORY;
return -1;
}
/* make space for the connection data */
con_data = XP_NEW_ZAP(MochaConData);
if (!con_data) {
ae->status = MK_OUT_OF_MEMORY;
return -1;
}
/* remember for next time */
con_data->ref_count = 1;
con_data->active_entry = ae;
ae->con_data = con_data;
/* set up some state so we remember where we are */
con_data->eval_what = eval_what;
con_data->single_shot = single_shot;
con_data->context = context;
/* fake out netlib so we don't select on the socket id */
ae->socket = NULL;
ae->local_file = TRUE;
if (eval_what) {
char *referer;
JSPrincipals *principals;
ETEvalStuff *stuff;
referer = getOriginFromURLStruct(context, url_struct);
if (!referer) {
ae->status = MK_OUT_OF_MEMORY;
return -1;
}
principals = LM_NewJSPrincipals(NULL, NULL, referer);
if (!principals) {
ae->status = MK_OUT_OF_MEMORY;
return -1;
}
/*
* send the buffer off to be evaluated
*/
stuff = (ETEvalStuff *) XP_NEW_ZAP(ETEvalStuff);
if (!stuff) {
ae->status = MK_OUT_OF_MEMORY;
return -1;
}
stuff->len = XP_STRLEN(what);
stuff->line_no = 0;
stuff->scope_to = NULL;
stuff->want_result = JS_TRUE;
stuff->data = con_data;
stuff->version = JSVERSION_UNKNOWN;
stuff->principals = principals;
ET_EvaluateScript(context, what, stuff, mk_mocha_eval_exit_fn);
}
else {
/* allocated above, don't need to free */
con_data->str = what;
con_data->len = XP_STRLEN(what);
con_data->is_valid = TRUE;
}
/* make sure netlib gets called so we know when our data gets back */
START_POLLING(ae, con_data);
/* ya'll come back now, ya'hear? */
return net_ProcessMocha(ae);
}
PRIVATE int
net_process_mocha(MochaConData * con_data)
{
int32 ref_count;
ref_count = con_data->ref_count;
DROP_CON_DATA(con_data);
if (ref_count == 1 || !con_data->active_entry)
return -1;
return net_ProcessMocha(con_data->active_entry);
}
static char nscp_open_tag[] = "<" PT_NSCP_OPEN ">";
/*
* If the mocha has finished evaluation shove the result
* down the stream and continue else just wait
*/
PRIVATE int32
net_ProcessMocha(ActiveEntry * ae)
{
FO_Present_Types output_format;
Bool to_layout;
Bool first_time;
NET_StreamClass *stream = NULL;
MochaConData * con_data = (MochaConData *) ae->con_data;
MWContext * context;
int status;
/* if we haven't gotten our data yet just return and wait */
if (!con_data || !con_data->is_valid)
return 0;
context = ae->window_id;
/*
* Race with the mocha thread until we can grab the JSLock
*/
if (!con_data->single_shot) {
MochaDecoder * decoder;
HOLD_CON_DATA(con_data);
if (!LM_AttemptLockJS((JSLockReleaseFunc)net_process_mocha, con_data))
return 0;
DROP_CON_DATA(con_data);
decoder = LM_GetMochaDecoder(context);
if (!decoder) {
LM_UnlockJS();
ae->status = MK_OUT_OF_MEMORY;
goto done;
}
stream = decoder->stream;
LM_PutMochaDecoder(decoder);
LM_UnlockJS();
}
else {
stream = con_data->stream;
}
/* we've gotten valid data, clear the callme all the time flag */
STOP_POLLING(ae, con_data);
/* see if there were any problems */
if (con_data->status < 0 || con_data->str == NULL) {
ET_SendLoadEvent(context, EVENT_LOAD, NULL, NULL,
LO_DOCUMENT_LAYER_ID, FALSE);
ae->status = con_data->status;
goto done;
}
/*
* If we don't already have a stream to take our output create one now
*/
first_time = !stream;
if (first_time) {
StrAllocCopy(ae->URL_s->content_type, TEXT_HTML);
ae->format_out = CLEAR_CACHE_BIT(ae->format_out);
stream = NET_StreamBuilder(ae->format_out, ae->URL_s, ae->window_id);
if (!stream) {
ae->status = MK_UNABLE_TO_CONVERT;
goto done;
}
}
/*
* If the stream we just created isn't ready for writing just
* hold onto the stream and try again later
*/
if (!stream->is_write_ready(stream)) {
con_data->stream = stream;
START_POLLING(ae, con_data);
return 0;
}
/* XXX this condition is fairly bogus */
output_format = CLEAR_CACHE_BIT(ae->format_out);
to_layout = (output_format != FO_INTERNAL_IMAGE &&
output_format != FO_MULTIPART_IMAGE &&
output_format != FO_EMBED &&
output_format != FO_PLUGIN);
if (to_layout) {
/* The string must end in a newline so the parser will flush it. */
if (con_data->len != 0 && con_data->str[con_data->len-1] != '\n') {
size_t new_len = con_data->len + 1;
char * new_str = XP_ALLOC((new_len + 1) * sizeof(char));
if (!new_str) {
ae->status = MK_OUT_OF_MEMORY;
goto done;
}
XP_MEMCPY(new_str, con_data->str, con_data->len);
new_str[new_len-1] = '\n';
new_str[new_len] = '\0';
con_data->str = new_str;
con_data->len = new_len;
}
}
/*
* If this is the first time do some initial setup. We'll set
* the window title and maybe shove out a <BASE> tag
*/
status = 0;
if (to_layout && first_time && con_data->eval_what) {
/* Feed layout an internal tag so it will create a new top state. */
stream->put_block(stream, nscp_open_tag,
sizeof nscp_open_tag - 1);
(void) LM_WysiwygCacheConverter(context, ae->URL_s,
con_data->wysiwyg_url,
con_data->base_href);
if (*con_data->str != '<') {
char * prefix = NULL;
StrAllocCopy(prefix, "<TITLE>");
StrAllocCat(prefix, ae->URL_s->address);
StrAllocCat(prefix, "</TITLE><PLAINTEXT>");
if (!prefix) {
ae->status = MK_OUT_OF_MEMORY;
goto done;
}
status = (*stream->put_block)(stream, prefix,
XP_STRLEN(prefix));
XP_FREE(prefix);
}
else {
if (con_data->base_href) {
status = (*stream->put_block)(stream,
con_data->base_href,
XP_STRLEN(con_data->base_href));
}
}
}
if (status >= 0) {
status = (*stream->put_block)(stream, con_data->str,
(int32)con_data->len);
}
if (con_data->single_shot && status >= 0)
(*stream->complete)(stream);
if (!con_data->single_shot && status >= 0) {
if (first_time) {
ET_SetDecoderStream(context, stream, ae->URL_s, JS_TRUE);
goto done;
}
} else {
if (status < 0)
(*stream->abort)(stream, status);
if (first_time)
XP_DELETE(stream);
}
ae->status = MK_DATA_LOADED;
done:
ae->con_data = NULL;
con_data->active_entry = NULL;
DROP_CON_DATA(con_data);
return -1;
}
PRIVATE int32
net_InterruptMocha(ActiveEntry *ae)
{
MochaConData * con_data = (MochaConData *) ae->con_data;
if (!con_data)
return MK_INTERRUPTED;
/* do we need to decrement the callme all the time flag? */
if (con_data->polling) {
STOP_POLLING(ae, con_data);
}
/* ae is about to go away, break its connection with con_data */
ae->con_data = NULL;
con_data->active_entry = NULL;
/* ae is about to go away, better get it off the JS lock waiters list */
if (LM_ClearAttemptLockJS((JSLockReleaseFunc)net_process_mocha, con_data))
DROP_CON_DATA(con_data);
return ae->status = MK_INTERRUPTED;
}
PRIVATE void
net_CleanupMocha(void)
{
/* nothing so far needs freeing */
return;
}
MODULE_PRIVATE void
NET_InitMochaProtocol(void)
{
static NET_ProtoImpl mocha_proto_impl;
mocha_proto_impl.init = net_MochaLoad;
mocha_proto_impl.process = net_ProcessMocha;
mocha_proto_impl.interrupt = net_InterruptMocha;
mocha_proto_impl.cleanup = net_CleanupMocha;
NET_RegisterProtocolImplementation(&mocha_proto_impl, MOCHA_TYPE_URL);
}

View File

@@ -0,0 +1,26 @@
/* -*- 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.
*/
#ifndef MKMOCHA_H
#define MKMOCHA_H
/*
* Mocha netlib-specific stuff.
*/
extern void NET_InitMochaProtocol(void);
#endif /* MKMOCHA_H */

5326
mozilla/lib/libnet/mknews.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
/* -*- 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.
*/
#ifndef MKNEWS_H
#define MKNEWS_H
#ifndef MKGETURL_H
#include "mkgeturl.h"
#endif /* MKGETURL_H */
extern CONST char * NET_MKGetNewsHost ();
extern int net_InitializeNewsFeData (ActiveEntry * cur_entry);
extern void NET_InitNewsProtocol(void);
#endif /* MKNEWS_H */

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More