From 62fc785e241f456e60290571b0c5e5777d111d66 Mon Sep 17 00:00:00 2001 From: Fumitoshi UKAI Date: Fri, 15 Nov 2002 15:19:43 +0000 Subject: [w3m-dev 03431] save file by background process * file.c (loadGeneralFile): use _doFileCopy() (_doFileCopy): renamed from doFileCopy() lock fork & save (doFileSave): lock fork & save * fm.h (DownloadList): added (FirstDL): added (LastDL): added * form.c (struct internal_action): add download * funcname.tab (DOWNLOAD_LIST): added * html.h (URLFile): add url * main.c (dump_extra): add add_download_list (main): add_download_list, ldDL() (_quitfm): added (quitfm): rewrite with _quitfm() (qquitfm): ditto (w3m_exit): stopDownload() (addDownloadList): added (checkDownloadList): added (convert_size3): added (DownloadListBuffer): added (download_action): added (stopDownload): added (ldDL): added * proto.h (ldDL): added (convert_size): added (convert_size2): added (doFileCopy): deleted (_doFileCopy): added (addDownloadList): added (stopDownload): added (checkDownloadList): added (download_action): added * url.c (openURL): save url in uf From: Hironori SAKAMOTO --- ChangeLog | 41 +++++++++- file.c | 84 +++++++++++++++++-- fm.h | 16 +++- form.c | 3 +- funcname.tab | 3 +- html.h | 3 +- main.c | 257 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- proto.h | 13 ++- url.c | 3 +- 9 files changed, 392 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7b75389..0db3148 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,42 @@ +2002-11-16 Hironori SAKAMOTO + + * [w3m-dev 03431] save file by background process + * file.c (loadGeneralFile): use _doFileCopy() + (_doFileCopy): renamed from doFileCopy() + lock + fork & save + (doFileSave): lock + fork & save + * fm.h (DownloadList): added + (FirstDL): added + (LastDL): added + * form.c (struct internal_action): add download + * funcname.tab (DOWNLOAD_LIST): added + * html.h (URLFile): add url + * main.c (dump_extra): add add_download_list + (main): add_download_list, ldDL() + (_quitfm): added + (quitfm): rewrite with _quitfm() + (qquitfm): ditto + (w3m_exit): stopDownload() + (addDownloadList): added + (checkDownloadList): added + (convert_size3): added + (DownloadListBuffer): added + (download_action): added + (stopDownload): added + (ldDL): added + * proto.h (ldDL): added + (convert_size): added + (convert_size2): added + (doFileCopy): deleted + (_doFileCopy): added + (addDownloadList): added + (stopDownload): added + (checkDownloadList): added + (download_action): added + * url.c (openURL): save url in uf + 2002-11-15 Hironori SAKAMOTO * [w3m-dev 03430] disable display of alarm command @@ -4643,4 +4682,4 @@ a * [w3m-dev 03276] compile error on EWS4800 * release-0-2-1 * import w3m-0.2.1 -$Id: ChangeLog,v 1.513 2002/11/14 17:01:25 ukai Exp $ +$Id: ChangeLog,v 1.514 2002/11/15 15:19:43 ukai Exp $ diff --git a/file.c b/file.c index ad345ff..7eba2af 100644 --- a/file.c +++ b/file.c @@ -1,4 +1,4 @@ -/* $Id: file.c,v 1.115 2002/11/13 15:47:12 ukai Exp $ */ +/* $Id: file.c,v 1.116 2002/11/15 15:19:43 ukai Exp $ */ #include "fm.h" #include #include "myctype.h" @@ -1944,9 +1944,9 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer, signal(SIGINT, prevtrap); if (pu.scheme == SCM_LOCAL) { UFclose(&f); - doFileCopy(pu.real_file, + _doFileCopy(pu.real_file, conv_from_system(guess_save_name - (NULL, pu.real_file))); + (NULL, pu.real_file)), TRUE); } else { if (DecodeCTE && IStype(f.stream) != IST_ENCODED) @@ -7178,11 +7178,18 @@ _MoveFile(char *path1, char *path2) } void -doFileCopy(char *tmpf, char *defstr) +_doFileCopy(char *tmpf, char *defstr, int download) { Str msg; Str filen; char *p, *q = NULL; + pid_t pid; + char *lock; +#if !(defined(HAVE_SYMLINK) && defined(HAVE_LSTAT)) + FILE *f; +#endif + struct stat st; + clen_t size = 0; if (fmInitialized) { p = searchKeyData(); @@ -7207,10 +7214,40 @@ doFileCopy(char *tmpf, char *defstr) disp_err_message(msg->ptr, FALSE); return; } - if (_MoveFile(tmpf, p) < 0) { - msg = Sprintf("Can't save to %s", p); - disp_err_message(msg->ptr, FALSE); + if (!download) { + if (_MoveFile(tmpf, p) < 0) { + msg = Sprintf("Can't save to %s", p); + disp_err_message(msg->ptr, FALSE); + } + return; } + lock = tmpfname(TMPF_DFL, ".lock")->ptr; +#if defined(HAVE_SYMLINK) && defined(HAVE_LSTAT) + symlink(p, lock); +#else + f = fopen(lock, "w"); + if (f) + fclose(f); +#endif + pushText(fileToDelete, lock); + flush_tty(); + pid = fork(); + if (!pid) { + reset_signals(); + signal(SIGINT, SIG_IGN); +#ifdef HAVE_SETPGRP + SETPGRP(); +#endif + close_tty(); + QuietMessage = TRUE; + fmInitialized = FALSE; + _MoveFile(tmpf, p); + unlink(lock); + exit(0); + } + if (!stat(tmpf, &st)) + size = st.st_size; + addDownloadList(pid, tmpf, p, lock, size); } else { q = searchKeyData(); @@ -7255,6 +7292,11 @@ doFileSave(URLFile uf, char *defstr) Str msg; Str filen; char *p, *q; + pid_t pid; + char *lock; +#if !(defined(HAVE_SYMLINK) && defined(HAVE_LSTAT)) + FILE *f; +#endif if (fmInitialized) { p = searchKeyData(); @@ -7272,10 +7314,38 @@ doFileSave(URLFile uf, char *defstr) disp_err_message(msg->ptr, FALSE); return; } +/* if (save2tmp(uf, p) < 0) { msg = Sprintf("Can't save to %s", p); disp_err_message(msg->ptr, FALSE); } +*/ + lock = tmpfname(TMPF_DFL, ".lock")->ptr; +#if defined(HAVE_SYMLINK) && defined(HAVE_LSTAT) + symlink(p, lock); +#else + f = fopen(lock, "w"); + if (f) + fclose(f); +#endif + pushText(fileToDelete, lock); + flush_tty(); + pid = fork(); + if (!pid) { + reset_signals(); + signal(SIGINT, SIG_IGN); +#ifdef HAVE_SETPGRP + SETPGRP(); +#endif + close_tty(); + QuietMessage = TRUE; + fmInitialized = FALSE; + save2tmp(uf, p); + UFclose(&uf); + unlink(lock); + exit(0); + } + addDownloadList(pid, uf.url, p, lock, current_content_length); } else { q = searchKeyData(); diff --git a/fm.h b/fm.h index 5e63e24..4a151f9 100644 --- a/fm.h +++ b/fm.h @@ -1,4 +1,4 @@ -/* $Id: fm.h,v 1.76 2002/11/14 16:56:23 ukai Exp $ */ +/* $Id: fm.h,v 1.77 2002/11/15 15:19:44 ukai Exp $ */ /* * w3m: WWW wo Miru utility * @@ -453,6 +453,18 @@ typedef struct _TabBuffer { Buffer *firstBuffer; } TabBuffer; +typedef struct _DownloadList { + pid_t pid; + char *url; + char *save; + char *lock; + clen_t size; + time_t time; + int ok; + struct _DownloadList *next; + struct _DownloadList *prev; +} DownloadList; + #define COPY_BUFPOSITION(dstbuf, srcbuf) {\ (dstbuf)->topLine = (srcbuf)->topLine; \ (dstbuf)->currentLine = (srcbuf)->currentLine; \ @@ -795,6 +807,8 @@ global int TabCols init(10); : (nTab - 1) / ((nTab * TabCols - 1) / (COLS - 2) + 1) + 1) #define Currentbuf (CurrentTab->currentBuffer) #define Firstbuf (CurrentTab->firstBuffer) +global DownloadList *FirstDL init(NULL); +global DownloadList *LastDL init(NULL); global int CurrentKey; global char *CurrentKeyData; global char *CurrentCmdData; diff --git a/form.c b/form.c index af3adcc..cc7a374 100644 --- a/form.c +++ b/form.c @@ -1,4 +1,4 @@ -/* $Id: form.c,v 1.22 2002/11/12 13:06:14 ukai Exp $ */ +/* $Id: form.c,v 1.23 2002/11/15 15:19:44 ukai Exp $ */ /* * HTML forms */ @@ -31,6 +31,7 @@ struct { #ifdef USE_COOKIE {"cookie", set_cookie_flag}, #endif /* USE_COOKIE */ + {"download", download_action}, {"none", NULL}, {NULL, NULL}, }; diff --git a/funcname.tab b/funcname.tab index a3bd25f..202d54a 100644 --- a/funcname.tab +++ b/funcname.tab @@ -1,4 +1,4 @@ -# $Id: funcname.tab,v 1.12 2002/11/05 17:10:05 ukai Exp $ +# $Id: funcname.tab,v 1.13 2002/11/15 15:19:45 ukai Exp $ # macro name function name #---------------------------- @@@ nulcmd @@ -20,6 +20,7 @@ DICT_WORD_AT dictwordat DISPLAY_IMAGE dispI DOWN ldown1 DOWNLOAD svSrc +DOWNLOAD_LIST ldDL EDIT editBf EDIT_SCREEN editScr END goLineL diff --git a/html.h b/html.h index cde57c6..677ad29 100644 --- a/html.h +++ b/html.h @@ -1,4 +1,4 @@ -/* $Id: html.h,v 1.9 2002/10/10 16:59:33 ukai Exp $ */ +/* $Id: html.h,v 1.10 2002/11/15 15:19:45 ukai Exp $ */ #ifndef _HTML_H #define _HTML_H #ifdef USE_SSL @@ -72,6 +72,7 @@ typedef struct { #ifdef USE_SSL char *ssl_certificate; #endif + char *url; } URLFile; #define CMP_NOCOMPRESS 0 diff --git a/main.c b/main.c index f09f190..5e37dcc 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.131 2002/11/14 17:01:29 ukai Exp $ */ +/* $Id: main.c,v 1.132 2002/11/15 15:19:46 ukai Exp $ */ #define MAINPROGRAM #include "fm.h" #include @@ -85,6 +85,7 @@ static void dump_extra(Buffer *); int prec_num = 0; int prev_key = -1; int on_target = 1; +static int add_download_list = FALSE; void set_buffer_environ(Buffer *); @@ -1026,6 +1027,10 @@ main(int argc, char **argv, char **envp) set_buffer_environ(Currentbuf); keyPressEventProc((int)c); prec_num = 0; + if (add_download_list) { + add_download_list = FALSE; + ldDL(); + } } } prev_key = CurrentKey; @@ -2165,23 +2170,21 @@ movRW(void) displayBuffer(Currentbuf, B_NORMAL); } -/* Question and Quit */ -void -qquitfm(void) +static void +_quitfm(int confirm) { - char *ans; - if (!confirm_on_quit) - quitfm(); - ans = inputChar("Do you want to exit w3m? (y/n)"); - if (ans && tolower(*ans) == 'y') - quitfm(); - displayBuffer(Currentbuf, B_NORMAL); -} + char *ans = "y"; + + if (checkDownloadList()) + ans = inputChar("Download process retains. " + "Do you want to exit w3m? (y/n)"); + else if (confirm) + ans = inputChar("Do you want to exit w3m? (y/n)"); + if (!(ans && tolower(*ans) == 'y')) { + displayBuffer(Currentbuf, B_NORMAL); + return; + } -/* Quit */ -void -quitfm(void) -{ term_title(""); /* XXX */ #ifdef USE_IMAGE if (activeImage) @@ -2198,6 +2201,20 @@ quitfm(void) w3m_exit(0); } +/* Quit */ +void +quitfm(void) +{ + _quitfm(FALSE); +} + +/* Question and Quit */ +void +qquitfm(void) +{ + _quitfm(confirm_on_quit); +} + /* Select buffer */ void selBuf(void) @@ -5158,6 +5175,7 @@ w3m_exit(int i) #ifdef USE_MIGEMO init_migemo(); /* close pipe to migemo */ #endif + stopDownload(); deleteFiles(); #ifdef USE_SSL free_ssl_ctx(); @@ -5683,3 +5701,210 @@ tabL(void) tab = tab->prevTab, i++) ; moveTab(CurrentTab, tab ? tab : FirstTab, FALSE); } + +void +addDownloadList(pid_t pid, char *url, char *save, char *lock, clen_t size) +{ + DownloadList *d; + + d = New(DownloadList); + d->pid = pid; + d->url = url; + if (save[0] != '/' && save[0] != '~') + save = Strnew_m_charp(CurrentDir, "/", save, NULL)->ptr; + d->save = expandName(save); + d->lock = lock; + d->size = size; + d->time = time(0); + d->ok = FALSE; + d->next = NULL; + d->prev = LastDL; + if (LastDL) + LastDL->next = d; + else + FirstDL = d; + LastDL = d; + add_download_list = TRUE; +} + +int +checkDownloadList(void) +{ + DownloadList *d; + struct stat st; + + if (!FirstDL) + return FALSE; + for (d = FirstDL; d != NULL; d = d->next) { +#ifdef HAVE_LSTAT + if (!d->ok && !lstat(d->lock, &st)) +#else + if (!d->ok && !stat(d->lock, &st)) +#endif + return TRUE; + } + return FALSE; +} + +static char * +convert_size3(clen_t size) +{ + Str tmp = Strnew(); + int n; + + do { + n = size % 1000; + size /= 1000; + tmp = Sprintf(size ? ",%.3d%s" : "%d%s", n, tmp->ptr); + } while (size); + return tmp->ptr; +} + +static Buffer * +DownloadListBuffer(void) +{ + DownloadList *d; + Str src = NULL; + struct stat st; + time_t cur_time; + int duration, rate, eta; + size_t size; + + if (!FirstDL) + return NULL; + cur_time = time(0); + src = Strnew_charp("Download Panel\ +

Download Panel

\ +
\ +
\n"); + for (d = LastDL; d != NULL; d = d->prev) { +#ifdef HAVE_LSTAT + if (lstat(d->lock, &st)) +#else + if (stat(d->lock, &st)) +#endif + d->ok = TRUE; + Strcat_charp(src, "
\n");
+	Strcat(src, Sprintf("%s\n  --> %s\n  ", html_quote(d->url),
+			    html_quote(d->save)));
+	duration = cur_time - d->time;
+	if (!stat(d->save, &st)) {
+	    size = st.st_size;
+	    if (d->ok) {
+		d->size = size;
+		duration = st.st_mtime - d->time;
+	    }
+	}
+	else
+	    size = 0;
+	if (d->size) {
+	    int i, l = COLS - 6;
+	    if (size < d->size)
+		i = l * size / d->size;
+	    else
+		i = l;
+	    l -= i;
+	    while (i-- > 0)
+		Strcat_char(src, '#');
+	    while (l-- > 0)
+		Strcat_char(src, '_');
+	    Strcat_char(src, '\n');
+	}
+	if (!d->ok && size < d->size)
+	    Strcat(src, Sprintf("  %s / %s bytes (%d%%)",
+				convert_size3(size), convert_size3(d->size),
+				(int)(100.0 * size / d->size)));
+	else
+	    Strcat(src, Sprintf("  %s bytes loaded", convert_size3(size)));
+	if (duration > 0) {
+	    rate = size / duration;
+	    Strcat(src, Sprintf("  %02d:%02d:%02d  rate %s/sec",
+				duration / (60 * 60), (duration / 60) % 60,
+				duration % 60, convert_size(rate, 1)));
+	    if (!d->ok && size < d->size && rate) {
+	    	eta = (d->size - size) / rate;
+		Strcat(src, Sprintf("  eta %02d:%02d:%02d", eta / (60 * 60),
+				    (eta / 60) % 60, eta % 60));
+	    }
+	}
+	Strcat_char(src, '\n');
+	if (d->ok) {
+	    Strcat(src, Sprintf("",
+				d->pid));
+	    if (size < d->size)
+	        Strcat_charp(src, " Download incompleted");
+	    else
+	        Strcat_charp(src, " Download completed");
+	} else
+	    Strcat(src, Sprintf("",
+				d->pid));
+	Strcat_charp(src, "\n

\n"); + } + Strcat_charp(src, "
"); + return loadHTMLString(src); +} + +void +download_action(struct parsed_tagarg *arg) +{ + DownloadList *d; + pid_t pid; + + for (; arg; arg = arg->next) { + if (!strcmp(arg->arg, "update")) + break; + else if (!strncmp(arg->arg, "stop", 4)) { + pid = (pid_t)atoi(&arg->arg[4]); + kill(pid, SIGKILL); + } + else if (!strncmp(arg->arg, "ok", 2)) + pid = (pid_t)atoi(&arg->arg[2]); + else + continue; + for (d = FirstDL; d; d = d->next) { + if (d->pid == pid) { + unlink(d->lock); + if (d->prev) + d->prev->next = d->next; + else + FirstDL = d->next; + if (d->next) + d->next->prev = d->prev; + else + LastDL = d->prev; + break; + } + } + } + if (FirstDL) { + ldDL(); + deletePrevBuf(); + } + else + backBf(); +} + +void +stopDownload(void) +{ + DownloadList *d; + + if (!FirstDL) + return; + for (d = FirstDL; d != NULL; d = d->next) { + if (d->ok) + continue; + kill(d->pid, SIGKILL); + unlink(d->lock); + } +} + +/* download panel */ +void +ldDL(void) +{ + if (!FirstDL) + return; + cmd_loadBuffer(DownloadListBuffer(), BP_NO_URL, LB_NOLINK); + nextA(); +} diff --git a/proto.h b/proto.h index ddb1e63..9807c44 100644 --- a/proto.h +++ b/proto.h @@ -1,4 +1,4 @@ -/* $Id: proto.h,v 1.54 2002/11/10 11:59:15 ukai Exp $ */ +/* $Id: proto.h,v 1.55 2002/11/15 15:19:46 ukai Exp $ */ /* * This file was automatically generated by version 1.7 of cextract. * Manual editing not recommended. @@ -128,6 +128,7 @@ extern void tabURL(void); extern void tabrURL(void); extern void tabR(void); extern void tabL(void); +extern void ldDL(void); extern int currentLn(Buffer *buf); extern void tmpClearBuffer(Buffer *buf); @@ -185,6 +186,8 @@ extern void HTMLlineproc0(char *istr, struct html_feed_environ *h_env, int internal); #define HTMLlineproc1(x,y) HTMLlineproc0(x,y,TRUE) extern Buffer *loadHTMLBuffer(URLFile *f, Buffer *newBuf); +extern char *convert_size(clen_t size, int usefloat); +extern char *convert_size2(clen_t size1, clen_t size2, int usefloat); extern void showProgress(clen_t *linelen, clen_t *trbyte); extern void init_henv(struct html_feed_environ *, struct readbuffer *, struct environment *, int, TextLineList *, int, int); @@ -209,7 +212,8 @@ extern Line *getNextPage(Buffer *buf, int plen); extern int save2tmp(URLFile uf, char *tmpf); extern int doExternal(URLFile uf, char *path, char *type, Buffer **bufp, Buffer *defaultbuf); -extern void doFileCopy(char *tmpf, char *defstr); +extern void _doFileCopy(char *tmpf, char *defstr, int download); +#define doFileCopy(tmpf, defstr) _doFileCopy(tmpf, defstr, FALSE); extern void doFileMove(char *tmpf, char *defstr); extern void doFileSave(URLFile uf, char *defstr); extern int checkCopyFile(char *path1, char *path2); @@ -221,6 +225,11 @@ extern void readHeader(URLFile *uf, Buffer *newBuf, int thru, ParsedURL *pu); extern char *checkHeader(Buffer *buf, char *field); extern TabBuffer *newTab(void); extern TabBuffer *deleteTab(TabBuffer *tab); +extern void addDownloadList(pid_t pid, char *url, char *save, char *lock, + clen_t size); +extern void stopDownload(void); +extern int checkDownloadList(void); +extern void download_action(struct parsed_tagarg *arg); extern Buffer *newBuffer(int width); extern Buffer *nullBuffer(void); extern void clearBuffer(Buffer *buf); diff --git a/url.c b/url.c index b07a330..dedcbc6 100644 --- a/url.c +++ b/url.c @@ -1,4 +1,4 @@ -/* $Id: url.c,v 1.56 2002/11/14 16:56:24 ukai Exp $ */ +/* $Id: url.c,v 1.57 2002/11/15 15:19:46 ukai Exp $ */ #include "fm.h" #include #include @@ -1476,6 +1476,7 @@ openURL(char *url, ParsedURL *pu, ParsedURL *current, } uf.scheme = pu->scheme; + uf.url = parsedURL2Str(pu)->ptr; pu->is_nocache = (option->flag & RG_NOCACHE); uf.ext = filename_extension(pu->file, 1); -- cgit v1.2.3