home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / libnet / mkgeturl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  164.6 KB  |  5,878 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. /*
  19.  * mkgeturl.c
  20.  *  This file implements the main calling api for netlib.
  21.  *    Includes NET_InitNetlib, NET_Shutdown, NET_GetURL, and NET_ProcessNet
  22.  *
  23.  * Designed and originally implemented by Lou Montulli '94
  24.  * Additions/Changes by Judson Valeski, Gagan Saksena 1997.
  25.  */
  26. #include "mkutils.h"
  27. #include "mkgeturl.h"
  28. #include "shist.h"
  29. #include "mkparse.h"
  30. #include "mkformat.h"
  31. #include "mkstream.h"
  32. #include "mkpadpac.h"
  33.  
  34. #include "mkhttp.h"
  35. #include "mkftp.h"
  36. #include "mkgopher.h"
  37. #include "mkremote.h"
  38. #include "mknews.h"
  39. #include "mkpop3.h"
  40. #include "mkdaturl.h"
  41. #include "mkfile.h"
  42. #include "mksmtp.h"
  43. #include "mkcache.h"
  44. #include "mkmemcac.h"
  45. #include "glhist.h"
  46. #include "mkaccess.h"
  47. #include "mkmailbx.h"
  48. #include "mkautocf.h"
  49. #include "mkmarimb.h"
  50. #include "mkabook.h"
  51. #include "mkhelp.h"
  52. #include "ssl.h"
  53. #include "mkcertld.h"
  54.  
  55. #ifdef MOZ_LDAP
  56. #incclude "mkldap.h"
  57. #endif
  58.  
  59. #ifdef MOZ_MAIL_NEWS
  60. #include "mkimap4.h"
  61. #endif
  62.  
  63. #include "mktcp.h"  /* for NET_InGetHostByName semaphore */
  64. #include "cert.h"
  65. #ifdef MOZILLA_CLIENT
  66. #include "secnav.h"
  67. #ifdef MOCHA
  68. #include "libmocha.h"
  69. #include "libevent.h"
  70. #include "jscompat.h"
  71. #include "jspubtd.h"
  72. #endif
  73. #endif
  74.  
  75. #include "libimg.h"             /* Image Lib public API. */ 
  76. #include "il_strm.h"             /* Image Lib public API. */
  77.  
  78. #include "libi18n.h"
  79. #include "xp_sec.h"
  80. #include "mkmocha.h"
  81. #include "htmldlgs.h"
  82.  
  83. #include "np.h"
  84. #include "prefapi.h"
  85. #ifdef NSPR20
  86. #ifdef XP_MAC
  87. #include "prpriv.h"             /* for NewNamedMonitor */
  88. #else
  89. #include "private/prpriv.h"
  90. #endif
  91. #endif /* NSPR20 */
  92.  
  93. #include "sslerr.h"
  94. #include "xp_error.h"
  95. #include "merrors.h"
  96. #include "prefetch.h"
  97.  
  98. #ifdef XP_OS2
  99. #include "os2sock.h"
  100. #endif
  101.              
  102. #ifdef EDITOR
  103. #include "edt.h"
  104. #endif
  105.  
  106. #ifdef MOCHA
  107. #include "libmocha.h"
  108. #endif
  109.  
  110. #ifdef XP_UNIX
  111. #include "prnetdb.h"
  112. #else
  113. #define PRHostEnt struct hostent
  114. #endif
  115.  
  116. #include "xplocale.h"
  117.  
  118. /* This is only until all platforms have libfont/ checked in */
  119. #define WEBFONTS
  120.  
  121. #ifdef WEBFONTS
  122. #include "nf.h"
  123. #endif /* WEBFONTS */
  124.  
  125. /* plugins:  */
  126. #include "np.h"
  127.  
  128. /* for XP_GetString() */
  129. #include "xpgetstr.h"
  130. extern int MK_CONNECTION_REFUSED;
  131. extern int MK_CONNECTION_TIMED_OUT;
  132. extern int MK_MALFORMED_URL_ERROR;
  133. extern int MK_OUT_OF_MEMORY;
  134. extern int MK_RELATIVE_TIMEBOMB_MESSAGE;
  135. extern int MK_RELATIVE_TIMEBOMB_WARNING_MESSAGE;
  136. extern int MK_TIMEBOMB_MESSAGE;
  137. extern int MK_TIMEBOMB_URL_PROHIBIT;
  138. extern int MK_TIMEBOMB_WARNING_MESSAGE;
  139. extern int MK_UNABLE_TO_CONNECT;
  140. extern int MK_UNABLE_TO_CREATE_SOCKET;
  141. extern int MK_UNABLE_TO_LOCATE_HOST;
  142. extern int MK_UNABLE_TO_LOCATE_PROXY;
  143. extern int XP_ALERT_CONNECTION_LESSZERO;
  144. extern int XP_ALERT_INTERRUPT_WINDOW;
  145. extern int XP_ALERT_URLS_LESSZERO;
  146. extern int XP_CONFIRM_REPOST_FORMDATA;
  147. extern int XP_CONSULT_SYS_ADMIN;
  148. extern int XP_HTML_MISSING_REPLYDATA;
  149. extern int XP_SOCKS_NS_ENV_VAR;
  150. extern int XP_SOME_HOSTS_UNREACHABLE;
  151. extern int XP_THIS_IS_DNS_VERSION;
  152. extern int XP_THIS_IS_YP_VERSION;
  153. extern int XP_UNKNOWN_HOST;
  154. extern int XP_UNKNOWN_HOSTS;
  155. extern int XP_UNKNOWN_HTTP_PROXY;
  156. extern int XP_UNKNOWN_SOCKS_HOST;
  157. extern int XP_URLS_WAITING_FOR_AN_OPEN_SOCKET;
  158. extern int XP_URLS_WAITING_FOR_FEWER_ACTIVE_URLS;
  159. extern int XP_CONNECTIONS_OPEN;
  160. extern int XP_ACTIVE_URLS;
  161. extern int XP_USING_PREVIOUSLY_CACHED_COPY_INSTEAD;
  162. extern int XP_BAD_AUTOCONFIG_NO_FAILOVER;
  163.  
  164. extern int XP_SOCK_CON_SOCK_PROTOCOL;                   
  165. extern int XP_URL_NOT_FOUND_IN_CACHE;                   
  166. extern int XP_PARTIAL_CACHE_ENTRY;
  167. extern int XP_CHECKING_SERVER__FORCE_RELOAD;
  168. extern int XP_OBJECT_HAS_EXPIRED;
  169. extern int XP_CHECKING_SERVER_CACHE_ENTRY;
  170. extern int XP_CHECKING_SERVER__LASTMOD_MISS;
  171. extern int XP_NETSITE_  ;
  172. extern int XP_LOCATION_ ;
  173. extern int XP_FILE_MIME_TYPE_   ;
  174. extern int XP_CURRENTLY_UNKNOWN;
  175. extern int XP_SOURCE_ ;
  176. extern int XP_CURRENTLY_IN_DISK_CACHE   ;
  177. extern int XP_CURRENTLY_IN_MEM_CACHE; 
  178. extern int XP_CURRENTLY_NO_CACHE        ;
  179. extern int XP_LOCAL_CACHE_FILE_ ;
  180. extern int XP_NONE      ;
  181. extern int XP_LOCAL_TIME_FMT ;
  182. extern int XP_LAST_MODIFIED ;
  183. extern int XP_GMT_TIME_FMT      ;
  184. extern int XP_CONTENT_LENGTH_   ;
  185. extern int XP_NO_DATE_GIVEN;
  186. extern int XP_EXPIRES_  ;
  187. extern int XP_MAC_TYPE_ ;
  188. extern int XP_MAC_CREATOR_      ;
  189. extern int XP_CHARSET_  ;
  190. extern int XP_STATUS_UNKNOWN ;
  191. extern int XP_SECURITY_ ;
  192. extern int XP_CERTIFICATE_      ;
  193. extern int XP_UNTITLED_DOCUMENT ;
  194. extern int XP_HAS_THE_FOLLOWING_STRUCT  ;
  195. extern int XP_DOCUMENT_INFO ;
  196. extern int XP_THE_WINDOW_IS_NOW_INACTIVE ;
  197. extern int XP_MSG_UNKNOWN ;
  198. extern int XP_EDIT_NEW_DOC_URL;
  199. extern int XP_EDIT_NEW_DOC_NAME;
  200. extern int XP_CONFIRM_MAILTO_POST_1;
  201. extern int XP_CONFIRM_MAILTO_POST_2;
  202.  
  203. extern int XP_ALERT_OFFLINE_MODE_SELECTED;
  204.  
  205.  
  206. #if defined(JAVA)
  207. #include "nslocks.h"
  208. #include "prlog.h"
  209. #include <stdarg.h>
  210.  
  211. PRMonitor* libnet_asyncIO;
  212.  
  213. #if defined(SOLARIS)
  214. extern int gethostname(char *, int);
  215. #endif /* SOLARIS */
  216.  
  217. #endif /* JAVA */
  218.  
  219. #define LIBNET_UNLOCK_AND_RETURN(value) \
  220.     do { int rv = (value); LIBNET_UNLOCK(); return rv; } while (0)
  221.  
  222. /*
  223. ** Don't ever forget about this!!!
  224. **
  225. ** This is ALL superseeded by the setting in /ns/modules/libpref/src/init/all.js
  226. ** lock for timebomb.use_timebomb
  227.  
  228. ** Define TIMEBOMB_ON for beta builds.
  229. ** Undef TIMEBOMB_ON for release builds.
  230. */
  231. #define TIMEBOMB_ON
  232. /* #undef TIMEBOMB_ON  */
  233. /*
  234. ** After this date all hell breaks loose
  235. */
  236. #define TIME_BOMB_TIME          888739203       /* 3/01/98 + 3 secs */
  237. #ifdef XP_OS2
  238. #define TIME_BOMB_WARNING_TIME  869976003       /* 7/21/97 + 3 secs */
  239. #else
  240. #define TIME_BOMB_WARNING_TIME  857203203       /* 3/01/97 + 3 secs */
  241. #endif
  242.  
  243. #ifndef XP_UNIX
  244. #ifdef NADA_VERSION
  245. static char *https_security = "SECURITY_VERSION: -https";
  246. #else
  247. static char *https_security = "SECURITY_VERSION: +https";
  248. #endif
  249. #endif
  250.  
  251. #ifdef EDITOR
  252. /* 
  253.  * Strings used for new, empty document creation
  254.  * Kluge we use to load a new document is resource with one space.
  255.  * These strings are loaded from XP_MSG.I on first GetURL call
  256.  * (this allows changing "Untitled" for other languages)
  257. */
  258. PUBLIC char *XP_NEW_DOC_URL = NULL; /* "about:editfilenew" */
  259. /* 
  260.  * This is the name we want to appear as the URL address
  261.  * You can load a new doc using this - it will be changed 
  262.  *  to XP_NEW_DOC_URL. 
  263.  * When done, XP_NEW_DOC_URL will be changed to XP_NEW_DOC_NAME
  264. */
  265. PUBLIC char *XP_NEW_DOC_NAME = NULL; /* "Untitled" */
  266. #endif
  267.  
  268. #ifdef PROFILE
  269. #pragma profile on
  270. #endif
  271.  
  272. /* forward decl's */
  273. PRIVATE void add_slash_to_URL (URL_Struct *URL_s);
  274. PRIVATE Bool override_proxy (CONST char * URL);
  275. PRIVATE int net_output_about_url(ActiveEntry * this_entry);
  276. PRIVATE int net_output_security_url(ActiveEntry * this_entry, MWContext *cx);
  277. PRIVATE Bool net_about_kludge(URL_Struct *URL_s);
  278. PRIVATE void net_FreeURLAllHeaders(URL_Struct * URL_s);
  279. PRIVATE void NET_InitAboutProtocol(void);
  280. PRIVATE void NET_InitSecurityProtocol(void);
  281.  
  282. PRIVATE NET_TimeBombActive = FALSE;
  283.  
  284. typedef struct _WaitingURLStruct {
  285.     int                 type;
  286.     URL_Struct         *URL_s;
  287.     FO_Present_Types    format_out;
  288.     MWContext          *window_id;
  289.     Net_GetUrlExitFunc *exit_routine;
  290. } WaitingURLStruct;
  291.  
  292. /* Pointers to proxy servers
  293.  * They are pointers to a host if
  294.  * a proxy environment variable
  295.  * was found or they are zero if not.
  296.  */
  297. PRIVATE char * MKftp_proxy=0;
  298. PRIVATE char * MKgopher_proxy=0;
  299. PRIVATE char * MKhttp_proxy=0;
  300. PRIVATE char * MKhttps_proxy=0;
  301. PRIVATE char * MKwais_proxy=0;
  302. PRIVATE char * MKnews_proxy=0;
  303. PRIVATE char * MKno_proxy=0;
  304. PRIVATE char * MKproxy_ac_url=0;
  305. PRIVATE NET_ProxyStyle MKproxy_style = PROXY_STYLE_UNSET;
  306.  
  307. PRIVATE char * MKglobal_config_url = 0;
  308.  
  309. PRIVATE XP_List * net_EntryList=0;
  310.  
  311. MODULE_PRIVATE CacheUseEnum NET_CacheUseMethod=CU_CHECK_PER_SESSION;
  312.  
  313. #ifdef XP_WIN16
  314. #define MAX_NUMBER_OF_PROCESSING_URLS 8
  315. #else
  316. #define MAX_NUMBER_OF_PROCESSING_URLS 15
  317. #endif
  318.  
  319. #define INITIAL_MAX_ALL_HEADERS 10
  320. #define MULT_ALL_HEADER_COUNT   2
  321. #define MAX_ALL_HEADER_COUNT    16000
  322.  
  323. #ifndef XP_MAC
  324.     /* I don't want these annoying asserts in the Mac build but in case some other platform does... */
  325.     #define DO_ANNOYING_ASSERTS_IN_STUBS    1
  326. #endif
  327.  
  328. MODULE_PRIVATE time_t NET_StartupTime=0;
  329.  
  330. MODULE_PRIVATE XP_Bool NET_ProxyAcLoaded = FALSE;
  331. MODULE_PRIVATE XP_Bool NET_GlobalAcLoaded = FALSE;
  332. MODULE_PRIVATE int NET_TotalNumberOfOpenConnections=0;
  333. MODULE_PRIVATE int NET_MaxNumberOfOpenConnections=100;
  334. MODULE_PRIVATE int NET_MaxNumberOfOpenConnectionsPerContext=4;
  335. MODULE_PRIVATE int NET_TotalNumberOfProcessingURLs=0;
  336. PRIVATE XP_List  * net_waiting_for_actives_url_list=0;
  337. PRIVATE XP_List  * net_waiting_for_connection_url_list=0;
  338.  
  339. typedef struct NETExitCallbackNode {
  340.     struct NETExitCallbackNode *next;
  341.     void *arg;
  342.     void (* func)(void *arg);
  343. } NETExitCallbackNode;
  344.  
  345. PRIVATE NETExitCallbackNode *NETExitCallbackHead = NULL;
  346.  
  347. /* forward decl */
  348. PRIVATE void net_cleanup_reg_protocol_impls(void);
  349. PRIVATE void NET_InitTotallyRandomStuffPeopleAddedProtocols(void);
  350.  
  351.  
  352.  
  353. /* fix Mac warning for missing prototype */
  354. PUBLIC void
  355. NET_AddExitCallback( void (* func)(void *arg), void *arg);
  356.  
  357. PUBLIC void
  358. NET_AddExitCallback( void (* func)(void *arg), void *arg)
  359. {
  360.     NETExitCallbackNode *node;
  361.     
  362.     /* alloc node */
  363.     node = XP_ALLOC(sizeof(NETExitCallbackNode));
  364.     if ( node != NULL ) {
  365.         /* fill it in */
  366.         node->func = func;
  367.         node->arg = arg;
  368.         /* link it into the list */
  369.         node->next = NETExitCallbackHead;
  370.         NETExitCallbackHead = node;
  371.     }
  372.     
  373.     return;
  374. }
  375.  
  376. PRIVATE void
  377. NET_ProcessExitCallbacks(void)
  378. {
  379.     NETExitCallbackNode *node, *freenode;
  380.  
  381.     node = NETExitCallbackHead;
  382.     
  383.     while ( node != NULL ) {
  384.         (* node->func)(node->arg);
  385.         freenode = node;
  386.         node = node->next;
  387.         XP_FREE(freenode);
  388.     }
  389.     
  390.     NETExitCallbackHead = NULL;
  391.     
  392.     return;
  393. }
  394.  
  395. /*  Gather manual proxy information from the prefapi. Called from 
  396.    SetupPrefs and SelectProxyStyle */
  397. PRIVATE void
  398. NET_UpdateManualProxyInfo(const char * prefChanged) {
  399.  
  400.     XP_Bool bSetupAll=FALSE;
  401.     char * proxy = NULL;
  402.     int32 iPort=0;
  403.     char text[MAXHOSTNAMELEN + 8];
  404.  
  405.     if (!prefChanged)
  406.         bSetupAll = TRUE;
  407.  
  408.     if (bSetupAll || !XP_STRCMP(prefChanged, "network.proxy.ftp") || 
  409.         !XP_STRCMP(prefChanged, "network.proxy.ftp_port")) {
  410.         PREF_CopyCharPref("network.proxy.ftp",&proxy);
  411.         if(proxy && *proxy) {
  412.             PREF_GetIntPref("network.proxy.ftp_port",&iPort);
  413.             sprintf(text,"%s:%d", proxy, iPort);
  414.             StrAllocCopy(MKftp_proxy, text);
  415.             iPort=0;
  416.         }
  417.         else 
  418.             FREE_AND_CLEAR(MKftp_proxy);
  419.     }
  420.     if (proxy) FREE_AND_CLEAR(proxy);
  421.  
  422.     if (bSetupAll || !XP_STRCMP(prefChanged, "network.proxy.gopher") || 
  423.         !XP_STRCMP(prefChanged, "network.proxy.gopher_port")) {
  424.         PREF_CopyCharPref("network.proxy.gopher",&proxy);
  425.         if(proxy && *proxy) {
  426.             PREF_GetIntPref("network.proxy.gopher_port",&iPort);
  427.             sprintf(text,"%s:%d", proxy, iPort);  
  428.             StrAllocCopy(MKgopher_proxy, text);
  429.             iPort=0;
  430.         }
  431.         else 
  432.             FREE_AND_CLEAR(MKgopher_proxy);
  433.     }
  434.     if (proxy) FREE_AND_CLEAR(proxy);
  435.  
  436.     if (bSetupAll || !XP_STRCMP(prefChanged, "network.proxy.http") || 
  437.         !XP_STRCMP(prefChanged, "network.proxy.http_port")) {
  438.         PREF_CopyCharPref("network.proxy.http",&proxy);
  439.         if(proxy && *proxy) {
  440.             PREF_GetIntPref("network.proxy.http_port",&iPort);
  441.             sprintf(text,"%s:%d", proxy, iPort);  
  442.             StrAllocCopy(MKhttp_proxy, text);
  443.             iPort=0;
  444.         }
  445.         else 
  446.             FREE_AND_CLEAR(MKhttp_proxy);
  447.     }
  448.     if (proxy) FREE_AND_CLEAR(proxy);
  449.  
  450.     if (bSetupAll || !XP_STRCMP(prefChanged, "network.proxy.ssl") || 
  451.         !XP_STRCMP(prefChanged, "network.proxy.ssl_port")) {
  452.         PREF_CopyCharPref("network.proxy.ssl",&proxy);
  453.         if(proxy && *proxy) {
  454.             PREF_GetIntPref("network.proxy.ssl_port",&iPort);
  455.             sprintf(text,"%s:%d", proxy, iPort);  
  456.             StrAllocCopy(MKhttps_proxy, text);
  457.             iPort=0;
  458.         }
  459.         else 
  460.             FREE_AND_CLEAR(MKhttps_proxy);
  461.     }
  462.     if (proxy) FREE_AND_CLEAR(proxy);
  463.  
  464.     if (bSetupAll || !XP_STRCMP(prefChanged, "network.proxy.news") || 
  465.         !XP_STRCMP(prefChanged, "network.proxy.news_port")) {
  466.         PREF_CopyCharPref("network.proxy.news",&proxy);
  467.         if(proxy && *proxy) {
  468.             PREF_GetIntPref("network.proxy.news_port",&iPort);
  469.             sprintf(text,"%s:%d", proxy, iPort);  
  470.             StrAllocCopy(MKnews_proxy, text);
  471.             iPort=0;
  472.         }
  473.         else 
  474.             FREE_AND_CLEAR(MKnews_proxy);
  475.     }
  476.     if (proxy) FREE_AND_CLEAR(proxy);
  477.  
  478.     if (bSetupAll || !XP_STRCMP(prefChanged, "network.proxy.wais") || 
  479.         !XP_STRCMP(prefChanged, "network.proxy.wais_port")) {
  480.         PREF_CopyCharPref("network.proxy.wais",&proxy);
  481.         if(proxy && *proxy) {
  482.             PREF_GetIntPref("network.proxy.wais_port",&iPort);
  483.             sprintf(text,"%s:%d", proxy, iPort);  
  484.             StrAllocCopy(MKwais_proxy, text);
  485.             iPort=0;
  486.         }
  487.         else 
  488.             FREE_AND_CLEAR(MKwais_proxy);
  489.     }
  490.     if (proxy) FREE_AND_CLEAR(proxy);
  491.  
  492.     if (bSetupAll || !XP_STRCMP(prefChanged, "network.hosts.socks_server") || 
  493.         !XP_STRCMP(prefChanged, "network.hosts.socks_serverport")) {
  494.         PREF_CopyCharPref("network.hosts.socks_server",&proxy);
  495.         if (proxy && *proxy) {
  496.             PREF_GetIntPref("network.hosts.socks_serverport",&iPort);
  497.             PR_snprintf(text, sizeof(text), "%s:%d", proxy, iPort);  
  498.             NET_SetSocksHost(text);
  499.         }
  500.         else {
  501.             NET_SetSocksHost(proxy); /* NULL is ok */
  502.         }
  503.         iPort=0;
  504.     }
  505.     if (proxy) FREE_AND_CLEAR(proxy);
  506.  
  507.     if (bSetupAll || !XP_STRCMP(prefChanged, "network.proxy.no_proxies_on")) {
  508.         PREF_CopyCharPref("network.proxy.no_proxies_on",&proxy);
  509.         if(proxy && *proxy) {
  510.             StrAllocCopy(MKno_proxy, proxy);
  511.         }
  512.         else 
  513.             FREE_AND_CLEAR(MKno_proxy);
  514.     }
  515.     if (proxy) FREE_AND_CLEAR(proxy);
  516.     return;
  517. }
  518.  
  519. PUBLIC NET_ProxyStyle
  520. NET_GetProxyStyle(void)
  521. {
  522.     return MKproxy_style;
  523. }
  524.  
  525. /* These are used in netlib only for exposing the MKproxy_ac_url 
  526.  * to proxy autodiscovery stuff in mkpadpac.c */
  527. MODULE_PRIVATE const char *
  528. net_GetPACUrl(void) {
  529.     return MKproxy_ac_url;
  530. }
  531.  
  532. MODULE_PRIVATE void
  533. net_SetPACUrl(char *u) {
  534.     /* Do a straight assignment, no checking. */
  535.     MKproxy_ac_url=u;
  536. }
  537.  
  538. PUBLIC void
  539. NET_SelectProxyStyle(NET_ProxyStyle style)
  540. {
  541.  /* The NET_ProxyStyle enum is defined in net.h.
  542.     PROXY_STYLE_UNSET               = 0             -- ?
  543.     PROXY_STYLE_MANUAL              = 1             -- old style proxies
  544.     PROXY_STYLE_AUTOMATIC   = 2             -- new style proxies
  545.     PROXY_STYLE_NONE                = 3             -- no proxies, direct connection
  546.  */     
  547.     char * proxy=0;
  548.  
  549.     if (MKproxy_style != style) {
  550.         NET_ProxyAcLoaded = FALSE;
  551.     }
  552.  
  553.     MKproxy_style = style;
  554.  
  555.     if (MKproxy_style == PROXY_STYLE_MANUAL) {
  556.         /* Get the manual info */
  557.         NET_UpdateManualProxyInfo(NULL);
  558.     } 
  559.     
  560.     if (MKproxy_style == PROXY_STYLE_AUTOMATIC) {
  561.         /* Get the autoconfig url */
  562.         PREF_CopyCharPref("network.proxy.autoconfig_url",&proxy);
  563.         if (proxy && *proxy) {
  564.             StrAllocCopy(MKproxy_ac_url, proxy);
  565.             NET_ProxyAcLoaded = FALSE;
  566.         }
  567.         if (proxy) FREE_AND_CLEAR(proxy);
  568.     }
  569.  
  570.     /* If we're not in automatic or manual style, clear un-needed internal info */
  571.     if (MKproxy_style != PROXY_STYLE_AUTOMATIC) {
  572.         FREE_AND_CLEAR(MKproxy_ac_url);
  573.         NET_ProxyAcLoaded = FALSE;
  574.     }
  575.  
  576.     /* If we're not in manual (proxies) clear the un-needed internal info. */
  577.     if (MKproxy_style != PROXY_STYLE_MANUAL) {
  578.         FREE_AND_CLEAR(MKftp_proxy);
  579.         FREE_AND_CLEAR(MKgopher_proxy);
  580.         FREE_AND_CLEAR(MKhttp_proxy);
  581.         FREE_AND_CLEAR(MKhttps_proxy);
  582.         FREE_AND_CLEAR(MKwais_proxy);
  583.         FREE_AND_CLEAR(MKnews_proxy);
  584.         FREE_AND_CLEAR(MKno_proxy);
  585.  
  586.         NET_SetSocksHost(NULL);
  587.     } 
  588. }
  589.  
  590. /* this function loads the proxy values from the various preferences and
  591. sets up the internal cached values...It is called during Init and whenever
  592. a proxy pref is changed...If no specific pref is passed, it sets them all
  593. up */
  594.  
  595. PUBLIC void
  596. NET_SetupPrefs(const char * prefChanged)
  597. {
  598.     XP_Bool bSetupAll=FALSE;
  599.     char * proxy = NULL;
  600.  
  601.     /* if prefChanged is null the following XP_STRCMP's are never executed because the
  602.        || statement never gets that far because when prefChanged is null bSetupAll is
  603.        set to true and is always checked first in the if statement. Don't set prefChanged
  604.        to "" if it is null because the UpdateManualProxyInfo below needs null not "" if
  605.        prefChanged was originally null. */
  606.     if (!prefChanged)
  607.         bSetupAll = TRUE;
  608.  
  609.     if (bSetupAll || !XP_STRCMP(prefChanged, "network.sendRefererHeader")) {
  610.         Bool b;
  611.         PREF_GetBoolPref("network.sendRefererHeader", &b);
  612.         NET_SetSendRefererHeader(b);
  613.     }
  614.  
  615.     if (bSetupAll || !XP_STRCMP(prefChanged, "network.dnsCacheExpiration")) {
  616.         int32 n;
  617.         PREF_GetIntPref("network.dnsCacheExpiration",&n);
  618.         NET_SetDNSExpirationPref(n);
  619.     }
  620.     
  621.     if (bSetupAll || !XP_STRCMP(prefChanged,"browser.prefetch")) {
  622.         XP_Bool enabled;
  623.         PREF_GetBoolPref("browser.prefetch",&enabled);
  624.         PRE_Enable(enabled);
  625.     }
  626.         
  627.     if (bSetupAll || !XP_STRCMP(prefChanged,"browser.cache.memory_cache_size")) {
  628.         int32 nMemCache;
  629.         PREF_GetIntPref("browser.cache.memory_cache_size",&nMemCache);
  630.         NET_SetMemoryCacheSize(nMemCache * 1024);
  631.     }
  632.  
  633.     if (bSetupAll || !XP_STRCMP(prefChanged,"browser.cache.disk_cache_size")) {
  634.         int32 nDiskCache;
  635.         PREF_GetIntPref("browser.cache.disk_cache_size",&nDiskCache);
  636.         NET_SetDiskCacheSize(nDiskCache * 1024);
  637.     }
  638.  
  639.     if (bSetupAll || !XP_STRCMP(prefChanged, "browser.cache.check_doc_frequency")) {
  640.         int32 nDocReqFreq;
  641.         PREF_GetIntPref("browser.cache.check_doc_frequency" ,&nDocReqFreq);
  642.         NET_SetCacheUseMethod((CacheUseEnum)nDocReqFreq);
  643.     }
  644.     
  645.     if (bSetupAll || !XP_STRCMP(prefChanged,"browser.cache.disk_cache_ssl")) {
  646.         XP_Bool prefBool;
  647.         PREF_GetBoolPref("browser.cache.disk_cache_ssl",&prefBool);
  648.         NET_DontDiskCacheSSL(!prefBool);
  649.     }
  650. #ifdef MOZ_MAIL_NEWS
  651.     if (bSetupAll || !XP_STRCMP(prefChanged,"mail.allow_at_sign_in_user_name")) {
  652.         XP_Bool prefBool;
  653.         PREF_GetBoolPref("mail.allow_at_sign_in_user_name",&prefBool);
  654.         NET_SetAllowAtSignInMailUserName (prefBool);
  655.     }
  656. #endif /* MOZ_MAIL_NEWS */
  657.     
  658.     if (bSetupAll || !XP_STRCMP(prefChanged,"network.proxy.autoconfig_url")) {
  659.         PREF_CopyCharPref("network.proxy.autoconfig_url",&proxy);
  660.         if (proxy && *proxy) {
  661.             StrAllocCopy(MKproxy_ac_url, proxy);
  662.             NET_ProxyAcLoaded = FALSE;
  663.         }
  664.         else 
  665.             FREE_AND_CLEAR(MKproxy_ac_url);
  666.     }
  667.     if (proxy) FREE_AND_CLEAR(proxy);
  668.     
  669.     NET_UpdateManualProxyInfo(prefChanged);
  670.  
  671.     if (bSetupAll || !XP_STRCMP(prefChanged, "network.proxy.type")) {
  672.         int32 iType;
  673.         PREF_GetIntPref("network.proxy.type",&iType);
  674.     NET_SelectProxyStyle((NET_ProxyStyle)iType);
  675.     }
  676. }
  677.  
  678. /* register preference callbacks for netlib prefs
  679. */
  680.  
  681. MODULE_PRIVATE int PR_CALLBACK NET_PrefChangedFunc(const char *pref, void *data) {
  682.     NET_SetupPrefs(pref);
  683.     return TRUE;
  684.  
  685. /* initialize the netlibrary and set the socket buffer size
  686.  */
  687. PUBLIC int
  688. NET_InitNetLib(int socket_buffer_size, int max_number_of_connections)
  689. {
  690.     int status;
  691.  
  692. #if defined(NSPR20) && defined(DEBUG)
  693.         if (NETLIB==NULL)
  694.            NETLIB = PR_NewLogModule("NETLIB");
  695. #endif
  696.  
  697.     TRACEMSG(("Initializing Network library"));
  698.  
  699.     NET_StartupTime = time(NULL);
  700.  
  701.     /* seed the random generator
  702.      */
  703.     XP_SRANDOM((unsigned int) time(NULL));
  704.  
  705.     if(max_number_of_connections < 1)
  706.         max_number_of_connections = 1;
  707.  
  708. #ifdef XP_UNIX
  709.     signal(SIGPIPE, SIG_IGN);
  710. #endif
  711.     
  712.  
  713.     status = NET_ChangeSocketBufferSize(socket_buffer_size);
  714.  
  715.     NET_ChangeMaxNumberOfConnections(max_number_of_connections);
  716.     net_waiting_for_actives_url_list = XP_ListNew();
  717.     net_waiting_for_connection_url_list = XP_ListNew();
  718.  
  719.     net_EntryList = XP_ListNew();
  720.  
  721. #ifdef MOZILLA_CLIENT
  722.     NET_ReadCacheFAT("", TRUE);
  723.  
  724.     NET_ReadCookies("");
  725.  
  726.     
  727. #endif /* MOZILLA_CLIENT */
  728.  
  729.     NET_TotalNumberOfProcessingURLs=0; /* reset */
  730.  
  731. #ifdef XP_UNIX
  732.     {
  733.         char *ac_url = getenv("AUTOCONF_URL");
  734.         if (ac_url) {
  735.             NET_SetProxyServer(PROXY_AUTOCONF_URL, ac_url);
  736.             NET_SelectProxyStyle(PROXY_STYLE_AUTOMATIC);
  737.         }
  738.     }
  739. #endif
  740.  
  741. #ifdef JAVA
  742.     libnet_asyncIO = PR_NewNamedMonitor("libnet");
  743. #endif
  744.     NET_SetupPrefs(NULL);  /* setup initial proxy, socks, dnsExpiration and cache preference info */
  745.     PREF_RegisterCallback("network.proxy",NET_PrefChangedFunc,NULL);
  746.     PREF_RegisterCallback("browser.cache",NET_PrefChangedFunc,NULL);
  747.     PREF_RegisterCallback("network.hosts.socks_server",NET_PrefChangedFunc,NULL);
  748.     PREF_RegisterCallback("network.hosts.socks_serverport",NET_PrefChangedFunc,NULL);
  749.     PREF_RegisterCallback("network.dnsCacheExpiration",NET_DNSExpirationPrefChanged,NULL);
  750.     NET_RegisterCookiePrefCallbacks(); /* simply inits cookie info in mkaccess.c */
  751.                                        /* and registers the callbacks */
  752.     /* inits the proxy autodiscovery vars and registers their callbacks. */
  753.     NET_RegisterPadPrefCallbacks();
  754.     NET_RegisterEnableUrlMatchCallback();
  755.     PREF_RegisterCallback("mail.allow_at_sign_in_user_name", NET_PrefChangedFunc, NULL);
  756.  
  757.     /* initialize protocol modules 
  758.      *
  759.      * eventually this should be done dynamically,
  760.      * but first we need to make URL types be dynamically
  761.      * registered, and make URL parsing dynamic as well.
  762.      *
  763.      * Currently, registering them in the most used order is 
  764.      * very slightly more efficient
  765.      */
  766.     NET_InitFileProtocol();
  767.     NET_InitHTTPProtocol();
  768.     NET_InitMemCacProtocol();
  769.     NET_InitFTPProtocol();
  770.     NET_InitAboutProtocol();
  771.     NET_InitGopherProtocol();
  772.     NET_InitMochaProtocol();
  773.     NET_InitNFSProtocol();
  774.     NET_InitURNProtocol();
  775.     NET_InitWAISProtocol();
  776.     NET_InitRemoteProtocol();
  777.     NET_InitDataURLProtocol();
  778. #ifdef JAVA
  779.     NET_InitMarimbaProtocol();
  780. #endif
  781.     NET_InitTotallyRandomStuffPeopleAddedProtocols();
  782.  
  783.     NET_InitMailtoProtocol();  /* has a stub for MOZ_MAIL_NEWS */
  784. #ifdef MOZ_MAIL_NEWS    
  785.     NET_InitNewsProtocol();
  786.     NET_InitMailboxProtocol();
  787.     NET_InitMsgSearchProtocol();
  788.     NET_InitPop3Protocol();
  789.     NET_InitLDAPProtocol();
  790.     NET_InitCertLdapProtocol();
  791.     NET_InitAddressBookProtocol();
  792. #endif /* MOZ_MAIL_NEWS */
  793.  
  794.     return(status);
  795. }
  796.  
  797. /* set the maximum allowable number of open connections at any one
  798.  * time regardless of the context
  799.  */
  800. PUBLIC void
  801. NET_ChangeMaxNumberOfConnections(int max_number_of_connections)
  802. {
  803.  
  804.     /* if already equal return */
  805.     if(NET_MaxNumberOfOpenConnections == max_number_of_connections)
  806.         return;
  807.  
  808.     if(max_number_of_connections < 1)
  809.         max_number_of_connections = 1;
  810.  
  811.     /* make sure that # conns per context is less than or equal
  812.      * to this Max
  813.      */
  814.     if(NET_MaxNumberOfOpenConnectionsPerContext > max_number_of_connections)
  815.         NET_MaxNumberOfOpenConnectionsPerContext = max_number_of_connections;
  816.  
  817.     NET_MaxNumberOfOpenConnections = max_number_of_connections;
  818.  
  819.     /* close any open connections to prevent deadlock
  820.      */
  821.     net_cleanup_reg_protocol_impls();
  822. }
  823.  
  824. /* set the maximum allowable number of open connections at any one
  825.  * time Per context
  826.  */
  827. PUBLIC void
  828. NET_ChangeMaxNumberOfConnectionsPerContext(int max_number_of_connections)
  829. {
  830.  
  831.     /* if already equal return */
  832.     if(NET_MaxNumberOfOpenConnectionsPerContext == max_number_of_connections)
  833.         return;
  834.  
  835.     /* gate the number of max connections to be within 1 and 4
  836.      */
  837.     if(max_number_of_connections < 1)
  838.         max_number_of_connections = 1;
  839.  
  840.     if(max_number_of_connections > 6)
  841.         max_number_of_connections = 6;
  842.  
  843.     NET_MaxNumberOfOpenConnectionsPerContext = max_number_of_connections;
  844.  
  845.     /* close any open connections to prevent deadlock
  846.      */
  847. /* @@@@    NET_CleanupFTP(); */
  848. #ifdef MOZILLA_CLIENT
  849. #ifdef MOZ_MAIL_NEWS    
  850. /* @@@@    NET_CleanupNews(); */
  851. #endif /* MOZ_MAIL_NEWS */   
  852. #endif /* MOZILLA_CLIENT */
  853.  
  854. }
  855.  
  856. /* check the date and set off the timebomb if necessary
  857.  *
  858.  * Calls FE_Alert with a message and then disables
  859.  * all network calls to hosts not in our domains,
  860.  * except for FTP connects.
  861.  */
  862. PUBLIC Bool
  863. NET_CheckForTimeBomb(MWContext *context)
  864. {
  865.     static Bool done = FALSE;
  866.     time_t cur_time;
  867.     time_t timebomb_time = 0;
  868.     time_t timebomb_warning_time = 0;
  869.     
  870.     int32 relative_timebomb_days = 0;
  871.     int32 relative_timebomb_warning_days = 0;
  872.     time_t relative_timebomb_start_date = 0;
  873.     char *relative_timebomb_prefs_name;
  874.     time_t relative_timebomb_time = 0;
  875.     time_t relative_timebomb_warning_time = 0;
  876.     Bool have_relative_timebomb = FALSE;
  877.     Bool just_started_relative_timebomb = FALSE;
  878.  
  879.     if(done)
  880.         return(NET_TimeBombActive);
  881.  
  882.     /*
  883.      * Check if any timebomb is enabled
  884.      */
  885.     PREF_GetConfigInt("timebomb.expiration_time",(int32 *)&timebomb_time);
  886.     PREF_GetConfigInt("timebomb.relative_timebomb_days",
  887.                                 (int32 *)&relative_timebomb_days);
  888.  
  889.     if (relative_timebomb_days >= 1)
  890.         have_relative_timebomb = TRUE;
  891.  
  892.     done = TRUE;
  893.  
  894.     if ((timebomb_time < 1) && (have_relative_timebomb == FALSE))
  895.         return FALSE;
  896.  
  897.     cur_time  = XP_TIME();
  898.  
  899.     /*
  900.      * check the absolute timebomb
  901.      */
  902.     TRACEMSG(("current time is: %ld %s", cur_time, ctime(&cur_time)));
  903.     TRACEMSG(("Timebomb time is: %ld %s", timebomb_time,ctime(&timebomb_time)));
  904.     if ((timebomb_time >= 1) && (cur_time > timebomb_time))
  905.       {
  906.         char * alert = NET_ExplainErrorDetails(MK_TIMEBOMB_MESSAGE);
  907.  
  908.         FE_Alert(context, alert);
  909.         FREE(alert);
  910.  
  911.         NET_TimeBombActive = TRUE;
  912.  
  913.         return(TRUE);
  914.       }
  915.  
  916.     /*
  917.      * check the relative timebomb
  918.      * (note: we store the start date in prefs using a "secret" name )
  919.      */
  920.     if (have_relative_timebomb) {
  921.         TRACEMSG(("Relative timebomb days = %ld", relative_timebomb_days));
  922.         relative_timebomb_prefs_name = NULL;
  923.         PREF_CopyConfigString("timebomb.relative_timebomb_secret_name",
  924.                                 &relative_timebomb_prefs_name);
  925.         if (relative_timebomb_prefs_name == NULL)
  926.             relative_timebomb_prefs_name = 
  927.                                 XP_STRDUP("general.bproxy_cert_digest");
  928.         relative_timebomb_start_date = 0;
  929.         PREF_GetIntPref(relative_timebomb_prefs_name,
  930.                                 (int32 *)&relative_timebomb_start_date);
  931.  
  932.         if (relative_timebomb_start_date < 1)
  933.         {
  934.             /* if no value must be first time so set start date */
  935.             just_started_relative_timebomb = TRUE;
  936.             relative_timebomb_start_date = cur_time;
  937.             PREF_SetIntPref(relative_timebomb_prefs_name,
  938.                             (int32)relative_timebomb_start_date);
  939.         }
  940.         XP_FREE(relative_timebomb_prefs_name);
  941.         relative_timebomb_time = relative_timebomb_start_date +
  942.                                 (relative_timebomb_days * 24 * 60 * 60);
  943.         if (cur_time > relative_timebomb_time)
  944.         {
  945.             char *alert = NET_ExplainErrorDetails(MK_RELATIVE_TIMEBOMB_MESSAGE);
  946.  
  947.             FE_Alert(context, alert);
  948.             FREE(alert);
  949.  
  950.             NET_TimeBombActive = TRUE;
  951.  
  952.             return(TRUE);
  953.         }
  954.     }
  955.  
  956.     /*
  957.      * check the absolute timebomb warning
  958.      */
  959.     PREF_GetConfigInt("timebomb.warning_time",(int32 *)&timebomb_warning_time);
  960.     TRACEMSG(("Timebomb warning time is: %ld %s", timebomb_warning_time,
  961.                                 ctime(&timebomb_warning_time)));
  962.     if ((timebomb_warning_time >= 1) && (cur_time > timebomb_warning_time))
  963.       {
  964.         char * alert = NET_ExplainErrorDetails( MK_TIMEBOMB_WARNING_MESSAGE,
  965.                                         INTL_ctime(context, &timebomb_time));
  966.         FE_Alert(context, alert);
  967.         FREE(alert);
  968.  
  969.         NET_TimeBombActive = FALSE;
  970.  
  971.         return(FALSE);
  972.       }
  973.  
  974.     /*
  975.      * check the relative timebomb warning
  976.      * also: on first use warn user this is timebombed 
  977.      */
  978.     if (have_relative_timebomb) {
  979.         relative_timebomb_warning_days = 0;
  980.         PREF_GetConfigInt("timebomb.relative_timebomb_warning_days",
  981.                                 (int32 *)&relative_timebomb_warning_days);
  982.         TRACEMSG(("Relative timebomb warning days = %ld", 
  983.                                     relative_timebomb_warning_days));
  984.         if (relative_timebomb_warning_days >= 1)
  985.             relative_timebomb_warning_time = relative_timebomb_start_date +
  986.                                 (relative_timebomb_warning_days * 24 * 60 * 60);
  987.         else
  988.             relative_timebomb_warning_time = cur_time;
  989.         if (just_started_relative_timebomb ||
  990.                 (cur_time > relative_timebomb_warning_time))
  991.         {
  992.             char * alert = NET_ExplainErrorDetails(
  993.                         MK_RELATIVE_TIMEBOMB_WARNING_MESSAGE,
  994.                         INTL_ctime(context, &relative_timebomb_time));
  995.             FE_Alert(context, alert);
  996.             FREE(alert);
  997.  
  998.             NET_TimeBombActive = FALSE;
  999.  
  1000.             return(FALSE);
  1001.         }
  1002.     }
  1003.  
  1004.     return(FALSE);
  1005. }
  1006.  
  1007. /* set the way the cache should be used
  1008.  */
  1009. PUBLIC void
  1010. NET_SetCacheUseMethod(CacheUseEnum method)
  1011. {
  1012.     NET_CacheUseMethod = method;
  1013. }
  1014.  
  1015. PRIVATE void
  1016. net_CallExitRoutine(Net_GetUrlExitFunc *exit_routine,
  1017.                     URL_Struct                 *URL_s,
  1018.                     int                 status,
  1019.                     FO_Present_Types        format_out,
  1020.                     MWContext          *window_id)
  1021. {
  1022. #ifdef EDITOR
  1023.     /* History_entry * his; */
  1024.     /* Change all references to "about:editfilenew" into "file:///Untitled" */
  1025.     /* Do this for both Browser and Editor windows */
  1026.     if( /* EDT_IS_EDITOR(window_id) && */
  1027.     URL_s && URL_s->address &&
  1028.     0 == XP_STRCMP(URL_s->address, XP_NEW_DOC_URL) )
  1029.     {
  1030.     XP_FREE(URL_s->address);
  1031.     URL_s->address = XP_STRDUP(XP_NEW_DOC_NAME);
  1032.        
  1033.     /* Not sure if this is the best place to do this,
  1034.      * but it needs to go someplace!        
  1035.     */
  1036.     LO_SetBaseURL(window_id, XP_NEW_DOC_NAME);
  1037.  
  1038.     /* Setting context title to NULL will trigger
  1039.      * Windows front end to use the URL address and set 
  1040.      * doc and window title to "Untitled"
  1041.      * Do all front ends do this?
  1042.      * If not, they will have to use EDT_IS_NEW_DOCUMENT
  1043.      *  to test for new doc and update title (in exit_routine)
  1044.     */
  1045.     if ( window_id->title ) {
  1046.         XP_FREE(window_id->title);
  1047.         window_id->title = NULL;
  1048.     }
  1049.     /* Note: We replace "about:editfilenew" with "file:///Untitled"
  1050.      * in SHIST_AddDocument(), so we don't need to mess with
  1051.      * History data here.
  1052.     */
  1053.  
  1054.     /* Set  window_id->is_new_document flag appropriately 
  1055.      * This flag allows quicker response for often-called 
  1056.      * status queries at front end
  1057.     */
  1058.     if ( EDT_IS_EDITOR(window_id) ) {
  1059.         EDT_NEW_DOCUMENT(window_id, TRUE);
  1060.     }
  1061.     }
  1062. #endif /* EDITOR */
  1063. #if defined(XP_WIN) || defined (XP_MAC) || defined (XP_OS2)
  1064.     FE_URLEcho(URL_s, status, window_id);
  1065. #endif /* XP_WIN/MAC/OS2 */
  1066.  
  1067.     if (!URL_s->load_background)
  1068.       FE_EnableClicking(window_id);
  1069.  
  1070. #ifdef MOZILLA_CLIENT
  1071.     if(URL_s->refresh_url && status != MK_INTERRUPTED)
  1072.         FE_SetRefreshURLTimer(window_id, URL_s->refresh, URL_s->refresh_url);
  1073. #endif /* MOZILLA_CLIENT */
  1074.  
  1075.     if (URL_s->pre_exit_fn)
  1076.       {
  1077.         Net_GetUrlExitFunc *per = URL_s->pre_exit_fn;
  1078.         URL_s->pre_exit_fn = 0;
  1079.         (*per) (URL_s, status, window_id);
  1080.       }
  1081.     /* byrd:  plugin specific stuff, where we've added our own exit routine:  */
  1082.     if ((URL_s->owner_data != NULL) && 
  1083.         (URL_s->owner_id == 0x0000BAC0)){
  1084.             NPL_URLExit(URL_s,status,window_id);
  1085.     }
  1086.  
  1087.     if ( exit_routine != NULL ) {
  1088.         (*exit_routine) (URL_s, status, window_id);
  1089.     }
  1090. }
  1091.  
  1092. PRIVATE XP_Bool
  1093. net_does_url_require_socket_limit(int urltype)
  1094. {
  1095.     if( urltype == HTTP_TYPE_URL
  1096.     || urltype == SECURE_HTTP_TYPE_URL
  1097.     || urltype == FTP_TYPE_URL
  1098.     || urltype == NEWS_TYPE_URL
  1099.     || urltype == GOPHER_TYPE_URL)
  1100.         return TRUE;
  1101.  
  1102.     return(FALSE);
  1103. }
  1104.  
  1105.  
  1106. PRIVATE XP_Bool
  1107. net_is_one_url_allowed_to_run(MWContext *context, int url_type)
  1108. {
  1109.     /* put a limit on the total number of open connections
  1110.      */
  1111.     if(NET_TotalNumberOfOpenConnections < NET_MaxNumberOfOpenConnectionsPerContext
  1112.     || !net_does_url_require_socket_limit(url_type))
  1113.       {
  1114.         return(TRUE);
  1115.       }
  1116.     else if(NET_TotalNumberOfOpenConnections >= NET_MaxNumberOfOpenConnections)
  1117.       {
  1118.         return(FALSE);
  1119.       }
  1120.     else
  1121.       {
  1122.     XP_List * list_ptr;
  1123.     ActiveEntry * tmpEntry;
  1124.     int32 cur_win_id = FE_GetContextID(context);
  1125.     int real_number_of_connections = 0;
  1126.  
  1127.  
  1128.         /* run through the list of running URLs and check
  1129.          * for open connections only for this context.
  1130.          * This will allow for the Total number of open
  1131.          * connections to only apply to each window not
  1132.          * to the whole program
  1133.          */
  1134.     list_ptr = net_EntryList;
  1135.     while((tmpEntry = (ActiveEntry *) XP_ListNextObject(list_ptr)) != NULL)
  1136.       {
  1137.         if(cur_win_id == FE_GetContextID(tmpEntry->window_id)
  1138.                 && net_does_url_require_socket_limit(url_type))
  1139.               {
  1140.                 real_number_of_connections++;
  1141.           }
  1142.       } /* end while */
  1143.  
  1144.         /* pause it if the number of connections per context
  1145.          * is higher than the per context limit or
  1146.          */
  1147.     if(real_number_of_connections >= NET_MaxNumberOfOpenConnectionsPerContext)
  1148.  
  1149.           {
  1150.             return(FALSE);
  1151.           }
  1152.       }
  1153.  
  1154.     return(TRUE);
  1155. }
  1156.  
  1157. static int
  1158. net_push_url_on_wait_queue(int                 url_type,
  1159.                            URL_Struct         *URL_s,
  1160.                            FO_Present_Types    format_out,
  1161.                            MWContext          *context,
  1162.                            Net_GetUrlExitFunc  exit_routine)
  1163. {
  1164.  
  1165.     WaitingURLStruct * wus = XP_NEW(WaitingURLStruct);
  1166.  
  1167.     TRACEMSG(("Pushing URL on wait queue with %d open connections",
  1168.                      NET_TotalNumberOfOpenConnections ));
  1169.     if(!wus)
  1170.       {
  1171.         net_CallExitRoutine(exit_routine,
  1172.                             URL_s,
  1173.                             MK_OUT_OF_MEMORY,
  1174.                             format_out,
  1175.                             context);
  1176.         return(MK_OUT_OF_MEMORY);
  1177.       }
  1178.  
  1179.     wus->type         = url_type;
  1180.     wus->URL_s        = URL_s;
  1181.     wus->format_out   = format_out;
  1182.     wus->window_id    = context;
  1183.     wus->exit_routine = exit_routine;
  1184.  
  1185.     /* add "text/ *" to beginning of list so it gets processed first */
  1186.     if (CLEAR_CACHE_BIT(format_out) == FO_INTERNAL_IMAGE)
  1187.         /* low priority */
  1188.         XP_ListAddObjectToEnd(net_waiting_for_connection_url_list, wus);
  1189.     else
  1190.         /* higher priority */
  1191.         XP_ListAddObject(net_waiting_for_connection_url_list, wus);
  1192.  
  1193.     return(0);
  1194. }
  1195.  
  1196. /* returns a malloc'd string that has a bunch of netlib
  1197.  * status info in it.
  1198.  *
  1199.  * please free the pointer when done.
  1200.  */
  1201. PUBLIC char *
  1202. NET_PrintNetlibStatus()
  1203. {
  1204.     char small_buf[128];
  1205.     XP_List * list_ptr;
  1206.     ActiveEntry *tmpEntry;
  1207.     char *rv=0;
  1208.  
  1209.     LIBNET_LOCK();
  1210.     list_ptr = net_EntryList;
  1211.  
  1212.     sprintf(small_buf, XP_GetString( XP_URLS_WAITING_FOR_AN_OPEN_SOCKET ),
  1213.                         XP_ListCount(net_waiting_for_connection_url_list),
  1214.                         NET_MaxNumberOfOpenConnectionsPerContext);
  1215.     StrAllocCat(rv, small_buf);
  1216.  
  1217.     sprintf(small_buf, XP_GetString( XP_URLS_WAITING_FOR_FEWER_ACTIVE_URLS ),
  1218.                     XP_ListCount(net_waiting_for_actives_url_list));
  1219.     StrAllocCat(rv, small_buf);
  1220.  
  1221.     sprintf(small_buf, XP_GetString( XP_CONNECTIONS_OPEN ),
  1222.                                         NET_TotalNumberOfOpenConnections);
  1223.     StrAllocCat(rv, small_buf);
  1224.  
  1225.     sprintf(small_buf, XP_GetString( XP_ACTIVE_URLS ),
  1226.     NET_TotalNumberOfProcessingURLs);
  1227.     StrAllocCat(rv, small_buf);
  1228.  
  1229.     while((tmpEntry = (ActiveEntry *)XP_ListNextObject(list_ptr)) != 0)
  1230.      {
  1231.        sprintf(small_buf, "------------------------------------\nURL:");
  1232.        StrAllocCat(rv, small_buf);
  1233.        StrAllocCat(rv, tmpEntry->URL_s->address);
  1234.        StrAllocCat(rv, "\n");
  1235.  
  1236.        sprintf(small_buf, XP_GetString(XP_SOCK_CON_SOCK_PROTOCOL),
  1237.                     tmpEntry->socket, tmpEntry->con_sock, tmpEntry->protocol);
  1238.        StrAllocCat(rv, small_buf);
  1239.      }
  1240.  
  1241. #if defined(DEBUG) && defined(JAVA)
  1242.     {
  1243.         static int loggingOn = 0;
  1244. #ifndef NSPR20
  1245.         NETLIBLog.level = (loggingOn ? PRLogLevel_none : PRLogLevel_debug);
  1246.         NETLIBLog.depth = 0;    /* keep it from auto-initializing */
  1247. #else
  1248.         NETLIB->level = (loggingOn ? PR_LOG_NONE : PR_LOG_DEBUG);
  1249. #endif /* NSPR20 */
  1250.         loggingOn = !loggingOn;
  1251.     }
  1252. #endif /*  defined(DEBUG) && defined(JAVA) */
  1253.  
  1254.     LIBNET_UNLOCK();
  1255.     return(rv);
  1256. }
  1257.  
  1258. #define RELEASE_PREFERRED_URLS TRUE
  1259. #define RELEASE_PREFERRED_OR_NON_PREFERRED FALSE
  1260. #define RELEASE_PREFETCH_URLS TRUE
  1261. #define DONT_RELEASE_PREFETCH_URLS FALSE
  1262. PRIVATE void
  1263. net_release_urls_for_processing(XP_Bool release_prefered, XP_Bool release_prefetch)
  1264. {
  1265.     XP_List * list_ptr = net_waiting_for_connection_url_list;
  1266.     WaitingURLStruct * wus;
  1267.  
  1268.     while((wus = (WaitingURLStruct *)
  1269.                         XP_ListNextObject(list_ptr)) != NULL)
  1270.       {
  1271.  
  1272.         if(!release_prefered
  1273.            || ( (wus->format_out != FO_INTERNAL_IMAGE
  1274.                 && wus->format_out != FO_CACHE_AND_INTERNAL_IMAGE)
  1275. #ifdef MOZILLA_CLIENT
  1276.                 || IL_PreferredStream(wus->URL_s) ) )
  1277. #else
  1278.           ) )
  1279. #endif /* MOZILLA_CLIENT */
  1280.           {
  1281.             /* if the type passed in NOT Prefetch_priority then only
  1282.              * release URL's that are NOT Prefetch_priority
  1283.              */
  1284.             if(release_prefetch || wus->URL_s->priority != Prefetch_priority)
  1285.             {
  1286.                 XP_ListRemoveObject(net_waiting_for_connection_url_list, wus);
  1287.  
  1288.                 /* change prefetch to active prefetch to allow it to load */
  1289.                 if(wus->URL_s->priority == Prefetch_priority)
  1290.                     wus->URL_s->priority = CurrentlyPrefetching_priority;
  1291.  
  1292.                 NET_GetURL(wus->URL_s,
  1293.                            wus->format_out,
  1294.                            wus->window_id,
  1295.                            wus->exit_routine);
  1296.                 FREE(wus);
  1297.                 break;
  1298.             }
  1299.           }
  1300.       }
  1301. }
  1302.  
  1303. PRIVATE void
  1304. net_release_prefetch_urls_for_processing(void)
  1305. {
  1306.     /* for now release just one url at a time to give the best possibility
  1307.      * of individual URL's completeing before the user interrupts things
  1308.      */
  1309.     net_release_urls_for_processing(RELEASE_PREFERRED_OR_NON_PREFERRED, 
  1310.                                     RELEASE_PREFETCH_URLS);
  1311.  
  1312. }
  1313.  
  1314. /*
  1315.  * Must be called under the cover of the LIBNET_LOCK!
  1316.  * 
  1317.  * The was_background parameter is used to determine when to call
  1318.  * FE_AllConnectionsComplete. It should only be called if we've just
  1319.  * completed processing a URL that's *not* a background loading URL.
  1320.  * A background URL is one that loads without UI activity e.g. no
  1321.  * status bar and thermo activity.
  1322.  * This ensures that looping animations don't call 
  1323.  * FE_AllConnectionsComplete on every loop cycle.
  1324. */
  1325. PRIVATE void
  1326. net_CheckForWaitingURL(MWContext * window_id, int protocol, Bool was_background)
  1327. {
  1328. #ifdef NSPR
  1329.     XP_ASSERT(LIBNET_IS_LOCKED());
  1330. #endif
  1331.  
  1332.     /* decrement here since this function is called
  1333.      * after every exit_routine
  1334.      */
  1335.     NET_TotalNumberOfProcessingURLs--;
  1336.  
  1337.     if(NET_TotalNumberOfProcessingURLs < 0)
  1338.       {
  1339.     FE_Alert(window_id, XP_GetString(XP_ALERT_URLS_LESSZERO));
  1340.     NET_TotalNumberOfProcessingURLs = 0;
  1341.       }
  1342.  
  1343.     if(NET_TotalNumberOfOpenConnections < 0)
  1344.       {
  1345.         FE_Alert(window_id, XP_GetString(XP_ALERT_CONNECTION_LESSZERO));
  1346.         NET_TotalNumberOfOpenConnections = 0;
  1347.       }
  1348.  
  1349.     TRACEMSG(("In: net_CheckForWaitingURL with %d connection waiting URL's, %d active waiting URL's and %d open connections",
  1350.           XP_ListCount(net_waiting_for_connection_url_list),
  1351.           XP_ListCount(net_waiting_for_actives_url_list),
  1352.           NET_TotalNumberOfOpenConnections));
  1353.  
  1354.     /* release preferred streams first */
  1355.     net_release_urls_for_processing(RELEASE_PREFERRED_URLS,
  1356.                                     DONT_RELEASE_PREFETCH_URLS);
  1357.  
  1358.     /* release non-prefered streams */
  1359.     net_release_urls_for_processing(RELEASE_PREFERRED_OR_NON_PREFERRED, 
  1360.                                     DONT_RELEASE_PREFETCH_URLS);
  1361.  
  1362.  
  1363.     if(!NET_AreThereActiveConnectionsForWindow(window_id))
  1364.       {
  1365.         /* if there are prefetch URL's in the queue then we
  1366.          * arn't quite done yet
  1367.          */
  1368.         net_release_prefetch_urls_for_processing();
  1369.  
  1370.         if(!was_background)
  1371.         {
  1372.             ET_SendLoadEvent(window_id, EVENT_XFER_DONE, 
  1373.                      NULL, NULL, LO_DOCUMENT_LAYER_ID,
  1374.                      FALSE);
  1375.             FE_AllConnectionsComplete(window_id);
  1376.         }
  1377.       }
  1378.  
  1379. }
  1380.  
  1381. PRIVATE int
  1382. net_AbortWaitingURL(MWContext * window_id, Bool all, XP_List *list)
  1383. {
  1384.     XP_List * list_ptr;                     /* Can't initialize here as list might be null */
  1385.     XP_List * prev_list_ptr = list;
  1386.     XP_List * tmp_list_ptr;
  1387.     WaitingURLStruct * wus;
  1388.     int32 cur_win_id=0;
  1389.     int number_killed = 0;
  1390.  
  1391.     /* make sure we actually got a list of things to Abort */
  1392.     if (!list)
  1393.         return(number_killed);
  1394.     
  1395.     /* Now initialize the list pointer */
  1396.     list_ptr = list->next;
  1397.     
  1398.     if(!all && window_id)
  1399.         cur_win_id = FE_GetContextID(window_id);
  1400.  
  1401.     while(list_ptr)
  1402.       {
  1403.         wus = (WaitingURLStruct *)list_ptr->object;
  1404.  
  1405.         if(all || (window_id && cur_win_id == FE_GetContextID(wus->window_id)))
  1406.           {
  1407.             TRACEMSG(("killing waiting URL"));
  1408.  
  1409.             /* call exit routine since we are done */
  1410.             net_CallExitRoutine(wus->exit_routine,
  1411.                                 wus->URL_s,
  1412.                                 MK_INTERRUPTED,
  1413.                                 wus->format_out,
  1414.                                 wus->window_id);
  1415.  
  1416.             number_killed += 1;
  1417.  
  1418.             tmp_list_ptr = list_ptr;
  1419.             list_ptr = list_ptr->next;
  1420.  
  1421.             /* remove the element from the list
  1422.              *
  1423.              * we have to use the function since it does
  1424.              * funky doubly linked list stuff.
  1425.              */
  1426.             XP_ListRemoveObject(list, wus);
  1427.  
  1428.             FREE(wus);
  1429.           }
  1430.         else
  1431.           {
  1432.             prev_list_ptr = list_ptr;
  1433.             list_ptr = list_ptr->next;
  1434.           }
  1435.       }
  1436.  
  1437.     return(number_killed);
  1438. }
  1439.  
  1440.  
  1441. /* Helper function for NET_SanityCheckDNS() */
  1442. PRIVATE Bool
  1443. net_IsHostResolvable (CONST char *hostname, MWContext *context)
  1444. {
  1445. #ifdef XP_UNIX
  1446.     int rv;
  1447.     PRHostEnt hpbuf;
  1448.     char dbbuf[PR_NETDB_BUF_SIZE];
  1449. #ifndef NSPR20
  1450.     rv = (PR_gethostbyname(hostname, &hpbuf, dbbuf, sizeof(dbbuf), 0)
  1451.           ? TRUE : FALSE);
  1452. #else
  1453.         if (PR_GetHostByName(hostname, dbbuf, sizeof(dbbuf), &hpbuf) == PR_FAILURE)
  1454.         rv = FALSE;
  1455.     else
  1456.         rv = TRUE;
  1457. #endif
  1458.     return rv;
  1459. #else
  1460.     return(FALSE);
  1461. #endif
  1462. }
  1463.  
  1464.  
  1465. #if defined(__sun) && !defined(__svr4__)
  1466. /* From xfe/dns-stub.o or xfe/nis-stub.o, depending.  Gag. */
  1467. extern int fe_HaveDNS;
  1468. #endif
  1469.  
  1470.  
  1471. PUBLIC void
  1472. NET_SanityCheckDNS (MWContext *context)
  1473. {
  1474. #ifdef XP_UNIX
  1475.  
  1476.   char *proxy = MKhttp_proxy;
  1477.   char *socks = NET_SocksHostName;
  1478.   char *test_host_1 = "home.netscape.com";
  1479.   char *test_host_2 = "home6.netscape.com";
  1480.   char *test_host_3 = "internic.net";
  1481.   char *message;
  1482. #if defined(__sun) && !defined(__svr4__)
  1483.   char temp[1000];
  1484. #endif
  1485.  
  1486.   static Bool done;
  1487.   if (done) return;
  1488.   done = TRUE;
  1489.  
  1490.   message = (char *) XP_ALLOC (3000);
  1491.   if (! message)
  1492.     return;
  1493.   *message = 0;
  1494.  
  1495.   if (proxy)
  1496.     proxy = XP_STRDUP (proxy);
  1497.   if (socks)
  1498.     socks = XP_STRDUP (socks);
  1499.  
  1500.   /* Strip off everything after last colon. */
  1501.   {
  1502.     char *s;
  1503.     if (proxy && (s = XP_STRRCHR (proxy, ':')))
  1504.       *s = 0;
  1505.     if (socks && (s = XP_STRRCHR (socks, ':')))
  1506.       *s = 0;
  1507.   }
  1508.  
  1509.   if (proxy)
  1510.     proxy = XP_StripLine (proxy); /* in case it was "hostname:  80" */
  1511.   if (socks)
  1512.     socks = XP_StripLine (socks);
  1513.  
  1514.   /* If the hosts are specified as IP numbers, don't try and resolve them.
  1515.      (Yes, hostnames can't begin with digits.) */
  1516.   if (proxy && proxy[0] >= '0' && proxy[0] <= '9')
  1517.     XP_FREE (proxy), proxy = 0;
  1518.   if (socks && socks[0] >= '0' && socks[0] <= '9')
  1519.     XP_FREE (socks), socks = 0;
  1520.  
  1521.   if (proxy && *proxy)
  1522.     {
  1523.       /* If there is an HTTP proxy, then we shouldn't try to resolve any
  1524.      other hosts at all, because they might legitimately be unresolvable.
  1525.      The HTTP proxy will do all lookups.
  1526.        */
  1527.       if (!net_IsHostResolvable (proxy, context))
  1528.     {
  1529.           sprintf(message, XP_GetString(XP_UNKNOWN_HTTP_PROXY), proxy);
  1530.     }
  1531.     }
  1532.   else
  1533.     {
  1534.       /* There is not an HTTP proxy specified.  So check the other hosts.
  1535.        */
  1536.  
  1537.       if (socks && *socks && !net_IsHostResolvable (socks, context))
  1538.     {
  1539.           sprintf(message, XP_GetString(XP_UNKNOWN_SOCKS_HOST), socks);
  1540. #ifdef XP_UNIX
  1541.             XP_STRCAT (message, XP_GetString(XP_SOCKS_NS_ENV_VAR));
  1542.           /* Only Unix has the $SOCKS_NS environment variable. */
  1543. #endif /* XP_UNIX */
  1544.             XP_STRCAT (message, XP_GetString(XP_CONSULT_SYS_ADMIN));
  1545.     }
  1546.       else
  1547.     {
  1548.       /* At this point, we're not using a proxy, and either we're not
  1549.          using a SOCKS host or we're using a resolvable SOCKS host.
  1550.          So that means that all the usual host names should be resolvable,
  1551.          and the world is broken if they're not.
  1552.        */
  1553.       char *losers [10];
  1554.       int loser_count = 0;
  1555.  
  1556. #ifdef XP_UNIX
  1557.       char local [255], *local2;
  1558.       PRHostEnt *hent, hpbuf;
  1559.           char dbbuf[PR_NETDB_BUF_SIZE];
  1560.  
  1561.       if (gethostname (local, sizeof (local) - 1))
  1562.         local [0] = 0;
  1563.  
  1564.       /* gethostname() and gethostbyname() often return different data -
  1565.          on many systems, the former is basename, the latter is FQDN. */
  1566. #ifndef NSPR20
  1567.       if (local &&
  1568.           (hent = PR_gethostbyname (local, &hpbuf, dbbuf, sizeof(dbbuf), 0)) &&
  1569.           XP_STRCMP (local, hent->h_name))
  1570.         local2 = XP_STRDUP (hent->h_name);
  1571.       else
  1572.         local2 = 0;
  1573. #else
  1574.           local2 = 0;
  1575.       if (local &&
  1576.           (PR_GetHostByName (local, dbbuf, sizeof(dbbuf), &hpbuf) == PR_SUCCESS)) { 
  1577.       hent = &hpbuf;
  1578.       if (XP_STRCMP (local, hent->h_name))
  1579.         local2 = XP_STRDUP (hent->h_name);
  1580.       }
  1581. #endif
  1582.       if (local && *local && !net_IsHostResolvable (local, context))
  1583.         losers [loser_count++] = local;
  1584.       if (local2 && *local2 && !net_IsHostResolvable (local2, context))
  1585.         losers [loser_count++] = local2;
  1586. #endif /* XP_UNIX */
  1587.  
  1588.       if (!net_IsHostResolvable (test_host_1, context))
  1589.         losers [loser_count++] = test_host_1;
  1590.       if (!net_IsHostResolvable (test_host_2, context))
  1591.         losers [loser_count++] = test_host_2;
  1592.       if (!net_IsHostResolvable (test_host_3, context))
  1593.         losers [loser_count++] = test_host_3;
  1594.  
  1595.       if (loser_count > 0)
  1596.         {
  1597.           if (loser_count > 1)
  1598.         {
  1599.           int i;
  1600.           sprintf(message, XP_GetString(XP_UNKNOWN_HOSTS));
  1601.           for (i = 0; i < loser_count; i++)
  1602.             {
  1603.               XP_STRCAT (message, "                    ");
  1604.               XP_STRCAT (message, losers [i]);
  1605.               XP_STRCAT (message, "\n");
  1606.             }
  1607.         }
  1608.           else
  1609.         {
  1610.                   sprintf(message, XP_GetString(XP_UNKNOWN_HOST), losers[0]);
  1611.         }
  1612.           XP_STRCAT (message, XP_GetString(XP_SOME_HOSTS_UNREACHABLE));
  1613. #ifdef XP_UNIX
  1614. # if defined(__sun) && !defined(__svr4__)       /* compiled on SunOS 4.1.3 */
  1615.               if (fe_HaveDNS)
  1616.                 /* Don't talk about $SOCKS_NS in the YP/NIS version. */
  1617. # endif
  1618.                 XP_STRCAT (message, XP_GetString(XP_SOCKS_NS_ENV_VAR));
  1619.  
  1620. #if defined(__sun) && !defined(__svr4__)        /* compiled on SunOS 4.1.3 */
  1621.               assert (XP_AppName);
  1622.               if (fe_HaveDNS)
  1623.                 {
  1624.                     sprintf(temp, XP_GetString(XP_THIS_IS_DNS_VERSION),
  1625.                         XP_AppName);
  1626.                 }
  1627.               else
  1628.                 {
  1629.                     sprintf(temp, XP_GetString(XP_THIS_IS_YP_VERSION),
  1630.                         XP_AppName);
  1631.                 }
  1632.               XP_STRCAT(message, temp);
  1633. # endif /*  SunOS 4.* */
  1634. #endif /* XP_UNIX */
  1635.           XP_STRCAT (message, XP_GetString(XP_CONSULT_SYS_ADMIN));
  1636.         }
  1637.  
  1638. #ifdef XP_UNIX
  1639.       if (local2) XP_FREE (local2);
  1640. #endif /* XP_UNIX */
  1641.     }
  1642.     }
  1643.  
  1644.   if (proxy) XP_FREE (proxy);
  1645.   if (socks) XP_FREE (socks);
  1646.  
  1647.   if (*message)
  1648.     FE_Alert (context, message);
  1649.   XP_FREE (message);
  1650. #endif /* XP_UNIX full function wrap */
  1651. }
  1652.  
  1653.  
  1654. /* shutdown the netlibrary, cancel all
  1655.  * conections and free all
  1656.  * memory
  1657.  */
  1658. PUBLIC void
  1659. NET_ShutdownNetLib(void)
  1660. {
  1661.     ActiveEntry *tmpEntry;
  1662.  
  1663. /* #ifdef XP_WIN */
  1664. #ifdef JAVA
  1665.     if (libnet_asyncIO) LIBNET_LOCK();
  1666. #else
  1667.     LIBNET_LOCK();
  1668. #endif
  1669.  
  1670.     if(net_waiting_for_actives_url_list) {
  1671.         net_AbortWaitingURL(0, TRUE, net_waiting_for_actives_url_list);
  1672.     XP_ListDestroy(net_waiting_for_actives_url_list);
  1673.     net_waiting_for_actives_url_list = 0;
  1674.     }
  1675.  
  1676.     if(net_waiting_for_connection_url_list) {
  1677.     net_AbortWaitingURL(0, TRUE, net_waiting_for_connection_url_list);
  1678.     XP_ListDestroy(net_waiting_for_connection_url_list);
  1679.     net_waiting_for_connection_url_list = 0;
  1680.     }
  1681.  
  1682.     /* run through list of
  1683.      * connections
  1684.      */
  1685.     while((tmpEntry = (ActiveEntry *)XP_ListRemoveTopObject(net_EntryList)) != 0)
  1686.       {
  1687.  
  1688.         if(tmpEntry->proto_impl)
  1689.         {
  1690.             (*tmpEntry->proto_impl->interrupt)(tmpEntry);
  1691.         }
  1692.         else
  1693.         {
  1694.             XP_ASSERT(0);
  1695.         }
  1696.  
  1697.          /* XP_OS2_FIX IBM-MAS: limit length of output to keep from blowing trace buffer! */
  1698.         TRACEMSG(("End of transfer, entry (soc=%d, con=%d) being removed from list with %d status: %-.1900s",
  1699.                tmpEntry->socket, tmpEntry->con_sock, tmpEntry->status, tmpEntry->URL_s->address));
  1700.  
  1701.          /* call exit routine since we know we are done */
  1702.          net_CallExitRoutine(tmpEntry->exit_routine,
  1703.                              tmpEntry->URL_s,
  1704.                              tmpEntry->status,
  1705.                              tmpEntry->format_out,
  1706.                              tmpEntry->window_id);
  1707.          XP_FREE(tmpEntry);  /* free the no longer active entry */
  1708.       }
  1709.  
  1710.     XP_ListDestroy(net_EntryList);
  1711.     net_EntryList = 0;
  1712.  
  1713.     /* free any memory in the protocol modules
  1714.      */
  1715.     net_cleanup_reg_protocol_impls();
  1716.  
  1717. #ifdef MOZILLA_CLIENT
  1718.     NET_SaveCookies("");
  1719.     GH_SaveGlobalHistory();
  1720. #endif /* MOZILLA_CLIENT */
  1721.  
  1722.     /* purge existing cache files */
  1723.  
  1724.     /* free memory in the tcp routines
  1725.      */
  1726.     NET_CleanupTCP();
  1727.  
  1728. #ifdef MOZILLA_CLIENT
  1729.     NET_CleanupCache("");
  1730.     NET_SetMemoryCacheSize(0); /* free memory cache */
  1731.  
  1732. #endif /* MOZILLA_CLIENT */
  1733.  
  1734. #ifdef XP_UNIX
  1735.     NET_CleanupFileFormat(NULL);
  1736. #else
  1737.     NET_CleanupFileFormat();
  1738. #endif
  1739.  
  1740. /* #ifdef XP_WIN */
  1741. #ifdef JAVA
  1742.     if (libnet_asyncIO) LIBNET_UNLOCK();
  1743. #else
  1744.     LIBNET_UNLOCK();
  1745. #endif
  1746. }
  1747.  
  1748. static PRBool warn_on_mailto_post = PR_TRUE;
  1749.  
  1750. extern void
  1751. NET_WarnOnMailtoPost(PRBool warn)
  1752. {
  1753.     warn_on_mailto_post = warn;
  1754.     return;
  1755. }
  1756.  
  1757. /* use a small static array for speed of traversal.
  1758.  * We rely on the fact that we dont expect ton's of 
  1759.  * protocol implementations to be dynamically added
  1760.  * so a static size is managable for now.
  1761.  *
  1762.  * URL types should really be dynamic so that we dont have
  1763.  * to define types in net.h
  1764.  */
  1765. #define MAX_NUMBER_OF_PROTOCOL_IMPLS LAST_URL_TYPE
  1766.  
  1767. typedef struct {
  1768.     NET_ProtoImpl *impl;
  1769.     int            url_type;
  1770. } net_ProtoImplAndTypeAssoc;
  1771.  
  1772. PRIVATE net_ProtoImplAndTypeAssoc net_proto_impls[MAX_NUMBER_OF_PROTOCOL_IMPLS];
  1773. PRIVATE net_number_of_proto_impls = 0;
  1774.  
  1775. /* registers a protocol impelementation for a particular url_type
  1776.  * see NET_URL_Type() for types
  1777.  */
  1778. void NET_RegisterProtocolImplementation(NET_ProtoImpl *impl, int for_url_type)
  1779. {
  1780.  
  1781.     if(!impl || for_url_type < 0 || for_url_type > LAST_URL_TYPE)
  1782.     {
  1783.         XP_ASSERT(0);
  1784.         return;
  1785.     }
  1786.  
  1787.     net_proto_impls[net_number_of_proto_impls].impl = impl;
  1788.     net_proto_impls[net_number_of_proto_impls].url_type = for_url_type;
  1789.     
  1790.     net_number_of_proto_impls++;
  1791. }
  1792.  
  1793. /* get a handle to a protocol implemenation
  1794.  */
  1795. NET_ProtoImpl *
  1796. net_get_protocol_impl(int for_url_type)
  1797. {
  1798.     int count=0;
  1799.  
  1800.     /* if we ever get around to doing dynamic protocol loading
  1801.      * this would be a good place to plug it in.
  1802.      * just load a DLL with the implementation and
  1803.      * return the handle.
  1804.      * The integer URL_TYPE would need to be replaced with
  1805.      * strings or some other identifier so that it can all be
  1806.      * handled dynamically
  1807.      */
  1808.  
  1809.     for(; count < net_number_of_proto_impls; count++)
  1810.     {
  1811.         if(net_proto_impls[count].url_type == for_url_type)
  1812.             return net_proto_impls[count].impl;
  1813.     }
  1814.  
  1815.     XP_ASSERT(0);  /* should always find one */
  1816.     return NULL; 
  1817. }
  1818.  
  1819. void
  1820. net_cleanup_reg_protocol_impls(void)
  1821. {
  1822.     int count=0;
  1823.  
  1824.     for(; count < net_number_of_proto_impls; count++)
  1825.     {
  1826.         (*net_proto_impls[count].impl->cleanup)();
  1827.     }
  1828.  
  1829. }
  1830.  
  1831. /* register and begin a transfer.
  1832.  *
  1833.  * returns negative if the transfer errored or finished during the call
  1834.  * otherwise returns 0 or greater.
  1835.  *
  1836.  * A URL, an output format, a window context pointer, and a callback routine
  1837.  * should be passed in.
  1838.  */
  1839.  
  1840. PUBLIC int
  1841. NET_GetURL (URL_Struct *URL_s,
  1842.         FO_Present_Types output_format,
  1843.         MWContext *window_id,
  1844.         Net_GetUrlExitFunc* exit_routine)
  1845. {
  1846.     int          status=MK_MALFORMED_URL_ERROR;
  1847.     int          pacf_status=TRUE;
  1848.     int          type;
  1849.     int          cache_method=0;
  1850.     ActiveEntry *this_entry=0;  /* a new entry */
  1851.     char        *new_address;
  1852.     int processcallbacks = 0;
  1853.     Bool confirm;
  1854.     Bool load_background;
  1855.     char *confirmstring;
  1856.     TRACEMSG(("Entering NET_GetURL"));
  1857.     LIBNET_LOCK();
  1858.  
  1859. #if !defined(NSPR20_DISABLED) && defined(XP_UNIX)
  1860.     /* temporarily use busy poll to ease transition */
  1861.     NET_SetCallNetlibAllTheTime(window_id, "mkgeturl");
  1862. #endif
  1863.     
  1864. #ifdef XP_WIN
  1865.     /* this runs a timer to periodically call the netlib
  1866.      * so that we still get events even when OnIdle is never
  1867.      * called
  1868.      */
  1869.     NET_SetNetlibSlowKickTimer(TRUE);
  1870. #endif
  1871.  
  1872.     XP_ASSERT (URL_s && URL_s->address);
  1873. #ifdef MOZILLA_CLIENT
  1874.     if ( URL_s->mailto_post && warn_on_mailto_post) {
  1875.         confirmstring = NULL;
  1876.         confirm = FALSE;
  1877.         
  1878.         StrAllocCopy(confirmstring, XP_GetString(XP_CONFIRM_MAILTO_POST_1));
  1879.         StrAllocCat(confirmstring, XP_GetString(XP_CONFIRM_MAILTO_POST_2));
  1880.         
  1881.         if ( confirmstring ) {
  1882.             confirm = FE_Confirm(window_id, confirmstring);
  1883.             XP_FREE(confirmstring);
  1884.         }
  1885.         
  1886.         if ( !confirm ) {
  1887.             /* abort url
  1888.              */
  1889.             net_CallExitRoutine(exit_routine,
  1890.                                 URL_s,
  1891.                                 MK_INTERRUPTED,
  1892.                                 output_format,
  1893.                                 window_id);
  1894.             LIBNET_UNLOCK_AND_RETURN(MK_INTERRUPTED);
  1895.         }
  1896.     }
  1897. #endif /* MOZILLA_CLIENT */     
  1898. #ifdef EDITOR
  1899.     /* First time here - get our strings out of XP_MSG */
  1900.     if (XP_NEW_DOC_URL == NULL) {
  1901.         StrAllocCopy(XP_NEW_DOC_URL, XP_GetString(XP_EDIT_NEW_DOC_URL));
  1902.     }
  1903.     if (XP_NEW_DOC_NAME == NULL) {
  1904.         StrAllocCopy(XP_NEW_DOC_NAME, XP_GetString(XP_EDIT_NEW_DOC_NAME));
  1905.     }
  1906.  
  1907.     /* Test for "Untitled" URL */
  1908.     if( 0 == XP_STRCMP(URL_s->address, XP_NEW_DOC_NAME) ) {
  1909.         /* Change request to load "file:///Untitled" into "about:editfilenew"  */
  1910.         XP_FREE(URL_s->address);
  1911.         URL_s->address = XP_STRDUP(XP_NEW_DOC_URL);
  1912.         /* Set flag so FE can quickly detect new doc */
  1913.         window_id->is_new_document = TRUE;
  1914.     }
  1915.     else if( 0 == XP_STRCMP(URL_s->address, XP_NEW_DOC_URL) ) {
  1916.         window_id->is_new_document = TRUE;
  1917.     }
  1918.     else {
  1919.         /* Be sure this is FALSE if not a new document */
  1920.         window_id->is_new_document = FALSE;
  1921.     }
  1922.     /* Hack to allow special URL for new Editor doc 
  1923.      *   and still allow filtering of non-editable doc types
  1924.      * All editor GetUrl calls should use FO_CACHE_AND_EDIT
  1925.      *   except in the case of the new document URL
  1926.     */
  1927.     if( EDT_IS_EDITOR(window_id) && window_id->is_new_document ) {
  1928.         output_format = FO_CACHE_AND_PRESENT;
  1929.     }
  1930. #endif
  1931. #ifdef MOZILLA_CLIENT
  1932.  
  1933.         /* Hack. Proxy AutoDiscovery. If we want to use proxy autodiscovery
  1934.          * simply point the MKproxy_ac_url to the MK_padpacURL and use all 
  1935.          * all the same logic. */
  1936.         if(!MKproxy_ac_url && NET_UsingPadPac()) {
  1937.             NET_SetNoProxyFailover();
  1938.             MKproxy_ac_url=MK_padPacURL;
  1939.         }
  1940.  
  1941.     /* Initialize global/auto proxy codepath. This gets called for every 
  1942.      * NET_GetURL() call. */
  1943.     if (
  1944. #ifdef MOZ_OFFLINE
  1945.         !NET_IsOffline() &&
  1946. #endif /* MOZ_OFFLINE */
  1947.         /* Do we even have auto config urls set? If not, don't bother
  1948.          * continuing. See mkautocf.c for more info. */
  1949.         (MKglobal_config_url || MKproxy_ac_url)
  1950.         && (CLEAR_CACHE_BIT(output_format) == FO_PRESENT)
  1951.         && (!(type = NET_URL_Type(URL_s->address))
  1952.          || type == HTTP_TYPE_URL
  1953.          || type == SECURE_HTTP_TYPE_URL
  1954.          || type == GOPHER_TYPE_URL
  1955.          || type == FTP_TYPE_URL
  1956.          || type == WAIS_TYPE_URL
  1957.          || type == URN_TYPE_URL
  1958.          || type == NFS_TYPE_URL
  1959.          || type == POP3_TYPE_URL
  1960.          || (type == NEWS_TYPE_URL && !strncasecomp(URL_s->address, "snews:", 6)))
  1961.          ) {
  1962.         int status=-1;
  1963.         /* Figure out which auto config we're dealing (global or pac file
  1964.          * with and load it.
  1965.          * If the status is other than -1, the load started and the 
  1966.          * originally requested url will be loaded by the pre_exit_fn()
  1967.          * that is in the proxy auto config URL_Struct. */
  1968.         if(MKglobal_config_url && !NET_GlobalAcLoaded) {
  1969.             NET_GlobalAcLoaded=TRUE;
  1970.             status=NET_LoadProxyConfig(MKglobal_config_url,
  1971.                                         URL_s,
  1972.                                         output_format,
  1973.                                         window_id,
  1974.                                         exit_routine);
  1975.         } 
  1976.         /* else we know we're dealing with a proxyACL (the other 
  1977.          * possibility in the above if statement) so see if it's 
  1978.          * loaded or not. Also make sure we want to use it (i.e. style is
  1979.          * automatic or if we want to use a proxy autodiscovery url). */
  1980.         else if(!NET_ProxyAcLoaded
  1981.                 && (   (MKproxy_style == PROXY_STYLE_AUTOMATIC) 
  1982.                     || !MKproxy_style
  1983.                     || NET_UsingPadPac() ) ) {
  1984.             NET_ProxyAcLoaded=TRUE;
  1985.             status=NET_LoadProxyConfig(MKproxy_ac_url,
  1986.                                         URL_s,
  1987.                                         output_format,
  1988.                                         window_id,
  1989.                                         exit_routine);
  1990.         }
  1991.         if(status != -1)
  1992.             LIBNET_UNLOCK_AND_RETURN(status);
  1993.     } /* End big proxy if */
  1994.  
  1995. #endif  /* MOZILLA_CLIENT */
  1996.  
  1997.     load_background = URL_s->load_background;
  1998.  
  1999.     /* kill leading and trailing spaces in the URL address
  2000.      */
  2001.     new_address = XP_StripLine(URL_s->address);
  2002.     if(new_address != URL_s->address)
  2003.       {
  2004.         XP_MEMMOVE(URL_s->address, new_address, XP_STRLEN(new_address)+1);
  2005.       }
  2006.  
  2007.     /* get the protocol type
  2008.      */
  2009.     type = NET_URL_Type(URL_s->address);
  2010.  
  2011.     if (URL_s->method == URL_HEAD_METHOD &&
  2012.         type != HTTP_TYPE_URL && type != SECURE_HTTP_TYPE_URL && type != FILE_TYPE_URL) {
  2013.       /* We can only do HEAD on http connections. */
  2014.       net_CallExitRoutine(exit_routine,
  2015.                           URL_s,
  2016.                           MK_MALFORMED_URL_ERROR, /* Is this right? ### */
  2017.                           output_format,
  2018.                           window_id);
  2019.       /* increment since it will get decremented */
  2020.       NET_TotalNumberOfProcessingURLs++;
  2021.       net_CheckForWaitingURL(window_id, 0, load_background);
  2022.  
  2023.       LIBNET_UNLOCK_AND_RETURN(MK_MALFORMED_URL_ERROR);
  2024.     }
  2025.  
  2026.     /* XP_OS2_FIX IBM-MAS:limit length of output to keep from blowing trace buffer! */
  2027.    TRACEMSG(("Called NET_GetURL with FO: %d URL %-.1900s --", output_format, URL_s->address));
  2028.    TRACEMSG(("with method: %d, and post headers: %s", URL_s->method,
  2029.             URL_s->post_headers ? URL_s->post_headers : "none"));
  2030.  
  2031.     /* if this URL is for prefetching, put it on the wait queue until
  2032.      * everything else is done
  2033.      */
  2034.     if(URL_s->priority == Prefetch_priority)
  2035.     {
  2036.         LIBNET_UNLOCK_AND_RETURN(net_push_url_on_wait_queue(type,
  2037.                                                             URL_s,
  2038.                                                             output_format,
  2039.                                                             window_id,
  2040.                                                             exit_routine));
  2041.     }
  2042.  
  2043.     /* put a limit on the total number of active urls
  2044.      */
  2045.     if((NET_TotalNumberOfProcessingURLs >= MAX_NUMBER_OF_PROCESSING_URLS) && 
  2046.        ((output_format & FO_ONLY_FROM_CACHE) == 0))
  2047.       {
  2048.     LIBNET_UNLOCK_AND_RETURN(net_push_url_on_wait_queue(type,
  2049.                                                             URL_s,
  2050.                                                             output_format,
  2051.                                                             window_id,
  2052.                                                             exit_routine));
  2053.       }
  2054.  
  2055.     /* if we get this far then we should add the URL
  2056.      * to the number of processing URL's
  2057.      */
  2058.     NET_TotalNumberOfProcessingURLs++;
  2059.  
  2060.     if(type == VIEW_SOURCE_TYPE_URL)
  2061.       {
  2062.         /* this is a view-source: URL
  2063.          * strip off the front stuff 
  2064.          */
  2065.         char *new_address=0;
  2066.         /* the colon is guarenteed to be there */
  2067.         StrAllocCopy(new_address, XP_STRCHR(URL_s->address, ':')+1);
  2068.         FREE(URL_s->address);
  2069.         URL_s->address = new_address;
  2070.  
  2071.         type = NET_URL_Type(URL_s->address);
  2072.  
  2073.         /* remap the format out for the fo_present type
  2074.          */
  2075.         if(CLEAR_CACHE_BIT(output_format) == FO_PRESENT)
  2076.             output_format = FO_VIEW_SOURCE;
  2077.       }
  2078.  
  2079.     if(type == MARIMBA_TYPE_URL)
  2080.       {
  2081.         /* If this a castanet URL, and Netcaster is not installed, try http://
  2082.          * Otherwise, we let the castanet protocol handler do its thing.
  2083.          */
  2084.         if( ! FE_IsNetcasterInstalled() )
  2085.         {
  2086.             char *new_address;
  2087.             /* Replace castanet:// with http:// */
  2088.             /* Allocate space for 'http' + the rest of the string */
  2089.             new_address = XP_ALLOC(XP_STRLEN(XP_STRCHR(URL_s->address, ':'))+5);
  2090.  
  2091.             XP_ASSERT(new_address);
  2092.             *new_address=0;
  2093.             XP_STRCAT(new_address,"http");
  2094.             XP_STRCAT(new_address,XP_STRCHR(URL_s->address, ':'));
  2095.  
  2096.             FREE(URL_s->address);
  2097.             URL_s->address = new_address;
  2098.  
  2099.             type = NET_URL_Type(URL_s->address);
  2100.         }
  2101.       }
  2102.  
  2103.     if(type == NETHELP_TYPE_URL)
  2104.       {
  2105.         /* this is a nethelp: URL
  2106.          * separate into its component parts, the mapping file in URL_s->address,
  2107.          * and the topic in URL_s->fe_data
  2108.          */
  2109.  
  2110.         if (NET_ParseNetHelpURL(URL_s) == MK_OUT_OF_MEMORY) {
  2111.             LIBNET_UNLOCK_AND_RETURN(MK_OUT_OF_MEMORY);
  2112.         }
  2113.         
  2114.         type = NET_URL_Type(URL_s->address);
  2115.  
  2116.         output_format = FO_LOAD_HTML_HELP_MAP_FILE;
  2117.       }
  2118.  
  2119. #ifdef MOZILLA_CLIENT
  2120.     if(
  2121. #if defined(XP_WIN) || defined(XP_MAC) || defined(XP_OS2)
  2122.        FE_UseExternalProtocolModule(window_id, output_format, URL_s, exit_routine) ||
  2123. #endif
  2124.        NPL_HandleURL(window_id, output_format, URL_s, exit_routine))
  2125.       {
  2126.         /* don't call the exit routine since the
  2127.          * External protocol module will call it
  2128.          */
  2129.     net_CheckForWaitingURL(window_id, 0, load_background);
  2130.  
  2131.     LIBNET_UNLOCK_AND_RETURN(-1); /* all done */
  2132.       }
  2133.  
  2134.     if(NET_TimeBombActive)
  2135.       {
  2136.         /* Timebomb has gone off!!
  2137.          *
  2138.          * limit URL's to FTP and anything in our domains
  2139.          */
  2140.         if(type != FTP_TYPE_URL
  2141.             && type != ABOUT_TYPE_URL
  2142.              && type != FILE_TYPE_URL
  2143.               && type != MAILBOX_TYPE_URL
  2144.                && type != IMAP_TYPE_URL
  2145.                && type != POP3_TYPE_URL
  2146.                 && type != MOCHA_TYPE_URL
  2147.                  && type != DATA_TYPE_URL
  2148.               && type != HTML_DIALOG_HANDLER_TYPE_URL
  2149.                    && type != HTML_PANEL_HANDLER_TYPE_URL
  2150.                     && type != INTERNAL_SECLIB_TYPE_URL
  2151.  
  2152.               && !strcasestr(URL_s->address, "mcom.com")
  2153.                    &&  !strcasestr(URL_s->address, "netscape.com"))
  2154.           {
  2155.             char * alert = NET_ExplainErrorDetails(MK_TIMEBOMB_URL_PROHIBIT);
  2156.  
  2157.             FE_Alert(window_id, alert);
  2158.             FREE(alert);
  2159.  
  2160.         /* we need at least an address
  2161.          * if we don't have it exit this routine
  2162.          */
  2163.         net_CallExitRoutine(exit_routine,
  2164.                 URL_s,
  2165.                 MK_TIMEBOMB_URL_PROHIBIT,
  2166.                             output_format,
  2167.                 window_id);
  2168.  
  2169.             net_CheckForWaitingURL(window_id, 0, load_background);
  2170.  
  2171.         LIBNET_UNLOCK_AND_RETURN(MK_TIMEBOMB_URL_PROHIBIT);
  2172.           }
  2173.       }
  2174.  
  2175.     /* put up security dialog boxes to tell the user
  2176.      * about transitions
  2177.      *
  2178.      * only do this for FO_PRESENT objects and objects
  2179.      * not coming out of history
  2180.      * and also make sure that the object is not being asked
  2181.      * for twice via the "304 use local copy" method
  2182.      */
  2183.     if(output_format == FO_CACHE_AND_PRESENT
  2184.         && !URL_s->history_num
  2185.          && !URL_s->use_local_copy)
  2186.       {
  2187.         Bool continue_loading_url = TRUE;
  2188.         History_entry * h = SHIST_GetCurrent(&window_id->hist);
  2189.  
  2190.         /* this is some protection against the "mail document"
  2191.          * feature popping up a dialog warning about an insecure
  2192.          * post.
  2193.          * If the type is MAILTO and the first post header
  2194.          * begins with "Content-type" then it is a post from
  2195.          * inside a form, otherwise it is just a normal MAILTO
  2196.          *
  2197.          * And, of course, anything not a MAILTO link will fall
  2198.          * into the if as well.
  2199.          */
  2200.         if(type != MAILTO_TYPE_URL
  2201.             || !URL_s->post_headers
  2202.              || !XP_STRNCMP("Content-type", URL_s->post_headers, 12))
  2203.           {
  2204.             if(h && h->security_on)
  2205.               {
  2206.                 /* if this is not a secure transaction */
  2207.                 if(type != SECURE_HTTP_TYPE_URL
  2208.                     && !(type == NEWS_TYPE_URL &&
  2209.                          toupper(*URL_s->address) == 'S') )
  2210.                   {
  2211.                     if(URL_s->method == URL_POST_METHOD)
  2212.                       {
  2213.                         continue_loading_url = (Bool)SECNAV_SecurityDialog(window_id,
  2214.                                            SD_INSECURE_POST_FROM_SECURE_DOC);
  2215.                       }
  2216.                     else if(!URL_s->redirecting_url
  2217.                              && type != MAILTO_TYPE_URL
  2218.                                 && type != ABOUT_TYPE_URL
  2219.                                    && type != MOCHA_TYPE_URL)
  2220.                       {
  2221.                         /* don't put up in case of redirect or mocha
  2222.                          */
  2223.                         continue_loading_url = (Bool)SECNAV_SecurityDialog(window_id,
  2224.                                            SD_LEAVING_SECURE_SPACE);
  2225.                       }
  2226.                   }
  2227.               }
  2228.             else
  2229.               {
  2230.                 /* put up a dialog for all insecure posts
  2231.                  * except news and mail posts
  2232.                  */
  2233.                 if(URL_s->method == URL_POST_METHOD
  2234.                     && type != SECURE_HTTP_TYPE_URL
  2235.                      && type != INTERNAL_NEWS_TYPE_URL
  2236.                      && type != NEWS_TYPE_URL
  2237.                       && type != HTML_DIALOG_HANDLER_TYPE_URL
  2238.                        && type != HTML_PANEL_HANDLER_TYPE_URL
  2239.                        && type != INTERNAL_SECLIB_TYPE_URL
  2240.                         && type != MAILTO_TYPE_URL)
  2241.           {
  2242.                     continue_loading_url = (Bool)SECNAV_SecurityDialog(window_id,
  2243.                        SD_INSECURE_POST_FROM_INSECURE_DOC);
  2244.           }
  2245.               }
  2246.  
  2247.             if(!continue_loading_url)
  2248.               {
  2249.                 /* abort url
  2250.          */
  2251.         net_CallExitRoutine(exit_routine,
  2252.                                     URL_s,
  2253.                                     MK_INTERRUPTED,
  2254.                                     output_format,
  2255.                                     window_id);
  2256.         net_CheckForWaitingURL(window_id, 0, load_background);
  2257.  
  2258.         LIBNET_UNLOCK_AND_RETURN(MK_INTERRUPTED);
  2259.               }
  2260.           }
  2261.       }
  2262. #endif /* MOZILLA_CLIENT */
  2263.  
  2264.     /*
  2265.      * if the string is not a valid URL we are just going
  2266.      * to punt, so we may as well try it as http
  2267.      */
  2268.     if(type==0)
  2269.     {
  2270.         char *munged;
  2271.  
  2272. #define INT_SEARCH_URL "http://cgi.netscape.com/cgi-bin/url_search.cgi?search="
  2273. #define INT_SEARCH_URL_TYPE HTTP_TYPE_URL
  2274.  
  2275.         if(!(munged = (char*) XP_ALLOC(XP_STRLEN(URL_s->address)+20)))
  2276.         {
  2277.             net_CallExitRoutine(exit_routine,
  2278.                                 URL_s,
  2279.                                 MK_OUT_OF_MEMORY,
  2280.                                 output_format,
  2281.                                 window_id);
  2282.             
  2283.             LIBNET_UNLOCK_AND_RETURN(MK_OUT_OF_MEMORY);
  2284.         }       
  2285.  
  2286. #ifdef EDITOR
  2287.     /* Some platforms resize a window while creating it. An example is
  2288.      * Windows in Communicator 4.0. On these platforms,
  2289.      * the Composer View Document Source window can end up here with a
  2290.      * bizarre (and potentially localized) URL of "View Document Source".
  2291.      * If we allow this URL to be resolved, it will cause a search engine
  2292.      * to be triggered.
  2293.      * Fortunately, edit_view_source_hack is TRUE iff the context is
  2294.      * a Composer View Document Source window.
  2295.      */
  2296.     if ( window_id->edit_view_source_hack ){
  2297.         net_CallExitRoutine(exit_routine,
  2298.                                 URL_s,
  2299.                                 MK_INTERRUPTED,
  2300.                                 output_format,
  2301.                                 window_id);
  2302.             LIBNET_UNLOCK_AND_RETURN(MK_INTERRUPTED);
  2303.     }
  2304. #endif
  2305.  
  2306.         /* if it starts with a question mark or has a space it's
  2307.          * a search URL
  2308.          */
  2309.         if(*URL_s->address == '?' || XP_STRCHR(URL_s->address, ' '))
  2310.           {
  2311.             /* URL contains spaces.  Treat it as search text. */
  2312.             char *escaped;
  2313.  
  2314.             if(*URL_s->address == '?')
  2315.                 escaped = NET_Escape(URL_s->address+1, URL_XPALPHAS);
  2316.             else
  2317.                 escaped = NET_Escape(URL_s->address, URL_XPALPHAS);
  2318.  
  2319.             if(escaped)
  2320.               {
  2321.                 char *pUrl;
  2322.                 PREF_CopyCharPref("network.search.url",&pUrl);
  2323.                 FREE(munged);
  2324.                 if (pUrl) {
  2325.                     munged = PR_smprintf("%s%s", pUrl, escaped);
  2326.                     FREE(escaped);
  2327.                     XP_FREE(pUrl);
  2328.                 }
  2329.                 type = INT_SEARCH_URL_TYPE;
  2330.               }
  2331.           }
  2332.         else
  2333.           {
  2334.             if(*URL_s->address == '/')
  2335.               {
  2336.                 XP_STRCPY(munged, "file:");
  2337.                 type = FILE_TYPE_URL;
  2338.               }
  2339.             else if(!strncasecomp(URL_s->address, "ftp", 3))
  2340.               {
  2341.                 XP_STRCPY(munged, "ftp://");
  2342.                 type = FTP_TYPE_URL;
  2343.               }
  2344.             else if(!strncasecomp(URL_s->address, "gopher", 6))
  2345.               {
  2346.                 XP_STRCPY(munged, "gopher://");
  2347.                 type = GOPHER_TYPE_URL;
  2348.               }
  2349.             else if(!strncasecomp(URL_s->address, "news", 4)
  2350.                     || !strncasecomp(URL_s->address, "nntp", 4))
  2351.               {
  2352.                 XP_STRCPY(munged, "news://");
  2353.                 type = NEWS_TYPE_URL;
  2354.               }
  2355.             else
  2356.               {
  2357.                 XP_STRCPY(munged, "http://");
  2358.                 type = HTTP_TYPE_URL;
  2359.               }
  2360.     
  2361.             XP_STRCAT(munged, URL_s->address);
  2362.           }
  2363.  
  2364.         XP_FREE(URL_s->address);
  2365.         URL_s->address = munged;
  2366.  
  2367. #ifdef MOZILLA_CLIENT
  2368.         /*      Try the external protocol handlers again, since with the
  2369.          *              newly appended protocol, they might work this time.
  2370.          */
  2371.         if(
  2372.     #if defined(XP_WIN) || defined(XP_MAC)
  2373.            FE_UseExternalProtocolModule(window_id, output_format, URL_s, exit_routine) ||
  2374.     #endif
  2375.            NPL_HandleURL(window_id, output_format, URL_s, exit_routine))
  2376.           {
  2377.             /* don't call the exit routine since the
  2378.              * External protocol module will call it
  2379.              */
  2380.         net_CheckForWaitingURL(window_id, 0, load_background);
  2381.  
  2382.         LIBNET_UNLOCK_AND_RETURN(-1); /* all done */
  2383.           }
  2384. #endif /* MOZILLA_CLIENT */
  2385.     }
  2386.  
  2387.     if(type == HTTP_TYPE_URL || type == FILE_TYPE_URL ||
  2388.         type == SECURE_HTTP_TYPE_URL || type == GOPHER_TYPE_URL
  2389. #ifdef JAVA
  2390.     /* Castanet URLs don't work when there's no Java */
  2391.         || type == MARIMBA_TYPE_URL
  2392. #endif
  2393.         )
  2394.     add_slash_to_URL(URL_s);
  2395.  
  2396. #ifdef MOZILLA_CLIENT
  2397.     /*
  2398.      * If this is a resize-reload OR a view-source URL, try to use the
  2399.      * URL's wysiwyg: counterpart.
  2400.      */
  2401.     URL_s->resize_reload = (URL_s->force_reload == NET_RESIZE_RELOAD);
  2402.     if(URL_s->wysiwyg_url &&
  2403.        (URL_s->resize_reload == TRUE ||
  2404.         CLEAR_CACHE_BIT(output_format) == FO_VIEW_SOURCE))
  2405.       {
  2406.         StrAllocCopy(URL_s->address, URL_s->wysiwyg_url);
  2407.         type = WYSIWYG_TYPE_URL;
  2408.       }
  2409.  
  2410.     /* the FE's were screwing up the use of force_reload
  2411.      * to get around a bug in the scroll to named anchor
  2412.      * code.  So I gave them an enum NET_RESIZE_RELOAD
  2413.      * that they could use instead.  NET_RESIZE_RELOAD
  2414.      * should be treated just like NET_DONT_RELOAD within
  2415.      * the netlib
  2416.      */
  2417.     if((URL_s->force_reload == NET_RESIZE_RELOAD) ||
  2418.        (URL_s->force_reload == NET_CACHE_ONLY_RELOAD))
  2419.         URL_s->force_reload = NET_DONT_RELOAD;
  2420.  
  2421.     /* check for the url in the cache
  2422.      */
  2423.     cache_method = NET_FindURLInCache(URL_s, window_id);
  2424.  
  2425.     if (!cache_method)
  2426.       {
  2427.         /* cache testing stuff */
  2428.         if(NET_CacheTraceOn)
  2429.           {
  2430.             char *buf = 0;
  2431.             StrAllocCopy(buf, XP_GetString(XP_URL_NOT_FOUND_IN_CACHE));
  2432.             StrAllocCat(buf, URL_s->address);
  2433.             FE_Alert(window_id, buf);
  2434.             FREE(buf);
  2435.           }
  2436.  
  2437.         /* if wysiwyg, there must be a cache entry or we retry the real url */
  2438.         if(type == WYSIWYG_TYPE_URL)
  2439.           {
  2440.             const char *real_url = LM_SkipWysiwygURLPrefix(URL_s->address);
  2441.  
  2442.             /* XXX can't use StrAllocCopy because it frees dest first */
  2443.             if (real_url && (new_address = XP_STRDUP(real_url)) != NULL)
  2444.               {
  2445.                 /* cache miss: we must clear this flag so scripts rerun */
  2446.                 URL_s->resize_reload = FALSE;
  2447.  
  2448.                 XP_FREE(URL_s->address);
  2449.                 URL_s->address = new_address;
  2450.                 FREE_AND_CLEAR(URL_s->wysiwyg_url);
  2451.                 /* 
  2452.                  * Since the call to NET_GetURL will increment the
  2453.                  * following counter again, we decrement it so as not
  2454.                  * to overcount.
  2455.                  */
  2456.                 NET_TotalNumberOfProcessingURLs--;
  2457.                 LIBNET_UNLOCK_AND_RETURN(
  2458.                             NET_GetURL(URL_s, output_format, window_id, exit_routine)
  2459.                         );
  2460.               }
  2461.           }
  2462.       }
  2463.  
  2464.     /* if cache_method is non zero then we have this URL cached.  Use
  2465.      * the bogus cache url type
  2466.      *
  2467.      * This nasty bit of logic figures out if we really
  2468.      * need to reload it or if we can use the cached copy
  2469.      */
  2470.     else
  2471.       {
  2472.         if(URL_s->use_local_copy || output_format & FO_ONLY_FROM_CACHE)
  2473.           {
  2474.         /* the cached file is valid so use it unilaterally
  2475.          */
  2476.         type = cache_method;
  2477.           }
  2478.         else if(URL_s->real_content_length > URL_s->content_length)
  2479.           {
  2480.             /* cache testing stuff */
  2481.             if(NET_CacheTraceOn)
  2482.               {
  2483.                 char *buf = 0;
  2484.                 StrAllocCopy(buf, XP_GetString(XP_PARTIAL_CACHE_ENTRY));
  2485.                 StrAllocCat(buf, URL_s->address);
  2486.                 FE_Alert(window_id, buf);
  2487.                 FREE(buf);
  2488.               }
  2489.  
  2490.         URL_s->memory_copy = 0;
  2491.         cache_method = 0;
  2492.         TRACEMSG(("Getting the rest of a partial cache file"));
  2493.           }
  2494.     else if (URL_s->force_reload != NET_DONT_RELOAD)
  2495.       {
  2496.         TRACEMSG(("Force reload flag set.  Checking server to see if modified"));
  2497.         /* cache testing stuff */
  2498.         if(NET_CacheTraceOn)
  2499.           {
  2500.         char *buf = 0;
  2501.         StrAllocCopy(buf, XP_GetString(XP_CHECKING_SERVER__FORCE_RELOAD));
  2502.         StrAllocCat(buf, URL_s->address);
  2503.         FE_Alert(window_id, buf);
  2504.         FREE(buf);
  2505.           }
  2506.  
  2507.         /* strip the cache file and
  2508.          * memory pointer
  2509.          */
  2510.         if (type == WYSIWYG_TYPE_URL)
  2511.         type = cache_method;
  2512.         else
  2513.           {
  2514.         FREE_AND_CLEAR(URL_s->cache_file);
  2515.         URL_s->memory_copy = 0;
  2516.         cache_method = 0;
  2517.           }
  2518.       }
  2519.     else if(URL_s->expires)         
  2520.       {
  2521.         time_t cur_time = time(NULL);
  2522.  
  2523.         if(cur_time > URL_s->expires)
  2524.           {
  2525.         FREE_AND_CLEAR(URL_s->cache_file);
  2526.         URL_s->memory_copy = 0;
  2527.         URL_s->expires = 0;  /* remove cache reference */
  2528.         cache_method = 0;
  2529.  
  2530.         /* cache testing stuff */
  2531.         if(NET_CacheTraceOn)
  2532.           {
  2533.             char *buf = 0;
  2534.             StrAllocCopy(buf, XP_GetString(XP_OBJECT_HAS_EXPIRED));
  2535.             StrAllocCat(buf, URL_s->address);
  2536.             FE_Alert(window_id, buf);
  2537.             FREE(buf);
  2538.           }
  2539.           }
  2540.             else
  2541.               {
  2542.             /* the cached file is valid so use it unilaterally
  2543.              */
  2544.         type = cache_method;
  2545.               }
  2546.           }
  2547.         else if((NET_CacheUseMethod == CU_NEVER_CHECK || URL_s->history_num)
  2548.                   && !URL_s->expires)
  2549.           {
  2550.         type = cache_method;
  2551.           }
  2552.         else if(NET_CacheUseMethod == CU_CHECK_ALL_THE_TIME
  2553.                 && CLEAR_CACHE_BIT(output_format) == FO_PRESENT
  2554.                   && (type == HTTP_TYPE_URL || type == SECURE_HTTP_TYPE_URL)
  2555.                       && !URL_s->expires)
  2556.           {
  2557.             /* cache testing stuff */
  2558.             if(NET_CacheTraceOn)
  2559.               {
  2560.                 char *buf = 0;
  2561.                 StrAllocCopy(buf, XP_GetString(XP_CHECKING_SERVER_CACHE_ENTRY));
  2562.                 StrAllocCat(buf, URL_s->address);
  2563.                 FE_Alert(window_id, buf);
  2564.                 FREE(buf);
  2565.               }
  2566.  
  2567.              /* if it's an HTTP URL and its not an Internal image
  2568.               * and it's not being asked for with ONLY FROM CACHE
  2569.               * and it's not coming out of the history
  2570.               * and it doesn't have an expiration date...
  2571.               * FORCE Reload it
  2572.               */
  2573.         TRACEMSG(("Non history http file found. Force reloading it "));
  2574.         /* strip the cache file and
  2575.          * memory pointer
  2576.          */
  2577.         FREE_AND_CLEAR(URL_s->cache_file);
  2578.         URL_s->memory_copy = 0;
  2579.         cache_method = 0;
  2580.  
  2581.           }
  2582.         else if(!URL_s->last_modified
  2583.                 && CLEAR_CACHE_BIT(output_format) == FO_PRESENT
  2584.                 && (type == HTTP_TYPE_URL || type == SECURE_HTTP_TYPE_URL) 
  2585. #ifdef MOZ_OFFLINE            
  2586.         && !NET_IsOffline() 
  2587. #endif /* MOZ_OFFLINE */
  2588.         )  /* *X* check for is offline */
  2589.           {
  2590.             TRACEMSG(("Non history cgi script found (probably)."
  2591.                       " Force reloading it "));
  2592.             /* cache testing stuff */
  2593.             if(NET_CacheTraceOn)
  2594.               {
  2595.                 char *buf = 0;
  2596.                 StrAllocCopy(buf, XP_GetString(XP_CHECKING_SERVER__LASTMOD_MISS));
  2597.                 StrAllocCat(buf, URL_s->address);
  2598.                 FE_Alert(window_id, buf);
  2599.                 FREE(buf);
  2600.               }
  2601.  
  2602.         /* strip the cache file and
  2603.          * memory pointer
  2604.          */
  2605.         FREE_AND_CLEAR(URL_s->cache_file);
  2606.         URL_s->memory_copy = 0;
  2607.         URL_s->expires = 0;  /* remove cache reference */
  2608.         cache_method = 0;
  2609.           }
  2610.         else
  2611.           {
  2612.             /* the cached file is valid so use it unilaterally
  2613.              */
  2614.         type = cache_method;
  2615.           }
  2616.       }
  2617. #endif /* MOZILLA_CLIENT */
  2618.  
  2619.     /*
  2620.      * If the object should only come out of the cache
  2621.      * we should abort now if there is not a cache object
  2622.      */
  2623.     if(output_format & FO_ONLY_FROM_CACHE)
  2624.       {
  2625.         TRACEMSG(("object called with ONLY_FROM_CACHE format out"));
  2626.  
  2627.         if(!cache_method)
  2628.           {
  2629.             net_CallExitRoutine(exit_routine,
  2630.                                 URL_s,
  2631.                                 MK_OBJECT_NOT_IN_CACHE,
  2632.                                 output_format,
  2633.                                 window_id);
  2634.             net_CheckForWaitingURL(window_id, type, load_background);
  2635.  
  2636.             LIBNET_UNLOCK_AND_RETURN(MK_OBJECT_NOT_IN_CACHE);
  2637.           }
  2638.         else
  2639.           {
  2640.             /* remove the ONLY_FROM_CACHE designation and replace
  2641.              * it with CACHE_AND.. so that we go through the cacheing
  2642.              * module again so that we can memory cache disk objects
  2643.              * and do the right thing in general
  2644.              */
  2645.             output_format = CLEAR_PRESENT_BIT(output_format,FO_ONLY_FROM_CACHE);
  2646.             output_format = SET_PRESENT_BIT(output_format,FO_CACHE_ONLY);
  2647.           }
  2648.       }
  2649.  
  2650.     /* put a limit on the total number of open connections
  2651.      */
  2652.     if(!net_is_one_url_allowed_to_run(window_id, type))
  2653.       {
  2654.         NET_TotalNumberOfProcessingURLs--; /* waiting not processing */
  2655.         LIBNET_UNLOCK_AND_RETURN(net_push_url_on_wait_queue(type,
  2656.                                                             URL_s,
  2657.                                                             output_format,
  2658.                                                             window_id,
  2659.                                                             exit_routine));
  2660.       }
  2661.  
  2662.     /* start a new entry */
  2663.     this_entry = XP_NEW(ActiveEntry);
  2664.     if(!this_entry)
  2665.       {
  2666.     net_CallExitRoutine(exit_routine,
  2667.                             URL_s,
  2668.                             MK_OUT_OF_MEMORY,
  2669.                             output_format,
  2670.                             window_id);
  2671.  
  2672.         LIBNET_UNLOCK_AND_RETURN(MK_OUT_OF_MEMORY);
  2673.       }
  2674.  
  2675.     /* init new entry */
  2676.     XP_MEMSET(this_entry, 0, sizeof(ActiveEntry));
  2677.     this_entry->URL_s        = URL_s;
  2678.     this_entry->socket       = NULL;
  2679.     this_entry->con_sock     = NULL;
  2680.     this_entry->exit_routine = exit_routine;
  2681.     this_entry->window_id    = window_id;
  2682.     this_entry->protocol     = type;
  2683.  
  2684.     /* set the format out for the entry
  2685.      */
  2686.     this_entry->format_out = output_format;
  2687.  
  2688.     /* set it busy */
  2689.     this_entry->busy = TRUE;
  2690.  
  2691.     /* add it to the processing list now
  2692.      */
  2693.     XP_ListAddObjectToEnd(net_EntryList, this_entry);
  2694.  
  2695.     /* this will protect against multiple posts unknown to the
  2696.      * user
  2697.      *
  2698.      * check if the method is post and it came from the
  2699.      * history and it isn't coming from the cache
  2700.      */
  2701.     if(URL_s->method == URL_POST_METHOD
  2702.         && !URL_s->expires
  2703.          && !cache_method
  2704.           && URL_s->history_num)
  2705.       {
  2706.         if(URL_s->force_reload != NET_DONT_RELOAD)
  2707.           {
  2708.             if(!FE_Confirm(window_id, XP_GetString(XP_CONFIRM_REPOST_FORMDATA)))
  2709.               {
  2710.                 XP_ListRemoveObject(net_EntryList, this_entry);
  2711.                 net_CallExitRoutine(exit_routine,
  2712.                                     URL_s,
  2713.                                     MK_INTERRUPTED,
  2714.                                     output_format,
  2715.                                     window_id);
  2716.                 /* will get decremented */
  2717.                 net_CheckForWaitingURL(window_id, this_entry->protocol, 
  2718.                                        load_background);
  2719.  
  2720.                 XP_FREE(this_entry);  /* not needed any more */
  2721.  
  2722.                 LIBNET_UNLOCK_AND_RETURN(MK_INTERRUPTED);
  2723.               }
  2724.             /* otherwise fall through and repost
  2725.              */
  2726.           }
  2727.         else
  2728.           {
  2729.             NET_StreamClass * stream;
  2730.             char buffer[1000];
  2731.  
  2732.             StrAllocCopy(URL_s->content_type, TEXT_HTML);
  2733.             stream =  NET_StreamBuilder(CLEAR_CACHE_BIT(output_format),
  2734.                                         URL_s,
  2735.                                         window_id);
  2736.             if(stream)
  2737.               {
  2738.                 XP_STRCPY(buffer, XP_GetString(XP_HTML_MISSING_REPLYDATA));
  2739.                 (*stream->put_block)(stream,
  2740.                                      buffer,
  2741.                                      XP_STRLEN(buffer));
  2742.                 (*stream->complete)(stream);
  2743.               }
  2744.  
  2745.             XP_ListRemoveObject(net_EntryList, this_entry);
  2746.  
  2747.             net_CallExitRoutine(exit_routine,
  2748.                                 URL_s,
  2749.                                 MK_INTERRUPTED,
  2750.                                 output_format,
  2751.                                 window_id);
  2752.             net_CheckForWaitingURL(window_id, this_entry->protocol,
  2753.                                    load_background);
  2754.  
  2755.             XP_FREE(this_entry);  /* not needed any more */
  2756.  
  2757.             LIBNET_UNLOCK_AND_RETURN(MK_INTERRUPTED);
  2758.           }
  2759.       }
  2760.  
  2761. redo_load_switch:   /* come here on file/ftp retry */
  2762.  
  2763.     /* This code path handles the case when a pac/global file has been loaded
  2764.      * and we now want to use it in for a request. If we find a proxy/socks
  2765.      * server to use, we call NET_HTTPLoad here, skipping the below switch.
  2766.      * See mkautocf.c for more info. */
  2767.     pacf_status = TRUE;
  2768.     if ((NET_ProxyAcLoaded || NET_GlobalAcLoaded) 
  2769.         && (this_entry->protocol == HTTP_TYPE_URL
  2770.             || this_entry->protocol == SECURE_HTTP_TYPE_URL
  2771.             || this_entry->protocol == GOPHER_TYPE_URL
  2772.             || this_entry->protocol == FTP_TYPE_URL
  2773.             || this_entry->protocol == WAIS_TYPE_URL
  2774.             || this_entry->protocol == URN_TYPE_URL
  2775.             || this_entry->protocol == NFS_TYPE_URL
  2776.             || (this_entry->protocol == NEWS_TYPE_URL 
  2777.                 && !strncasecomp(URL_s->address, "snews:", 6)
  2778.                 )
  2779.             )
  2780.         && (this_entry->proxy_conf =
  2781.              pacf_find_proxies_for_url(window_id, URL_s)) != NULL
  2782.         && (pacf_status = pacf_get_proxy_addr(window_id,
  2783.                              this_entry->proxy_conf,
  2784.                              &this_entry->proxy_addr,
  2785.                              &this_entry->socks_host,
  2786.                              &this_entry->socks_port))
  2787.         && this_entry->proxy_addr
  2788.         )
  2789.       {
  2790.         TRACEMSG(("PAC returned \"%s\" for \"%s\".", this_entry->proxy_conf, URL_s->address));
  2791.         /* Secure protocols need to be kept in their own protocol
  2792.          * to make SSL tunneling happen. */
  2793.         if (this_entry->protocol != SECURE_HTTP_TYPE_URL 
  2794.             && this_entry->protocol != NEWS_TYPE_URL) {
  2795.                 this_entry->protocol = HTTP_TYPE_URL;
  2796.         }
  2797.  
  2798.         /* Everything else except SNEWS gets loaded by HTTP loader,
  2799.          * including HTTPS. */
  2800.         if (this_entry->protocol != NEWS_TYPE_URL) {
  2801.             this_entry->proto_impl = net_get_protocol_impl(HTTP_TYPE_URL);
  2802.         } else {
  2803.             this_entry->proto_impl = net_get_protocol_impl(NEWS_TYPE_URL);
  2804.         }
  2805.  
  2806.         if(this_entry->proto_impl)
  2807.             status = (*this_entry->proto_impl->init)(this_entry);
  2808.       }
  2809.     else if ( pacf_status == FALSE && NET_GetNoProxyFailover() == TRUE ) 
  2810.       {
  2811.         status = MK_UNABLE_TO_LOCATE_PROXY;
  2812.         FE_Alert(window_id, XP_GetString(XP_BAD_AUTOCONFIG_NO_FAILOVER));
  2813.       } 
  2814.     else
  2815.       {
  2816.           char *proxy_address = NET_FindProxyHostForUrl(type, this_entry->URL_s->address);
  2817.         
  2818.             if(proxy_address)
  2819.             {
  2820.                 this_entry->protocol = HTTP_TYPE_URL;
  2821.                 this_entry->proxy_addr = proxy_address;
  2822.             }
  2823.             
  2824.           this_entry->proto_impl = net_get_protocol_impl(this_entry->protocol);
  2825.  
  2826.           if(this_entry->proto_impl)
  2827.           {
  2828.             status = (*this_entry->proto_impl->init)(this_entry);
  2829.           }
  2830.           else
  2831.           {
  2832.                 /* bad url */
  2833.                 URL_s->error_msg =
  2834.                     NET_ExplainErrorDetails(MK_MALFORMED_URL_ERROR,
  2835.                                             this_entry->URL_s->address);
  2836.                 status = MK_MALFORMED_URL_ERROR;
  2837.                 this_entry->status = MK_MALFORMED_URL_ERROR;
  2838.           }
  2839.     }
  2840.  
  2841.     /* the entry is no longer busy
  2842.      */
  2843.     this_entry->busy = FALSE;
  2844.  
  2845. #ifdef MOZILLA_CLIENT
  2846.     /* OH NASTY A GOTO!
  2847.      * If we went into load file and what we really wanted to do
  2848.      * was use FTP, LoadFile will return MK_USE_FTP_INSTEAD so
  2849.      * we will go back up to the beginning of the switch and
  2850.      * use ftp instead
  2851.      */
  2852.     if(status == MK_USE_FTP_INSTEAD)
  2853.       {
  2854.         type = FTP_TYPE_URL;
  2855.         this_entry->protocol = type; /* change protocol designator */
  2856.         this_entry->status = 0; /* reset */
  2857.         goto redo_load_switch;
  2858.       }
  2859.     else 
  2860. #endif /* MOZILLA_CLIENT */
  2861.     if(this_entry->status == MK_USE_COPY_FROM_CACHE)
  2862.       {
  2863.         TRACEMSG(("304 Not modified recieved using cached entry\n"));
  2864.  
  2865. #ifdef MOZILLA_CLIENT
  2866.         NET_RefreshCacheFileExpiration(this_entry->URL_s);
  2867. #endif /* MOZILLA_CLIENT */
  2868.  
  2869.         /* turn off force reload by telling it to use local copy
  2870.          */
  2871.         this_entry->URL_s->use_local_copy = TRUE;
  2872.  
  2873.         /* restart the transfer
  2874.          */
  2875.         XP_ListRemoveObject(net_EntryList, this_entry);
  2876.         status = NET_GetURL(this_entry->URL_s,
  2877.                    this_entry->format_out,
  2878.                    this_entry->window_id,
  2879.                    this_entry->exit_routine);
  2880.  
  2881.         net_CheckForWaitingURL(this_entry->window_id,
  2882.                                this_entry->protocol,
  2883.                                this_entry->URL_s->load_background);
  2884.  
  2885.         XP_FREE(this_entry);
  2886.         LIBNET_UNLOCK_AND_RETURN(0);
  2887.       }
  2888.     else if(this_entry->status == MK_DO_REDIRECT)
  2889.       {
  2890.         /* this redirect should just call GetURL again
  2891.          */
  2892.         int status;
  2893.         XP_ListRemoveObject(net_EntryList, this_entry);
  2894.         status =NET_GetURL(this_entry->URL_s, 
  2895.                            this_entry->format_out,
  2896.                            this_entry->window_id,
  2897.                            this_entry->exit_routine);
  2898.         net_CheckForWaitingURL(this_entry->window_id, 
  2899.                                this_entry->protocol,
  2900.                                load_background);
  2901.         XP_FREE(this_entry);  /* not needed any more */
  2902.         LIBNET_UNLOCK_AND_RETURN(0);
  2903.       }
  2904.     else if(this_entry->status == MK_TOO_MANY_OPEN_FILES)
  2905.       {
  2906.         /* Queue this URL so it gets tried again
  2907.          */
  2908.         XP_ListRemoveObject(net_EntryList, this_entry);
  2909.         status = net_push_url_on_wait_queue(
  2910.                         NET_URL_Type(this_entry->URL_s->address),
  2911.                         this_entry->URL_s,
  2912.                         this_entry->format_out,
  2913.                         this_entry->window_id,
  2914.                         this_entry->exit_routine);
  2915.         NET_TotalNumberOfProcessingURLs--;
  2916.         XP_FREE(this_entry);
  2917.         LIBNET_UNLOCK_AND_RETURN(status);
  2918.       }
  2919.     else if(this_entry->status == MK_OFFLINE)
  2920.       {
  2921.         /*  Stop the stars and put up a nice message
  2922.          */
  2923.         XP_ListRemoveObject(net_EntryList, this_entry);
  2924.         {
  2925.             if (window_id->type != MWContextMail && window_id->type != MWContextMailMsg &&
  2926.                 (CLEAR_CACHE_BIT(output_format) != FO_INTERNAL_IMAGE) &&
  2927.                 (CLEAR_CACHE_BIT(output_format) != FO_EMBED) &&
  2928.                 (CLEAR_CACHE_BIT(output_format) != FO_PLUGIN) &&
  2929.                 (CLEAR_CACHE_BIT(output_format) != FO_DO_JAVA))
  2930.             {
  2931.                 /* We only display the message for top-level items (i.e., not for
  2932.                    inline images, plugins, or java classes */
  2933.                    
  2934.                 char * alert = XP_STRDUP(XP_GetString(XP_ALERT_OFFLINE_MODE_SELECTED));
  2935.                 FE_Alert(window_id, alert);
  2936.                 FREE(alert);
  2937.             }
  2938.         }
  2939.         
  2940.         net_CallExitRoutine(this_entry->exit_routine,
  2941.                             this_entry->URL_s,
  2942.                             this_entry->status,
  2943.                             this_entry->format_out,
  2944.                             this_entry->window_id);
  2945.  
  2946.  
  2947.         /* Check for WaitingURL decrements TotalNumberofProcessingURLS */
  2948.         net_CheckForWaitingURL(this_entry->window_id, 
  2949.                                this_entry->protocol,
  2950.                                load_background);
  2951.  
  2952.         XP_FREE(this_entry);
  2953.         LIBNET_UNLOCK_AND_RETURN(MK_OFFLINE);
  2954.       }
  2955.  
  2956.     if(status < 0)  /* check for finished state */
  2957.       {
  2958.  
  2959.         /* XP_OS2_FIX IBM-MAS: limit length of output string to keep from blowing trace buffer */
  2960.       TRACEMSG(("End of transfer, entry (soc=%d, con=%d) being removed from list with %d status: %-.1900s",
  2961.              this_entry->socket, this_entry->con_sock, this_entry->status,
  2962.              this_entry->URL_s->address));
  2963.  
  2964.         XP_ListRemoveObject(net_EntryList, this_entry);
  2965.  
  2966.         net_CallExitRoutine(this_entry->exit_routine,
  2967.                             this_entry->URL_s,
  2968.                             this_entry->status,
  2969.                             this_entry->format_out,
  2970.                             this_entry->window_id);
  2971.         net_CheckForWaitingURL(this_entry->window_id, 
  2972.                                this_entry->protocol,
  2973.                                load_background);
  2974.         XP_FREE(this_entry);  /* not needed any more */
  2975.       }
  2976.  
  2977.     TRACEMSG(("Leaving GetURL with %d items in list",
  2978.               XP_ListCount(net_EntryList)));
  2979.  
  2980.     /* XXX - hack for chromeless windows - jsw 10/27/95 */
  2981.     LIBNET_UNLOCK();
  2982.     if ( processcallbacks ) {
  2983.         NET_ProcessExitCallbacks();
  2984.     }
  2985.     
  2986.     return status;
  2987.  
  2988. #ifdef NOTDEF /* this is the real code here */
  2989.     LIBNET_UNLOCK_AND_RETURN(status);
  2990. #endif
  2991. }
  2992.  
  2993. /* process_net is called from the client's main event loop and
  2994.  * causes connections to be read and processed.  Multiple
  2995.  * connections can be processed simultaneously.
  2996.  */
  2997. PUBLIC int NET_ProcessNet (PRFileDesc *ready_fd,  int fd_type)
  2998. {
  2999.     ActiveEntry * tmpEntry;
  3000.     XP_List * list_item;
  3001.     int rv= -1;
  3002.     Bool load_background;
  3003.  
  3004. #ifdef XP_OS2_FIX
  3005.    /* assume no local files in net_EntryList.
  3006.       see "Thrash Optomization", below */
  3007.    int localfiles = 0;
  3008. #endif
  3009.  
  3010.     TRACEMSG(("Entering ProcessNet!  ready_fd: %d", ready_fd));
  3011.     LIBNET_LOCK();
  3012.  
  3013.     if(XP_ListIsEmpty(net_EntryList))
  3014.       {
  3015.         TRACEMSG(("Invalid call to NET_ProcessNet with fd: %d - No active entries\n", ready_fd));
  3016.  
  3017. #ifdef MOZILLA_CLIENT
  3018.         if (fd_type == NET_EVERYTIME_TYPE)
  3019.           {
  3020.             MWContext *c = XP_FindContextOfType(0, MWContextBrowser);
  3021.             if (!c) c = XP_FindContextOfType(0, MWContextMail);
  3022.             if (!c) c = XP_FindContextOfType(0, MWContextNews);
  3023.             if (!c) c = XP_FindContextOfType(0, MWContextMessageComposition);
  3024.             if (!c) c = XP_FindContextOfType(0, MWContextMailMsg);
  3025.             if (!c) c = XP_FindContextOfType(0, MWContextPane);
  3026.  
  3027.             if (c)
  3028.             {
  3029.               if(NET_IsCallNetlibAllTheTimeSet(c, NULL))
  3030.               {    
  3031.                 NET_ClearCallNetlibAllTheTime(c, "mkgeturl");
  3032.               }
  3033.               NET_SetNetlibSlowKickTimer(FALSE);
  3034.             }
  3035.           }
  3036. #endif /* MOZILLA_CLIENT */
  3037.  
  3038.     LIBNET_UNLOCK_AND_RETURN(0); /* no entries to process */
  3039.       }
  3040.  
  3041.     if(NET_InGetHostByName)
  3042.       {
  3043.         TRACEMSG(("call to processnet while doing gethostbyname call"));
  3044.         XP_ASSERT(0);
  3045.         LIBNET_UNLOCK_AND_RETURN(1);
  3046.       }
  3047.  
  3048.     /*
  3049.      * if -1 is passed into ProcessNet use select to
  3050.      * figure out if a socket is ready
  3051.      */
  3052.     if(ready_fd == NULL)
  3053.       {
  3054.         /* try and find a socket ready for reading
  3055.          */
  3056. #define MAX_SIMULTANIOUS_SOCKETS 100
  3057.         /* should never have more than MAX sockets */
  3058.         PRPollDesc poll_desc_array[MAX_SIMULTANIOUS_SOCKETS];
  3059.         unsigned int fd_set_size=0;
  3060.  
  3061.         /* reorder the list so that we get a round robin effect */
  3062.         XP_ListMoveTopToBottom(net_EntryList);
  3063.  
  3064.         fd_type = NET_SOCKET_FD;
  3065.  
  3066.         /* process one socket ready for reading */
  3067.         list_item = net_EntryList;
  3068.         while((tmpEntry = (ActiveEntry *) XP_ListNextObject(list_item)) != 0)
  3069.           {
  3070.  
  3071.             if(tmpEntry->busy)
  3072.                 continue;
  3073.  
  3074.             if(!tmpEntry->local_file && !tmpEntry->memory_file)
  3075.               {
  3076.                 if (tmpEntry->socket != NULL)
  3077.                   {
  3078.  
  3079.                     if(tmpEntry->con_sock)
  3080.                     {
  3081.                         poll_desc_array[fd_set_size].fd = tmpEntry->con_sock;
  3082.                         poll_desc_array[fd_set_size].in_flags = PR_POLL_READ | PR_POLL_EXCEPT | PR_POLL_WRITE; 
  3083.                     }
  3084.                     else
  3085.                     {
  3086.                         poll_desc_array[fd_set_size].fd = tmpEntry->socket;
  3087.                         poll_desc_array[fd_set_size].in_flags = PR_POLL_READ | PR_POLL_EXCEPT; 
  3088.                     }
  3089.  
  3090.                     fd_set_size++;
  3091.                     XP_ASSERT(fd_set_size < MAX_SIMULTANIOUS_SOCKETS);
  3092.                   }
  3093.               }
  3094.             else if(tmpEntry == 
  3095.                     (ActiveEntry *) XP_ListGetObjectNum(net_EntryList, 1))
  3096.               {
  3097.                 /* if this is the very first object in the list
  3098.                  * and it's a local file or a memory cache copy
  3099.                  * then use this one entry and skip the select call
  3100.                  * we won't deadlock because we reorder the list
  3101.                  * with every call to net process net.
  3102.                  */
  3103.                 fd_type = NET_LOCAL_FILE_FD;
  3104.                 ready_fd = tmpEntry->socket;  /* it's actually going to be NULL in this case */
  3105.  
  3106.                 /* call yeild to let other thread do something */
  3107.                 PR_Sleep(PR_INTERVAL_NO_WAIT);
  3108.  
  3109.                 break;  /* exit while */
  3110.               }
  3111.           }
  3112.  
  3113.         if(fd_type == NET_SOCKET_FD) /* in case we set it for the local file type above */
  3114.           {
  3115.             int count=0;
  3116.             int ret;
  3117.             
  3118. #ifndef NSPR20_DISABLED
  3119.             PR_Sleep(PR_INTERVAL_NO_WAIT); /* thread yeild */
  3120. #endif
  3121.  
  3122.             ret = PR_Poll(poll_desc_array,
  3123.                              fd_set_size,
  3124.                              0);
  3125.  
  3126.             if(ret < 1)
  3127.               {
  3128.  
  3129.                 TRACEMSG(("Select returned no active sockets! "
  3130.                           "WASTED CALL TO PROCESS NET"));
  3131.                 LIBNET_UNLOCK_AND_RETURN(XP_ListIsEmpty(net_EntryList) ? 0 : 1);
  3132.               }
  3133.  
  3134.             /* process one socket ready for reading,
  3135.              * find the first one ready
  3136.              */
  3137.             list_item = net_EntryList;
  3138.             while((tmpEntry=(ActiveEntry *) XP_ListNextObject(list_item)) != 0)
  3139.               {
  3140.  
  3141.                 if(tmpEntry->busy)
  3142.                     continue;
  3143.  
  3144.                 if(!tmpEntry->local_file && !tmpEntry->memory_file)
  3145.                   {
  3146.                     /* count should line up to the appropriate socket since
  3147.                      * it was added in the same order
  3148.                      */
  3149.                     XP_ASSERT(poll_desc_array[count].fd == tmpEntry->socket
  3150.                               || poll_desc_array[count].fd == tmpEntry->con_sock);
  3151.                     if(poll_desc_array[count].out_flags & (PR_POLL_READ | PR_POLL_WRITE | PR_POLL_EXCEPT))
  3152.                       {
  3153.                         ready_fd = tmpEntry->socket;
  3154.                         break;
  3155.                       }
  3156.                     count++;
  3157.                   }
  3158.               }
  3159.  
  3160.             if(!ready_fd)
  3161.             {
  3162.                 /* couldn't find the active socket.  Shouldn't ever happen */
  3163.                 XP_ASSERT(0);
  3164.                 LIBNET_UNLOCK_AND_RETURN(XP_ListIsEmpty(net_EntryList) ? 0 : 1);
  3165.             }
  3166.  
  3167.           }
  3168.       }
  3169.  
  3170.     list_item = net_EntryList;
  3171.  
  3172.     /* process one socket ready for reading
  3173.      *
  3174.      * find the ready socket in the active entry list
  3175.      */
  3176.     while((tmpEntry = (ActiveEntry *) XP_ListNextObject(list_item)) != 0)
  3177.       {
  3178.         TRACEMSG(("Found item in Active Entry List. sock #%d  con_sock #%d",
  3179.                 tmpEntry->socket, tmpEntry->con_sock));
  3180.  
  3181.         if(tmpEntry->busy)
  3182.         {
  3183.             /* I guess this is alright since one of the streams
  3184.              * (Play audio for instance) may put up a modal dialog
  3185.              * box which causes the main event loop to get called
  3186.              * from within the stream
  3187.              *
  3188.              * FE_Alert(tmpEntry->window_id, "reentrant call to Process Net");
  3189.              */
  3190.         }
  3191.             /* this will activate local and memory files as well since the ready_fd
  3192.              * will be zero and will match the NULL socket ID.
  3193.              *
  3194.              * We won't have starvation because the list is reordered every time
  3195.              */
  3196.         else if(ready_fd == tmpEntry->socket
  3197.                 || ready_fd == tmpEntry->con_sock)
  3198.         {
  3199.  
  3200.             tmpEntry->busy = TRUE;
  3201.  
  3202.              TRACEMSG(("Item has data ready for read"));
  3203.  
  3204.             rv = (*tmpEntry->proto_impl->process)(tmpEntry);
  3205.  
  3206.             tmpEntry->busy = FALSE;
  3207.         
  3208.             /* check for done status on transfer and call
  3209.              * exit routine if done.
  3210.              */
  3211.             if(rv < 0)
  3212.               {
  3213.  
  3214.                 XP_ListRemoveObject(net_EntryList, tmpEntry);
  3215.  
  3216.                 if(tmpEntry->status == MK_USE_COPY_FROM_CACHE)
  3217.                   {
  3218.                     TRACEMSG(("304 Not modified recieved using cached entry\n"));
  3219.     #ifdef MOZILLA_CLIENT
  3220.                     NET_RefreshCacheFileExpiration(tmpEntry->URL_s);
  3221.     #endif /* MOZILLA_CLIENT */
  3222.  
  3223.                     /* turn off force reload by telling it to use local copy
  3224.                      */
  3225.                     tmpEntry->URL_s->use_local_copy = TRUE;
  3226.  
  3227.                     /* restart the transfer
  3228.                      */
  3229.                     NET_GetURL(tmpEntry->URL_s,
  3230.                                    tmpEntry->format_out,
  3231.                                    tmpEntry->window_id,
  3232.                                    tmpEntry->exit_routine);
  3233.  
  3234.                     net_CheckForWaitingURL(tmpEntry->window_id,
  3235.                                                tmpEntry->protocol,
  3236.                                                tmpEntry->URL_s->load_background);
  3237.  
  3238.                   }
  3239.                 else if(tmpEntry->status == MK_DO_REDIRECT)
  3240.                   {
  3241.                     TRACEMSG(("Doing redirect part in ProcessNet"));
  3242.  
  3243.                     /* restart the whole transfer */
  3244.                     NET_GetURL(tmpEntry->URL_s,
  3245.                            tmpEntry->format_out,
  3246.                            tmpEntry->window_id,
  3247.                            tmpEntry->exit_routine);
  3248.  
  3249.                     net_CheckForWaitingURL(tmpEntry->window_id,
  3250.                                                tmpEntry->protocol,
  3251.                                                tmpEntry->URL_s->load_background);                  
  3252.                 }
  3253.                 else if(tmpEntry->status == MK_TOO_MANY_OPEN_FILES)
  3254.                 {
  3255.                     /* Queue this URL so it gets tried again
  3256.                      */
  3257.                     LIBNET_UNLOCK_AND_RETURN(net_push_url_on_wait_queue(
  3258.                         NET_URL_Type(tmpEntry->URL_s->address),
  3259.                         tmpEntry->URL_s,
  3260.                         tmpEntry->format_out,
  3261.                         tmpEntry->window_id,
  3262.                         tmpEntry->exit_routine));
  3263.                 }
  3264.                 else if(tmpEntry->status < 0
  3265.                             && !tmpEntry->URL_s->use_local_copy
  3266.                             && XP_GetError() != SSL_ERROR_BAD_CERTIFICATE
  3267.                         && (tmpEntry->status == MK_CONNECTION_REFUSED
  3268.                             || tmpEntry->status == MK_CONNECTION_TIMED_OUT
  3269.                             || tmpEntry->status == MK_UNABLE_TO_CREATE_SOCKET
  3270.                             || tmpEntry->status == MK_UNABLE_TO_LOCATE_HOST
  3271.                             || tmpEntry->status == MK_UNABLE_TO_CONNECT)
  3272.                         && (NET_IsURLInDiskCache(tmpEntry->URL_s)
  3273.                             || NET_IsURLInMemCache(tmpEntry->URL_s)))
  3274.                 {
  3275.                     /* if the status is negative something went wrong
  3276.                      * with the load.  If last_modified is set
  3277.                      * then we probably have a cache file,
  3278.                      * but it might be a broken image so
  3279.                      * make sure "use_local_copy" is not
  3280.                      * set.
  3281.                      *
  3282.                      * Only do this when we can't connect to the
  3283.                      * server.
  3284.                      */
  3285.  
  3286.                     /* if we had a cache file and got a load
  3287.                       * error, go ahead and use it anyways
  3288.                       */
  3289.  
  3290.                     /* turn off force reload by telling it to use local copy
  3291.                       */
  3292.                     tmpEntry->URL_s->use_local_copy = TRUE;
  3293.  
  3294.                     if(CLEAR_CACHE_BIT(tmpEntry->format_out) == FO_PRESENT)
  3295.                       {
  3296.                         StrAllocCat(tmpEntry->URL_s->error_msg,
  3297.                         XP_GetString( XP_USING_PREVIOUSLY_CACHED_COPY_INSTEAD ) );
  3298.  
  3299.                         FE_Alert(tmpEntry->window_id,
  3300.                                  tmpEntry->URL_s->error_msg);
  3301.                       }
  3302.  
  3303.                     FREE_AND_CLEAR(tmpEntry->URL_s->error_msg);
  3304.  
  3305.                     /* restart the transfer
  3306.                       */
  3307.                     NET_GetURL(tmpEntry->URL_s,
  3308.                                tmpEntry->format_out,
  3309.                                tmpEntry->window_id,
  3310.                                tmpEntry->exit_routine);
  3311.  
  3312.                     net_CheckForWaitingURL(tmpEntry->window_id,
  3313.                                                tmpEntry->protocol,
  3314.                                             tmpEntry->URL_s->load_background);
  3315.                 }
  3316.                 else
  3317.                 {
  3318.                     /* XP_OS2_FIX IBM-MAS: limit size of URL string to 100 to keep from blowing trace message buffer! */
  3319.                     TRACEMSG(("End of transfer, entry (soc=%d, con=%d) being removed from list with %d status: %-.1900s",
  3320.                             tmpEntry->socket, tmpEntry->con_sock, tmpEntry->status,
  3321.                             (tmpEntry->URL_s->address ? tmpEntry->URL_s->address : "")));
  3322.  
  3323.                     /* catch out of memory errors at the lowest
  3324.                      * level since we don't do it at all the out
  3325.                      * of memory condition spots
  3326.                      */
  3327.                     if(tmpEntry->status == MK_OUT_OF_MEMORY
  3328.                             && !tmpEntry->URL_s->error_msg)
  3329.                       {
  3330.                         tmpEntry->URL_s->error_msg =
  3331.                             NET_ExplainErrorDetails(MK_OUT_OF_MEMORY);
  3332.                       }
  3333.  
  3334.                     load_background = tmpEntry->URL_s->load_background;
  3335.                     /* run the exit routine
  3336.                      */
  3337.                     net_CallExitRoutine(tmpEntry->exit_routine,
  3338.                                             tmpEntry->URL_s,
  3339.                                             tmpEntry->status,
  3340.                                             tmpEntry->format_out,
  3341.                                             tmpEntry->window_id);
  3342.  
  3343.                     net_CheckForWaitingURL(tmpEntry->window_id,
  3344.                                            tmpEntry->protocol,
  3345.                                            load_background);
  3346.  
  3347.     #ifdef MILAN
  3348.                     /* if the error was caused by a NETWORK DOWN
  3349.                      * then interrupt the window.  This
  3350.                      * could still be a problem since another
  3351.                      * window may be active, but it should get
  3352.                      * the same error
  3353.                      */
  3354.                     if(SOCKET_ERRNO == XP_ERRNO_ENETDOWN)
  3355.                     {
  3356.                         NET_SilentInterruptWindow(tmpEntry->window_id);
  3357.                     }
  3358.     #endif /* MILAN */
  3359.                   }
  3360.  
  3361.                 XP_FREE(tmpEntry);  /* free the now non active entry */
  3362.  
  3363.             } /* end if  rv < 0 */
  3364.  
  3365.             TRACEMSG(("Leaving process net with %d items in list",
  3366.                           XP_ListCount(net_EntryList)));
  3367.  
  3368.             LIBNET_UNLOCK_AND_RETURN(XP_ListIsEmpty(net_EntryList) ? 0 : 1); /* all done */
  3369.  
  3370.           } /* end if */
  3371.  
  3372.       } /* end while */
  3373.  
  3374.  
  3375.     /* the active socket wasn't found in the list :(
  3376.      */
  3377.     TRACEMSG(("Invalid call to NET_ProcessNet: Active item with passed in fd: %d not found\n", ready_fd));
  3378.  
  3379.     LIBNET_UNLOCK_AND_RETURN(XP_ListIsEmpty(net_EntryList) ? 0 : 1);
  3380. }
  3381.  
  3382. /*
  3383.  *      net_InterruptActiveStream
  3384.  *      Kills a single stream given its ActiveEntry*
  3385.  *      *       FrontEndCancel -> NetInterruptWindow -> net_InterruptActiveStream
  3386.  *      *       LayoutNewDoc -> KillOtherLayouts -> net_InterruptActiveStream
  3387.  *
  3388.  *      Also removes the entry from the active list and frees it.
  3389.  *      Also allows waiting urls into the active list.
  3390.  */
  3391. PRIVATE int
  3392. net_InterruptActiveStream (ActiveEntry *entry)
  3393. {
  3394.     TRACEMSG(("Terminating transfer on port #%d, proto: %d",
  3395.                                 entry->socket, entry->protocol));
  3396.  
  3397.     /* remove it from the active list first to prevent
  3398.      * reentrant problem
  3399.      */
  3400.     XP_ListRemoveObject(net_EntryList, entry);
  3401.  
  3402.     if(entry->proto_impl)
  3403.     {
  3404.         (*entry->proto_impl->interrupt)(entry);
  3405.     }
  3406.     else
  3407.     {
  3408.         XP_ASSERT(0);
  3409.     }
  3410.  
  3411.     /* XP_OS2_FIX IBM-MAS: limit length of output string to keep from blowing trace buffer */
  3412.    TRACEMSG(("End of transfer, entry (soc=%d, con=%d) being removed from list with %d status: %-.1900s",
  3413.            entry->socket, entry->con_sock, entry->status, entry->URL_s->address));
  3414.  
  3415.     /* call exit routine since we know we are done */
  3416.     net_CallExitRoutine(entry->exit_routine,
  3417.                         entry->URL_s,
  3418.                         entry->status,
  3419.                         entry->format_out,
  3420.                         entry->window_id);
  3421.  
  3422.     /* decrement here since we don't call checkForWaitingURL's
  3423.      */
  3424.     NET_TotalNumberOfProcessingURLs--;
  3425.  
  3426.     if(!NET_AreThereActiveConnectionsForWindow(entry->window_id))
  3427.         FE_AllConnectionsComplete(entry->window_id);
  3428.  
  3429.     /* free the no longer active entry */
  3430.     XP_FREE(entry);
  3431.  
  3432.     return 0;
  3433. }
  3434.  
  3435. /* use a URL struct to find an active entry
  3436.  * The netlib lock must be held prior to calling this
  3437.  * returns NULL if not found
  3438.  */
  3439. PRIVATE ActiveEntry *
  3440. net_find_ac_from_url(URL_Struct *nurl)
  3441. {
  3442.     XP_List * iter = net_EntryList;
  3443.     ActiveEntry *tmpEntry = NULL, *rv = NULL;
  3444.  
  3445.     while ((tmpEntry = (ActiveEntry *) XP_ListNextObject(iter)) != NULL) 
  3446.       {
  3447.         if (tmpEntry->URL_s == nurl) 
  3448.         {
  3449.             rv = tmpEntry;
  3450.             break;
  3451.         }
  3452.       }
  3453.  
  3454.     return(rv);
  3455. }
  3456.  
  3457. PUBLIC Bool
  3458. NET_SetActiveEntryBusyStatus(URL_Struct *nurl, Bool set_busy)
  3459. {
  3460.     ActiveEntry *entry = NULL;
  3461.  
  3462.     entry = net_find_ac_from_url(nurl);
  3463.  
  3464.     if(entry)
  3465.         entry->busy = set_busy;
  3466.  
  3467.     return (entry != 0);
  3468. }
  3469.  
  3470. /*
  3471.  *      NET_InterruptStream kills just stream associated with an URL.
  3472.  */
  3473. PUBLIC int
  3474. NET_InterruptStream (URL_Struct *nurl)
  3475. {
  3476.     /* Find the ActiveEntry structure for this URL */
  3477.     ActiveEntry *entryToKill = NULL;
  3478.     int status;
  3479.     
  3480.     TRACEMSG(("Entering NET_InterruptStream"));
  3481.     LIBNET_LOCK();
  3482.  
  3483.     if(NET_InGetHostByName)
  3484.       {
  3485.         TRACEMSG(("call to InterrruptStream while doing gethostbyname call"));
  3486.         LIBNET_UNLOCK_AND_RETURN(1);
  3487.       }
  3488.  
  3489.     entryToKill = net_find_ac_from_url(nurl);
  3490.  
  3491. /*    assert (entryToKill);*/
  3492.     /* Kill it & free it */
  3493.     if (entryToKill)
  3494.         status = net_InterruptActiveStream (entryToKill);
  3495.     else
  3496.         status = -1;
  3497.  
  3498.     LIBNET_UNLOCK_AND_RETURN(status);
  3499. }
  3500.  
  3501.  
  3502. /* interrupt a LoadURL action by using a socket number as
  3503.  * an index.  NOTE: that this cannot interrupt non-socket
  3504.  * based operations such as file or memory cache loads
  3505.  *
  3506.  * returns -1 on error.
  3507.  */
  3508. PUBLIC int
  3509. NET_InterruptSocket (PRFileDesc *socket)
  3510. {
  3511.     /* Find the ActiveEntry structure for this URL */
  3512.     ActiveEntry *tmpEntry = NULL, *entryToKill = NULL;
  3513.     XP_List * iter;
  3514.     int status;
  3515.  
  3516.     TRACEMSG(("Entering NET_InterruptSocket"));
  3517.     LIBNET_LOCK();
  3518.     iter = net_EntryList;
  3519.  
  3520.     if(NET_InGetHostByName)
  3521.       {
  3522.     TRACEMSG(("call to InterrruptStream while doing gethostbyname call"));
  3523.     LIBNET_UNLOCK_AND_RETURN(1);
  3524.       }
  3525.  
  3526.     while ((tmpEntry = (ActiveEntry *) XP_ListNextObject(iter)) != NULL) {
  3527.     if (tmpEntry->con_sock == socket || tmpEntry->socket == socket) {
  3528.         entryToKill = tmpEntry;
  3529.         break;
  3530.     }
  3531.     }
  3532.  
  3533.     if (entryToKill)
  3534.         status = net_InterruptActiveStream (entryToKill);
  3535.     else
  3536.         status = -1;
  3537.  
  3538.     LIBNET_UNLOCK_AND_RETURN(status);
  3539. }
  3540.  
  3541. /*
  3542.  *  NET_SetNewContext changes the context associated with a URL Struct.
  3543.  *      can also change the url exit routine, which causes the old one to be
  3544.  *      called with a status of MK_CHANGING_CONTEXT
  3545.  */
  3546. PUBLIC int
  3547. NET_SetNewContext(URL_Struct *URL_s, MWContext * new_context, Net_GetUrlExitFunc *exit_routine)
  3548. {
  3549.     /* Find the ActiveEntry structure for this URL */
  3550.     ActiveEntry *tmpEntry = NULL;
  3551.     XP_List * iter;
  3552.     MWContext *old_window_id;
  3553.  
  3554.     LIBNET_LOCK();
  3555.     iter = net_EntryList;
  3556.  
  3557.     while ((tmpEntry = (ActiveEntry *) XP_ListNextObject(iter)) != NULL)
  3558.       {
  3559.     if (tmpEntry->URL_s == URL_s)
  3560.           {
  3561.             /* call the old exit routine now with the old context */
  3562.             /* call with MK_CHANGING_CONTEXT, FE shouldn't free URL_s */
  3563.             net_CallExitRoutine(tmpEntry->exit_routine,
  3564.                                 URL_s,
  3565.                                 MK_CHANGING_CONTEXT,
  3566.                                 0,
  3567.                                 tmpEntry->window_id);
  3568.  
  3569.             /*      see if we're changing exit routines */
  3570.             if(exit_routine != NULL)        {
  3571.                 /*      okay to change now. */
  3572.                 tmpEntry->exit_routine = exit_routine;
  3573.             }
  3574.             old_window_id = tmpEntry->window_id;
  3575.         tmpEntry->window_id = new_context;
  3576.  
  3577. #ifdef XP_WIN
  3578.             /*
  3579.              *      Windows needs a way to know when a URL switches contexts,
  3580.              *              so that it can keep the NCAPI progress messages
  3581.              *              specific to a URL loading and not specific to the
  3582.              *              context attempting to load.
  3583.              *      So sue me.  GAB 10-16-95
  3584.              */
  3585.             FE_UrlChangedContext(URL_s, old_window_id, new_context);
  3586. #endif /* XP_WIN */
  3587.  
  3588.             /*      if there are no more connections in the old context, we
  3589.              *      need to call AllConnectionsComplete
  3590.              */
  3591.         if(!NET_AreThereActiveConnectionsForWindow(old_window_id))
  3592.                 FE_AllConnectionsComplete(old_window_id);
  3593.  
  3594.             LIBNET_UNLOCK();
  3595.         return(0);
  3596.       }
  3597.       }
  3598.  
  3599.     /* couldn't find it :( */
  3600.     XP_ASSERT (0);
  3601.  
  3602.     LIBNET_UNLOCK();
  3603.     return(-1);
  3604. }
  3605.  
  3606. /* returns true if the stream is safe for setting up a new
  3607.  * context and using a separate window.
  3608.  *
  3609.  * This will return FALSE in multipart/mixed cases where
  3610.  * it is impossible to use separate windows for the
  3611.  * same stream.
  3612.  */
  3613. PUBLIC Bool
  3614. NET_IsSafeForNewContext(URL_Struct *URL_s)
  3615. {
  3616.     if(!URL_s || URL_s->is_active)
  3617.         return(FALSE);
  3618.  
  3619.     return(TRUE);
  3620. }
  3621.  
  3622.  
  3623. /* NET_InterruptTransfer
  3624.  *
  3625.  * Interrupts all transfers in progress that have the same window id as
  3626.  * the one passed in.
  3627.  */
  3628. PRIVATE int
  3629. net_InternalInterruptWindow(MWContext * window_id, Bool show_warning)
  3630. {
  3631.     int starting_list_count;
  3632.     ActiveEntry * tmpEntry;
  3633.     ActiveEntry * tmpEntry2;
  3634.     XP_List * list_item;
  3635.     int32 cur_win_id = FE_GetContextID(window_id);
  3636.     int number_killed=0;
  3637.     XP_Bool call_all_connections_complete = TRUE;
  3638.  
  3639.     TRACEMSG(("-------Interrupt Transfer called!"));
  3640.  
  3641.     LIBNET_LOCK();
  3642.     list_item = net_EntryList;
  3643.     starting_list_count = XP_ListCount(net_EntryList);
  3644.  
  3645. #ifdef DEBUG
  3646.     if(NET_InGetHostByName)
  3647.       {
  3648.         TRACEMSG(("call to InterrruptWindow while doing gethostbyname call"));
  3649.         LIBNET_UNLOCK_AND_RETURN(1);
  3650.       }
  3651. #endif /* DEBUG */
  3652.  
  3653.     number_killed = net_AbortWaitingURL(window_id,
  3654.                                         FALSE,
  3655.                                         net_waiting_for_actives_url_list);
  3656.     number_killed += net_AbortWaitingURL(window_id,
  3657.                                         FALSE,
  3658.                                         net_waiting_for_connection_url_list);
  3659.  
  3660.     /* run through the whole list of connections and
  3661.      * interrupt any of them that have a matching window
  3662.      * id.
  3663.      */
  3664.     tmpEntry = (ActiveEntry *) XP_ListNextObject(list_item);
  3665.  
  3666.     while(tmpEntry)
  3667.       {
  3668.     /* advance to the next item NOW in case we free this one */
  3669.     tmpEntry2 = (ActiveEntry *) XP_ListNextObject(list_item);
  3670.  
  3671.     if(FE_GetContextID(tmpEntry->window_id) == cur_win_id)
  3672.       {
  3673.             if(tmpEntry->busy)
  3674.               {
  3675.                 if(show_warning)
  3676.                   {
  3677.                 TRACEMSG(("AAAACK, reentrant protection kicking in.!!!"));
  3678. #ifdef DEBUG
  3679.                 FE_Alert(tmpEntry->window_id, XP_GetString(XP_ALERT_INTERRUPT_WINDOW));
  3680. #endif /* DEBUG */
  3681.                   }
  3682.               }
  3683.             else
  3684.               {
  3685.                 FE_EnableClicking(window_id);
  3686.                 net_InterruptActiveStream (tmpEntry);
  3687.                 number_killed += 1;
  3688.  
  3689.                 /* unset call_all_connections_complete here
  3690.                  * since InterruptActiveStream will already
  3691.                  * call all_connections_complete when it detects
  3692.                  * that there are no more active connections
  3693.                  * going on for the window.
  3694.                  */
  3695.                 call_all_connections_complete = FALSE;
  3696.               }
  3697.       } /* end if cur_win_id */
  3698.  
  3699.         tmpEntry = tmpEntry2;
  3700.       } /* end while */
  3701.  
  3702.     /* If all_connection_complete was called, FE might have destroyed
  3703.      * the context. So dont call FE_EnableClicking() if
  3704.      * call_all_connections_complete was already called.
  3705.      */
  3706.     if (call_all_connections_complete)
  3707.         FE_EnableClicking(window_id);
  3708.  
  3709.     /* we are sure that all connections are complete
  3710.      * but only call it if we killed one.
  3711.      */
  3712.     if(number_killed && call_all_connections_complete)
  3713.     FE_AllConnectionsComplete(window_id);
  3714.  
  3715.  
  3716.     TRACEMSG(("Leaving Interrupt transfer with %d items in list",
  3717.                 XP_ListCount(net_EntryList)));
  3718.  
  3719.     LIBNET_UNLOCK_AND_RETURN(starting_list_count - XP_ListCount(net_EntryList));
  3720.  
  3721. }
  3722.  
  3723. /*
  3724.  * Interrupts all transfers in progress that have the same window id as
  3725.  * the one passed in.
  3726.  */
  3727. PUBLIC int
  3728. NET_InterruptWindow(MWContext * window_id)
  3729. {
  3730. /* call interruptwindow twice so that things we interrupt that call NET_GetURL
  3731.  * will be interrupted as well
  3732.  */
  3733.     
  3734.     int rv = net_InternalInterruptWindow(window_id, TRUE);
  3735.     #ifdef XP_MAC
  3736.     /* pchen - Fix bug #72831. On Mac, continuously call
  3737.      * net_InternalInterruptWindow while
  3738.      * NET_AreThereNonBusyActiveConnectionsForWindow returns true
  3739.      */
  3740.     while(NET_AreThereNonBusyActiveConnectionsForWindow(window_id))
  3741.     #endif /* XP_MAC */
  3742.     rv += net_InternalInterruptWindow(window_id, TRUE);
  3743.     return(rv);
  3744. }
  3745.  
  3746. /*
  3747.  * Silently Interrupts all transfers in progress that have the same
  3748.  * window id as the one passed in.
  3749.  */
  3750. MODULE_PRIVATE int
  3751. NET_SilentInterruptWindow(MWContext * window_id)
  3752. {
  3753.     return(net_InternalInterruptWindow(window_id, FALSE));
  3754. }
  3755.  
  3756. /* check for any active URL transfers in progress for the given
  3757.  * window Id
  3758.  *
  3759.  * It is possible that there exist URL's on the wait queue that
  3760.  * will not be returned by this function.  It is recommended
  3761.  * that you call NET_InterruptWindow(MWContext * window_id)
  3762.  * when FALSE is returned to make sure that the wait queue is
  3763.  * cleared as well.
  3764.  * 
  3765.  * It is also possible that some URLs will be explicitly marked as
  3766.  * "background" URLs that are not identified as active, even though
  3767.  * they are.
  3768.  */
  3769. PUBLIC Bool
  3770. NET_AreThereActiveConnectionsForWindow(MWContext * window_id)
  3771. {
  3772.     ActiveEntry * tmpEntry;
  3773.     int32 cur_win_id = FE_GetContextID(window_id);
  3774.     XP_List * list_ptr;
  3775.     WaitingURLStruct * wus;
  3776.  
  3777.     LIBNET_LOCK();
  3778.  
  3779.     TRACEMSG(("-------NET_AreThereActiveConnectionsForWindow called!"));
  3780.  
  3781.     /* check for connections in the wait queue
  3782.      */
  3783.     list_ptr = net_waiting_for_actives_url_list;
  3784.     while((wus = (WaitingURLStruct*) XP_ListNextObject(list_ptr)) != NULL)
  3785.       {
  3786.     if(cur_win_id == FE_GetContextID(wus->window_id) &&
  3787.        !wus->URL_s->load_background)
  3788.           {
  3789.             LIBNET_UNLOCK();
  3790.             return(TRUE);
  3791.           }
  3792.       }
  3793.  
  3794.     /* check for connections in the connections wait queue
  3795.      */
  3796.     list_ptr = net_waiting_for_connection_url_list;
  3797.     while((wus = (WaitingURLStruct*) XP_ListNextObject(list_ptr)) != NULL)
  3798.       {
  3799.     if(cur_win_id == FE_GetContextID(wus->window_id) &&
  3800.        !wus->URL_s->load_background)
  3801.       {
  3802.         LIBNET_UNLOCK();
  3803.         return(TRUE);
  3804.       }
  3805.       }
  3806.  
  3807.     /* run through the whole list of active connections and
  3808.      * return true if any of them have the passed in window id
  3809.      */
  3810.     list_ptr = net_EntryList;
  3811.     while((tmpEntry = (ActiveEntry *) XP_ListNextObject(list_ptr)) != NULL)
  3812.       {
  3813.     if(cur_win_id == FE_GetContextID(tmpEntry->window_id) &&
  3814.        !tmpEntry->URL_s->load_background)
  3815.           {
  3816.             LIBNET_UNLOCK();
  3817.         return(TRUE);
  3818.           }
  3819.  
  3820.       } /* end while */
  3821.  
  3822.     LIBNET_UNLOCK();
  3823.     return(FALSE);
  3824. }
  3825.  
  3826. #ifdef XP_MAC
  3827. /* pchen - Fix bug #72831. Same as NET_AreThereActiveConnectionsForWindow
  3828.  * except that it will return false if there is an active connection that
  3829.  * is busy.
  3830.  */
  3831. PUBLIC Bool
  3832. NET_AreThereNonBusyActiveConnectionsForWindow(MWContext * window_id)
  3833. {
  3834.     ActiveEntry * tmpEntry;
  3835.     int32 cur_win_id = FE_GetContextID(window_id);
  3836.     XP_List * list_ptr;
  3837.     WaitingURLStruct * wus;
  3838.  
  3839.     LIBNET_LOCK();
  3840.  
  3841.     TRACEMSG(("-------NET_AreThereActiveConnectionsForWindow called!"));
  3842.  
  3843.     /* check for connections in the wait queue
  3844.      */
  3845.     list_ptr = net_waiting_for_actives_url_list;
  3846.     while((wus = (WaitingURLStruct*) XP_ListNextObject(list_ptr)) != NULL)
  3847.       {
  3848.     if(cur_win_id == FE_GetContextID(wus->window_id) &&
  3849.        !wus->URL_s->load_background)
  3850.           {
  3851.             LIBNET_UNLOCK();
  3852.             return(TRUE);
  3853.           }
  3854.       }
  3855.  
  3856.     /* check for connections in the connections wait queue
  3857.      */
  3858.     list_ptr = net_waiting_for_connection_url_list;
  3859.     while((wus = (WaitingURLStruct*) XP_ListNextObject(list_ptr)) != NULL)
  3860.       {
  3861.     if(cur_win_id == FE_GetContextID(wus->window_id) &&
  3862.        !wus->URL_s->load_background)
  3863.       {
  3864.         LIBNET_UNLOCK();
  3865.         return(TRUE);
  3866.       }
  3867.       }
  3868.  
  3869.     /* run through the whole list of active connections and
  3870.      * return true if any of them have the passed in window id
  3871.      */
  3872.     list_ptr = net_EntryList;
  3873.     while((tmpEntry = (ActiveEntry *) XP_ListNextObject(list_ptr)) != NULL)
  3874.       {
  3875.     if(cur_win_id == FE_GetContextID(tmpEntry->window_id) &&
  3876.        !tmpEntry->URL_s->load_background &&
  3877.        !tmpEntry->busy)
  3878.           {
  3879.             LIBNET_UNLOCK();
  3880.         return(TRUE);
  3881.           }
  3882.  
  3883.       } /* end while */
  3884.  
  3885.     LIBNET_UNLOCK();
  3886.     return(FALSE);
  3887. }
  3888. #endif /* XP_MAC */
  3889.  
  3890. /* KM - Are there other ActiveEntry structures being processed with the same
  3891.     context? */
  3892. /* fix Mac warning for missing prototype */
  3893. PUBLIC Bool
  3894. NET_AreThereActiveConnectionsForWindowWithOtherActiveEntry(ActiveEntry *thisEntry);
  3895.  
  3896. PUBLIC Bool
  3897. NET_AreThereActiveConnectionsForWindowWithOtherActiveEntry(ActiveEntry *thisEntry)
  3898. {
  3899.     ActiveEntry * tmpEntry;
  3900.     int32 cur_win_id = FE_GetContextID(thisEntry->window_id);
  3901.     XP_List * list_ptr;
  3902.  
  3903.     LIBNET_LOCK();
  3904.     
  3905.     /* run through the whole list of active connections and
  3906.      * return true if any of them have the passed in window id
  3907.      * with a different entry
  3908.      */
  3909.     list_ptr = net_EntryList;
  3910.     while((tmpEntry = (ActiveEntry *) XP_ListNextObject(list_ptr)) != NULL)
  3911.       {
  3912.     if((cur_win_id == FE_GetContextID(tmpEntry->window_id)) &&
  3913.        (tmpEntry != thisEntry))
  3914.           {
  3915.             LIBNET_UNLOCK();
  3916.         return(TRUE);
  3917.           }
  3918.  
  3919.       } /* end while */
  3920.  
  3921.     LIBNET_UNLOCK();
  3922.     return(FALSE);
  3923. }
  3924.  
  3925.  
  3926. /*
  3927.  *  GAB 04-23-96
  3928.  *  We're interested in knowing if there are any operations which
  3929.  *      will cause activity of the said type, in the said context.
  3930.  *  This is in the interests of PE, where they desire a world of
  3931.  *      dial on demand (hanging up the phone when we're not doing anything
  3932.  *      on the network).
  3933.  *
  3934.  *  Args:
  3935.  *      window_id   The said context to check.
  3936.  *                  If NULL, check them all (disregard).
  3937.  *      waiting     Include waiting queues in check if TRUE.
  3938.  *                  Note that waiting queues do not know thier type
  3939.  *                      yet (local, cache, or net), thus type can not
  3940.  *                      be correctly checked.  I can only assume that
  3941.  *                      we have the technology to mostly decide this
  3942.  *                      before the fact, but I see no facility available.
  3943.  *      background  Include background activity in the check if TRUE.
  3944.  *  Returns:
  3945.  *      Bool        TRUE, there is chance of activity of said type.
  3946.  *                  FALSE, that particular type of activity is not present.
  3947.  *
  3948.  */
  3949. PUBLIC Bool
  3950. NET_HasNetworkActivity(MWContext * window_id, Bool waiting, Bool background)
  3951. {
  3952.     ActiveEntry * tmpEntry;
  3953.     XP_List * list_ptr;
  3954.     WaitingURLStruct * wus;
  3955.  
  3956.     LIBNET_LOCK();
  3957.  
  3958.     TRACEMSG(("-------NET_HasNetworkActivity called!"));
  3959.  
  3960.     /* check for connections in the wait queue
  3961.      */
  3962.     if(waiting)
  3963.       {
  3964.     list_ptr = net_waiting_for_actives_url_list;
  3965.     while((wus = (WaitingURLStruct*) XP_ListNextObject(list_ptr)) != NULL)
  3966.       {
  3967.         if((window_id == NULL ||
  3968.         FE_GetContextID(window_id) ==
  3969.         FE_GetContextID(wus->window_id)) &&
  3970.         (background || !wus->URL_s->load_background))
  3971.               {
  3972.                 LIBNET_UNLOCK();
  3973.                 return(TRUE);
  3974.               }
  3975.       }
  3976.  
  3977.     /* check for connections in the connections wait queue
  3978.      */
  3979.         list_ptr = net_waiting_for_connection_url_list;
  3980.     while((wus = (WaitingURLStruct*) XP_ListNextObject(list_ptr)) != NULL)
  3981.       {
  3982.         if((window_id == NULL ||
  3983.         FE_GetContextID(window_id) ==
  3984.         FE_GetContextID(wus->window_id)) &&
  3985.         (background || !wus->URL_s->load_background))
  3986.           {
  3987.         LIBNET_UNLOCK();
  3988.         return(TRUE);
  3989.           }
  3990.       }
  3991.       }
  3992.  
  3993.     /* run through the whole list of active connections
  3994.      */
  3995.     list_ptr = net_EntryList;
  3996.     while((tmpEntry = (ActiveEntry *) XP_ListNextObject(list_ptr)) != NULL)
  3997.       {
  3998.     if((window_id == NULL ||
  3999.         FE_GetContextID(window_id) ==
  4000.         FE_GetContextID(tmpEntry->window_id)) &&
  4001.         (background || !tmpEntry->URL_s->load_background) &&
  4002.         !tmpEntry->memory_file &&
  4003.         !tmpEntry->local_file)
  4004.           {
  4005.             LIBNET_UNLOCK();
  4006.         return(TRUE);
  4007.           }
  4008.  
  4009.       } /* end while */
  4010.  
  4011.     LIBNET_UNLOCK();
  4012.     return(FALSE);
  4013. }
  4014.  
  4015.  
  4016. /* malloc, init, and set the URL structure used
  4017.  * for the network library
  4018.  */
  4019. PUBLIC URL_Struct * 
  4020. NET_CreateURLStruct (CONST char *url, NET_ReloadMethod force_reload)
  4021. {
  4022.     uint32 all_headers_size;
  4023.     URL_Struct * URL_s  = XP_NEW(URL_Struct);
  4024.  
  4025.     if(!URL_s)
  4026.       {
  4027.         return NULL;
  4028.       }
  4029.  
  4030.     /* zap the whole structure */
  4031.     XP_MEMSET (URL_s, 0, sizeof (URL_Struct));
  4032.  
  4033.     URL_s->SARCache = NULL;
  4034.  
  4035.     /* we haven't modified the address at all (since we are just creating it)*/
  4036.     URL_s->address_modified=NO;
  4037.  
  4038.     URL_s->method = URL_GET_METHOD;
  4039.  
  4040.     URL_s->force_reload = force_reload;
  4041.  
  4042.     URL_s->load_background = FALSE;
  4043.  
  4044.     URL_s->ref_count = 1;
  4045.  
  4046.     /* Allocate space for pointers to hold message (http, news etc) headers */
  4047.     all_headers_size = 
  4048.     INITIAL_MAX_ALL_HEADERS * sizeof (URL_s->all_headers.key[0]);
  4049.     URL_s->all_headers.key = (char **) XP_ALLOC(all_headers_size);
  4050.     if(!URL_s->all_headers.key)
  4051.       {
  4052.     NET_FreeURLStruct(URL_s);
  4053.     return NULL;
  4054.       }
  4055.     XP_MEMSET (URL_s->all_headers.key, 0, all_headers_size);
  4056.  
  4057.     all_headers_size = 
  4058.     INITIAL_MAX_ALL_HEADERS * sizeof (URL_s->all_headers.value[0]);
  4059.     URL_s->all_headers.value = (char **) XP_ALLOC(all_headers_size);
  4060.     if(!URL_s->all_headers.value)
  4061.       {
  4062.     NET_FreeURLStruct(URL_s);
  4063.     return NULL;
  4064.       }
  4065.     XP_MEMSET (URL_s->all_headers.value, 0, all_headers_size);
  4066.  
  4067.     URL_s->all_headers.max_index = INITIAL_MAX_ALL_HEADERS;
  4068.  
  4069.     URL_s->owner_data = NULL;
  4070.     URL_s->owner_id   = 0;
  4071.  
  4072.     /* set the passed in value */
  4073.     StrAllocCopy(URL_s->address, url);
  4074.     if (!URL_s->address) {
  4075.         /* out of memory, clean up previously allocated objects */
  4076.         NET_FreeURLStruct(URL_s);
  4077.         URL_s = NULL;
  4078.     }
  4079.  
  4080.     return(URL_s);
  4081. }
  4082.  
  4083. /* Increase the size of AllHeaders in URL_struct
  4084.  */
  4085. PRIVATE Bool 
  4086. net_EnlargeURLAllHeaders (URL_Struct * URL_s)
  4087. {
  4088.     uint32 number_of_entries = 
  4089.     URL_s->all_headers.empty_index * MULT_ALL_HEADER_COUNT;
  4090.     uint32 realloc_size = 
  4091.     number_of_entries * sizeof (URL_s->all_headers.key[0]);
  4092.     char **temp;
  4093.  
  4094.     if (number_of_entries < MAX_ALL_HEADER_COUNT) {
  4095.  
  4096.     temp = (char **) XP_REALLOC(URL_s->all_headers.key, realloc_size);
  4097.     if (temp) {
  4098.         URL_s->all_headers.key = temp;
  4099.  
  4100.         temp = (char **) XP_REALLOC(URL_s->all_headers.value, realloc_size);
  4101.         if (temp) {
  4102.         URL_s->all_headers.value = temp;
  4103.  
  4104.         URL_s->all_headers.max_index = number_of_entries;
  4105.         return(TRUE);
  4106.         }
  4107.     }
  4108.     }
  4109.     net_FreeURLAllHeaders(URL_s);
  4110.     return(FALSE);
  4111. }
  4112.  
  4113.  
  4114. /* Append Key, Value pair into AllHeaders list of URL_struct
  4115.  */
  4116. PUBLIC Bool 
  4117. NET_AddToAllHeaders(URL_Struct * URL_s, char *name, char *value)
  4118. {
  4119.     char *key_ptr;
  4120.     char *value_ptr;
  4121.  
  4122.     XP_ASSERT(URL_s);
  4123.     XP_ASSERT(name);
  4124.     XP_ASSERT(value);
  4125.  
  4126.     if ((URL_s->all_headers.empty_index >= URL_s->all_headers.max_index) &&
  4127.     (!net_EnlargeURLAllHeaders(URL_s))) {
  4128.     return(FALSE);
  4129.     }
  4130.  
  4131.     key_ptr = URL_s->all_headers.key[URL_s->all_headers.empty_index] =
  4132.     XP_STRDUP(name);
  4133.     if (!key_ptr) {
  4134.     net_FreeURLAllHeaders(URL_s);
  4135.     return(FALSE);
  4136.     }
  4137.  
  4138.     value_ptr = URL_s->all_headers.value[URL_s->all_headers.empty_index] = 
  4139.     XP_STRDUP(value);
  4140.     if (!value_ptr) {
  4141.     XP_FREE(key_ptr);
  4142.     URL_s->all_headers.key[URL_s->all_headers.empty_index] = NULL;
  4143.     net_FreeURLAllHeaders(URL_s);
  4144.     return(FALSE);
  4145.     }
  4146.     URL_s->all_headers.empty_index++;
  4147.     return(TRUE);
  4148. }
  4149.  
  4150. /* Set the option IPAddressString field
  4151.  * This field overrides the hostname when doing the connect, 
  4152.  * and allows Java to specify a spelling of an IP number.
  4153.  * Out of memory condition will cause the URL_struct to be destroyed.
  4154.  */
  4155. PUBLIC int
  4156. NET_SetURLIPAddressString (URL_Struct * URL_s, CONST char *ip_string)
  4157. {
  4158.     XP_ASSERT(URL_s);
  4159.  
  4160.     FREEIF(URL_s->IPAddressString);
  4161.     URL_s->IPAddressString = NULL;
  4162.  
  4163.     /* set the passed in value */
  4164.     StrAllocCopy(URL_s->IPAddressString, ip_string);
  4165.     return NULL == URL_s->IPAddressString;
  4166. }
  4167.  
  4168. PUBLIC URL_Struct *
  4169. NET_HoldURLStruct (URL_Struct * URL_s)
  4170. {
  4171.     if(URL_s) {
  4172.     XP_ASSERT(URL_s->ref_count > 0);
  4173.     URL_s->ref_count++;
  4174.     }
  4175.     return URL_s;
  4176. }
  4177.  
  4178.  
  4179. /* free the contents and the URL structure when finished
  4180.  */
  4181. PUBLIC void
  4182. NET_FreeURLStruct (URL_Struct * URL_s)
  4183. {
  4184.     if(!URL_s)
  4185.     return;
  4186.     
  4187.     /* if someone is holding onto a pointer to us don't die */
  4188.     XP_ASSERT(URL_s->ref_count > 0);
  4189.     URL_s->ref_count--;
  4190.     if(URL_s->ref_count > 0)
  4191.     return;
  4192.  
  4193.     FREEIF(URL_s->address);
  4194.     FREEIF(URL_s->username);
  4195.     FREEIF(URL_s->password);
  4196.     FREEIF(URL_s->IPAddressString);
  4197.     FREEIF(URL_s->referer);
  4198.     FREEIF(URL_s->post_data);
  4199.     FREEIF(URL_s->post_headers);
  4200.     FREEIF(URL_s->content_type);
  4201.     FREEIF(URL_s->content_encoding);
  4202.     FREEIF(URL_s->x_mac_type);
  4203.     FREEIF(URL_s->x_mac_creator);
  4204.     FREEIF(URL_s->charset);
  4205.     FREEIF(URL_s->boundary);
  4206.     FREEIF(URL_s->redirecting_url);
  4207.     FREEIF(URL_s->authenticate);
  4208.     FREEIF(URL_s->protection_template);
  4209.     FREEIF(URL_s->http_headers);
  4210.     FREEIF(URL_s->cache_file);
  4211.     FREEIF(URL_s->window_target);
  4212.     FREEIF(URL_s->window_chrome);
  4213.     FREEIF(URL_s->refresh_url);
  4214.     FREEIF(URL_s->wysiwyg_url);
  4215.     FREEIF(URL_s->error_msg);
  4216.  
  4217.     FREEIF(URL_s->key_cipher);
  4218.     FREEIF(URL_s->key_issuer);
  4219.     FREEIF(URL_s->key_subject);
  4220.     if ( URL_s->certificate ) {
  4221.         CERT_DestroyCertificate(URL_s->certificate);
  4222.     }
  4223.     
  4224.     if ( URL_s->redirecting_cert ) {
  4225.         CERT_DestroyCertificate(URL_s->redirecting_cert);
  4226.     }
  4227.  
  4228.     /* Free all memory associated with header information */
  4229.     net_FreeURLAllHeaders(URL_s);
  4230.  
  4231.     if(URL_s->files_to_post)
  4232.       {
  4233.         /* free a null terminated array of filenames
  4234.          */
  4235.         int i=0;
  4236.         for(i=0; URL_s->files_to_post[i] != NULL; i++)
  4237.           {
  4238.             FREE(URL_s->files_to_post[i]); /* free the filenames */
  4239.           }
  4240.         FREE(URL_s->files_to_post); /* free the array */
  4241.       }
  4242.  
  4243.     /* Like files_to_post. */
  4244.     if(URL_s->post_to)
  4245.       {
  4246.         /* free a null terminated array of filenames
  4247.          */
  4248.         int i=0;
  4249.         for(i=0; URL_s->post_to[i] != NULL; i++)
  4250.           {
  4251.             FREE(URL_s->post_to[i]); /* free the URLs */
  4252.           }
  4253.         FREE(URL_s->post_to); /* free the array */
  4254.       }
  4255.  
  4256.  
  4257.   /* free the array */
  4258.   XP_FREEIF(URL_s->add_crlf);
  4259.  
  4260.      XP_FREEIF(URL_s->page_services_url);
  4261.  
  4262.     XP_FREE(URL_s);
  4263.  
  4264. }
  4265.  
  4266. /* free the contents of AllHeader structure that is part of URL_Struct
  4267.  */
  4268. PRIVATE void
  4269. net_FreeURLAllHeaders (URL_Struct * URL_s)
  4270. {
  4271.     uint32 i=0;
  4272.  
  4273.     /* Free all memory associated with header information */
  4274.     for (i = 0; i < URL_s->all_headers.empty_index; i++) {
  4275.     if (URL_s->all_headers.key) {
  4276.         FREEIF(URL_s->all_headers.key[i]);
  4277.     }
  4278.     if (URL_s->all_headers.value) {
  4279.         FREEIF(URL_s->all_headers.value[i]);
  4280.     }
  4281.     }
  4282.     URL_s->all_headers.empty_index = URL_s->all_headers.max_index = 0;
  4283.  
  4284.     FREEIF(URL_s->all_headers.key);
  4285.     FREEIF(URL_s->all_headers.value);
  4286.     URL_s->all_headers.key = URL_s->all_headers.value = NULL;
  4287. }
  4288.  
  4289.  
  4290. /* if there is no slash in a URL besides the two that specify a host
  4291.  * then add one to the end.
  4292.  */
  4293. PRIVATE void add_slash_to_URL (URL_Struct *URL_s)
  4294. {
  4295.     char *colon=XP_STRCHR(URL_s->address,':');  /* must find colon */
  4296.     char *slash;
  4297.  
  4298.     /* make sure there is a hostname
  4299.      */
  4300.     if(*(colon+1) == '/' && *(colon+2) == '/')
  4301.         slash = XP_STRCHR(colon+3,'/');
  4302.     else
  4303.         return;
  4304.  
  4305.     if(slash==NULL)
  4306.       {
  4307.       TRACEMSG(("GetURL: URL %-.1900s changed to ",URL_s->address));
  4308.  
  4309. #ifdef MOZILLA_CLIENT
  4310.         /* add it now to the Global history since we can't get this
  4311.          * name back :(  this is a bug because we are not sure
  4312.          * that the link will actually work.
  4313.          */
  4314.         GH_UpdateGlobalHistory(URL_s);
  4315. #endif /* MOZILLA_CLIENT */
  4316.  
  4317.     StrAllocCat(URL_s->address, "/");
  4318.     URL_s->address_modified = YES;
  4319.  
  4320.     TRACEMSG(("%-.1900s",URL_s->address));
  4321.       }
  4322. }
  4323.  
  4324. #ifdef MOZILLA_CLIENT
  4325. PRIVATE void
  4326. net_OutputURLDocInfo(MWContext *ctxt, char *which, char **data, int32 *length)
  4327. {
  4328.     char *output=0;
  4329.     URL_Struct *URL_s = NET_CreateURLStruct(which, NET_DONT_RELOAD);
  4330.     struct tm *tm_struct_p;
  4331.     char buf[64];
  4332.     char *tmp=0;
  4333.     char *sec_msg, *il_msg;
  4334.  
  4335.     NET_FindURLInCache(URL_s, ctxt);
  4336.  
  4337. #define CELL_TOP                                                        \
  4338.     StrAllocCat(output,                                     \
  4339.                 "<TR><TD VALIGN=BASELINE ALIGN=RIGHT><B>");     
  4340. #define CELL_TITLE(title)                                       \
  4341.     StrAllocCat(output, title);
  4342. #define CELL_MIDDLE                                                     \
  4343.     StrAllocCat(output,                                     \
  4344.                 "</B></TD>"                                     \
  4345.                 "<TD>");
  4346. #define CELL_BODY(body)                                         \
  4347.     StrAllocCat(output, body);
  4348. #define CELL_END                                                        \
  4349.     StrAllocCat(output,                                     \
  4350.                 "</TD></TR>");
  4351. #define ADD_CELL(c_title, c_body)                       \
  4352.     CELL_TOP;                                                               \
  4353.     CELL_TITLE(c_title);                                    \
  4354.     CELL_MIDDLE;                                                    \
  4355.     CELL_BODY(c_body);                                              \
  4356.     CELL_END;
  4357.  
  4358.     StrAllocCopy(output, "<TABLE>");
  4359.  
  4360.     StrAllocCopy(tmp, "<A HREF=\"");
  4361.     StrAllocCat(tmp, URL_s->address);
  4362.     StrAllocCat(tmp, "\">");
  4363.     StrAllocCat(tmp, URL_s->address);
  4364.     StrAllocCat(tmp, "</a>");
  4365.     if(URL_s->is_netsite)
  4366.       {
  4367.         ADD_CELL(XP_GetString(XP_NETSITE_), tmp);
  4368.       }
  4369.     else
  4370.       {
  4371.         ADD_CELL(XP_GetString(XP_LOCATION_), tmp);
  4372.       }
  4373.     FREE(tmp);
  4374.  
  4375.     ADD_CELL(XP_GetString(XP_FILE_MIME_TYPE_), 
  4376.              URL_s->content_type ? URL_s->content_type : XP_GetString(XP_CURRENTLY_UNKNOWN)); 
  4377.     ADD_CELL(XP_GetString(XP_SOURCE_), URL_s->cache_file
  4378.                             ? XP_GetString(XP_CURRENTLY_IN_DISK_CACHE)
  4379.                               : URL_s->memory_copy ? 
  4380.                                 XP_GetString(XP_CURRENTLY_IN_MEM_CACHE) 
  4381.                                 : XP_GetString(XP_CURRENTLY_NO_CACHE));
  4382.  
  4383.     ADD_CELL(XP_GetString(XP_LOCAL_CACHE_FILE_), URL_s->cache_file 
  4384.                                  ? URL_s->cache_file
  4385.                                     :  XP_GetString(XP_NONE));
  4386.  
  4387.     tm_struct_p = localtime(&URL_s->last_modified);
  4388.  
  4389.     if(tm_struct_p)
  4390.       {
  4391. #ifdef XP_UNIX
  4392.         strftime(buf, 64, XP_GetString(XP_LOCAL_TIME_FMT),
  4393.                                        tm_struct_p);
  4394. #else
  4395.        char tmpbuf[64];
  4396.        XP_StrfTime(ctxt,tmpbuf,64,XP_LONG_DATE_TIME_FORMAT,
  4397.            tm_struct_p);
  4398.        /* NOTE: XP_LOCAL_TIME_FMT is different depend on platform */
  4399.        PR_snprintf(buf, 64, XP_GetString(XP_LOCAL_TIME_FMT), tmpbuf);
  4400. #endif
  4401.       }
  4402.     else
  4403.       {
  4404.         buf[0] = 0;
  4405.       }
  4406.     ADD_CELL(XP_GetString(XP_LAST_MODIFIED), URL_s->last_modified ? buf :  XP_GetString(XP_MSG_UNKNOWN));
  4407.  
  4408.     tm_struct_p = gmtime(&URL_s->last_modified);
  4409.  
  4410.     if(tm_struct_p)
  4411.       {
  4412. #ifdef XP_UNIX
  4413.         strftime(buf, 64, XP_GetString(XP_GMT_TIME_FMT),
  4414.                                        tm_struct_p);
  4415. #else
  4416.        char tmpbuf[64];
  4417.        XP_StrfTime(ctxt,tmpbuf,64,XP_LONG_DATE_TIME_FORMAT,
  4418.                    tm_struct_p);
  4419.        /* NOTE: XP_GMT_TIME_FMT is different depend on platform */
  4420.        PR_snprintf(buf, 64, XP_GetString(XP_GMT_TIME_FMT), tmpbuf);
  4421. #endif
  4422.       }
  4423.     else
  4424.       {
  4425.         buf[0] = 0;
  4426.       }
  4427.  
  4428.     ADD_CELL(XP_GetString(XP_LAST_MODIFIED), URL_s->last_modified ? buf :  XP_GetString(XP_MSG_UNKNOWN));
  4429.  
  4430. #ifdef DEBUG
  4431.     PR_snprintf(buf, 64, "%lu seconds since 1-1-70 GMT", URL_s->last_modified);
  4432.     ADD_CELL("Last Modified:", URL_s->last_modified ? buf :  "Unknown");
  4433. #endif
  4434.  
  4435.     XP_SPRINTF(buf, "%lu", URL_s->content_length);
  4436.     ADD_CELL(XP_GetString(XP_CONTENT_LENGTH_), URL_s->content_length 
  4437.                                  ? buf
  4438.                                     :  XP_GetString(XP_MSG_UNKNOWN));
  4439.     ADD_CELL(XP_GetString(XP_EXPIRES_), URL_s->expires > 0
  4440.                                  ? INTL_ctime(ctxt, &URL_s->expires)
  4441.                                     :  XP_GetString(XP_NO_DATE_GIVEN));
  4442.  
  4443.     if (URL_s->x_mac_type && *URL_s->x_mac_type)
  4444.       {
  4445.         ADD_CELL(XP_GetString(XP_MAC_TYPE_), URL_s->x_mac_type);
  4446.       }
  4447.     if (URL_s->x_mac_creator && *URL_s->x_mac_creator)
  4448.       {
  4449.         ADD_CELL(XP_GetString(XP_MAC_CREATOR_), URL_s->x_mac_creator);
  4450.       }
  4451.  
  4452.     if (URL_s->charset)
  4453.       {
  4454.         ADD_CELL(XP_GetString(XP_CHARSET_), URL_s->charset);
  4455.       }
  4456.     else 
  4457.       {
  4458.         ADD_CELL(XP_GetString(XP_CHARSET_), XP_GetString(XP_MSG_UNKNOWN));
  4459.       }
  4460.  
  4461.     if(URL_s->cache_file || URL_s->memory_copy)
  4462.         sec_msg = XP_PrettySecurityStatus(URL_s->security_on, 
  4463.                                           URL_s->key_cipher, 
  4464.                                           URL_s->key_size, 
  4465.                                           URL_s->key_secret_size);
  4466.     else
  4467.         sec_msg = XP_STRDUP(XP_GetString(XP_STATUS_UNKNOWN));
  4468.  
  4469.     if(sec_msg)
  4470.       {
  4471.         ADD_CELL(XP_GetString(XP_SECURITY_), sec_msg);
  4472.         FREE(sec_msg);
  4473.       }
  4474.  
  4475.     if(URL_s->certificate)
  4476.         sec_msg = CERT_HTMLCertInfo(URL_s->certificate, PR_TRUE,
  4477.                         PR_TRUE);
  4478.     else
  4479.         sec_msg = 0;
  4480.  
  4481.     if(sec_msg)
  4482.       {
  4483.         char *extstring;
  4484.         extstring = SECNAV_MakeCertButtonString(URL_s->certificate);
  4485.         if ( extstring ) {
  4486.             StrAllocCat(sec_msg, extstring);
  4487.             XP_FREE(extstring);
  4488.         }
  4489.         ADD_CELL(XP_GetString(XP_CERTIFICATE_), sec_msg);
  4490.         FREE(sec_msg);
  4491.       }
  4492.     StrAllocCat(output, "</TABLE>");
  4493.  
  4494.     if(URL_s->content_type 
  4495.         && !strncasecomp(URL_s->content_type, "image", 5))
  4496.       {
  4497.     /* Have a seat. Lie down.  Tell me about yourself. */
  4498.     il_msg = IL_HTMLImageInfo(URL_s->address);
  4499.     if (il_msg) {
  4500.       StrAllocCat(output, "<HR>\n");
  4501.       StrAllocCat(output, il_msg);
  4502.       XP_FREE(il_msg);
  4503.     }
  4504.       }
  4505.         
  4506.     *data = output;
  4507.     *length = XP_STRLEN(output);
  4508.  
  4509.     NET_FreeURLStruct(URL_s);
  4510.     return;
  4511. }
  4512.  
  4513. /* prints information about a context usint HTML.
  4514.  *
  4515.  * The context passed in as arg2 is the context that
  4516.  * we are printing info about and the context that
  4517.  * is in the ActiveEntry is the window we are displaying
  4518.  * within
  4519.  */
  4520. PRIVATE
  4521. int
  4522. net_PrintContextInfo(ActiveEntry *cur_entry, MWContext *context)
  4523. {
  4524.     History_entry *his;
  4525.     NET_StreamClass *stream;
  4526.     char buf[64];
  4527.     char *tmp;
  4528.  
  4529.     /* get the current history entry and
  4530.      * extract the URL from it.  That has
  4531.      * the top level document URL and the title
  4532.      */
  4533.     his = SHIST_GetCurrent (&context->hist);
  4534.    
  4535.     cur_entry->format_out = CLEAR_CACHE_BIT(cur_entry->format_out);
  4536.     StrAllocCopy(cur_entry->URL_s->content_type, TEXT_HTML);
  4537.     stream = NET_StreamBuilder(cur_entry->format_out,
  4538.                    cur_entry->URL_s, cur_entry->window_id);
  4539.  
  4540.     if(!stream)
  4541.     return(MK_UNABLE_TO_CONVERT);
  4542.  
  4543.     XP_STRCPY(buf, "<FONT SIZE=+2><b>");
  4544.     (*stream->put_block)(stream, buf, XP_STRLEN(buf));
  4545.  
  4546.     if(his && his->title)
  4547.         tmp = XP_STRDUP(his->title);
  4548.     else
  4549.         tmp = XP_STRDUP(XP_GetString(XP_UNTITLED_DOCUMENT));
  4550.  
  4551.     (*stream->put_block)(stream, tmp, XP_STRLEN(tmp));
  4552.  
  4553.     XP_STRCPY(buf, XP_GetString(XP_HAS_THE_FOLLOWING_STRUCT));
  4554.     (*stream->put_block)(stream, buf, XP_STRLEN(buf));
  4555.  
  4556.     LO_DocumentInfo(context, stream);
  4557.  
  4558.     (*stream->complete)(stream);
  4559.     cur_entry->status = MK_DATA_LOADED;
  4560.     cur_entry->status = MK_DATA_LOADED;
  4561.  
  4562.     return(-1);
  4563. }
  4564. #endif /* MOZILLA_CLIENT */
  4565.  
  4566. #define PICS_SUPPORT
  4567.  
  4568. PRIVATE char * 
  4569. net_gen_pics_document(ActiveEntry *cur_entry)
  4570. {
  4571.     char *rv = NULL;
  4572. #ifdef PICS_SUPPORT
  4573.     char *help_dir = FE_GetNetHelpDir();
  4574.  
  4575.     if(help_dir)
  4576.     {
  4577.         if (help_dir[XP_STRLEN(help_dir)-1] != '/')
  4578.             StrAllocCat(help_dir, "/");
  4579.         
  4580.         if (!help_dir)
  4581.             return NULL;
  4582.             
  4583. #define PICS_HTML " \
  4584. <TITLE>XXXXXXXXXXXXXXX</TITLE> \
  4585. <FRAMESET border=no cols=1,100%%> \
  4586. <FRAME src=about:blank> \
  4587. <FRAME src='%spicsfail.htm'> \
  4588. </FRAMESET>"
  4589.  
  4590.         rv = PR_smprintf(PICS_HTML, help_dir);
  4591.  
  4592.         FREE(help_dir);
  4593.     }
  4594.  
  4595. #endif /* PICS_SUPPORT */
  4596.  
  4597.     return rv;
  4598. }
  4599.  
  4600. /* print out silly about type URL
  4601.  */
  4602. PRIVATE int net_output_about_url(ActiveEntry * cur_entry)
  4603. {
  4604.     NET_StreamClass * stream;
  4605.     char * data=0;
  4606.     char * content_type=0;
  4607.     int32 length;
  4608.     char * which = cur_entry->URL_s->address;
  4609.     char * colon = strchr (which, ':');
  4610.     void * fe_data = NULL;
  4611.     Bool   uses_fe_data=FALSE;
  4612.  
  4613.     
  4614.     if (colon)
  4615.       which = colon + 1;
  4616.  
  4617.     if(0)
  4618.       {
  4619.         /* placeholder to make ifdef's easier */
  4620.       }
  4621. #ifdef MOZILLA_CLIENT
  4622.     else if(NET_URL_Type(which))
  4623.       {
  4624.         /* this url is asking for document info about this
  4625.          * URL.
  4626.          * Call a NET function to generate the HTML block
  4627.          */
  4628.         net_OutputURLDocInfo(cur_entry->window_id, which, &data, &length);
  4629.         StrAllocCopy(content_type, TEXT_HTML);
  4630.       }
  4631.     else if(!strncasecomp(which, "pics", 4))
  4632.       {
  4633.         data = net_gen_pics_document(cur_entry);
  4634.            if (data) {
  4635.             length = XP_STRLEN(data);
  4636.             content_type = XP_STRDUP(TEXT_HTML);
  4637.             uses_fe_data = FALSE;
  4638.         } 
  4639.       }
  4640.     else if(!strcasecomp(which, "cookies"))
  4641.     {
  4642.         NET_DisplayCookieInfoAsHTML(cur_entry);
  4643.         return(-1);
  4644.     }
  4645.     else if(!strncasecomp(which, "cache", 5))
  4646.       {
  4647.         NET_DisplayCacheInfoAsHTML(cur_entry);
  4648.         return(-1);
  4649.       }
  4650.     else if(!strcasecomp(which, "memory-cache"))
  4651.       {
  4652.         NET_DisplayMemCacheInfoAsHTML(cur_entry);
  4653.         return(-1);
  4654.       }
  4655.     else if(!strcasecomp(which, "image-cache"))
  4656.       {
  4657.     IL_DisplayMemCacheInfoAsHTML(cur_entry->format_out, cur_entry->URL_s,
  4658.                      cur_entry->window_id);
  4659.         return(-1);
  4660.       }
  4661. #ifdef DEBUG
  4662.     else if(!strcasecomp(which, "streams"))
  4663.       {
  4664.     NET_DisplayStreamInfoAsHTML(cur_entry);
  4665.     return(-1);
  4666.       }
  4667. #endif /* DEBUG */
  4668.     else if(!strcasecomp(which, "document"))
  4669.       {
  4670.         char buf[64];
  4671.         History_entry *his;
  4672.         MWContext *context;
  4673.  
  4674.         /* output a Grid here with the first grid
  4675.          * cell containing an about: url with the
  4676.          * context pointer as the argument.
  4677.          * 
  4678.          * also put the context pointer in as the post data
  4679.          * if it's not there already so that history will
  4680.          * do the right thing.
  4681.          *
  4682.          * also output blank string for all FO's not view source
  4683.          * and save
  4684.          */
  4685.  
  4686.         /* if there is post data then a context ID is hiding
  4687.          * in there.  Get it and verify it
  4688.          */
  4689.         if(cur_entry->URL_s->post_data)
  4690.           {
  4691. #if defined(__sun) && !defined(SVR4) /* sun 4.1.3 */
  4692.             sscanf(cur_entry->URL_s->post_data, "%lu", &context);
  4693. #else
  4694.             sscanf(cur_entry->URL_s->post_data, "%p", &context);
  4695. #endif
  4696.             if(!XP_IsContextInList(context))
  4697.                 context = cur_entry->window_id;
  4698.           }
  4699.         else
  4700.           {
  4701.             context = cur_entry->window_id;
  4702.           }
  4703.             
  4704.         /* get the current history entry and
  4705.          * extract the URL from it.  That has
  4706.          * the top level document URL 
  4707.          */
  4708.         his = SHIST_GetCurrent (&context->hist);
  4709.  
  4710.         StrAllocCat(data, "<TITLE>");
  4711.         StrAllocCat(data, XP_GetString(XP_DOCUMENT_INFO));
  4712.         StrAllocCat(data,       "</TITLE>"
  4713.                             "<frameset rows=\"40%,60%\">"
  4714.                             "<frame src=about:");
  4715.  
  4716.         StrAllocCopy(cur_entry->URL_s->window_target, "%DocInfoWindow");
  4717.         /* add a Chrome Struct so that we can control the window */
  4718.         cur_entry->URL_s->window_chrome = XP_NEW(Chrome);
  4719.  
  4720.         if(cur_entry->URL_s->window_chrome)
  4721.           {
  4722.             XP_MEMSET(cur_entry->URL_s->window_chrome, 0, sizeof(Chrome));
  4723.             /* it should be MWContextDialog
  4724.              * but X isn't ready for it yet...
  4725.              */
  4726. /* X is ready for MWContextDialog now...
  4727.  *#ifdef XP_UNIX
  4728.  *                      cur_entry->URL_s->window_chrome->type = MWContextBrowser;
  4729.  *#else
  4730.  */
  4731.             cur_entry->URL_s->window_chrome->type = MWContextDialog;
  4732. /*
  4733.  *#endif
  4734.  */
  4735.             cur_entry->URL_s->window_chrome->show_scrollbar = TRUE;
  4736.             cur_entry->URL_s->window_chrome->allow_resize = TRUE;
  4737.             cur_entry->URL_s->window_chrome->allow_close = TRUE;
  4738.           }
  4739.  
  4740.         /* don't let people really view the source of this... */
  4741.         if(FO_PRESENT != CLEAR_CACHE_BIT(cur_entry->format_out))        
  4742.           {
  4743.             StrAllocCat(data, "blank");
  4744.           }
  4745.         else
  4746.           {
  4747.             StrAllocCat(data, "FeCoNtExT=");
  4748.  
  4749.             if(!cur_entry->URL_s->post_data)
  4750.               {
  4751. #if defined(__sun) && !defined(SVR4) /* sun 4.1.3 */
  4752.                 XP_SPRINTF(buf, "%lu", context);
  4753. #else
  4754.                 XP_SPRINTF(buf, "%p", context);
  4755. #endif
  4756.                 StrAllocCat(data, buf);
  4757.                 StrAllocCopy(cur_entry->URL_s->post_data, buf);
  4758.               }
  4759.             else
  4760.               {
  4761.                 StrAllocCat(data, cur_entry->URL_s->post_data);
  4762.               }
  4763.           }
  4764.  
  4765.         StrAllocCat(data, "><frame name=Internal_URL_Info src=about:");
  4766.         
  4767.         if(his && his->address)
  4768.             StrAllocCat(data, his->address);
  4769.         else
  4770.             StrAllocCat(data, "blank");
  4771.  
  4772.         StrAllocCat(data, "></frameset>");
  4773.  
  4774.         length = XP_STRLEN(data);
  4775.         StrAllocCopy(content_type, TEXT_HTML);
  4776.       }
  4777.     else if(!strncasecomp(which, "Global", 6))
  4778.       {
  4779.         cur_entry->status = NET_DisplayGlobalHistoryInfoAsHTML(
  4780.                                                     cur_entry->window_id,
  4781.                                     cur_entry->URL_s,
  4782.                                     cur_entry->format_out);
  4783.  
  4784.         return(-1);
  4785.  
  4786.       }
  4787.     else if(!XP_STRNCMP(which, "FeCoNtExT=", 10))
  4788.       {
  4789.         MWContext *old_ctxt;
  4790.         
  4791. #if defined(__sun) && !defined(SVR4) /* sun 4.1.3 */
  4792.         sscanf(which+10, "%lu", &old_ctxt);
  4793. #else
  4794.         sscanf(which+10, "%p", &old_ctxt);
  4795. #endif
  4796.  
  4797.         /* verify that we have the right context 
  4798.          *
  4799.          */
  4800.         if(!XP_IsContextInList(old_ctxt))
  4801.           {
  4802.             StrAllocCopy(data, XP_GetString(XP_THE_WINDOW_IS_NOW_INACTIVE));
  4803.           }
  4804.         else    
  4805.           {
  4806.             return(net_PrintContextInfo(cur_entry, old_ctxt));
  4807.           }             
  4808.     
  4809.         length = XP_STRLEN(data);
  4810.         StrAllocCopy(content_type, TEXT_HTML);
  4811.  
  4812.       }
  4813. #endif /* MOZILLA_CLIENT */
  4814.     else if(!strncasecomp(which, "authors", 7))
  4815.       {
  4816.         static const char *d =
  4817.           ("<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html\" "
  4818.            "CHARSET=\"iso-8859-1\"><TITLE>Mozilla Über Alles</TITLE>"
  4819.            "<BODY BGCOLOR=\"#C0C0C0\" TEXT=\"#000000\">"
  4820.            "<TABLE width=\"100%\" height=\"100%\"><TR><TD ALIGN=CENTER>"
  4821.            "<FONT SIZE=5><FONT COLOR=\"#0000EE\">about:authors</FONT> "
  4822.            "removed.</FONT></TD></TR></TABLE>");
  4823.         data = XP_STRDUP(d);
  4824.         length = (d ? XP_STRLEN(d) : 0);
  4825.         content_type = XP_STRDUP(TEXT_HTML);
  4826.         uses_fe_data = FALSE;
  4827.       }
  4828.     /* Admin Kit/xp prefs diagnostic support */
  4829.     else if (!strncasecomp(which, "config", 6))
  4830.     {
  4831.         data = PREF_AboutConfig();
  4832.         if (data) {
  4833.             length = XP_STRLEN(data);
  4834.             content_type = XP_STRDUP(TEXT_HTML);
  4835.         }
  4836.     }
  4837. #ifdef XP_UNIX
  4838.     else if (!strncasecomp(which, "minibuffer", 10))
  4839.     {
  4840.         extern void FE_ShowMinibuffer(MWContext *);
  4841.  
  4842.         FE_ShowMinibuffer(cur_entry->window_id);
  4843.     }
  4844. #endif
  4845. #ifdef WEBFONTS
  4846.     else if (!strncasecomp(which, "fonts", 5))
  4847.     {
  4848.         NF_AboutFonts(cur_entry->window_id, which);
  4849.         return (-1);
  4850.     }
  4851. #endif /* WEBFONTS */
  4852.     else
  4853.       {
  4854.         fe_data = FE_AboutData(which, &data, &length, &content_type);
  4855.         uses_fe_data=TRUE;
  4856.       }
  4857.  
  4858.     if (!data || !content_type)
  4859.       {
  4860.         cur_entry->status = MK_MALFORMED_URL_ERROR;
  4861.       }
  4862.     else
  4863.       {
  4864.         int status;
  4865.         StrAllocCopy(cur_entry->URL_s->content_type, content_type);
  4866.  
  4867.         cur_entry->format_out = CLEAR_CACHE_BIT(cur_entry->format_out);
  4868.  
  4869.         stream = NET_StreamBuilder(cur_entry->format_out,
  4870.                                    cur_entry->URL_s, cur_entry->window_id);
  4871.  
  4872.         if(!stream)
  4873.           {
  4874.             cur_entry->status = MK_UNABLE_TO_CONVERT;
  4875.             return(MK_UNABLE_TO_CONVERT);
  4876.           }
  4877.  
  4878.         status = (*stream->put_block)(stream, data, length);
  4879.  
  4880.         if (status >= 0) {
  4881.             /* Append optional Admin Kit-specified about page text */
  4882.             char* custom_text = NULL;
  4883.             if (XP_STRCMP(which, "") == 0 &&
  4884.                 PREF_CopyConfigString("about_text", &custom_text) == PREF_NOERROR) {
  4885.                 (*stream->put_block)(stream, custom_text, XP_STRLEN(custom_text));
  4886.             }
  4887.         
  4888.             (*stream->complete) (stream);
  4889.             
  4890.             FREEIF(custom_text);
  4891.         }
  4892.         else
  4893.           (*stream->abort) (stream, status);
  4894.  
  4895.         cur_entry->status = status;
  4896.  
  4897.         FREE(stream);
  4898.       }
  4899.  
  4900.     if(uses_fe_data)
  4901.       {
  4902. #if defined(XP_MAC) || defined(XP_UNIX) || defined (XP_WIN)
  4903.         FE_FreeAboutData (fe_data, which);
  4904. #endif /* XP_MAC || XP_UNIX */
  4905.       }
  4906.     else
  4907.       {
  4908.         FREE(data);
  4909.         FREE(content_type);
  4910.       }
  4911.  
  4912.  
  4913.     return(-1);
  4914. }
  4915.  
  4916. #ifdef MOZILLA_CLIENT
  4917. /* print out security URL
  4918.  */
  4919. PRIVATE int net_output_security_url(ActiveEntry * cur_entry, MWContext *cx)
  4920. {
  4921.     NET_StreamClass * stream;
  4922.     char * content_type;
  4923.     char * which = cur_entry->URL_s->address;
  4924.     char * colon = XP_STRCHR (which, ':');
  4925.  
  4926.     if (colon)
  4927.       {
  4928.         /* found the first colon; now find the question mark
  4929.            (as in "about:security?certs"). */
  4930.         which = colon + 1;
  4931.         colon = XP_STRCHR (which, '?');
  4932.         if (colon)
  4933.           which = colon + 1;
  4934.         else
  4935.           which = which + XP_STRLEN (which); /* give it "" */
  4936.       }
  4937.  
  4938.     content_type = SECNAV_SecURLContentType(which);
  4939.     if (!content_type) {
  4940.         cur_entry->status = MK_MALFORMED_URL_ERROR;
  4941.  
  4942.     } else if (!strcasecomp(content_type, "advisor")) {
  4943.         cur_entry->status = SECNAV_SecHandleSecurityAdvisorURL(cx, which);
  4944.  
  4945.     } else {
  4946.         int status;
  4947.  
  4948.         StrAllocCopy(cur_entry->URL_s->content_type, content_type);
  4949.  
  4950.         cur_entry->format_out = CLEAR_CACHE_BIT(cur_entry->format_out);
  4951.  
  4952.         stream = NET_StreamBuilder(cur_entry->format_out,
  4953.                                    cur_entry->URL_s, cur_entry->window_id);
  4954.  
  4955.         if (!stream)
  4956.             return(MK_UNABLE_TO_CONVERT);
  4957.  
  4958.         status = SECNAV_SecURLData(which, stream, cx);
  4959.  
  4960.         if (status >= 0) {
  4961.             (*stream->complete) (stream);
  4962.         } else {
  4963.             (*stream->abort) (stream, status);
  4964.         }
  4965.  
  4966.         cur_entry->status = status;
  4967.  
  4968.         FREE(stream);
  4969.     }
  4970.  
  4971.     return(-1);
  4972. }
  4973.  
  4974. PRIVATE int32
  4975. net_SecurityURLLoad(ActiveEntry *ce)
  4976. {
  4977.     if(ce->URL_s)
  4978.         StrAllocCopy(ce->URL_s->charset, INTL_ResourceCharSet());
  4979.     return net_output_security_url(ce, ce->window_id);
  4980. }
  4981.  
  4982. PRIVATE int32
  4983. net_SeclibURLLoad(ActiveEntry *ce)
  4984. {
  4985.     if(ce->URL_s)
  4986.         StrAllocCopy(ce->URL_s->charset, INTL_ResourceCharSet());
  4987.     SECNAV_HandleInternalSecURL(ce->URL_s, ce->window_id);
  4988.     return -1;
  4989. }
  4990.  
  4991. PRIVATE int32
  4992. net_HTMLPanelLoad(ActiveEntry *ce)
  4993. {
  4994.     if(ce->URL_s)
  4995.         StrAllocCopy(ce->URL_s->charset, INTL_ResourceCharSet());
  4996.     XP_HandleHTMLPanel(ce->URL_s);
  4997.     return -1;
  4998. }
  4999.  
  5000. PRIVATE int32
  5001. net_HTMLDialogLoad(ActiveEntry *ce)
  5002. {
  5003.     if(ce->URL_s)
  5004.         StrAllocCopy(ce->URL_s->charset, INTL_ResourceCharSet());
  5005.     XP_HandleHTMLDialog(ce->URL_s);
  5006.     return -1;
  5007. }
  5008.  
  5009. PRIVATE int32
  5010. net_WysiwygLoad(ActiveEntry *ce)
  5011. {
  5012.     const char *real_url = LM_SkipWysiwygURLPrefix(ce->URL_s->address);
  5013.     char *new_address;
  5014.  
  5015.     /* XXX can't use StrAllocCopy because it frees dest first */
  5016.     if (real_url && (new_address = XP_STRDUP(real_url)) != NULL)
  5017.     {
  5018.         XP_FREE(ce->URL_s->address);
  5019.         ce->URL_s->address = new_address;
  5020.         FREE_AND_CLEAR(ce->URL_s->wysiwyg_url);
  5021.     }
  5022.  
  5023.     /* no need to free real_url */
  5024.  
  5025.     ce->status = MK_DO_REDIRECT;
  5026.     return MK_DO_REDIRECT;
  5027. }
  5028.  
  5029. PRIVATE int32
  5030. net_ProtoMainStub(ActiveEntry *ce)
  5031. {
  5032. #ifdef DO_ANNOYING_ASSERTS_IN_STUBS
  5033.     XP_ASSERT(0);
  5034. #endif
  5035.     return -1;
  5036. }
  5037.  
  5038. PRIVATE void
  5039. net_ProtoCleanupStub(void)
  5040. {
  5041. }
  5042.  
  5043. PRIVATE void
  5044. net_reg_random_protocol(NET_ProtoInitFunc *LoadRoutine, int type)
  5045. {
  5046.     NET_ProtoImpl *random_proto_impl;
  5047.  
  5048.     random_proto_impl = XP_NEW(NET_ProtoImpl);
  5049.  
  5050.     if(!random_proto_impl)
  5051.         return;
  5052.     
  5053.     random_proto_impl->init = LoadRoutine;
  5054.     random_proto_impl->process = net_ProtoMainStub;
  5055.     random_proto_impl->interrupt = net_ProtoMainStub;
  5056.     random_proto_impl->cleanup = net_ProtoCleanupStub;
  5057.  
  5058.     NET_RegisterProtocolImplementation(random_proto_impl, type);
  5059. }
  5060.  
  5061. /* don't you just hate it when people come along and hack this
  5062.  * kind of stuff into your code.
  5063.  *
  5064.  * @@@ clean this up some time
  5065.  */
  5066. PRIVATE void
  5067. NET_InitTotallyRandomStuffPeopleAddedProtocols(void)
  5068. {
  5069.     net_reg_random_protocol(net_SecurityURLLoad, SECURITY_TYPE_URL);
  5070.     net_reg_random_protocol(net_SeclibURLLoad, INTERNAL_SECLIB_TYPE_URL);
  5071.     net_reg_random_protocol(net_HTMLPanelLoad, HTML_PANEL_HANDLER_TYPE_URL);
  5072.     net_reg_random_protocol(net_HTMLDialogLoad, HTML_DIALOG_HANDLER_TYPE_URL);
  5073.     net_reg_random_protocol(net_WysiwygLoad, WYSIWYG_TYPE_URL);
  5074. }
  5075.  
  5076. #endif /* MOZILLA_CLIENT */
  5077.  
  5078. PRIVATE Bool net_about_kludge(URL_Struct *URL_s)
  5079. {
  5080.   unsigned char *url = (unsigned char *) URL_s->address;
  5081.   unsigned char *user = (unsigned char *) XP_STRDUP ((char*)(url + 6));
  5082.   unsigned char *tmp;
  5083.  
  5084.   if (user == NULL)
  5085.     return FALSE;
  5086.  
  5087.   for (tmp = user; *tmp; tmp++) *tmp += 23;
  5088.  
  5089.   if (     !XP_STRCMP((char*)user, "\170\202\202\170\205\170") ||    /* akkana */
  5090.      !XP_STRCMP((char*)user, "\170\211\200") ||                /* ari */
  5091.      !XP_STRCMP((char*)user, "\170\211\212\177\170\173") ||            /* arshad */
  5092.      !XP_STRCMP((char*)user, "\170\213\206\213\200\172") ||            /* atotic */
  5093.      !XP_STRCMP((char*)user, "\171\176\170\220") ||                /* bgay */
  5094.      !XP_STRCMP((char*)user, "\171\201\206\205\174\212") ||            /* bjones */
  5095.      !XP_STRCMP((char*)user, "\171\203\220\213\177\174") ||            /* blythe */
  5096.      !XP_STRCMP((char*)user, "\171\205\174\203\212\206\205") ||        /* bnelson */
  5097.      !XP_STRCMP((char*)user, "\171\206\171") ||                /* bob */
  5098.      !XP_STRCMP((char*)user, "\171\206\171\201") ||                /* bobj */
  5099.      !XP_STRCMP((char*)user, "\171\211\170\173\174") ||            /* brade */
  5100.      !XP_STRCMP((char*)user, "\171\211\200\170\205\206") ||            /* briano */
  5101.      !XP_STRCMP((char*)user, "\171\211\200\173\176\174") ||            /* bridge */
  5102.      !XP_STRCMP((char*)user, "\172\170\213\177\203\174\174\204") ||        /* cathleen */
  5103.      !XP_STRCMP((char*)user, "\172\177\206\214\172\202") ||            /* chouck */
  5104.      !XP_STRCMP((char*)user, "\172\177\211\200\212\175") ||            /* chrisf */
  5105.      !XP_STRCMP((char*)user, "\172\202\211\200\213\221\174\211") ||        /* ckritzer */
  5106.      !XP_STRCMP((char*)user, "\172\204\170\205\212\202\174") ||        /* cmanske */
  5107.      !XP_STRCMP((char*)user, "\172\206\205\215\174\211\212\174") ||        /* converse */
  5108.      !XP_STRCMP((char*)user, "\172\206\211\171\170\205") ||            /* corban */
  5109.      !XP_STRCMP((char*)user, "\172\217\214\174") ||                /* cxue */
  5110.      !XP_STRCMP((char*)user, "\172\220\174\177") ||                /* cyeh */
  5111.      !XP_STRCMP((char*)user, "\173\170\205\173\170") ||             /* danda */
  5112.      !XP_STRCMP((char*)user, "\173\170\205\204") ||                /* danm */
  5113.      !XP_STRCMP((char*)user, "\173\170\215\200\173\204") ||            /* davidm */
  5114.      !XP_STRCMP((char*)user, "\173\174\172\170\212\213\211\200") || /* decastri */
  5115.      !XP_STRCMP((char*)user, "\173\201\216") ||                /* djw */
  5116.      !XP_STRCMP((char*)user, "\173\202\170\211\203\213\206\205") ||        /* dkarlton */
  5117.      !XP_STRCMP((char*)user, "\173\204\206\212\174") ||            /* dmose */
  5118.      !XP_STRCMP((char*)user, "\173\206\205") ||                /* don */
  5119.      !XP_STRCMP((char*)user, "\173\206\211\170") ||                /* dora */
  5120.      !XP_STRCMP((char*)user, "\173\206\214\176") ||                /* doug */
  5121.      !XP_STRCMP((char*)user, "\173\207") ||                    /* dp */
  5122.      !XP_STRCMP((char*)user, "\174\171\200\205\170") ||            /* ebina */
  5123.      !XP_STRCMP((char*)user, "\174\204\170\173\174\211") ||            /* emader */
  5124.      !XP_STRCMP((char*)user, "\174\211\200\202") ||                /* erik */
  5125.      !XP_STRCMP((char*)user, "\175\211\200\174\173\204\170\205") ||        /* friedman */
  5126.      !XP_STRCMP((char*)user, "\175\213\170\205\176") ||            /* ftang */
  5127.      !XP_STRCMP((char*)user, "\175\214\171\200\205\200") ||            /* fubini */
  5128.      !XP_STRCMP((char*)user, "\175\214\211") ||                /* fur */
  5129.      !XP_STRCMP((char*)user, "\176\170\176\170\205") ||            /* gagan */
  5130.      !XP_STRCMP((char*)user, "\176\203\220\205\205") ||            /* glynn */\
  5131.      !XP_STRCMP((char*)user, "\176\211\206\216\203\213\200\176\174\211") ||    /* growltiger */\
  5132.      !XP_STRCMP((char*)user, "\177\170\176\170\205") ||            /* hagan */
  5133.      !XP_STRCMP((char*)user, "\177\170\211\173\213\212") ||            /* hardts */
  5134.       !XP_STRCMP((char*)user, "\177\212\177\170\216") ||            /* hshaw */
  5135.       !XP_STRCMP((char*)user, "\177\220\170\213\213") ||            /* hyatt */
  5136.      !XP_STRCMP((char*)user, "\200\211\174\205\174") ||            /* irene */
  5137.      !XP_STRCMP((char*)user, "\201\170\211") ||                /* jar */
  5138.      !XP_STRCMP((char*)user, "\201\174\175\175") ||                /* jeff */
  5139.      !XP_STRCMP((char*)user, "\201\174\215\174\211\200\205\176") ||        /* jevering */  
  5140.      !XP_STRCMP((char*)user, "\201\176") ||                    /* jg */
  5141.      !XP_STRCMP((char*)user, "\201\176\174\203\203\204\170\205") ||        /* jgellman */
  5142.      !XP_STRCMP((char*)user, "\201\201") ||                    /* jj */
  5143.      !XP_STRCMP((char*)user, "\201\206\174\211\214\175\175") ||        /* joeruff */
  5144.      !XP_STRCMP((char*)user, "\201\206\202\200") ||                /* joki */
  5145.      !XP_STRCMP((char*)user, "\201\206\205\170\212") ||            /* jonas */
  5146.      !XP_STRCMP((char*)user, "\201\207\204") ||                /* jpm */
  5147.      !XP_STRCMP((char*)user, "\201\212\216") ||                /* jsw */
  5148.      !XP_STRCMP((char*)user, "\201\216\221") ||                /* jwz */
  5149.      !XP_STRCMP((char*)user, "\202\170\177\174\211\205") ||            /* kahern */
  5150.      !XP_STRCMP((char*)user, "\202\170\211\203\213\206\205") ||        /* karlton */
  5151.      !XP_STRCMP((char*)user, "\202\200\207\207") ||                /* kipp */
  5152.      !XP_STRCMP((char*)user, "\202\204\172\174\205\213\174\174") ||        /* kmcentee */
  5153.      !XP_STRCMP((char*)user, "\202\206\174\177\204") ||            /* koehm */
  5154.      !XP_STRCMP((char*)user, "\202\211\200\212\213\200\205") ||        /* kristin */
  5155.      !XP_STRCMP((char*)user, "\203\170\211\214\171\171\200\206") ||        /* larubbio */
  5156.     !XP_STRCMP((char*)user, "\203\170\216") ||                     /* law */
  5157.      !XP_STRCMP((char*)user, "\203\174\205\221") ||                /* lenz */
  5158.      !XP_STRCMP((char*)user, "\203\206\211\200\202") ||            /* lorik */
  5159.      !XP_STRCMP((char*)user, "\203\213\170\171\171") ||            /* ltabb */
  5160.      !XP_STRCMP((char*)user, "\204\170\203\204\174\211") ||            /* malmer */
  5161.      !XP_STRCMP((char*)user, "\204\170\211\172\170") ||            /* marca */
  5162.      !XP_STRCMP((char*)user, "\204\170\213\213") ||                /* matt */ 
  5163.      !XP_STRCMP((char*)user, "\204\172\170\175\174\174") ||            /* mcafee */
  5164.      !XP_STRCMP((char*)user, "\204\172\204\214\203\203\174\205") ||        /* mcmullen */
  5165.      !XP_STRCMP((char*)user, "\204\174\173\200\213\170\213\200\206\205") ||    /* meditation */
  5166.      !XP_STRCMP((char*)user, "\204\203\204") ||                /* mlm */
  5167.      !XP_STRCMP((char*)user, "\204\206\205\200\210\214\174") ||        /* monique */
  5168.      !XP_STRCMP((char*)user, "\204\206\205\213\214\203\203\200")||        /* montulli */
  5169.      !XP_STRCMP((char*)user, "\204\206\211\212\174") ||            /* morse */
  5170.      !XP_STRCMP((char*)user, "\204\206\214\211\174\220")||            /* mourey */
  5171.      !XP_STRCMP((char*)user, "\204\213\206\220") ||                /* mtoy */
  5172.      !XP_STRCMP((char*)user, "\204\216\174\203\172\177") ||            /* mwelch */
  5173.      !XP_STRCMP((char*)user, "\205\174\203\212\206\205\171") ||        /* nelsonb */
  5174.      !XP_STRCMP((char*)user, "\205\200\212\177\174\174\213\177") ||        /* nisheeth */
  5175.      !XP_STRCMP((char*)user, "\206\200\205\202") ||                /* oink */
  5176.      !XP_STRCMP((char*)user, "\207\170\203\174\215\200\172\177") ||        /* palevich */
  5177.      !XP_STRCMP((char*)user, "\207\170\210\214\200\205") ||            /* paquin */
  5178.      !XP_STRCMP((char*)user, "\207\170\214\203\173") ||            /* pauld */
  5179.      !XP_STRCMP((char*)user, "\207\172\177\174\205") ||            /* pchen */
  5180.      !XP_STRCMP((char*)user, "\207\200\174\211\211\174") ||            /* pierre */
  5181.      !XP_STRCMP((char*)user, "\207\200\176\203\174\213") ||            /* piglet */
  5182.      !XP_STRCMP((char*)user, "\207\200\205\202\174\211\213\206\205") ||    /* pinkerton */
  5183.      !XP_STRCMP((char*)user, "\211\170\204\170\205") ||            /* raman */
  5184.      !XP_STRCMP((char*)user, "\211\170\204\200\211\206") ||            /* ramiro */
  5185.      !XP_STRCMP((char*)user, "\211\174\172\214\211\212\200\206\205") ||    /* recursion */
  5186.      !XP_STRCMP((char*)user, "\211\174\207\202\170") ||            /* repka */
  5187.      !XP_STRCMP((char*)user, "\211\200\172\170\211\173\206\171") ||        /* ricardob */
  5188.      !XP_STRCMP((char*)user, "\211\201\172") ||                /* rjc */
  5189.      !XP_STRCMP((char*)user, "\211\204\216") ||                /* rmw */
  5190.      !XP_STRCMP((char*)user, "\211\170\204\211\170\201") ||        /* ramraj */
  5191.      !XP_STRCMP((char*)user, "\211\206\171\204") ||                /* robm */
  5192.      !XP_STRCMP((char*)user, "\211\206\174\171\174\211") ||            /* roeber */
  5193.      !XP_STRCMP((char*)user, "\211\207\206\213\213\212") ||            /* rpotts */
  5194.      !XP_STRCMP((char*)user, "\211\214\212\203\170\205") ||            /* ruslan */
  5195.      !XP_STRCMP((char*)user, "\212\172\172") ||                /* scc */
  5196.      !XP_STRCMP((char*)user, "\212\173\170\176\203\174\220") ||        /* sdagley */
  5197.      !XP_STRCMP((char*)user, "\212\177\170\211\206\205\200") ||        /* sharoni */
  5198.      !XP_STRCMP((char*)user, "\212\177\214\170\205\176") ||            /* shuang */
  5199.      !XP_STRCMP((char*)user, "\212\202") ||                    /* sk */
  5200.      !XP_STRCMP((char*)user, "\212\202\220\174") ||                /* skye */
  5201.      !XP_STRCMP((char*)user, "\212\203\170\204\204") ||            /* slamm */
  5202.      !XP_STRCMP((char*)user, "\212\204\212\200\203\215\174\211") ||        /* smsilver */
  5203.      !XP_STRCMP((char*)user, "\212\207\174\205\172\174") ||            /* spence */
  5204.      !XP_STRCMP((char*)user, "\212\207\200\173\174\211") ||            /* spider */
  5205.      !XP_STRCMP((char*)user, "\212\212\207\200\213\221\174\211") ||        /* sspitzer */
  5206.      !XP_STRCMP((char*)user, "\212\213\174\211\205") ||            /* stern */
  5207.      !XP_STRCMP((char*)user, "\213\170\211\170\177") ||            /* tarah */
  5208.      !XP_STRCMP((char*)user, "\213\174\211\211\220") ||            /* terry */
  5209.     !XP_STRCMP((char*)user, "\213\175\203\200\205\213") ||         /* tflint */
  5210.      !XP_STRCMP((char*)user, "\213\200\204\204") ||                /* timm */
  5211.      !XP_STRCMP((char*)user, "\213\206\212\177\206\202") ||            /* toshok */
  5212.      !XP_STRCMP((char*)user, "\213\211\170\172\220") ||            /* tracy */
  5213.      !XP_STRCMP((char*)user, "\213\211\200\212\213\170\205") ||        /* tristan */
  5214.      !XP_STRCMP((char*)user, "\213\211\214\173\174\203\203\174") ||        /* trudelle */
  5215.      !XP_STRCMP((char*)user, "\215\170\203\174\212\202\200") ||        /* valeski */
  5216.      !XP_STRCMP((char*)user, "\216\170\211\211\174\205") ||            /* warren */
  5217.      !XP_STRCMP((char*)user, "\216\201\212") )                /* wjs */
  5218.   {
  5219.       /* "http://people.netscape.com/" */
  5220.       char *head = ("\177\213\213\207\121\106\106\207\174\206\207\203\174\105"
  5221.             "\205\174\213\212\172\170\207\174\105\172\206\204\106");
  5222.       unsigned char *location = (unsigned char *)
  5223.         XP_ALLOC (XP_STRLEN ((char *) head) + XP_STRLEN ((char *) user) + 2);
  5224.       if (! location)
  5225.         {
  5226.           XP_FREE (user);
  5227.           return FALSE;
  5228.         }
  5229.       XP_STRCPY ((char *) location, (char *) head);
  5230.       XP_STRCAT ((char *) location, (char *) user);
  5231.       for (tmp = location; *tmp; tmp++) *tmp -= 23;
  5232.       XP_STRCAT ((char *) location, "/");
  5233.       XP_FREE (user);
  5234.       XP_FREE (URL_s->address);
  5235.       URL_s->address = (char *) location;
  5236.       URL_s->address_modified = TRUE;
  5237.       return TRUE;
  5238.     }
  5239.   else
  5240.     {
  5241.       XP_FREE (user);
  5242.       return FALSE;
  5243.     }
  5244. }
  5245.  
  5246. PRIVATE int32
  5247. net_AboutLoad(ActiveEntry *ce)
  5248. {
  5249.     if(net_about_kludge (ce->URL_s))
  5250.     {
  5251.         ce->status = MK_DO_REDIRECT;
  5252.         return MK_DO_REDIRECT;
  5253.     }
  5254.  
  5255.     return net_output_about_url(ce);
  5256. }
  5257.  
  5258. PRIVATE int32
  5259. net_AboutStub(ActiveEntry *ce)
  5260. {
  5261. #ifdef DO_ANNOYING_ASSERTS_IN_STUBS
  5262.     XP_ASSERT(0);
  5263. #endif
  5264.     return -1;
  5265. }
  5266.  
  5267. PRIVATE void
  5268. net_CleanupAbout(void)
  5269. {
  5270. }
  5271.  
  5272. PRIVATE void
  5273. NET_InitAboutProtocol(void)
  5274. {
  5275.         static NET_ProtoImpl about_proto_impl;
  5276.  
  5277.         about_proto_impl.init = net_AboutLoad;
  5278.         about_proto_impl.process = net_AboutStub;
  5279.         about_proto_impl.interrupt = net_AboutStub;
  5280.         about_proto_impl.cleanup = net_CleanupAbout;
  5281.  
  5282.         NET_RegisterProtocolImplementation(&about_proto_impl, ABOUT_TYPE_URL);
  5283. }
  5284.  
  5285. /*
  5286.  *  Check the no_proxy environment variable to get the list
  5287.  *  of hosts for which proxy server is not consulted.
  5288.  *
  5289.  *  no_proxy is a comma- or space-separated list of machine
  5290.  *  or domain names, with optional :port part.  If no :port
  5291.  *  part is present, it applies to all ports on that domain.
  5292.  *
  5293.  *  Example: "netscape.com,some.domain:8001"
  5294.  *
  5295.  */
  5296. PRIVATE Bool override_proxy (CONST char * URL)
  5297. {
  5298.     char * p = NULL;
  5299.     char * host = NULL;
  5300.     int port = 0;
  5301.     int h_len = 0;
  5302.     char *no_proxy = MKno_proxy;
  5303.  
  5304.     if(no_proxy==NULL)
  5305.     return(FALSE);
  5306.  
  5307.     if (!(host = NET_ParseURL(URL, GET_HOST_PART)))
  5308.     return NO;
  5309.  
  5310.     if (!*host)
  5311.       {
  5312.     XP_FREE(host);
  5313.     return NO;
  5314.       }
  5315.  
  5316.     p = XP_STRCHR(host, ':');
  5317.     if (p)     /* Port specified */
  5318.       {
  5319.     *p++ = 0;                       /* Chop off port */
  5320.     port = atoi(p);
  5321.       }
  5322.     else
  5323.       {                          /* Use default port */
  5324.     char * access = NET_ParseURL(URL, GET_PROTOCOL_PART);
  5325.     if (access) {
  5326.         if      (!XP_STRCMP(access,"http"))    port = 80;
  5327.         else if (!XP_STRCMP(access,"gopher"))  port = 70;
  5328.         else if (!XP_STRCMP(access,"ftp"))     port = 21;
  5329.         XP_FREE(access);
  5330.     }
  5331.       }
  5332.     if (!port) port = 80;           /* Default */
  5333.     h_len = XP_STRLEN(host);
  5334.  
  5335.     while (*no_proxy) {
  5336.     char * end;
  5337.     char * colon = NULL;
  5338.     int templ_port = 0;
  5339.     int t_len;
  5340.  
  5341.     while (*no_proxy && (isspace(*no_proxy) || *no_proxy==','))
  5342.     no_proxy++;                 /* Skip whitespace and separators */
  5343.  
  5344.     end = no_proxy;
  5345.     while (*end && !isspace(*end) && *end != ',')   /* Find separator */
  5346.           {
  5347.         if (*end==':') colon = end;                 /* Port number given */
  5348.         end++;
  5349.       }
  5350.  
  5351.     if (colon)
  5352.           {
  5353.         templ_port = atoi(colon+1);
  5354.         t_len = colon - no_proxy;
  5355.       }
  5356.         else
  5357.           {
  5358.         t_len = end - no_proxy;
  5359.       }
  5360.  
  5361.     /* don't worry about case when comparing the requested host to the proxies in the
  5362.        no proxy list, i.e. use XP_STRNCASECMP */
  5363.     if ((!templ_port || templ_port == port)  && (t_len > 0  &&  t_len <= h_len  &&
  5364.         !XP_STRNCASECMP(host + h_len - t_len, no_proxy, t_len))) 
  5365.           {
  5366.         XP_FREE(host);
  5367.         return YES;
  5368.       }
  5369.     if (*end)
  5370.         no_proxy = end+1;
  5371.     else
  5372.         break;
  5373.     }
  5374.  
  5375.     XP_FREE(host);
  5376.     return NO;
  5377. }
  5378.  
  5379. PUBLIC void
  5380. NET_SetProxyServer(NET_ProxyType type, const char * org_host_port)
  5381. {
  5382.     char *host_port = 0;
  5383.  
  5384.     if(org_host_port && *org_host_port) {
  5385.         host_port = XP_STRDUP(org_host_port);
  5386.  
  5387.         if(!host_port)
  5388.             return;
  5389.  
  5390.         /* limit the size of host_port to within MAXHOSTNAMELEN */
  5391.         if(XP_STRLEN(host_port) > MAXHOSTNAMELEN)
  5392.             host_port[MAXHOSTNAMELEN] = '\0';
  5393.     }
  5394.  
  5395.     TRACEMSG(("NET_SetProxyServer called with host: %-.1900s",
  5396.               host_port ? host_port : "(null)"));
  5397.  
  5398.     switch(type)
  5399.       {
  5400.         case PROXY_AUTOCONF_URL:
  5401.             if (host_port) {
  5402.                 if (!MKproxy_ac_url || XP_STRCMP(MKproxy_ac_url, org_host_port)) {
  5403.                     StrAllocCopy(MKproxy_ac_url, org_host_port);
  5404.                     NET_ProxyAcLoaded = FALSE;
  5405.                 }
  5406.             }
  5407.             else {
  5408.                 if (MKproxy_ac_url) {
  5409.                     FREE_AND_CLEAR(MKproxy_ac_url);
  5410.                     NET_ProxyAcLoaded = FALSE;
  5411.                 }
  5412.             }
  5413.             break;
  5414.  
  5415.         case FTP_PROXY:
  5416.             if(host_port)
  5417.             StrAllocCopy(MKftp_proxy, host_port);
  5418.             else
  5419.                 FREE_AND_CLEAR(MKftp_proxy);
  5420.             break;
  5421.         case GOPHER_PROXY:
  5422.             if(host_port)
  5423.             StrAllocCopy(MKgopher_proxy, host_port);
  5424.             else
  5425.                 FREE_AND_CLEAR(MKgopher_proxy);
  5426.             break;
  5427.         case HTTP_PROXY:
  5428.             if(host_port)
  5429.             StrAllocCopy(MKhttp_proxy, host_port);
  5430.             else
  5431.                 FREE_AND_CLEAR(MKhttp_proxy);
  5432.             break;
  5433.         case HTTPS_PROXY:
  5434.             if(host_port)
  5435.             StrAllocCopy(MKhttps_proxy, host_port);
  5436.             else
  5437.                 FREE_AND_CLEAR(MKhttps_proxy);
  5438.             break;
  5439.         case NEWS_PROXY:
  5440.             if(host_port)
  5441.             StrAllocCopy(MKnews_proxy, host_port);
  5442.             else
  5443.                 FREE_AND_CLEAR(MKnews_proxy);
  5444.             break;
  5445.         case WAIS_PROXY:
  5446.             if(host_port)
  5447.             StrAllocCopy(MKwais_proxy, host_port);
  5448.             else
  5449.                 FREE_AND_CLEAR(MKno_proxy);
  5450.             break;
  5451.  
  5452.         case NO_PROXY:
  5453.             if(host_port)
  5454.             StrAllocCopy(MKno_proxy, org_host_port);
  5455.             break;
  5456.  
  5457.         default:
  5458.             /* ignore */
  5459.             break;
  5460.       }
  5461.  
  5462.     FREEIF(host_port);
  5463. }
  5464.  
  5465. /* return a proxy server host and port to the caller or NULL
  5466.  *
  5467.  * all this proxy bussiness should be rewritten to be generalized
  5468.  * and not switch() based [LJM]
  5469.  */
  5470. MODULE_PRIVATE char *
  5471. NET_FindProxyHostForUrl(int url_type, char *url_address)
  5472. {
  5473.  
  5474.     if(override_proxy(url_address))
  5475.         return NULL;
  5476.  
  5477.     switch(url_type)
  5478.       {
  5479.         case FTP_TYPE_URL:
  5480.             return MKftp_proxy;
  5481.             break;
  5482.  
  5483.         case GOPHER_TYPE_URL:
  5484.             return(MKgopher_proxy);
  5485.             break;
  5486.  
  5487.         case HTTP_TYPE_URL:
  5488.         case URN_TYPE_URL:
  5489.         case NFS_TYPE_URL:
  5490.             return(MKhttp_proxy);
  5491.             break;
  5492.  
  5493.         case SECURE_HTTP_TYPE_URL:
  5494.             return(MKhttps_proxy);
  5495.             break;
  5496.  
  5497.         case NEWS_TYPE_URL:
  5498.         case INTERNAL_NEWS_TYPE_URL:
  5499.             return(MKnews_proxy);
  5500.             break;
  5501.  
  5502.         case WAIS_TYPE_URL:
  5503.             return(MKwais_proxy);
  5504.             break;
  5505.  
  5506.         default:
  5507.             /* ignore */
  5508.             break;
  5509.       }
  5510.  
  5511.     return NULL;
  5512. }
  5513.  
  5514. /* Force it to reload automatic proxy config.
  5515.  * This function simply sets a flag so the config will be 
  5516.  * reloaded during the next geturl. It doesn't actually
  5517.  * do the reloading here. */
  5518. #ifdef MOZILLA_CLIENT
  5519. PUBLIC void
  5520. NET_ReloadProxyConfig(MWContext *window_id)
  5521. {
  5522.     /* if we have a global config load it */
  5523.     if (MKglobal_config_url)
  5524.           NET_GlobalAcLoaded = FALSE;
  5525.     /* else if we have an old style proxy config and we are set on automatic...load it 
  5526.      * , or if we're using the old style proxy config that is actually a proxy autodiscovery
  5527.      * url, reload it also */
  5528.     else if( (MKproxy_ac_url &&    (!MKproxy_style || MKproxy_style == PROXY_STYLE_AUTOMATIC))
  5529.             || (NET_UsingPadPac()) )
  5530.           NET_ProxyAcLoaded = FALSE;
  5531. }
  5532. #endif  /* MOZILLA_CLIENT */
  5533.  
  5534.  
  5535. /* Debugging routine prints an URL (and string "header")
  5536.  */
  5537. #ifdef DEBUG
  5538. void TraceURL (URL_Struct *url, char *header)
  5539. {
  5540.     TRACEMSG(("URL %-.1900s", header));
  5541.     if (url->address)           TRACEMSG(("    address          %s", url->address));
  5542.     if (url->content_length)    TRACEMSG(("    content_length   %i", url->content_length));
  5543.     if (url->content_type)      TRACEMSG(("    content_type     %s", url->content_type));
  5544.     if (url->content_encoding)  TRACEMSG(("    content_encoding %s", url->content_encoding));
  5545. }
  5546. #endif
  5547.  
  5548. /* This function's existance was prompted by the front end desiring the ability to put the
  5549.    client in kiosk mode. The function removes any potentially sensitive information from the
  5550.    background: passwords, caches, histories, cookies. */
  5551. /* fix Mac warning of missing prototype */
  5552. PUBLIC void
  5553. NET_DestroyEvidence();
  5554.  
  5555. PUBLIC void
  5556. NET_DestroyEvidence()
  5557. {
  5558.     int32 oldSize = 0;
  5559.  
  5560.     /* Handle authorizations */
  5561.     NET_RemoveAllAuthorizations();
  5562.     
  5563.     /* Handle global history */
  5564.     GH_ClearGlobalHistory();
  5565.  
  5566.     /* Handle Session History */
  5567.  
  5568.     /* Handle cookies */
  5569.     NET_RemoveAllCookies();
  5570.  
  5571.     /* Handle disk cache */
  5572.     oldSize = NET_GetDiskCacheSize();
  5573.     NET_SetDiskCacheSize(0); /* zero it out */
  5574.     NET_SetDiskCacheSize(oldSize); /* set it back up */
  5575.  
  5576.     /* Handle memory cache */
  5577.     oldSize = NET_GetMemoryCacheSize();
  5578.     NET_SetMemoryCacheSize(0); /* zero it out */
  5579.     NET_SetMemoryCacheSize(oldSize); /* set it back up */
  5580. }
  5581.  
  5582. #ifndef MOZ_MAIL_NEWS
  5583.  
  5584. /* this whole mess should get moved to the mksmtp.c file
  5585.  * where it can share the InitMailtoProtocol function
  5586.  * since that is what it is trying to replace
  5587.  *
  5588.  * for now InitMailto will be duplicated inside the ifdef.
  5589.  */
  5590.  
  5591. #define CE_URL_S            cur_entry->URL_s
  5592. #define CE_STATUS           cur_entry->status
  5593.  
  5594. extern void FE_AlternateCompose(
  5595.     char * from, char * reply_to, char * to, char * cc, char * bcc,
  5596.     char * fcc, char * newsgroups, char * followup_to,
  5597.     char * organization, char * subject, char * references,
  5598.     char * other_random_headers, char * priority,
  5599.     char * attachment, char * newspost_url, char * body);
  5600.  
  5601. MODULE_PRIVATE
  5602. int32 net_MailtoLoad (ActiveEntry * cur_entry)
  5603. {
  5604.         char *parms = NET_ParseURL (CE_URL_S->address, GET_SEARCH_PART);
  5605.         char *rest = parms;
  5606.         char *from = 0;                        /* internal only */
  5607.         char *reply_to = 0;                    /* internal only */
  5608.         char *to = 0;
  5609.         char *cc = 0;
  5610.         char *bcc = 0;
  5611.         char *fcc = 0;                        /* internal only */
  5612.         char *newsgroups = 0;
  5613.         char *followup_to = 0;
  5614.         char *html_part = 0;                /* internal only */
  5615.         char *organization = 0;                /* internal only */
  5616.         char *subject = 0;
  5617.         char *references = 0;
  5618.         char *attachment = 0;                /* internal only */
  5619.         char *body = 0;
  5620.         char *other_random_headers = 0;        /* unused (for now) */
  5621.         char *priority = 0;
  5622.         char *newshost = 0;                    /* internal only */
  5623.         XP_Bool encrypt_p = FALSE;
  5624.         XP_Bool sign_p = FALSE;                /* internal only */
  5625.         char *newspost_url = 0;
  5626.         XP_Bool force_plain_text = FALSE;
  5627.         to = NET_ParseURL (CE_URL_S->address, GET_PATH_PART);
  5628.         if (rest && *rest == '?')
  5629.           {
  5630.              /* start past the '?' */
  5631.             rest++;
  5632.             rest = XP_STRTOK (rest, "&");
  5633.             while (rest && *rest)
  5634.               {
  5635.                 char *token = rest;
  5636.                 char *value = 0;
  5637.                 char *eq = XP_STRCHR (token, '=');
  5638.                 if (eq)
  5639.                   {
  5640.                     value = eq+1;
  5641.                     *eq = 0;
  5642.                   }
  5643.                 switch (*token)
  5644.                   {
  5645.                   case 'A': case 'a':
  5646.                     if (!strcasecomp (token, "attachment") &&
  5647.                         CE_URL_S->internal_url)
  5648.                       StrAllocCopy (attachment, value);
  5649.                     break;
  5650.                   case 'B': case 'b':
  5651.                     if (!strcasecomp (token, "bcc"))
  5652.                       {
  5653.                         if (bcc && *bcc)
  5654.                           {
  5655.                             StrAllocCat (bcc, ", ");
  5656.                             StrAllocCat (bcc, value);
  5657.                           }
  5658.                         else
  5659.                           {
  5660.                             StrAllocCopy (bcc, value);
  5661.                           }
  5662.                       }
  5663.                     else if (!strcasecomp (token, "body"))
  5664.                       {
  5665.                         if (body && *body)
  5666.                           {
  5667.                             StrAllocCat (body, "\n");
  5668.                             StrAllocCat (body, value);
  5669.                           }
  5670.                         else
  5671.                           {
  5672.                             StrAllocCopy (body, value);
  5673.                           }
  5674.                       }
  5675.                     break;
  5676.                   case 'C': case 'c':
  5677.                     if (!strcasecomp (token, "cc"))
  5678.                       {
  5679.                         if (cc && *cc)
  5680.                           {
  5681.                             StrAllocCat (cc, ", ");
  5682.                             StrAllocCat (cc, value);
  5683.                           }
  5684.                         else
  5685.                           {
  5686.                             StrAllocCopy (cc, value);
  5687.                           }
  5688.                       }
  5689.                     break;
  5690.                   case 'E': case 'e':
  5691.                     if (!strcasecomp (token, "encrypt") ||
  5692.                         !strcasecomp (token, "encrypted"))
  5693.                       encrypt_p = (!strcasecomp(value, "true") ||
  5694.                                    !strcasecomp(value, "yes"));
  5695.                     break;
  5696.                   case 'F': case 'f':
  5697.                     if (!strcasecomp (token, "followup-to"))
  5698.                       StrAllocCopy (followup_to, value);
  5699.                     else if (!strcasecomp (token, "from") &&
  5700.                              CE_URL_S->internal_url)
  5701.                       StrAllocCopy (from, value);
  5702.                     else if (!strcasecomp (token, "force-plain-text") &&
  5703.                              CE_URL_S->internal_url)
  5704.                         force_plain_text = TRUE;
  5705.                     break;
  5706.                   case 'H': case 'h':
  5707.                       if (!strcasecomp(token, "html-part") &&
  5708.                           CE_URL_S->internal_url) {
  5709.                         StrAllocCopy(html_part, value);
  5710.                       }
  5711.                   case 'N': case 'n':
  5712.                     if (!strcasecomp (token, "newsgroups"))
  5713.                       StrAllocCopy (newsgroups, value);
  5714.                     else if (!strcasecomp (token, "newshost") &&
  5715.                              CE_URL_S->internal_url)
  5716.                       StrAllocCopy (newshost, value);
  5717.                     break;
  5718.                   case 'O': case 'o':
  5719.                     if (!strcasecomp (token, "organization") &&
  5720.                         CE_URL_S->internal_url)
  5721.                       StrAllocCopy (organization, value);
  5722.                     break;
  5723.                   case 'R': case 'r':
  5724.                     if (!strcasecomp (token, "references"))
  5725.                       StrAllocCopy (references, value);
  5726.                     else if (!strcasecomp (token, "reply-to") &&
  5727.                              CE_URL_S->internal_url)
  5728.                       StrAllocCopy (reply_to, value);
  5729.                     break;
  5730.                   case 'S': case 's':
  5731.                     if(!strcasecomp (token, "subject"))
  5732.                       StrAllocCopy (subject, value);
  5733.                     else if ((!strcasecomp (token, "sign") ||
  5734.                               !strcasecomp (token, "signed")) &&
  5735.                              CE_URL_S->internal_url)
  5736.                       sign_p = (!strcasecomp(value, "true") ||
  5737.                                 !strcasecomp(value, "yes"));
  5738.                     break;
  5739.                   case 'P': case 'p':
  5740.                     if (!strcasecomp (token, "priority"))
  5741.                       StrAllocCopy (priority, value);
  5742.                     break;
  5743.                   case 'T': case 't':
  5744.                     if (!strcasecomp (token, "to"))
  5745.                       {
  5746.                         if (to && *to)
  5747.                           {
  5748.                             StrAllocCat (to, ", ");
  5749.                             StrAllocCat (to, value);
  5750.                           }
  5751.                         else
  5752.                           {
  5753.                             StrAllocCopy (to, value);
  5754.                           }
  5755.                       }
  5756.                     break;
  5757.                   }
  5758.                 if (eq)
  5759.                   *eq = '='; /* put it back */
  5760.                 rest = XP_STRTOK (0, "&");
  5761.               }
  5762.           }
  5763.  
  5764.         FREEIF (parms);
  5765.         if (to)
  5766.           NET_UnEscape (to);
  5767.         if (cc)
  5768.           NET_UnEscape (cc);
  5769.         if (subject)
  5770.           NET_UnEscape (subject);
  5771.         if (newsgroups)
  5772.           NET_UnEscape (newsgroups);
  5773.         if (references)
  5774.           NET_UnEscape (references);
  5775.         if (attachment)
  5776.           NET_UnEscape (attachment);
  5777.         if (body)
  5778.           NET_UnEscape (body);
  5779.         if (newshost)
  5780.           NET_UnEscape (newshost);
  5781.  
  5782.         if(newshost)
  5783.           {
  5784.             char *prefix = "news://";
  5785.             char *slash = XP_STRRCHR (newshost, '/');
  5786.             if (slash && !strcasecomp (slash, "/secure"))
  5787.               {
  5788.                 *slash = 0;
  5789.                 prefix = "snews://";
  5790.               }
  5791.             newspost_url = (char *) XP_ALLOC (XP_STRLEN (prefix) +
  5792.                                               XP_STRLEN (newshost) + 10);
  5793.             if (newspost_url)
  5794.               {
  5795.                 XP_STRCPY (newspost_url, prefix);
  5796.                 XP_STRCAT (newspost_url, newshost);
  5797.                 XP_STRCAT (newspost_url, "/");
  5798.               }
  5799.           }
  5800.         else
  5801.           {
  5802.             XP_Bool newsServerIsSecure = FALSE;
  5803.             PREF_GetBoolPref("news.server_is_secure", &newsServerIsSecure);
  5804.  
  5805.             if (newsServerIsSecure)
  5806.                 newspost_url = XP_STRDUP("snews:");
  5807.             else
  5808.                 newspost_url = XP_STRDUP ("news:");
  5809.           }
  5810.  
  5811. #if defined(XP_WIN) /* other FE's add here when Front end code added */
  5812.         FE_AlternateCompose(
  5813.             from, reply_to, to, cc, bcc, fcc,
  5814.             newsgroups, followup_to, organization,
  5815.             subject, references, other_random_headers,
  5816.             priority, attachment, newspost_url, body );
  5817. #endif /* XP_WIN */
  5818.  
  5819.         FREEIF(from);
  5820.         FREEIF(reply_to);
  5821.         FREEIF(to);
  5822.         FREEIF(cc);
  5823.         FREEIF(bcc);
  5824.         FREEIF(fcc);
  5825.         FREEIF(newsgroups);
  5826.         FREEIF(followup_to);
  5827.         FREEIF(html_part);
  5828.         FREEIF(organization);
  5829.         FREEIF(subject);
  5830.         FREEIF(references);
  5831.         FREEIF(attachment);
  5832.         FREEIF(body);
  5833.         FREEIF(other_random_headers);
  5834.         FREEIF(newshost);
  5835.         FREEIF(priority);
  5836.         FREEIF(newspost_url);
  5837.  
  5838.         CE_STATUS = MK_NO_DATA;
  5839.         return(-1);
  5840. }
  5841.  
  5842. PRIVATE int32
  5843. net_MailtoStub(ActiveEntry *ce)
  5844. {
  5845. #ifdef DO_ANNOYING_ASSERTS_IN_STUBS
  5846.     XP_ASSERT(0);
  5847. #endif
  5848.     return(0);        /* Well the function definition says it returns SOMETHING! */
  5849. }
  5850. PRIVATE void
  5851. net_CleanupMailtoStub(void)
  5852. {
  5853. #ifdef DO_ANNOYING_ASSERTS_IN_STUBS
  5854.     XP_ASSERT(0);
  5855. #endif
  5856. }
  5857.  
  5858. MODULE_PRIVATE void
  5859. NET_InitMailtoProtocol(void)
  5860. {
  5861.         static NET_ProtoImpl mailto_proto_impl;
  5862.  
  5863.         mailto_proto_impl.init = net_MailtoLoad;
  5864.         mailto_proto_impl.process = net_MailtoStub;
  5865.         mailto_proto_impl.interrupt = net_MailtoStub;
  5866.         mailto_proto_impl.cleanup = net_CleanupMailtoStub;
  5867.  
  5868.         NET_RegisterProtocolImplementation(&mailto_proto_impl, MAILTO_TYPE_URL);
  5869. }
  5870.  
  5871. #endif /* MOZ_MAIL_NEWS */
  5872.  
  5873. #ifdef PROFILE
  5874. #pragma profile off
  5875. #endif
  5876.  
  5877.