commit feb432e5a10fd985f65687a578666c6fcfb611e0
parent 88623d6c754c54dcd573d6e7369835cc959a60e8
Author: ukai <ukai>
Date: Sat, 11 Jan 2003 15:54:08 +0000
[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
From: Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
Diffstat:
M | ChangeLog | | | 19 | +++++++++++++++++++ |
M | file.c | | | 74 | +++++++++++++++++++++++++++++++++++--------------------------------------- |
M | ftp.c | | | 664 | +++++++++++++++++++++++++++++-------------------------------------------------- |
M | main.c | | | 1 | + |
M | proto.h | | | 12 | ++++++------ |
M | url.c | | | 6 | ------ |
6 files changed, 304 insertions(+), 472 deletions(-)
diff --git a/ChangeLog b/ChangeLog
@@ -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
diff --git a/file.c b/file.c
@@ -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
diff --git a/ftp.c b/ftp.c
@@ -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);
-}
diff --git a/main.c b/main.c
@@ -5473,6 +5473,7 @@ w3m_exit(int i)
#ifdef USE_SSL
free_ssl_ctx();
#endif
+ disconnectFTP();
#ifdef USE_NNTP
disconnectNews();
#endif
diff --git a/proto.h b/proto.h
@@ -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);
diff --git a/url.c b/url.c
@@ -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,