#ifndef EL__SESSION_DOWNLOAD_H #define EL__SESSION_DOWNLOAD_H #include "main/object.h" #include "network/state.h" #include "util/lists.h" #include "util/time.h" /* Silly BFU stuff */ struct dialog_data; struct listbox_item; struct terminal; struct cache_entry; struct connection; struct session; struct uri; struct download; typedef void (download_callback_T)(struct download *, void *); struct download { /* XXX: order matters there, there's some hard initialization in * src/session/session.c and src/viewer/text/view.c */ LIST_HEAD(struct download); struct connection *conn; struct cache_entry *cached; /** The callback is called when connection gets into a progress state, * after it's over (in a result state), and also periodically after * the download starts receiving some data. */ download_callback_T *callback; void *data; struct progress *progress; struct connection_state state; struct connection_state prev_error; enum connection_priority pri; }; /** The user has navigated to a resource that ELinks does not display * automatically because of its MIME type, and ELinks is asking what * to do. * * These structures are kept in the session.type_queries list, and * destroy_session() calls done_type_query() to destroy them too. */ struct type_query { LIST_HEAD(struct type_query); struct download download; struct cache_entry *cached; struct session *ses; struct uri *uri; unsigned char *target_frame; unsigned char *external_handler; int block; /** Whether the resource was generated by ELinks running * a local CGI program. If the user chooses to open the * resource with an external handler, ELinks normally saves * the resource to a temporary file and passes the name of * that to the external handler. However, if the resource is * from a "file" URI that does not refer to a local CGI, then * Elinks need not copy the file. */ unsigned int cgi:1; /* int frame; */ }; struct file_download { OBJECT_HEAD(struct file_download); struct uri *uri; unsigned char *file; unsigned char *external_handler; struct session *ses; struct terminal *term; time_t remotetime; off_t seek; int handle; int redirect_cnt; int notify; struct download download; /** Should the file be deleted when destroying the structure */ unsigned int delete:1; /** Should the download be stopped/interrupted when destroying the structure */ unsigned int stop:1; /** Whether to block the terminal when running the external handler. */ unsigned int block:1; /** The current dialog for this download. Can be NULL. */ struct dialog_data *dlg_data; struct listbox_item *box_item; }; /** Stack of all running downloads */ extern LIST_OF(struct file_download) downloads; static inline int is_in_downloads_list(struct file_download *file_download) { struct file_download *down; foreach (down, downloads) if (file_download == down) return 1; return 0; } int download_is_progressing(struct download *download); int are_there_downloads(void); /** Whether to resume downloading to a file. This is a bit mask. * Unrecognized bits should be preserved and ignored. */ enum download_resume { /** All bits clear. Downloading cannot be resumed; do not * offer such an option to the user. */ DOWNLOAD_RESUME_DISABLED = 0, /** Downloading can be resumed. This is the usual value. */ DOWNLOAD_RESUME_ALLOWED = 1, /** The user wants to resume downloading. This must not occur * without DOWNLOAD_RESUME_ALLOWED. */ DOWNLOAD_RESUME_SELECTED = 2 }; /** Type of the callback function that will be called when the file * has been opened, or when it is known that the file will not be * opened. * * @param term * The terminal on which the callback should display any windows. * Comes directly from the @a term argument of create_download_file(). * * @param fd * A file descriptor to the opened file, or -1 if the file will not be * opened. If the @a real_file argument of create_download_file() * was not NULL, the callback may read the name of this file from * *@a real_file. * * @param data * A pointer to any data that the callback cares about. * Comes directly from the @a data argument of create_download_file(). * * @param resume * The same as the @a resume argument of create_download_file(), * except the ::DOWNLOAD_RESUME_SELECTED bit will be changed to match * what the user chose. * * @relates cdf_hop */ typedef void cdf_callback_T(struct terminal *term, int fd, void *data, enum download_resume resume); void start_download(void *, unsigned char *); void resume_download(void *, unsigned char *); void create_download_file(struct terminal *, unsigned char *, unsigned char **, int, enum download_resume, cdf_callback_T *, void *); void abort_all_downloads(void); void destroy_downloads(struct session *); void detach_downloads_from_terminal(struct terminal *); int setup_download_handler(struct session *, struct download *, struct cache_entry *, int); void abort_download(struct file_download *file_download); void done_type_query(struct type_query *type_query); void tp_display(struct type_query *type_query); void tp_save(struct type_query *type_query); void tp_cancel(void *data); struct file_download *init_file_download(struct uri *uri, struct session *ses, unsigned char *file, int fd); #endif