void rdf_GetUrlExitFunc (URL_Struct *urls, int status, MWContext *cx) { char *navCenterURL = NULL; if ((status < 0) && (urls != NULL)) { if ((cx != NULL) && (urls->error_msg != NULL)) { FE_Alert(cx, urls->error_msg); } /* if unable to read in navcntr.rdf file, create some default views */ PREF_CopyCharPref("browser.NavCenter", &navCenterURL); if (navCenterURL != NULL) { if (urls->address != NULL) { if (!strcmp(urls->address, navCenterURL)) { remoteStoreAdd(gRemoteStore, gNavCenter->RDF_BookmarkFolderCategory, gCoreVocab->RDF_parent, gNavCenter->RDF_Top, RDF_RESOURCE_TYPE, 1); remoteStoreAdd(gRemoteStore, gNavCenter->RDF_History, gCoreVocab->RDF_parent, gNavCenter->RDF_Top, RDF_RESOURCE_TYPE, 1); remoteStoreAdd(gRemoteStore, gNavCenter->RDF_LocalFiles, gCoreVocab->RDF_parent, gNavCenter->RDF_Top, RDF_RESOURCE_TYPE, 1); } } freeMem(navCenterURL); } } NET_FreeURLStruct (urls); }
static void fe_movemail_perror(const char *message) { int e = errno; char *es = 0; char *buf1 = 0; char buf2[512]; char *suffix; int L; if ((unsigned)e < (unsigned)sys_nerr) { es = sys_errlist [e]; } else { snprintf (buf2, sizeof (buf2), XP_GetString( XFE_UNKNOWN_ERROR_CODE ), errno); printf("XFE_UNKNOWN_ERROR_CODE\n"); es = buf2; } suffix = XP_GetString(XFE_MOVEMAIL_FAILURE_SUFFIX); printf("XFE_MOVEMAIL_FAILURE_SUFFIX\n"); if(!suffix) suffix = ""; if(!message) message = ""; L = strlen(message) + strlen(es) + strlen(suffix) + 40; buf1 = (char *) malloc(L); if(!buf1) return; snprintf (buf1, L-1, "%s\n%s\n\n%s", message, es, suffix); #if 0 FE_Alert (buf1); #endif free(buf1); }
static void fe_movemail_perror(MWContext *context, const char *message) { int e = errno; char *es = 0; char *buf1 = 0; char buf2[512]; char *suffix; int L; XP_ASSERT(context); if (!context) return; if ((unsigned)e < (unsigned)sys_nerr) { es = sys_errlist [e]; } else { PR_snprintf (buf2, sizeof (buf2), XP_GetString( XFE_UNKNOWN_ERROR_CODE ), errno); es = buf2; } suffix = XP_GetString(XFE_MOVEMAIL_FAILURE_SUFFIX); if(!suffix) suffix = ""; if(!message) message = ""; L = XP_STRLEN(message) + XP_STRLEN(es) + XP_STRLEN(suffix) + 40; buf1 = (char *) XP_ALLOC(L); if(!buf1) return; PR_snprintf (buf1, L-1, "%s\n%s\n\n%s", message, es, suffix); FE_Alert (context, buf1); XP_FREE(buf1); }
void es_GetUrlExitFunc (URL_Struct *urls, int status, MWContext *cx) { RDF_Resource parent = NULL, child = NULL, r; _esFEData *feData; char *newURL, *p; feData = (_esFEData *)urls->fe_data; if ((status >= 0) && (feData != NULL)) { parent = RDF_GetResource(gNCDB, feData->parent, false); child = RDF_GetResource(gNCDB, feData->child, false); if ((parent != NULL) && (child != NULL)) { switch(feData->method) { case URL_POST_METHOD: if (((p = strrchr(resourceID(child), '/')) != NULL) && (*++p != '\0')) { if ((newURL = append2Strings(resourceID(parent), p)) != NULL) { if ((r = RDF_GetResource(gNCDB, newURL, 1)) != NULL) { setContainerp(r, containerp(child)); setResourceType(r, resourceType(child)); remoteStoreAdd(gRemoteStore, r, gCoreVocab->RDF_parent, parent, RDF_RESOURCE_TYPE, 1); } freeMem(newURL); } } break; case URL_DELETE_METHOD: remoteStoreRemove(gRemoteStore, child, gCoreVocab->RDF_parent, parent, RDF_RESOURCE_TYPE); break; } } } else if (status < 0) { if ((cx != NULL) && (urls != NULL) && (urls->error_msg != NULL)) { FE_Alert(cx, urls->error_msg); } } if (feData != NULL) { esFreeFEData(feData); } NET_FreeURLStruct (urls); }
JSBool PR_CALLBACK asd_alert (JSContext *cx, JSObject *obj, uint argc, jsval *argv, jsval *rval) { if (argc >= 1 && JSVAL_IS_STRING(argv[0])) { char* msg = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); MWContext* ctx = XP_FindSomeContext(); if (ctx) FE_Alert(ctx, msg); } return JS_TRUE; }
Boolean XFE_PrefsProxiesViewDialog::verifyPage() { char buf[10000]; char *buf2; char *warning; int size; buf2 = buf; strcpy (buf, XP_GetString(XFE_WARNING)); buf2 = buf + strlen (buf); warning = buf2; size = buf + sizeof (buf) - warning; XP_ASSERT(m_prefsDataProxiesView); PrefsDataProxiesView *fep = m_prefsDataProxiesView; PREFS_CHECK_PROXY (fep->ftp_proxy_text, fep->ftp_port_text, XP_GetString(XFE_FTP_PROXY_HOST), True, warning, size); PREFS_CHECK_PROXY (fep->gopher_proxy_text,fep->gopher_port_text, XP_GetString(XFE_GOPHER_PROXY_HOST), True, warning, size); PREFS_CHECK_PROXY (fep->http_proxy_text, fep->http_port_text, XP_GetString(XFE_HTTP_PROXY_HOST), True, warning, size); PREFS_CHECK_PROXY (fep->https_proxy_text, fep->https_port_text, XP_GetString(XFE_HTTPS_PROXY_HOST), True, warning, size); PREFS_CHECK_PROXY (fep->wais_proxy_text, fep->wais_port_text, XP_GetString(XFE_WAIS_PROXY_HOST), True, warning, size); PREFS_CHECK_PROXY (fep->socks_host_text, fep->socks_port_text, XP_GetString(XFE_SOCKS_HOST), False, warning, size); if (*buf2) { FE_Alert (m_prefsDialog->getContext(), fe_StringTrim (buf)); return FALSE; } else { return TRUE; } }
// Get URL exit routines. void CFE_GetUrlExitRoutine(URL_Struct *pUrl, int iStatus, MWContext *pContext) { // Enable clicking now. FE_EnableClicking(pContext); // Report any error. if(iStatus < 0 && pUrl->error_msg != NULL) { FE_Alert(pContext, pUrl->error_msg); } // Make sure the context is still valid. It's possible it's been deleted // out from under us while we were displaying the modal dialog box (and in // a sub-dispatch message loop) if (!XP_IsContextInList(pContext)) { return; } #ifdef EDITOR // Do stuff specific to the editor FE_EditorGetUrlExitRoutine(pUrl, iStatus, pContext); #ifdef MOZ_MAIL_NEWS if (IS_MESSAGE_COMPOSE(pContext)) { CGenericFrame * pFrame = wfe_FrameFromXPContext(pContext); if (pFrame) { CComposeFrame * pCompose = (CComposeFrame*)pFrame; if (pCompose->UseHtml() && !pCompose->Initialized()) pCompose->GoldDoneLoading(); } } #endif // MOZ_MAIL_NEWS #endif //EDITOR ABSTRACTCX(pContext)->GetUrlExitRoutine(pUrl, iStatus, pContext); if(iStatus != MK_CHANGING_CONTEXT) { // We autoproduce a title for those contexts which have none. // Message compose window title is set by msglib. We don't want to overwrite // it here. - kamal if(pContext->title == NULL && pUrl->address != NULL && (pContext->type == MWContextBrowser || pContext->type == MWContextPane) && !EDT_IS_EDITOR(pContext) ) { // Limit the automatically set titles to 50 chars. CString csTitle = pUrl->address; WFE_CondenseURL(csTitle, 50, FALSE); FE_SetDocTitle(pContext, (char *)(const char *)csTitle); } // Since a page was loaded, go through all internal contexts and update their // anchors so that we can have an updated display on all relevant windows. XP_RefreshAnchors(); // If the url has ncapi data, have it pass off this information to // external applications too (must happen before URL struct is // freed off (all connections complete). if(NCAPIDATA(pUrl) != NULL) { NCAPIDATA(pUrl)->EndProgress(); } // Make sure the NCAPI Url data will let us free off the URL. if(NCAPIDATA(pUrl) == NULL || NCAPIDATA(pUrl)->CanFreeUrl() == TRUE) { FEU_DeleteUrlData(pUrl, NULL); NET_FreeURLStruct(pUrl); } } }
PRIVATE void net_ParseHTMLHelpLoadHelpDoc(HTMLHelpParseObj *obj, MWContext *context) { URL_Struct *URL_s; char *frame_address = NULL; char *content_address = NULL; MWContext *new_context; frame_set_struct *fgs; if(obj->id_value || obj->default_id_value) content_address = NET_MakeAbsoluteURL(obj->url_to_map_file, obj->id_value ? obj->id_value : obj->default_id_value); if(!content_address) { FE_Alert(context, XP_GetString(MK_CANT_LOAD_HELP_TOPIC)); return; } fgs = XP_ListPeekTopObject(obj->frame_group_stack); if(fgs) { if(fgs->address) { frame_address = NET_MakeAbsoluteURL(obj->url_to_map_file, fgs->address); } } if(frame_address) URL_s = NET_CreateURLStruct(frame_address, NET_DONT_RELOAD); else URL_s = NET_CreateURLStruct(content_address, NET_DONT_RELOAD); if(!URL_s) goto cleanup; URL_s->window_chrome = XP_NEW(Chrome); if(!URL_s->window_chrome) goto cleanup; XP_MEMSET(URL_s->window_chrome, 0, sizeof(Chrome)); if(obj->window_name) URL_s->window_target = XP_STRDUP(obj->window_name); else URL_s->window_target = XP_STRDUP(DEFAULT_HELP_WINDOW_NAME); net_help_init_chrome(URL_s->window_chrome, obj->window_width, obj->window_height); /* We want to revert the character set of the help frame from the standard character set, not whatever happened to be the last viewed source */ StrAllocCopy(URL_s->charset, INTL_ResourceCharSet()); new_context = XP_FindNamedContextInList(NULL, URL_s->window_target); if(frame_address) { URL_Struct *content_URL_s; /* if there is a frame_address then we load the * frame first and then load the contents * in the frame exit function. */ content_URL_s = NET_CreateURLStruct(content_address, NET_DONT_RELOAD); if(obj->content_target) content_URL_s->window_target = XP_STRDUP(obj->content_target); else if(fgs->target) content_URL_s->window_target = XP_STRDUP(fgs->target); /* doesn't work: URL_s->fe_data = (void *) content_URL_s; */ /* hack for older versions, see pre_exit_routine_above */ if (obj->helpVersion < 2) { frame_content_for_pre_exit_routine = content_URL_s; } else { frame_content_for_pre_exit_routine = NULL; NET_FreeURLStruct(content_URL_s); } URL_s->pre_exit_fn = net_HelpPreExitRoutine; } if(!new_context) { /* this will cause the load too */ new_context = FE_MakeNewWindow(context, URL_s, (obj->window_name) ? obj->window_name : DEFAULT_HELP_WINDOW_NAME, URL_s->window_chrome); if (HELP_INFO_PTR(*new_context) == NULL) { new_context->pHelpInfo = XP_NEW_ZAP(HelpInfoStruct); } if (HELP_INFO_PTR(*new_context)->topicURL != NULL) { XP_FREE(HELP_INFO_PTR(*new_context)->topicURL); HELP_INFO_PTR(*new_context)->topicURL = NULL; } StrAllocCopy(HELP_INFO_PTR(*new_context)->topicURL, content_address); } else { if (HELP_INFO_PTR(*new_context) == NULL) { new_context->pHelpInfo = XP_NEW_ZAP(HelpInfoStruct); } if (HELP_INFO_PTR(*new_context)->topicURL != NULL) { XP_FREE(HELP_INFO_PTR(*new_context)->topicURL); HELP_INFO_PTR(*new_context)->topicURL = NULL; } StrAllocCopy(HELP_INFO_PTR(*new_context)->topicURL, content_address); FE_RaiseWindow(new_context); /* Compatibility with earlier versions of NetHelp */ if (obj->helpVersion < 2) { FE_GetURL(new_context, URL_s); } else { LM_SendOnHelp(new_context); } } cleanup: FREEIF(frame_address); FREE(content_address); return; }
/* this is the main converter for external viewers. * it returns the stream object as well * as a data object that it can reference * internally to save the state of the document */ NET_StreamClass *external_viewer_disk_stream(int iFormatOut, void *pDataObj, URL_Struct *pUrl, MWContext *pContext) { ASSERT(pUrl); ASSERT(pUrl->address); // Lookup the helper app, if one exists. // If not found, create one on the fly. CNetscapeApp *pNetscape = (CNetscapeApp *)AfxGetApp(); CHelperApp *pHelper; XP_Bool isNewHelper = FALSE; if(0 == pNetscape->m_HelperListByType.Lookup(pUrl->content_type, (CObject *&)pHelper)) { // couldn't find one. // create the new mime type. CString csText = pUrl->content_type; // If there's no slash, just send the type as the file type // (this usually only happens on server error, but we // should still behave ourselves). int iSlash = csText.Find('/'); if(iSlash != -1) { // this mess splits the string into the stuff before the slash and // the stuff after the slash pHelper = fe_AddNewFileFormatType(csText.Left(iSlash), csText.Right(csText.GetLength() - iSlash - 1)); isNewHelper = TRUE; } else { pHelper = fe_AddNewFileFormatType(csText, ""); isNewHelper = TRUE; } } // The helper app is now defined for the mime type in any case. // See how it is to be handled. BOOL bExternal = FALSE; BOOL bSave = FALSE; BOOL bMoreInfo = FALSE; switch(pHelper->how_handle) { case HANDLE_UNKNOWN: { // See what this is supposed to do via user input. CUnknownTypeDlg dlgUnknown(GetFrame(pContext)->GetFrameWnd(), pUrl->content_type, pHelper); int iDlg = dlgUnknown.DoModal(); if(iDlg == IDCANCEL) { // User hit cancel. Abort the load. if (pHelper && pHelper->cd_item && isNewHelper) { if (XP_ListRemoveObject(cinfo_MasterListPointer(), pHelper->cd_item)) { if (pHelper->cd_item) { if (pHelper->cd_item->ci.type) { theApp.m_HelperListByType.RemoveKey(pHelper->cd_item->ci.type); XP_FREE( pHelper->cd_item->ci.type ); } XP_FREE (pHelper->cd_item); } delete pHelper; } } return(NULL); } else if(iDlg == HANDLE_EXTERNAL) { char buf[256]; bExternal = TRUE; // We need to indicate that this is a user-defined MIME type. If we // don't, then we won't remember it the next time the Navigator is run sprintf(buf,"TYPE%d",theApp.m_iNumTypesInINIFile); theApp.m_iNumTypesInINIFile++; theApp.WriteProfileString("Viewers", buf, pUrl->content_type); pHelper->bNewType = FALSE; } else if(iDlg == HANDLE_SAVE) { bSave = TRUE; } else if(iDlg == HANDLE_MOREINFO) { bMoreInfo = TRUE; } break; } case HANDLE_EXTERNAL: case HANDLE_BY_OLE: { bExternal = TRUE; break; } case HANDLE_SHELLEXECUTE: { bExternal = TRUE; break; } case HANDLE_SAVE: { bSave = TRUE; break; } default: { // Shouldn't ever be other than the above types at this // point! ASSERT(0); return(NULL); } } // We know that we are either saving or spawning an external // viewer at this point. NET_StreamClass *pRetval = NULL; if (bSave == TRUE) { return ExternalFileSave(iFormatOut, pUrl, pContext); } else if (bExternal == TRUE) { // Prompt the user for a file name. // Security rist to let path information in externally provided // filename (content disposition, filename =) // XXX This code could be cleaned up -- eliminate aFileName // and just use what was allocated by WH_TempFileName. char aFileName[_MAX_PATH]; char *pSuggestedName = NULL; BOOL bUseContentName = FALSE; if (pUrl->content_name != NULL && strstr(pUrl->content_name, "../") == NULL && strstr(pUrl->content_name, "..\\") == NULL) { bUseContentName = TRUE; } else { pSuggestedName = fe_URLtoLocalName(pUrl->address, pUrl->content_type); } char *pDestination; ASSERT(pNetscape->m_pTempDir); if(pNetscape->m_pTempDir != NULL && pSuggestedName != NULL) { sprintf(aFileName, "%s\\%s", pNetscape->m_pTempDir, pSuggestedName); XP_FREE(pSuggestedName); pSuggestedName = NULL; pDestination = aFileName; } else { char aExt[_MAX_EXT]; size_t stExt = 0; DWORD dwFlags = 0; const char *pName = pUrl->address; if(bUseContentName) { pName = pUrl->content_name; } #ifdef XP_WIN16 dwFlags |= EXT_DOT_THREE; #endif aExt[0] = '\0'; stExt = EXT_Invent(aExt, sizeof(aExt), dwFlags, pName, pUrl->content_type); char *pTemp = WH_TempFileName(xpTemporary, "M", aExt); if(pTemp) { strcpy(aFileName, pTemp); XP_FREE(pTemp); pTemp = NULL; } else { aFileName[0] = '\0'; } } pDestination = aFileName; // Figure out the application that we'll be spawning. // Strip off odd things at the right hand side. CString csCommand; if(pHelper->how_handle == HANDLE_EXTERNAL) { csCommand = pHelper->csCmd; int iStrip = csCommand.ReverseFind('%'); if(iStrip > 0) { csCommand = csCommand.Left(iStrip - 1); } } // See if it's actually OK to spawn this application. CString csSpawn = csCommand; BOOL bShellExecute = FALSE; if(pHelper->how_handle == HANDLE_SHELLEXECUTE || pHelper->how_handle == HANDLE_BY_OLE) { // Shell execute type, figure out the exe. char aExe[_MAX_PATH]; memset(aExe, 0, sizeof(aExe)); if(FEU_FindExecutable(pDestination, aExe, FALSE)) { csSpawn = aExe; if(pHelper->how_handle == HANDLE_SHELLEXECUTE) { bShellExecute = TRUE; } } else { csSpawn.Empty(); } } // See whether the user wants to be prompted before we open the file if (pContext->type != MWContextPrint && theApp.m_pSpawn->PromptBeforeOpening((LPCSTR)csSpawn)) { BOOL bFree = FALSE; LPCSTR lpszFilename = NULL; if (pUrl->content_name != NULL && strstr(pUrl->content_name, "../") == NULL && strstr(pUrl->content_name, "..\\") == NULL) { lpszFilename = pUrl->content_name; } if (!lpszFilename) { lpszFilename = fe_URLtoLocalName(pUrl->address, pUrl->content_type); bFree = TRUE; } char* docExt[1]; const char * ptr1 = lpszFilename; int type = NET_URL_Type(pUrl->address); BOOL canHandleOLE = FALSE; if ((type != MAILBOX_TYPE_URL) && (type !=NEWS_TYPE_URL) && (type != IMAP_TYPE_URL) ) { docExt[0] = FE_FindFileExt((char*)ptr1); if (docExt[0]) canHandleOLE = fe_CanHandleByOLE(docExt, 1); } CLaunchHelper dlg(lpszFilename, (LPCSTR)csSpawn, canHandleOLE, GetFrame(pContext)->GetFrameWnd()); if (bFree) XP_FREE((LPVOID)lpszFilename); // Initialize the dialog to some defaults. dlg.m_bAlwaysAsk = TRUE; //dlg.m_nAction = HELPER_SAVE_TO_DISK; //Old statement CRN_MIME dlg.m_nAction = (pHelper->how_handle == HANDLE_SHELLEXECUTE) ? HELPER_OPEN_IT : HELPER_SAVE_TO_DISK; //New Statement. Set m_nAction based on pHelper->how_handle... CRN_MIME dlg.m_bHandleByOLE = fe_IsHandleByOLE(pUrl->content_type); // Ask the user if (dlg.DoModal() == IDCANCEL) return NULL; // See if they no longer want to be asked if (!dlg.m_bAlwaysAsk) { if (dlg.m_nAction == HELPER_SAVE_TO_DISK) { // User wants to just save to disk pHelper->how_handle = HANDLE_SAVE; pHelper->csCmd = MIME_SAVE; pHelper->bChanged = TRUE; } else { ASSERT(dlg.m_nAction == HELPER_OPEN_IT); theApp.m_pSpawn->SetPromptBeforeOpening((LPCSTR)csSpawn, FALSE); } } // Check whether the user wants to launch the application or save it // do disk if (dlg.m_nAction == HELPER_SAVE_TO_DISK) return ExternalFileSave(iFormatOut, pUrl, pContext); else { // open it case. // user want to handle this by OLE. if (dlg.m_bHandleByOLE) { fe_SetHandleByOLE(pUrl->content_type, pHelper, TRUE); } // Since mail and new will not be able launch using OLE inplace server, so we should not try to change helper app // how_handle here. else if (pHelper->how_handle == HANDLE_BY_OLE) { fe_SetHandleByOLE(pUrl->content_type, pHelper, FALSE); } } } // MWH -- see could we handle this via OLE. if ((iFormatOut == FO_PRESENT || iFormatOut == FO_PRINT) && (pHelper->how_handle == HANDLE_BY_OLE) && FE_FileType(pUrl->address, pUrl->content_type, pUrl->content_encoding)) { // can be handle by OLE. return OLE_ViewStream(iFormatOut, pDataObj, pUrl,pContext); } // It's OK to spawn this application. // Attempt to split it off into a seperate context. if(bShellExecute) { pRetval = CSaveCX::ViewUrlObject(pUrl, NULL); } else { pRetval = CSaveCX::ViewUrlObject(pUrl, csSpawn); } if(pRetval != NULL) { return(pRetval); } // Couldn't split off into a new context. // Handle as was handled before. // We have a destination file name. FILE *pSink = XP_FileOpen(pDestination, xpTemporary, "wb"); if(pSink == NULL) { FE_Alert(pContext, szLoadString(IDS_FAILED_CREATE_TEMP_FILE)); XP_FREE(pDestination); return(NULL); } // Create the data object that will be passed along down // the stream. DataObject *pMe = new DataObject; if(!pMe) return(NULL); memset(pMe, 0, sizeof(DataObject)); pMe->how_handle = pHelper->how_handle; pMe->fp = pSink; pMe->context = pContext; pMe->format_out = iFormatOut; pMe->filename = pDestination; pMe->content_length = pUrl->content_length < 0 ? 0 : pUrl->content_length; pMe->cur_loc = 0; StrAllocCopy(pMe->address, pUrl->address); StrAllocCopy(pMe->format_in, pUrl->content_type); // The spawn command. if(pMe->how_handle == HANDLE_EXTERNAL) { pMe->params = XP_STRDUP(pDestination); } else if(pMe->how_handle == HANDLE_SHELLEXECUTE) { csCommand += pDestination; } else if(pMe->how_handle == HANDLE_BY_OLE) { csCommand += pDestination; } pMe->command = XP_STRDUP(csCommand); // Progress. FE_SetProgressBarPercent(pContext, 0); // Delete the file on exit. FE_DeleteFileOnExit(pDestination, pUrl->address); // Set the waiting mode??? FE_EnableClicking(pContext); // Create the stream. pRetval = NET_NewStream("ServeAndView", disk_stream_write, disk_stream_complete, disk_stream_abort, write_ready, pMe, pContext); } if(bMoreInfo == TRUE) { char * url = NULL; PREF_CopyConfigString("internal_url.more_info_plugin.url",&url); if (url) { CString csUrlAddress = url; csUrlAddress += "?"; csUrlAddress += pUrl->content_type; (ABSTRACTCX(pContext))->NormalGetUrl(csUrlAddress, pUrl->address, csUrlAddress); XP_FREE(url); } } // Return the stream that was created. return(pRetval); }
static NET_StreamClass * ExternalFileSave(int iFormatOut, URL_Struct *pUrl, MWContext *pContext) { // // While we have a pointer to the original frame window query // for a filename // char *pDestination; char *pSuggested = NULL; NET_StreamClass *pRetval = NULL; // Prompt the user for a file name. // Security rist to let path information in externally provided // filename (content disposition, filename =) if (pUrl->content_name != NULL && strstr(pUrl->content_name, "../") == NULL && strstr(pUrl->content_name, "..\\") == NULL) { // Make a copy of the name, because that's what fe_URLtoLocalName() does // and the code below is going to XP_FREE pSuggested pSuggested = XP_STRDUP(pUrl->content_name); } if (!pSuggested) pSuggested = fe_URLtoLocalName(pUrl->address, pUrl->content_type); #ifdef XP_WIN16 char dosName[13]; FE_LongNameToDosName(dosName, pSuggested); pDestination = wfe_GetSaveFileName(GetFrame(pContext)->GetFrameWnd()->m_hWnd, szLoadString(IDS_SAVE_AS), dosName, NULL); #else pDestination = wfe_GetSaveFileName(GetFrame(pContext)->GetFrameWnd()->m_hWnd, szLoadString(IDS_SAVE_AS), pSuggested, NULL); #endif if(pSuggested != NULL) { XP_FREE(pSuggested); } if(pDestination == NULL) { return(NULL); } // We're going to be saving this stream. // Check to see if we should attempt to save the file in the // old fashion, or in the new external contexts. if(NET_IsSafeForNewContext(pUrl) != FALSE) { // Attempt to split it off into a new context. pRetval = CSaveCX::SaveUrlObject(pUrl, NULL, pDestination); } else { // We need to continue to use the old method of saving. // We have a destination file name. FILE *pSink = XP_FileOpen(pDestination, xpTemporary, "wb"); if(pSink == NULL) { FE_Alert(pContext, szLoadString(IDS_FAILED_CREATE_TEMP_FILE)); XP_FREE(pDestination); return(NULL); } // Create the data object that will be passed along down // the stream. DataObject *pMe = new DataObject; if(!pMe) return(NULL); memset(pMe, 0, sizeof(DataObject)); pMe->how_handle = HANDLE_SAVE; pMe->fp = pSink; pMe->context = pContext; pMe->format_out = iFormatOut; pMe->filename = pDestination; pMe->content_length = pUrl->content_length < 0 ? 0 : pUrl->content_length; pMe->cur_loc = 0; StrAllocCopy(pMe->address, pUrl->address); StrAllocCopy(pMe->format_in, pUrl->content_type); // Progress. FE_SetProgressBarPercent(pContext, 0); // Set the waiting mode??? FE_EnableClicking(pContext); // Create the stream. pRetval = NET_NewStream("ServeAndSave", disk_stream_write, disk_stream_complete, disk_stream_abort, write_ready, pMe, pContext); if(!pRetval) return(NULL); } return pRetval; }
int fe_MoveMail (MWContext *context, char *from, char *to) { XP_Bool succeeded = FALSE; char tmp_file[NAME_LEN]; char lock_file[NAME_LEN]; char spool_dir[NAME_LEN]; char *bp, buf[BUFSIZ]; char msgbuf[1024]; int from_fd = -1; int to_fd = -1; int tmp_fd = -1; int nread, nwritten, nbytes, ntodo; struct stat st; *lock_file = 0; if (!from || !to) return FALSE; if (strlen(from) > NAME_LEN - 1) return FALSE; /* Make spool_dir be "/var/spool/mail" from "/var/spool/mail/$USER". */ strcpy(spool_dir, from); while ((bp = strrchr(spool_dir, '/')) && bp[1] == '\0') *bp = '\0'; if (!bp) return FALSE; *bp = 0; /* If we can't write into the directory itself, we can't create files, so we lose. */ if (access(spool_dir, R_OK|W_OK) < 0) { PR_snprintf(msgbuf, sizeof (msgbuf), XP_GetString(XFE_CANT_MOVE_MAIL_UNABLE_TO_WRITE), from); fe_movemail_perror(context, msgbuf); goto FAIL; } /* If the mail-spool file doesn't exist, or is 0-length, bug out. */ if (stat(from, &st) < 0 || st.st_size == 0) { FE_Alert (context, XP_GetString(XFE_MOVEMAIL_NO_MESSAGES)); goto FAIL; } PR_snprintf(tmp_file, sizeof (tmp_file), "%s%s", from, TMP_SUFFIX); if (access(tmp_file, 0) == 0) { /* The tmp file exists; try to get rid of it */ if (unlink(tmp_file) < 0) { PR_snprintf(msgbuf, sizeof (msgbuf), XP_GetString( XFE_CANT_GET_NEW_MAIL_LOCK_FILE_EXISTS ), tmp_file); fe_movemail_perror(context, msgbuf); goto FAIL; } } PR_snprintf(lock_file, sizeof (lock_file), "%s%s", from, LOCK_SUFFIX); while (1) { int ret; /* First create a real file, $USER.nslock */ tmp_fd = open(tmp_file, O_WRONLY|O_CREAT|O_EXCL, 0666); if (tmp_fd < 0) { PR_snprintf(msgbuf, sizeof (msgbuf), XP_GetString( XFE_CANT_GET_NEW_MAIL_UNABLE_TO_CREATE_LOCK_FILE ), tmp_file); fe_movemail_perror(context, msgbuf); goto FAIL; } close(tmp_fd); tmp_fd = -1; /* Then make a hard link from $USER.lock to $USER.nslock -- this is the trick to make NFS behave synchronously. */ ret = link(tmp_file, lock_file); /* Now we've (attempted to) make the link. `ret' says whether it was successful. It would have failed if the lock was already being held. Regardless of whether it succeeded, we can now delete $USER.nslock (the thing to which the hard-link points.) */ if (unlink(tmp_file) < 0) { PR_snprintf(msgbuf, sizeof (msgbuf), /* This error message isn't quite right; what it really means is "can't delete $MAIL.nslock", but I guess that could only happen if some other user was the owner of it? Or if it was already gone? Weird... */ XP_GetString(XFE_MOVEMAIL_CANT_DELETE_LOCK), tmp_file); fe_movemail_perror(context, msgbuf); goto FAIL; } /* If we didn't obtain the lock (== make the hard-link), above, then retry getting it until the file is 60 seconds old... Then get Guido to go over and bust its kneecaps. */ if (ret < 0) { sleep (1); if (stat(lock_file, &st) >= 0) { int current = time(NULL); if (st.st_ctime < current - 60) unlink (lock_file); } } else { /* Got the lock - done waiting. */ break; } } /* All of this junk used to happen in a forked process, but that's not necessary any more (actually, hasn't been for a long time) since we no longer play any setuid/setgid games -- there is no gain to doing this in another fork and waiting for it to complete. */ /* Open the mail spool file for input... */ from_fd = open(from, O_RDWR, 0666); if (from_fd < 0) { int err; if (access(from, W_OK) < 0) /* look again, for right error message */ err = XFE_CANT_MOVE_MAIL_UNABLE_TO_WRITE; else if (access(from, 0) == 0) err = XFE_CANT_MOVE_MAIL_UNABLE_TO_READ; else err = XFE_CANT_MOVE_MAIL_UNABLE_TO_OPEN; PR_snprintf(msgbuf, sizeof (msgbuf), XP_GetString(err), from); fe_movemail_perror(context, msgbuf); goto FAIL; } /* Open the destination file for output... */ to_fd = open(to, O_WRONLY|O_CREAT|O_EXCL, 0666); if (to_fd < 0) { PR_snprintf(msgbuf, sizeof (msgbuf), XP_GetString( XFE_CANT_MOVE_MAIL_UNABLE_TO_OPEN ), to); fe_movemail_perror(context, msgbuf); goto FAIL; } /* copy the file */ nbytes = BUFSIZ; while (1) { nread = read(from_fd, buf, nbytes); if (nread < 0) { /* we're busted */ PR_snprintf(msgbuf, sizeof (msgbuf), XP_GetString( XFE_CANT_MOVE_MAIL_UNABLE_TO_READ ), from); fe_movemail_perror(context, msgbuf); goto FAIL; } if (!nread) { /* we're done */ break; } for (ntodo = nread, bp = buf; ntodo > 0; ntodo -= nwritten, bp += nwritten) { nwritten = write(to_fd, bp, ntodo); if (nwritten < 0) { PR_snprintf(msgbuf, sizeof (msgbuf), XP_GetString( XFE_CANT_MOVE_MAIL_UNABLE_TO_WRITE ), to); fe_movemail_perror(context, msgbuf); goto FAIL; } } } /* if we made it this far, we're done copying the file contents. First, close and sync the output file. */ if (fsync(to_fd) < 0 || close(to_fd) < 0) { PR_snprintf(msgbuf, sizeof (msgbuf), XP_GetString( XFE_CANT_MOVE_MAIL_UNABLE_TO_WRITE ), to); fe_movemail_perror(context, msgbuf); goto FAIL; } to_fd = -1; /* Now the output file is closed and sync'ed, so we can truncate the spool file. */ if (ftruncate(from_fd, (off_t)0) < 0) { PR_snprintf(msgbuf, sizeof (msgbuf), XP_GetString( XFE_THERE_WERE_PROBLEMS_CLEANING_UP ), from); fe_movemail_perror(context, msgbuf); goto FAIL; } succeeded = TRUE; FAIL: if (to_fd >= 0) close(to_fd); if (from_fd >= 0) close(from_fd); if (tmp_fd >= 0) close(tmp_fd); /* Unlink the lock file. If this fails, but we were otherwise successful, then whine about it. Otherwise, we've already presented an error dialog about something else. */ if (*lock_file && unlink(lock_file) < 0 && succeeded) { PR_snprintf(msgbuf, sizeof (msgbuf), XP_GetString( XFE_THERE_WERE_PROBLEMS_CLEANING_UP ), lock_file); fe_movemail_perror(context, msgbuf); succeeded = FALSE; } return succeeded; }