/** * Try and find the correct RISC OS filetype from a download context. */ static nserror download_ro_filetype(download_context *ctx, bits *ftype_out) { nsurl *url = download_context_get_url(ctx); bits ftype = 0; lwc_string *scheme; /* If the file is local try and read its filetype */ scheme = nsurl_get_component(url, NSURL_SCHEME); if (scheme != NULL) { bool filescheme; if (lwc_string_isequal(scheme, corestring_lwc_file, &filescheme) != lwc_error_ok) { filescheme = false; } if (filescheme) { lwc_string *path = nsurl_get_component(url, NSURL_PATH); if (path != NULL && lwc_string_length(path) != 0) { char *raw_path; if (url_unescape(lwc_string_data(path), lwc_string_length(path), &raw_path) == NSERROR_OK) { ftype = ro_filetype_from_unix_path(raw_path); free(raw_path); } } } } /* If we still don't have a filetype (i.e. failed reading local * one or fetching a remote object), then use the MIME type. */ if (ftype == 0) { /* convert MIME type to RISC OS file type */ os_error *error; const char *mime_type; mime_type = download_context_get_mime_type(ctx); error = xmimemaptranslate_mime_type_to_filetype(mime_type, &ftype); if (error) { LOG("xmimemaptranslate_mime_type_to_filetype: 0x%x: %s", error->errnum, error->errmess); ro_warn_user("MiscError", error->errmess); ftype = 0xffd; } } *ftype_out = ftype; return NSERROR_OK; }
static struct gui_download_window *gui_download_window_create(download_context *ctx, struct gui_window *gui) { const char *url = nsurl_access(download_context_get_url(ctx)); unsigned long total_size = download_context_get_total_length(ctx); struct gui_download_window *dw; char *dl_filename = ami_utf8_easy(download_context_get_filename(ctx)); APTR va[3]; dw = ami_misc_allocvec_clear(sizeof(struct gui_download_window), 0); if(gui && (!IsListEmpty(&gui->dllist)) && (dw->dln = (struct dlnode *)FindName(&gui->dllist,url))) { strcpy(dw->fname, dw->dln->filename); free(dw->dln->node.ln_Name); dw->dln->node.ln_Name = NULL; } else { if(AslRequestTags(savereq, ASLFR_Window, gui->shared->win, ASLFR_SleepWindow, TRUE, ASLFR_TitleText, messages_get("NetSurf"), ASLFR_Screen, scrn, ASLFR_InitialFile, dl_filename, TAG_DONE)) { strlcpy(dw->fname, savereq->fr_Drawer, 1024); AddPart((STRPTR)&dw->fname,savereq->fr_File,1024); if(!ami_download_check_overwrite(dw->fname, gui->shared->win, total_size)) { FreeVec(dw); return NULL; } } else { FreeVec(dw); return NULL; } } if(dl_filename) ami_utf8_free(dl_filename); dw->size = total_size; dw->downloaded = 0; if(gui) dw->bw = gui->bw; dw->url = url; va[0] = (APTR)dw->downloaded; va[1] = (APTR)dw->size; va[2] = 0; if(!(dw->fh = FOpen((STRPTR)&dw->fname,MODE_NEWFILE,0))) { FreeVec(dw); return NULL; } dw->objects[OID_MAIN] = WindowObj, WA_ScreenTitle, ami_gui_get_screen_title(), WA_Title, dw->url, WA_Activate, TRUE, WA_DepthGadget, TRUE, WA_DragBar, TRUE, WA_CloseGadget, FALSE, WA_SizeGadget, TRUE, WA_PubScreen,scrn, WINDOW_SharedPort,sport, WINDOW_UserData,dw, WINDOW_IconifyGadget, FALSE, WINDOW_LockHeight,TRUE, WINDOW_Position, WPOS_CENTERSCREEN, WINDOW_ParentGroup, dw->objects[GID_MAIN] = LayoutVObj, LAYOUT_AddChild, dw->objects[GID_STATUS] = FuelGaugeObj, GA_ID,GID_STATUS, GA_Text,messages_get("amiDownload"), FUELGAUGE_Min,0, FUELGAUGE_Max,total_size, FUELGAUGE_Level,0, FUELGAUGE_Ticks,11, FUELGAUGE_ShortTicks,TRUE, FUELGAUGE_VarArgs,va, FUELGAUGE_Percent,FALSE, FUELGAUGE_Justification,FGJ_CENTER, FuelGaugeEnd, CHILD_NominalSize,TRUE, CHILD_WeightedHeight,0, LAYOUT_AddChild, dw->objects[GID_CANCEL] = ButtonObj, GA_ID,GID_CANCEL, GA_RelVerify,TRUE, GA_Text,messages_get("Abort"), GA_TabCycle,TRUE, ButtonEnd, EndGroup, EndWindow; dw->win = (struct Window *)RA_OpenWindow(dw->objects[OID_MAIN]); dw->ctx = ctx; dw->node = AddObject(window_list,AMINS_DLWINDOW); dw->node->objstruct = dw; downloads_in_progress++; return dw; }
struct gui_download_window *gui_download_window_create(download_context *ctx, struct gui_window *gui) { const char *url = download_context_get_url(ctx); const char *mime_type = download_context_get_mime_type(ctx); const char *temp_name; char *scheme = NULL; char *filename = NULL; struct gui_download_window *dw; bool space_warning = false; os_error *error; url_func_result res; char *local_path; utf8_convert_ret err; size_t i, last_dot; dw = malloc(sizeof *dw); if (!dw) { warn_user("NoMemory", 0); return 0; } dw->ctx = ctx; dw->saved = false; dw->close_confirmed = false; dw->error = false; dw->query = QUERY_INVALID; dw->received = 0; dw->total_size = download_context_get_total_length(ctx); strncpy(dw->url, url, sizeof dw->url); dw->url[sizeof dw->url - 1] = 0; dw->status[0] = 0; gettimeofday(&dw->start_time, 0); dw->last_time = dw->start_time; dw->last_received = 0; dw->file_type = 0; dw->average_rate = 0; dw->average_points = 0; /* Get scheme from URL */ res = url_scheme(url, &scheme); if (res == URL_FUNC_NOMEM) { warn_user("NoMemory", 0); free(dw); return 0; } else if (res == URL_FUNC_OK) { /* If we have a scheme and it's "file", then * attempt to use the local filetype directly */ if (strcasecmp(scheme, "file") == 0) { char *path = NULL; res = url_path(url, &path); if (res == URL_FUNC_NOMEM) { warn_user("NoMemory", 0); free(scheme); free(dw); return 0; } else if (res == URL_FUNC_OK) { char *raw_path = curl_unescape(path, strlen(path)); if (raw_path == NULL) { warn_user("NoMemory", 0); free(path); free(scheme); free(dw); return 0; } dw->file_type = ro_filetype_from_unix_path(raw_path); curl_free(raw_path); free(path); } } free(scheme); } /* If we still don't have a filetype (i.e. failed reading local * one or fetching a remote object), then use the MIME type */ if (dw->file_type == 0) { /* convert MIME type to RISC OS file type */ error = xmimemaptranslate_mime_type_to_filetype(mime_type, &(dw->file_type)); if (error) { LOG(("xmimemaptranslate_mime_type_to_filetype: 0x%x: %s", error->errnum, error->errmess)); warn_user("MiscError", error->errmess); dw->file_type = 0xffd; } } /* open temporary output file */ temp_name = ro_gui_download_temp_name(dw); if (!ro_gui_download_check_space(dw, temp_name, NULL)) { /* issue a warning but continue with the download because the user can save it to another medium whilst it's downloading */ space_warning = true; } error = xosfind_openoutw(osfind_NO_PATH | osfind_ERROR_IF_DIR, temp_name, 0, &dw->file); if (error) { LOG(("xosfind_openoutw: 0x%x: %s", error->errnum, error->errmess)); warn_user("SaveError", error->errmess); free(dw); return 0; } /* fill in download window icons */ download_template->icons[ICON_DOWNLOAD_URL].data.indirected_text.text = dw->url; download_template->icons[ICON_DOWNLOAD_URL].data.indirected_text.size = sizeof dw->url; download_template->icons[ICON_DOWNLOAD_STATUS].data.indirected_text. text = dw->status; download_template->icons[ICON_DOWNLOAD_STATUS].data.indirected_text. size = sizeof dw->status; sprintf(dw->sprite_name, "file_%.3x", dw->file_type); if (!ro_gui_wimp_sprite_exists(dw->sprite_name)) strcpy(dw->sprite_name, "file_xxx"); download_template->icons[ICON_DOWNLOAD_ICON].data.indirected_sprite.id = (osspriteop_id) dw->sprite_name; /* Get a suitable path- and leafname for the download. */ temp_name = download_context_get_filename(dw->ctx); if (temp_name == NULL) temp_name = messages_get("SaveObject"); if (temp_name != NULL) filename = strdup(temp_name); if (filename == NULL) { LOG(("Failed to establish download filename.")); warn_user("SaveError", error->errmess); free(dw); return 0; } for (i = 0, last_dot = (size_t) -1; filename[i] != '\0'; i++) { const char c = filename[i]; if (c == '.') { last_dot = i; filename[i] = '/'; } else if (c <= ' ' || strchr(":*#$&@^%\\", c) != NULL) filename[i] = '_'; } if (option_strip_extensions && last_dot != (size_t) -1) filename[last_dot] = '\0'; if (download_dir != NULL && strlen(download_dir) > 0) snprintf(dw->path, RO_DOWNLOAD_MAX_PATH_LEN, "%s.%s", download_dir, filename); else snprintf(dw->path, RO_DOWNLOAD_MAX_PATH_LEN, "%s", filename); err = utf8_to_local_encoding(dw->path, 0, &local_path); if (err != UTF8_CONVERT_OK) { /* badenc should never happen */ assert(err != UTF8_CONVERT_BADENC); LOG(("utf8_to_local_encoding failed")); warn_user("NoMemory", 0); free(dw); return 0; } else { strncpy(dw->path, local_path, sizeof dw->path); free(local_path); } download_template->icons[ICON_DOWNLOAD_PATH].data.indirected_text.text = dw->path; download_template->icons[ICON_DOWNLOAD_PATH].data.indirected_text.size = sizeof dw->path; download_template->icons[ICON_DOWNLOAD_DESTINATION].data. indirected_text.text = dw->path; download_template->icons[ICON_DOWNLOAD_DESTINATION].data. indirected_text.size = sizeof dw->path; download_template->icons[ICON_DOWNLOAD_DESTINATION].flags |= wimp_ICON_DELETED; /* create and open the download window */ error = xwimp_create_window(download_template, &dw->window); if (error) { LOG(("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); free(dw); return 0; } dw->prev = 0; dw->next = download_window_list; if (download_window_list) download_window_list->prev = dw; download_window_list = dw; ro_gui_download_update_status(dw); ro_gui_dialog_open(dw->window); ro_gui_wimp_event_set_user_data(dw->window, dw); ro_gui_wimp_event_register_mouse_click(dw->window, ro_gui_download_click); ro_gui_wimp_event_register_keypress(dw->window, ro_gui_download_keypress); ro_gui_wimp_event_register_close_window(dw->window, ro_gui_download_close); /* issue the warning now, so that it appears in front of the download * window! */ if (space_warning) warn_user("DownloadWarn", messages_get("NoDiscSpace")); return dw; }
static struct gui_download_window * gui_download_window_create(download_context *ctx, struct gui_window *gui) { nsurl *url = download_context_get_url(ctx); unsigned long total_size = download_context_get_total_length(ctx); gchar *domain; gchar *destination; gboolean unknown_size = total_size == 0; const char *size = (total_size == 0 ? messages_get("gtkUnknownSize") : human_friendly_bytesize(total_size)); nsgtk_download_parent = nsgtk_scaffolding_window(nsgtk_get_scaffold(gui)); struct gui_download_window *download = malloc(sizeof *download); if (download == NULL) { return NULL; } /* set the domain to the host component of the url if it exists */ if (nsurl_has_component(url, NSURL_HOST)) { domain = g_strdup(lwc_string_data(nsurl_get_component(url, NSURL_HOST))); } else { domain = g_strdup(messages_get("gtkUnknownHost")); } if (domain == NULL) { free(download); return NULL; } /* show the dialog */ destination = nsgtk_download_dialog_show( download_context_get_filename(ctx), domain, size); if (destination == NULL) { g_free(domain); free(download); return NULL; } /* Add the new row and store the reference to it (which keeps track of * the tree changes) */ gtk_list_store_prepend(nsgtk_download_store, &nsgtk_download_iter); download->row = gtk_tree_row_reference_new( GTK_TREE_MODEL(nsgtk_download_store), gtk_tree_model_get_path( GTK_TREE_MODEL(nsgtk_download_store), &nsgtk_download_iter)); download->ctx = ctx; download->name = g_string_new(download_context_get_filename(ctx)); download->time_left = g_string_new(""); download->size_total = total_size; download->size_downloaded = 0; download->speed = 0; download->start_time = g_timer_elapsed(nsgtk_downloads_timer, NULL); download->time_remaining = -1; download->status = NSGTK_DOWNLOAD_NONE; download->progress = 0; download->error = NULL; download->write = g_io_channel_new_file(destination, "w", &download->error); if (nsgtk_download_handle_error(download->error)) { g_string_free(download->name, TRUE); g_string_free(download->time_left, TRUE); free(download); return NULL; } g_io_channel_set_encoding(download->write, NULL, &download->error); nsgtk_download_change_sensitivity(download, NSGTK_DOWNLOAD_CANCEL); nsgtk_download_store_create_item(download); nsgtk_download_show(nsgtk_download_parent); if (unknown_size) nsgtk_download_change_status(download, NSGTK_DOWNLOAD_WORKING); if (nsgtk_downloads_num_active == 0) { g_timeout_add(UPDATE_RATE, (GSourceFunc) nsgtk_download_update, FALSE); } nsgtk_downloads_list = g_list_prepend(nsgtk_downloads_list, download); return download; }
static struct gui_download_window * gui_download_window_create(download_context *ctx, struct gui_window *gui) { nsurl *url = download_context_get_url(ctx); const char *temp_name; char *filename = NULL; struct gui_download_window *dw; bool space_warning = false; os_error *error; char *local_path; nserror err; size_t i, last_dot; dw = malloc(sizeof *dw); if (!dw) { ro_warn_user("NoMemory", 0); return 0; } dw->ctx = ctx; dw->saved = false; dw->close_confirmed = false; dw->error = false; dw->query = QUERY_INVALID; dw->received = 0; dw->total_size = download_context_get_total_length(ctx); /** @todo change this to take a reference to the nsurl and use * that value directly rather than using a fixed buffer. */ strncpy(dw->url, nsurl_access(url), sizeof dw->url); dw->url[sizeof dw->url - 1] = 0; dw->status[0] = 0; gettimeofday(&dw->start_time, 0); dw->last_time = dw->start_time; dw->last_received = 0; dw->file_type = 0; dw->average_rate = 0; dw->average_points = 0; /* get filetype */ err = download_ro_filetype(ctx, &dw->file_type); if (err != NSERROR_OK) { ro_warn_user(messages_get_errorcode(err), 0); free(dw); return 0; } /* open temporary output file */ temp_name = ro_gui_download_temp_name(dw); if (!ro_gui_download_check_space(dw, temp_name, NULL)) { /* issue a warning but continue with the download because the user can save it to another medium whilst it's downloading */ space_warning = true; } error = xosfind_openoutw(osfind_NO_PATH | osfind_ERROR_IF_DIR, temp_name, 0, &dw->file); if (error) { LOG("xosfind_openoutw: 0x%x: %s", error->errnum, error->errmess); ro_warn_user("SaveError", error->errmess); free(dw); return 0; } /* fill in download window icons */ download_template->icons[ICON_DOWNLOAD_URL].data.indirected_text.text = dw->url; download_template->icons[ICON_DOWNLOAD_URL].data.indirected_text.size = sizeof dw->url; download_template->icons[ICON_DOWNLOAD_STATUS].data.indirected_text. text = dw->status; download_template->icons[ICON_DOWNLOAD_STATUS].data.indirected_text. size = sizeof dw->status; sprintf(dw->sprite_name, "file_%.3x", dw->file_type); if (!ro_gui_wimp_sprite_exists(dw->sprite_name)) strcpy(dw->sprite_name, "file_xxx"); download_template->icons[ICON_DOWNLOAD_ICON].data.indirected_sprite.id = (osspriteop_id) dw->sprite_name; /* Get a suitable path- and leafname for the download. */ temp_name = download_context_get_filename(dw->ctx); if (temp_name == NULL) temp_name = messages_get("SaveObject"); if (temp_name != NULL) filename = strdup(temp_name); if (filename == NULL) { LOG("Failed to establish download filename."); ro_warn_user("SaveError", error->errmess); free(dw); return 0; } for (i = 0, last_dot = (size_t) -1; filename[i] != '\0'; i++) { const char c = filename[i]; if (c == '.') { last_dot = i; filename[i] = '/'; } else if (c <= ' ' || strchr(":*#$&@^%\\", c) != NULL) filename[i] = '_'; } if (nsoption_bool(strip_extensions) && last_dot != (size_t) -1) filename[last_dot] = '\0'; if (download_dir != NULL && strlen(download_dir) > 0) snprintf(dw->path, RO_DOWNLOAD_MAX_PATH_LEN, "%s.%s", download_dir, filename); else snprintf(dw->path, RO_DOWNLOAD_MAX_PATH_LEN, "%s", filename); free(filename); err = utf8_to_local_encoding(dw->path, 0, &local_path); if (err != NSERROR_OK) { /* badenc should never happen */ assert(err !=NSERROR_BAD_ENCODING); LOG("utf8_to_local_encoding failed"); ro_warn_user("NoMemory", 0); free(dw); return 0; } else { strncpy(dw->path, local_path, sizeof dw->path); free(local_path); } download_template->icons[ICON_DOWNLOAD_PATH].data.indirected_text.text = dw->path; download_template->icons[ICON_DOWNLOAD_PATH].data.indirected_text.size = sizeof dw->path; download_template->icons[ICON_DOWNLOAD_DESTINATION].data. indirected_text.text = dw->path; download_template->icons[ICON_DOWNLOAD_DESTINATION].data. indirected_text.size = sizeof dw->path; download_template->icons[ICON_DOWNLOAD_DESTINATION].flags |= wimp_ICON_DELETED; /* create and open the download window */ error = xwimp_create_window(download_template, &dw->window); if (error) { LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess); ro_warn_user("WimpError", error->errmess); free(dw); return 0; } dw->prev = 0; dw->next = download_window_list; if (download_window_list) download_window_list->prev = dw; download_window_list = dw; ro_gui_download_update_status(dw); ro_gui_dialog_open(dw->window); ro_gui_wimp_event_set_user_data(dw->window, dw); ro_gui_wimp_event_register_mouse_click(dw->window, ro_gui_download_click); ro_gui_wimp_event_register_keypress(dw->window, ro_gui_download_keypress); ro_gui_wimp_event_register_close_window(dw->window, ro_gui_download_close); /* issue the warning now, so that it appears in front of the download * window! */ if (space_warning) ro_warn_user("DownloadWarn", messages_get("NoDiscSpace")); return dw; }