diff options
| -rw-r--r-- | ChangeLog | 21 | ||||
| -rw-r--r-- | file.c | 76 | ||||
| -rw-r--r-- | ftp.c | 666 | ||||
| -rw-r--r-- | main.c | 3 | ||||
| -rw-r--r-- | proto.h | 14 | ||||
| -rw-r--r-- | url.c | 8 | 
6 files changed, 310 insertions, 478 deletions
| @@ -1,3 +1,22 @@ +2003-01-12  Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp> + +	* [w3m-dev 03633] Re: cleanup (don't close connection of news server) +	* file.c (FTPhalfclose): deleted +		(loadGeneralFile): closeFTP when doFileSave is done +		(_doFileCopy): return int +		(doFileMove): return int +		(doFileSave): return int +	* ftp.c: rewrite +	* main.c (w3m_exit): disconnectFTP +	* proto.h (_doFileCopy): return int +		(doFileMove): return int +		(doFileSave): return int +		(openFTP): deleted +		(openFTPStream): return InputStream +		(closeFTP): no arg +		(Ftpfclose): disconnectFTP +	* url.c (openFTPstream): deleted +  2003-01-11  Fumitoshi UKAI  <ukai@debian.or.jp>  	* fix compiler warnings @@ -6354,4 +6373,4 @@ a	* [w3m-dev 03276] compile error on EWS4800  	* release-0-2-1  	* import w3m-0.2.1 -$Id: ChangeLog,v 1.672 2003/01/10 17:15:08 ukai Exp $ +$Id: ChangeLog,v 1.673 2003/01/11 15:54:08 ukai Exp $ @@ -1,4 +1,4 @@ -/* $Id: file.c,v 1.183 2003/01/10 17:06:20 ukai Exp $ */ +/* $Id: file.c,v 1.184 2003/01/11 15:54:08 ukai Exp $ */  #include "fm.h"  #include <sys/types.h>  #include "myctype.h" @@ -28,7 +28,6 @@  static int frame_source = 0; -static void FTPhalfclose(InputStream stream);  static int _MoveFile(char *path1, char *path2);  static void uncompress_stream(URLFile *uf, char **src);  static FILE *lessopen_stream(char *path); @@ -1939,9 +1938,8 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer,  	}  	else  	    file = guess_save_name(t_buf, pu.file); -	doFileSave(f, file); -	if (f.scheme == SCM_FTP) -	    FTPhalfclose(f.stream); +	if (doFileSave(f, file) == 0 && f.scheme == SCM_FTP) +	    closeFTP();  	else  	    UFclose(&f);  	return NO_BUFFER; @@ -2023,9 +2021,9 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer,  	    else {  		if (DecodeCTE && IStype(f.stream) != IST_ENCODED)  		    f.stream = newEncodedStream(f.stream, f.encoding); -		doFileSave(f, guess_save_name(t_buf, pu.file)); -		if (f.scheme == SCM_FTP) -		    FTPhalfclose(f.stream); +		if (doFileSave(f, guess_save_name(t_buf, pu.file)) == 0 && +		    f.scheme == SCM_FTP) +		    closeFTP();  		else  		    UFclose(&f);  	    } @@ -7248,15 +7246,6 @@ getNextPage(Buffer *buf, int plen)      return rl;  } -static void -FTPhalfclose(InputStream stream) -{ -    if (IStype(stream) == IST_FILE && file_of(stream)) { -	Ftpfclose(file_of(stream)); -	file_of(stream) = NULL; -    } -} -  int  save2tmp(URLFile uf, char *tmpf)  { @@ -7468,7 +7457,7 @@ _MoveFile(char *path1, char *path2)      return 0;  } -void +int  _doFileCopy(char *tmpf, char *defstr, int download)  {      Str msg; @@ -7489,7 +7478,7 @@ _doFileCopy(char *tmpf, char *defstr, int download)  	    q = inputLineHist("(Download)Save file to: ",  			      defstr, IN_COMMAND, SaveHist);  	    if (q == NULL || *q == '\0') -		return; +		return FALSE;  	    p = conv_to_system(q);  	}  	if (*p == '|' && PermitSaveToPipe) @@ -7501,20 +7490,20 @@ _doFileCopy(char *tmpf, char *defstr, int download)  	    }  	    p = expandName(p);  	    if (checkOverWrite(p) < 0) -		return; +		return -1;  	}  	if (checkCopyFile(tmpf, p) < 0) {  	    msg = Sprintf("Can't copy. %s and %s are identical.",  			  conv_from_system(tmpf), conv_from_system(p));  	    disp_err_message(msg->ptr, FALSE); -	    return; +	    return -1;  	}  	if (!download) {  	    if (_MoveFile(tmpf, p) < 0) {  		msg = Sprintf("Can't save to %s", conv_from_system(p));  		disp_err_message(msg->ptr, FALSE);  	    } -	    return; +	    return -1;  	}  	lock = tmpfname(TMPF_DFL, ".lock")->ptr;  #if defined(HAVE_SYMLINK) && defined(HAVE_LSTAT) @@ -7550,40 +7539,44 @@ _doFileCopy(char *tmpf, char *defstr, int download)  	    fflush(stdout);  	    filen = Strfgets(stdin);  	    if (filen->length == 0) -		return; +		return -1;  	    q = filen->ptr;  	}  	for (p = q + strlen(q) - 1; IS_SPACE(*p); p--) ;  	*(p + 1) = '\0';  	if (*q == '\0') -	    return; +	    return -1;  	p = q;  	if (*p == '|' && PermitSaveToPipe)  	    is_pipe = TRUE;  	else {  	    p = expandName(p);  	    if (checkOverWrite(p) < 0) -		return; +		return -1;  	}  	if (checkCopyFile(tmpf, p) < 0) {  	    printf("Can't copy. %s and %s are identical.", tmpf, p); -	    return; +	    return -1;  	} -	if (_MoveFile(tmpf, p) < 0) +	if (_MoveFile(tmpf, p) < 0) {  	    printf("Can't save to %s\n", p); -	else if (PreserveTimestamp && !is_pipe && !stat(tmpf, &st)) +	    return -1; +	} +	if (PreserveTimestamp && !is_pipe && !stat(tmpf, &st))  	    setModtime(p, st.st_mtime);      } +    return 0;  } -void +int  doFileMove(char *tmpf, char *defstr)  { -    doFileCopy(tmpf, defstr); +    int ret = doFileCopy(tmpf, defstr);      unlink(tmpf); +    return ret;  } -void +int  doFileSave(URLFile uf, char *defstr)  {      Str msg; @@ -7601,16 +7594,16 @@ doFileSave(URLFile uf, char *defstr)  	    p = inputLineHist("(Download)Save file to: ",  			      defstr, IN_FILENAME, SaveHist);  	    if (p == NULL || *p == '\0') -		return; +		return -1;  	    p = conv_to_system(p);  	}  	if (checkOverWrite(p) < 0) -	    return; +	    return -1;  	if (checkSaveFile(uf.stream, p) < 0) {  	    msg = Sprintf("Can't save. Load file and %s are identical.",  			  conv_from_system(p));  	    disp_err_message(msg->ptr, FALSE); -	    return; +	    return -1;  	}  	/*  	 * if (save2tmp(uf, p) < 0) { @@ -7650,25 +7643,28 @@ doFileSave(URLFile uf, char *defstr)  	    fflush(stdout);  	    filen = Strfgets(stdin);  	    if (filen->length == 0) -		return; +		return -1;  	    q = filen->ptr;  	}  	for (p = q + strlen(q) - 1; IS_SPACE(*p); p--) ;  	*(p + 1) = '\0';  	if (*q == '\0') -	    return; +	    return -1;  	p = expandName(q);  	if (checkOverWrite(p) < 0) -	    return; +	    return -1;  	if (checkSaveFile(uf.stream, p) < 0) {  	    printf("Can't save. Load file and %s are identical.", p); -	    return; +	    return -1;  	} -	if (save2tmp(uf, p) < 0) +	if (save2tmp(uf, p) < 0) {  	    printf("Can't save to %s\n", p); -	else if (PreserveTimestamp && uf.modtime != -1) +	    return -1; +	} +	if (PreserveTimestamp && uf.modtime != -1)  	    setModtime(p, uf.modtime);      } +    return 0;  }  int @@ -1,4 +1,4 @@ -/* $Id: ftp.c,v 1.20 2002/12/24 17:20:47 ukai Exp $ */ +/* $Id: ftp.c,v 1.21 2003/01/11 15:54:09 ukai Exp $ */  #include <stdio.h>  #include <pwd.h>  #include <Str.h> @@ -22,58 +22,44 @@  #endif  typedef struct _FTP { -    FILE *rcontrol; -    FILE *wcontrol; +    char *host; +    int port; +    char *user; +    char *pass; +    InputStream rf; +    FILE *wf;      FILE *data;  } *FTP; -#define FtpError(status) ((status)<0) -#define FTPDATA(ftp) ((ftp)->data) - -typedef int STATUS; - -static FTP current_ftp; +static struct _FTP current_ftp = { +    NULL, 0, NULL, NULL, NULL, NULL, NULL +};  static Str -read_response1(FTP ftp) +ftp_command(FTP ftp, char *cmd, char *arg, int *status)  { -    char c; -    Str buf = Strnew(); -    while (1) { -	c = getc(ftp->rcontrol); -	if (c == '\r') { -	    c = getc(ftp->rcontrol); -	    if (c == '\n') { -		Strcat_charp(buf, "\r\n"); -		break; -	    } -	    else { -		Strcat_char(buf, '\r'); -		Strcat_char(buf, c); -	    } -	} -	else if (c == '\n') { -	    Strcat_charp(buf, "\r\n"); -	    break; -	} -	else if (feof(ftp->rcontrol)) -	    break; +    Str tmp; + +    if (!ftp->host) +	return NULL; +    if (cmd) { +	if (arg) +	    tmp = Sprintf("%s %s\r\n", cmd, arg);  	else -	    Strcat_char(buf, c); +	    tmp = Sprintf("%s\r\n", cmd); +	fwrite(tmp->ptr, tmp->length, sizeof(char), ftp->wf); +	fflush(ftp->wf);      } -    return buf; -} - -Str -read_response(FTP ftp) -{ -    Str tmp; +    if (!status) +	return NULL; +    *status = -1;	/* error */ +    tmp = StrISgets(ftp->rf); +    if (IS_DIGIT(tmp->ptr[0]) && IS_DIGIT(tmp->ptr[1]) && +	IS_DIGIT(tmp->ptr[2]) && tmp->ptr[3] == ' ') +	sscanf(tmp->ptr, "%d", status); -    tmp = read_response1(ftp); -    if (feof(ftp->rcontrol)) { +    if (tmp->ptr[3] != '-')  	return tmp; -    } -    if (tmp->ptr[3] == '-') {  	/* RFC959 4.2 FTP REPLIES */  	/* multi-line response start */  	/*  @@ -83,110 +69,115 @@ read_response(FTP ftp)  	 * as Minus), followed by text.  The last line will begin  	 * with the same code, followed immediately by Space <SP>,   	 * optionally some text, and the Telnet end-of-line code. */ -	while (1) { -	    tmp = read_response1(ftp); -	    if (feof(ftp->rcontrol)) { -		break; -	    } -	    if (IS_DIGIT(tmp->ptr[0]) -		&& IS_DIGIT(tmp->ptr[1]) -		&& IS_DIGIT(tmp->ptr[2]) -		&& tmp->ptr[3] == ' ') { -		break; -	    } +    while (1) { +	tmp = StrISgets(ftp->rf); +	if (IS_DIGIT(tmp->ptr[0]) && IS_DIGIT(tmp->ptr[1]) && +	    IS_DIGIT(tmp->ptr[2]) && tmp->ptr[3] == ' ') { +	    sscanf(tmp->ptr, "%d", status); +	    break;  	}      }      return tmp;  } -int -FtpLogin(FTP * ftp_return, char *host, char *user, char *pass) +static void +ftp_close(FTP ftp) +{ +    if (!ftp->host) +	return; +    if (ftp->rf) { +	IStype(ftp->rf) &= ~IST_UNCLOSE; +        ISclose(ftp->rf); +        ftp->rf = NULL; +    } +    if (ftp->wf) { +	fclose(ftp->wf); +	ftp->wf = NULL; +    } +    if (ftp->data) { +	fclose(ftp->data); +	ftp->data = NULL; +    } +    ftp->host = NULL; +    return; +} + +static int +ftp_login(FTP ftp)  {      Str tmp; -    FTP ftp = New(struct _FTP); -    int fd; -    *ftp_return = current_ftp = ftp; -    fd = openSocket(host, "ftp", 21); -    if (fd < 0) -	return -1; +    int sock, status; + +    sock = openSocket(ftp->host, "ftp", 21); +    if (sock < 0) +	goto open_err;  #ifdef FTPPASS_HOSTNAMEGEN -    if (ftppass_hostnamegen && !strcmp(user, "anonymous")) { -	size_t n = strlen(pass); +    if (ftppass_hostnamegen && !strcmp(ftp->user, "anonymous")) { +	size_t n = strlen(ftp->pass); -	if (n > 0 && pass[n - 1] == '@') { +	if (n > 0 && ftp->pass[n - 1] == '@') {  	    struct sockaddr_in sockname;  	    int socknamelen = sizeof(sockname); -	    if (!getsockname(fd, (struct sockaddr *)&sockname, &socknamelen)) { +	    if (!getsockname(sock, (struct sockaddr *)&sockname, +			     &socknamelen)) {  		struct hostent *sockent; -		Str tmp2 = Strnew_charp(pass); +		tmp = Strnew_charp(ftp->pass);  		if ((sockent = gethostbyaddr((char *)&sockname.sin_addr,  					     sizeof(sockname.sin_addr),  					     sockname.sin_family))) -		    Strcat_charp(tmp2, sockent->h_name); +		    Strcat_charp(tmp, sockent->h_name);  		else -		    Strcat_m_charp(tmp2, "[", inet_ntoa(sockname.sin_addr), +		    Strcat_m_charp(tmp, "[", inet_ntoa(sockname.sin_addr),  				   "]", NULL); -		pass = tmp2->ptr; +		ftp->pass = tmp->ptr;  	    }  	}      }  #endif -    ftp->rcontrol = fdopen(fd, "rb"); -    ftp->wcontrol = fdopen(dup(fd), "wb"); -    ftp->data = NULL; -    tmp = read_response(ftp); -    if (atoi(tmp->ptr) != 220) -	return -1; +    ftp->rf = newInputStream(sock); +    ftp->wf = fdopen(dup(sock), "wb"); +    if (!ftp->rf || !ftp->wf) +	goto open_err; +    IStype(ftp->rf) |= IST_UNCLOSE; +    ftp_command(ftp, NULL, NULL, &status); +    if (status != 220) +	goto open_err;      if (fmInitialized) { -	message(Sprintf("Sending FTP username (%s) to remote server.", user)-> -		ptr, 0, 0); +	message(Sprintf("Sending FTP username (%s) to remote server.", +			ftp->user)->ptr, 0, 0);  	refresh();      } -    tmp = Sprintf("USER %s\r\n", user); -    fwrite(tmp->ptr, tmp->length, sizeof(char), ftp->wcontrol); -    fflush(ftp->wcontrol); -    tmp = read_response(ftp); +    ftp_command(ftp, "USER", ftp->user, &status);      /*       * Some ftp daemons(e.g. publicfile) return code 230 for user command.       */ -    if (atoi(tmp->ptr) == 230) +    if (status == 230)  	goto succeed; -    if (atoi(tmp->ptr) != 331) -	return -1; +    if (status != 331) +	goto open_err;      if (fmInitialized) { -	message(Sprintf("Sending FTP password to remote server.")->ptr, 0, 0); +	message("Sending FTP password to remote server.", 0, 0);  	refresh();      } -    tmp = Sprintf("PASS %s\r\n", pass); -    fwrite(tmp->ptr, tmp->length, sizeof(char), ftp->wcontrol); -    fflush(ftp->wcontrol); -    tmp = read_response(ftp); -    if (atoi(tmp->ptr) != 230) -	return -1; +    ftp_command(ftp, "PASS", ftp->pass, &status); +    if (status != 230) +	goto open_err;    succeed: -    return 0; -} - -int -FtpBinary(FTP ftp) -{ -    Str tmp; -    fwrite("TYPE I\r\n", 8, sizeof(char), ftp->wcontrol); -    fflush(ftp->wcontrol); -    tmp = read_response(ftp); -    if (atoi(tmp->ptr) != 200) -	return -1; -    return 0; +    return TRUE; +  open_err: +    ftp_close(ftp); +    return FALSE;  } -int +static int  ftp_pasv(FTP ftp)  { +    int status;      int n1, n2, n3, n4, p1, p2; -    int data_s; +    int data;      char *p;      Str tmp;      int family; @@ -199,7 +190,7 @@ ftp_pasv(FTP ftp)  #ifdef INET6      sockaddrlen = sizeof(sockaddr); -    if (getpeername(fileno(ftp->wcontrol), +    if (getpeername(fileno(ftp->wf),  		    (struct sockaddr *)&sockaddr, &sockaddrlen) < 0)  	return -1;      family = sockaddr.ss_family; @@ -209,10 +200,8 @@ ftp_pasv(FTP ftp)      switch (family) {  #ifdef INET6      case AF_INET6: -	fwrite("EPSV\r\n", 6, sizeof(char), ftp->wcontrol); -	fflush(ftp->wcontrol); -	tmp = read_response(ftp); -	if (atoi(tmp->ptr) != 229) +	ftp_command(ftp, "EPSV", NULL, &status); +	if (status != 229)  	    return -1;  	for (p = tmp->ptr + 4; *p && *p != '('; p++) ;  	if (*p == '\0') @@ -223,150 +212,43 @@ ftp_pasv(FTP ftp)  	if (getnameinfo((struct sockaddr *)&sockaddr, sockaddrlen,  			abuf, sizeof(abuf), NULL, 0, NI_NUMERICHOST) != 0)  	    return -1; -	tmp = Sprintf("%s", abuf); -	data_s = openSocket(tmp->ptr, "", port); +	data = openSocket(abuf, "", port);  	break;  #endif      case AF_INET: -	fwrite("PASV\r\n", 6, sizeof(char), ftp->wcontrol); -	fflush(ftp->wcontrol); -	tmp = read_response(ftp); -	if (atoi(tmp->ptr) != 227) +	tmp = ftp_command(ftp, "PASV", NULL, &status); +	if (status != 227)  	    return -1;  	for (p = tmp->ptr + 4; *p && !IS_DIGIT(*p); p++) ;  	if (*p == '\0')  	    return -1;  	sscanf(p, "%d,%d,%d,%d,%d,%d", &n1, &n2, &n3, &n4, &p1, &p2);  	tmp = Sprintf("%d.%d.%d.%d", n1, n2, n3, n4); -	data_s = openSocket(tmp->ptr, "", p1 * 256 + p2); +	data = openSocket(tmp->ptr, "", p1 * 256 + p2);  	break;      default:  	return -1;      } -    if (data_s < 0) +    if (data < 0)  	return -1; -    ftp->data = fdopen(data_s, "rb"); +    ftp->data = fdopen(data, "rb");      return 0;  } -static void -ftp_fclose(FTP ftp) -{ -    int control_closed = 0; - -    if (ftp->rcontrol != NULL) { -	fclose(ftp->rcontrol); -	ftp->rcontrol = NULL; -	control_closed = 1; -    } -    if (ftp->wcontrol != NULL) { -	fclose(ftp->wcontrol); -	ftp->wcontrol = NULL; -	control_closed = 1; -    } -    if (control_closed && ftp->data != NULL) { -	fclose(ftp->data); -	ftp->data = NULL; -    } -    return; -} - -int -FtpCwd(FTP ftp, char *path) -{ -    Str tmp; - -    tmp = Sprintf("CWD %s\r\n", path); -    fwrite(tmp->ptr, tmp->length, sizeof(char), ftp->wcontrol); -    fflush(ftp->wcontrol); -    tmp = read_response(ftp); -    if (tmp->ptr[0] == '5') { -	return -1; -    } -    return 0; -} - -int -FtpOpenReadBody(FTP ftp, char *path) -{ -    Str tmp; - -    tmp = Sprintf("RETR %s\r\n", path); -    fwrite(tmp->ptr, tmp->length, sizeof(char), ftp->wcontrol); -    fflush(ftp->wcontrol); -    tmp = read_response(ftp); -    if (tmp->ptr[0] == '5') { -	return -1; -    } -    return 0; -} - -int -FtpOpenRead(FTP ftp, char *path) -{ -    if (ftp_pasv(ftp) < 0) -	return -1; -    if (FtpOpenReadBody(ftp, path) < 0) { -	fclose(ftp->data); -	ftp->data = NULL; -	return -1; -    } -    return 0; -} - -int -Ftpfclose(FILE * f) -{ -    fclose(f); -    if (f == current_ftp->data) -	current_ftp->data = NULL; -    ftp_fclose(current_ftp); -    return 0; -} - -int -FtpDataBody(FTP ftp, char *cmd, char *arg, char *mode) -{ -    Str tmp; - -    tmp = Sprintf(cmd, arg); -    Strcat_charp(tmp, "\r\n"); -    fwrite(tmp->ptr, tmp->length, sizeof(char), ftp->wcontrol); -    fflush(ftp->wcontrol); -    tmp = read_response(ftp); -    if (tmp->ptr[0] == '5') { -	fclose(ftp->data); -	ftp->data = NULL; -	return -1; -    } -    return 0; -} - -int -FtpData(FTP ftp, char *cmd, char *arg, char *mode) -{ -    if (ftp_pasv(ftp) < 0) -	return -1; - -    return FtpDataBody(ftp, cmd, arg, mode); -} - -time_t -getFtpModtime(FTP ftp, char *path) +static time_t +ftp_modtime(FTP ftp, char *path)  { +    int status;      Str tmp;      char *p;      struct tm tm;      time_t t, lt, gt; -    memset(&tm, 0, sizeof(struct tm)); -    tmp = Sprintf("MDTM %s\r\n", path); -    fwrite(tmp->ptr, tmp->length, sizeof(char), ftp->wcontrol); -    fflush(ftp->wcontrol); -    tmp = read_response(ftp); -    if (atoi(tmp->ptr) != 213) +    tmp = ftp_command(ftp, "MDTM", path, &status); +    if (status != 213)  	return -1;      for (p = tmp->ptr + 4; *p && *p == ' '; p++) ; +    memset(&tm, 0, sizeof(struct tm));      if (sscanf(p, "%04d%02d%02d%02d%02d%02d",  	       &tm.tm_year, &tm.tm_mon, &tm.tm_mday,  	       &tm.tm_hour, &tm.tm_min, &tm.tm_sec) < 6) @@ -379,39 +261,22 @@ getFtpModtime(FTP ftp, char *path)      return t + (lt - gt);  } -int -FtpClose(FTP ftp) +static int +ftp_quit(FTP ftp)  { -    Str tmp; - -    fclose(ftp->data); -    ftp->data = NULL; -    tmp = read_response(ftp); -    if (atoi(tmp->ptr) != 226) +/* +    int status; +    ftp_command(ftp, "QUIT", NULL, &status); +    ftp_close(ftp); +    if (status != 221)  	return -1; +*/ +    ftp_command(ftp, "QUIT", NULL, NULL); +    ftp_close(ftp);      return 0;  } -int -FtpBye(FTP ftp) -{ -    Str tmp; -    int ret_val; - -    fwrite("QUIT\r\n", 6, sizeof(char), ftp->wcontrol); -    fflush(ftp->wcontrol); -    tmp = read_response(ftp); -    if (atoi(tmp->ptr) != 221) -	ret_val = -1; -    else -	ret_val = 0; -    ftp_fclose(ftp); -    return ret_val; -} - -  static int ex_ftpdir_name_size_date(char *, char **, char **, char **); -static int ftp_system(FTP);  #define	SERVER_NONE	0  #define	UNIXLIKE_SERVER	1 @@ -421,23 +286,39 @@ static int ftp_system(FTP);  #define	FTPDIR_LINK	2  #define	FTPDIR_FILE	3 -FILE * -openFTP(ParsedURL *pu, URLFile *uf) +static void +closeFTPdata(FILE *f)  { -    Str tmp2 = Strnew(); -    Str tmp3 = Strnew(); -    STATUS s; +    int status; +    if (f) { +	fclose(f); +	if (f == current_ftp.data) +	    current_ftp.data = NULL; +    } +    ftp_command(¤t_ftp, NULL, NULL, &status); +    /* status == 226 */ +} + +void +closeFTP(void) +{ +    ftp_close(¤t_ftp); +} + +InputStream +openFTPStream(ParsedURL *pu, URLFile *uf) +{ +    Str tmp; +    int status;      char *user = NULL;      char *pass = NULL;      Str pwd = NULL; -    int add_auth_cookie_flag; +    int add_auth_cookie_flag = FALSE;      char *realpathname = NULL; -#ifdef JP_CHARSET -    char code = '\0', ic; -    Str pathStr; -#endif -    add_auth_cookie_flag = 0; +    if (!pu->host) +	return NULL; +      if (pu->user == NULL && pu->pass == NULL) {  	Str uname, pwd;  	if (find_auth_user_passwd(pu, NULL, &uname, &pwd, 0)) { @@ -451,10 +332,23 @@ openFTP(ParsedURL *pu, URLFile *uf)  	/* do nothing */ ;      else if (pu->user)  	user = pu->user; -    else { -	Strcat_charp(tmp3, "anonymous"); -	user = tmp3->ptr; +    else +	user = "anonymous"; + +    if (current_ftp.host) { +	if (!strcmp(current_ftp.host, pu->host) && +	    current_ftp.port == pu->port && +	    !strcmp(current_ftp.user, user)) { +	    ftp_command(¤t_ftp, "NOOP", NULL, &status); +	    if (status != 200) +		ftp_close(¤t_ftp); +	    else +		goto ftp_read; +	} +	else +	    ftp_quit(¤t_ftp);      } +      if (pass)  	/* do nothing */ ;      else if (pu->pass) @@ -471,7 +365,7 @@ openFTP(ParsedURL *pu, URLFile *uf)  	    else {  		pwd = Strnew_charp((char *)getpass("Password: "));  	    } -	    add_auth_cookie_flag = 1; +	    add_auth_cookie_flag = TRUE;  	}  	pass = pwd->ptr;      } @@ -479,54 +373,41 @@ openFTP(ParsedURL *pu, URLFile *uf)  	pass = ftppasswd;      else {  	struct passwd *mypw = getpwuid(getuid()); -	if (mypw == NULL) -	    Strcat_charp(tmp2, "anonymous"); -	else -	    Strcat_charp(tmp2, mypw->pw_name); -	Strcat_char(tmp2, '@'); -	pass = tmp2->ptr; +	tmp = Strnew_charp(mypw ? mypw->pw_name : "anonymous"); +	Strcat_char(tmp, '@'); +	pass = tmp->ptr; +    } + +    if (!current_ftp.host) { +        current_ftp.host = allocStr(pu->host, -1); +        current_ftp.port = pu->port; +        current_ftp.user = allocStr(user, -1); +        current_ftp.pass = allocStr(pass, -1); +        if (!ftp_login(¤t_ftp)) +	    return NULL;      } -    s = FtpLogin(¤t_ftp, pu->host, user, pass); -    if (FtpError(s)) -	return NULL;      if (add_auth_cookie_flag)  	add_auth_cookie(pu->host, pu->port, pu->file, pu->user, pwd); + +  ftp_read: +    ftp_command(¤t_ftp, "TYPE", "I", &status); +    if (ftp_pasv(¤t_ftp) < 0) { +	ftp_quit(¤t_ftp); +	return NULL; +    }      if (pu->file == NULL || *pu->file == '\0')  	goto ftp_dir;      else  	realpathname = file_unquote(pu->file); -      if (pu->file[strlen(pu->file) - 1] == '/')  	goto ftp_dir; -      /* Get file */ -    uf->modtime = getFtpModtime(current_ftp, realpathname); -    FtpBinary(current_ftp); -    if (ftp_pasv(current_ftp) < 0) { -	FtpBye(current_ftp); -	return NULL; -    } -    s = FtpOpenReadBody(current_ftp, realpathname); -    if (!FtpError(s)) { -#ifdef JP_CHARSET -	pathStr = Strnew_charp(realpathname); -	if ((ic = checkShiftCode(pathStr, code)) != '\0') { -	    pathStr = conv_str(pathStr, (code = ic), InnerCode); -	    realpathname = pathStr->ptr; -	} -#endif				/* JP_CHARSET */ -	pu->file = realpathname; -	return FTPDATA(current_ftp); -    } -    goto ftp_dir1; +    uf->modtime = ftp_modtime(¤t_ftp, realpathname); +    ftp_command(¤t_ftp, "RETR", realpathname, &status); +    if (status == 125 || status == 150) +	return newFileStream(current_ftp.data, (void (*)())closeFTPdata); -    /* Get directory */    ftp_dir: -    if (ftp_pasv(current_ftp) < 0) { -	FtpBye(current_ftp); -	return NULL; -    } -  ftp_dir1:      pu->scheme = SCM_FTPDIR;      return NULL;  } @@ -534,80 +415,55 @@ openFTP(ParsedURL *pu, URLFile *uf)  Str  readFTPDir(ParsedURL *pu)  { -    Str FTPDIRtmp = Strnew(); -    Str host; -    Str curdir; -    char *fn; -    char *qdir; +    Str FTPDIRtmp; +    Str tmp; +    int status, sv_type; +    char *realpathname, *fn;      char **flist;      int i, nfile, nfile_max = 100; -    int sv_type; -    STATUS s; -    char *realpathname = NULL; -    Str tmp2 = Strnew(); -    if (current_ftp->data == NULL) -	return FTPDIRtmp; -    sv_type = ftp_system(current_ftp); +    if (current_ftp.data == NULL) +	return NULL; +    tmp = ftp_command(¤t_ftp, "SYST", NULL, &status); +    if (strstr(tmp->ptr, "UNIX") != NULL || +	!strncmp(tmp->ptr + 4, "Windows_NT", 10))	/* :-) */ +	sv_type = UNIXLIKE_SERVER; +    else +	sv_type = SERVER_NONE;      if (pu->file == NULL || *pu->file == '\0') { -	if (sv_type == UNIXLIKE_SERVER) { -	    s = FtpDataBody(current_ftp, "LIST", NULL, "r"); -	} -	else { -	    s = FtpDataBody(current_ftp, "NLST", NULL, "r"); -	} -	curdir = Strnew_charp("/"); +	if (sv_type == UNIXLIKE_SERVER) +	    ftp_command(¤t_ftp, "LIST", NULL, &status); +	else +	    ftp_command(¤t_ftp, "NLST", NULL, &status); +	pu->file = "/";      }      else { -	realpathname = file_unquote(pu->file); +	char *realpathname = file_unquote(pu->file);  	if (sv_type == UNIXLIKE_SERVER) { -	    s = FtpCwd(current_ftp, realpathname); -	    if (!FtpError(s)) { -		s = FtpDataBody(current_ftp, "LIST", NULL, "r"); -	    } -	} -	else { -	    s = FtpDataBody(current_ftp, "NLST %s", realpathname, "r"); +	    ftp_command(¤t_ftp, "CWD", realpathname, &status); +	    if (status == 250) +		ftp_command(¤t_ftp, "LIST", NULL, &status);  	} -	if (realpathname[0] == '/') -	    curdir = Strnew_charp(realpathname);  	else -	    curdir = Sprintf("/%s", realpathname); -	if (Strlastchar(curdir) != '/') -	    Strcat_char(curdir, '/'); +	    ftp_command(¤t_ftp, "NLST", realpathname, &status);      } -    if (FtpError(s)) { -	FtpBye(current_ftp); +    if (status != 125 && status != 150) { +	fclose(current_ftp.data); +	current_ftp.data = NULL;  	return NULL;      } -    host = Strnew_charp("ftp://"); -    if (pu->user) { -	Strcat_m_charp(host, pu->user, "@", NULL); -    } -    Strcat_charp(host, pu->host); -    if (Strlastchar(host) == '/') -	Strshrink(host, 1); -    qdir = html_quote(curdir->ptr); -    FTPDIRtmp = -	Sprintf -	("<html><head><title>%s%s</title></head><body><h1>Index of %s%s</h1>\n", -	 host->ptr, qdir, host->ptr, qdir); -    curdir = Strnew_charp(file_quote(curdir->ptr)); -    qdir = curdir->ptr; -    tmp2 = Strdup(curdir); -    if (Strcmp_charp(curdir, "/") != 0) { -	Strshrink(tmp2, 1); -	while (Strlastchar(tmp2) != '/' && tmp2->length > 0) -	    Strshrink(tmp2, 1); -    } -    if (sv_type == UNIXLIKE_SERVER) { -	Strcat_charp(FTPDIRtmp, "<pre><a href=\""); -    } -    else { -	Strcat_charp(FTPDIRtmp, "<ul><li><a href=\""); -    } -    Strcat_m_charp(FTPDIRtmp, host->ptr, -		   html_quote(tmp2->ptr), "\">[Upper Directory]</a>\n", NULL); +    tmp = parsedURL2Str(pu); +    if (Strlastchar(tmp) != '/') +	Strcat_char(tmp, '/'); +    fn = html_quote(tmp->ptr); +    FTPDIRtmp = Strnew_m_charp("<html><head><title>", fn, +			       "</title></head><body><h1>Index of ", fn, +			       "</h1>\n", NULL); +    if (sv_type == UNIXLIKE_SERVER) +	Strcat_charp(FTPDIRtmp, "<pre>"); +    else +	Strcat_charp(FTPDIRtmp, "<ul><li>"); +    Strcat_charp(FTPDIRtmp, "<a href=\"..\">[Upper Directory]</a>\n");      flist = New_N(char *, nfile_max);      nfile = 0; @@ -617,16 +473,13 @@ readFTPDir(ParsedURL *pu)  	Str line_tmp;  	max_len = 0; -	while (tmp2 = Strfgets(FTPDATA(current_ftp)), tmp2->length > 0) { -	    Strchop(tmp2); -	    if ((ftype = -		 ex_ftpdir_name_size_date(tmp2->ptr, &name, &date, &size)) -		== FTPDIR_NONE) { +	while (tmp = Strfgets(current_ftp.data), tmp->length > 0) { +	    Strchop(tmp); +	    if ((ftype = ex_ftpdir_name_size_date(tmp->ptr, &name, &date, +						  &size)) == FTPDIR_NONE)  		continue; -	    } -	    if (!strcmp(".", name) || !strcmp("..", name)) { +	    if (!strcmp(".", name) || !strcmp("..", name))  		continue; -	    }  	    len = strlen(name);  	    if (!len)  		continue; @@ -657,7 +510,7 @@ readFTPDir(ParsedURL *pu)  	    date = fn + strlen(fn) - 20;  	    if (*(date - 1) == '/') {  		ftype = FTPDIR_DIR; -		*(date - 1) = '\0'; +		*date = '\0';  	    }  	    else if (*(date - 1) == '@') {  		ftype = FTPDIR_LINK; @@ -669,16 +522,9 @@ readFTPDir(ParsedURL *pu)  	    }  	    date++;  	    len = strlen(fn); -	    Strcat_m_charp(FTPDIRtmp, "<a href=\"", -			   host->ptr, -			   qdir, -			   html_quote(file_quote(fn)), +	    Strcat_m_charp(FTPDIRtmp, "<a href=\"", html_quote(file_quote(fn)),  			   "\">", html_quote(fn), NULL); -	    if (ftype == FTPDIR_DIR) { -		Strcat_charp(FTPDIRtmp, "/"); -		len++; -	    } -	    else if (ftype == FTPDIR_LINK) { +	    if (ftype == FTPDIR_LINK) {  		Strcat_charp(FTPDIRtmp, "@");  		len++;  	    } @@ -696,9 +542,9 @@ readFTPDir(ParsedURL *pu)  	Strcat_charp(FTPDIRtmp, "</pre></body></html>\n");      }      else { -	while (tmp2 = Strfgets(FTPDATA(current_ftp)), tmp2->length > 0) { -	    Strchop(tmp2); -	    flist[nfile++] = mybasename(tmp2->ptr); +	while (tmp = Strfgets(current_ftp.data), tmp->length > 0) { +	    Strchop(tmp); +	    flist[nfile++] = mybasename(tmp->ptr);  	    if (nfile == nfile_max) {  		nfile_max *= 2;  		flist = New_Reuse(char *, flist, nfile_max); @@ -708,32 +554,19 @@ readFTPDir(ParsedURL *pu)  	for (i = 0; i < nfile; i++) {  	    fn = flist[i];  	    Strcat_m_charp(FTPDIRtmp, "<li><a href=\"", -			   host->ptr, qdir, -			   html_quote(file_quote(fn)), -			   "\">", html_quote(fn), "</a>\n", NULL); +			   html_quote(file_quote(fn)), "\">", html_quote(fn), +			   "</a>\n", NULL);  	}  	Strcat_charp(FTPDIRtmp, "</ul></body></html>\n");      } - -    FtpClose(current_ftp); -    FtpBye(current_ftp); +    closeFTPdata(current_ftp.data);      return FTPDIRtmp;  } -static int -ftp_system(FTP ftp) +void +disconnectFTP(void)  { -    int sv_type = SERVER_NONE; -    Str tmp; - -    fwrite("SYST\r\n", 6, sizeof(char), ftp->wcontrol); -    fflush(ftp->wcontrol); -    tmp = read_response(ftp); -    if (strstr(tmp->ptr, "UNIX") != NULL || !strncmp(tmp->ptr + 4, "Windows_NT", 10)) {	/* :-) */ -	sv_type = UNIXLIKE_SERVER; -    } - -    return (sv_type); +    ftp_quit(¤t_ftp);  }  #define XD_CTOD(c) {\ @@ -896,14 +729,3 @@ size_int2str(clen_t size)      return (size_str);  } - -void -closeFTP(FILE * f) -{ -    if (f) { -	fclose(f); -	if (f == current_ftp->data) -	    current_ftp->data = NULL; -    } -    FtpBye(current_ftp); -} @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.189 2003/01/10 16:42:52 ukai Exp $ */ +/* $Id: main.c,v 1.190 2003/01/11 15:54:09 ukai Exp $ */  #define MAINPROGRAM  #include "fm.h"  #include <signal.h> @@ -5473,6 +5473,7 @@ w3m_exit(int i)  #ifdef USE_SSL      free_ssl_ctx();  #endif +    disconnectFTP();  #ifdef USE_NNTP      disconnectNews();  #endif @@ -1,4 +1,4 @@ -/* $Id: proto.h,v 1.76 2003/01/06 15:37:00 ukai Exp $ */ +/* $Id: proto.h,v 1.77 2003/01/11 15:54:09 ukai Exp $ */  /*    *   This file was automatically generated by version 1.7 of cextract.   *   Manual editing not recommended. @@ -233,10 +233,10 @@ 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, int download); +extern int _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 doFileMove(char *tmpf, char *defstr); +extern int doFileSave(URLFile uf, char *defstr);  extern int checkCopyFile(char *path1, char *path2);  extern int checkSaveFile(InputStream stream, char *path);  extern int checkOverWrite(char *path); @@ -505,10 +505,10 @@ extern Str unquote_mailcap(char *qstr, char *type, char *name, char *attr,  extern char *guessContentType(char *filename);  extern TextList *make_domain_list(char *domain_list);  extern int check_no_proxy(char *domain); -extern FILE *openFTP(ParsedURL *pu, URLFile *uf); +extern InputStream openFTPStream(ParsedURL *pu, URLFile *uf);  extern Str readFTPDir(ParsedURL *pu); -extern void closeFTP(FILE * f); -extern int Ftpfclose(FILE * f); +extern void closeFTP(void); +extern void disconnectFTP(void);  #ifdef USE_NNTP  extern InputStream openNewsStream(ParsedURL *pu);  extern Str readNewsgroup(ParsedURL *pu); @@ -1,4 +1,4 @@ -/* $Id: url.c,v 1.67 2003/01/10 16:29:28 ukai Exp $ */ +/* $Id: url.c,v 1.68 2003/01/11 15:54:09 ukai Exp $ */  #include "fm.h"  #include <sys/types.h>  #include <sys/socket.h> @@ -1474,12 +1474,6 @@ init_stream(URLFile *uf, int scheme, InputStream stream)      uf->modtime = -1;  } -static InputStream -openFTPStream(ParsedURL *pu, URLFile *uf) -{ -    return newFileStream(openFTP(pu, uf), closeFTP); -} -  URLFile  openURL(char *url, ParsedURL *pu, ParsedURL *current,  	URLOption *option, FormList *request, TextList *extra_header, | 
