diff options
| author | Fumitoshi UKAI <ukai@debian.or.jp> | 2002-11-15 15:19:43 +0000 | 
|---|---|---|
| committer | Fumitoshi UKAI <ukai@debian.or.jp> | 2002-11-15 15:19:43 +0000 | 
| commit | 62fc785e241f456e60290571b0c5e5777d111d66 (patch) | |
| tree | 14912952e1902a503ce1974ed464c37303e72b20 | |
| parent | [w3m-dev 03430] disable display of alarm command (diff) | |
| download | w3m-62fc785e241f456e60290571b0c5e5777d111d66.tar.gz w3m-62fc785e241f456e60290571b0c5e5777d111d66.zip | |
[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 <hsaka@mth.biglobe.ne.jp>
| -rw-r--r-- | ChangeLog | 41 | ||||
| -rw-r--r-- | file.c | 84 | ||||
| -rw-r--r-- | fm.h | 16 | ||||
| -rw-r--r-- | form.c | 3 | ||||
| -rw-r--r-- | funcname.tab | 3 | ||||
| -rw-r--r-- | html.h | 3 | ||||
| -rw-r--r-- | main.c | 257 | ||||
| -rw-r--r-- | proto.h | 13 | ||||
| -rw-r--r-- | url.c | 3 | 
9 files changed, 392 insertions, 31 deletions
| @@ -1,3 +1,42 @@ +2002-11-16  Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp> + +	* [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 <hsaka@mth.biglobe.ne.jp>  	* [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 $ @@ -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 <sys/types.h>  #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(); @@ -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; @@ -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 @@ -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 @@ -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 <signal.h> @@ -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("<html><head><title>Download Panel</title></head>\ +<body><h1 align=center>Download Panel</h1>\ +<form method=internal action=download>\ +<input type=submit name=update value=Update><hr>\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, "<pre>\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("<input type=submit name=ok%d value=OK>", +				d->pid)); +	    if (size < d->size) +	        Strcat_charp(src, " Download incompleted"); +	    else +	        Strcat_charp(src, " Download completed"); +	} else +	    Strcat(src, Sprintf("<input type=submit name=stop%d value=STOP>", +				d->pid)); +	Strcat_charp(src, "\n</pre><hr>\n"); +    } +    Strcat_charp(src, "</form></body></html>"); +    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(); +} @@ -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); @@ -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 <sys/types.h>  #include <sys/socket.h> @@ -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); | 
