[w3m-dev 03784] ftp directory support
* ftp.c (AbortLoading): added (KeyAbort): added (openFTPStream): remove '~' in realpathname? (loadFTPDir): remove '~' in realpathname? keyabort new ex_ftpdir_name_size_date() add symlink information to flist (XD_CTOD): deleted (EX_COUNT_DIGIT): added (ex_ftpdir_name_size_date): add **link accept device file loose date check for localized server From: Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
This commit is contained in:
@@ -1,3 +1,19 @@
|
|||||||
|
2003-02-27 Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
|
||||||
|
|
||||||
|
* [w3m-dev 03784] ftp directory support
|
||||||
|
* ftp.c (AbortLoading): added
|
||||||
|
(KeyAbort): added
|
||||||
|
(openFTPStream): remove '~' in realpathname?
|
||||||
|
(loadFTPDir): remove '~' in realpathname?
|
||||||
|
keyabort
|
||||||
|
new ex_ftpdir_name_size_date()
|
||||||
|
add symlink information to flist
|
||||||
|
(XD_CTOD): deleted
|
||||||
|
(EX_COUNT_DIGIT): added
|
||||||
|
(ex_ftpdir_name_size_date): add **link
|
||||||
|
accept device file
|
||||||
|
loose date check for localized server
|
||||||
|
|
||||||
2003-02-27 Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
|
2003-02-27 Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
|
||||||
|
|
||||||
* [w3m-dev 03783] pipe to "command1 | command2"
|
* [w3m-dev 03783] pipe to "command1 | command2"
|
||||||
@@ -7271,4 +7287,4 @@ a * [w3m-dev 03276] compile error on EWS4800
|
|||||||
* release-0-2-1
|
* release-0-2-1
|
||||||
* import w3m-0.2.1
|
* import w3m-0.2.1
|
||||||
|
|
||||||
$Id: ChangeLog,v 1.767 2003/02/26 17:22:01 ukai Exp $
|
$Id: ChangeLog,v 1.768 2003/02/26 17:37:58 ukai Exp $
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $Id: ftp.c,v 1.27 2003/02/20 15:39:21 ukai Exp $ */
|
/* $Id: ftp.c,v 1.28 2003/02/26 17:38:00 ukai Exp $ */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <Str.h>
|
#include <Str.h>
|
||||||
@@ -35,6 +35,15 @@ static struct _FTP current_ftp = {
|
|||||||
NULL, 0, NULL, NULL, NULL, NULL, NULL
|
NULL, 0, NULL, NULL, NULL, NULL, NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static JMP_BUF AbortLoading;
|
||||||
|
|
||||||
|
static MySignalHandler
|
||||||
|
KeyAbort(SIGNAL_ARG)
|
||||||
|
{
|
||||||
|
LONGJMP(AbortLoading, 1);
|
||||||
|
SIGNAL_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
static Str
|
static Str
|
||||||
ftp_command(FTP ftp, char *cmd, char *arg, int *status)
|
ftp_command(FTP ftp, char *cmd, char *arg, int *status)
|
||||||
{
|
{
|
||||||
@@ -274,7 +283,7 @@ ftp_quit(FTP ftp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ex_ftpdir_name_size_date(char *, char **, char **, char **);
|
static int ex_ftpdir_name_size_date(char *, char **, char **, char **, char **);
|
||||||
|
|
||||||
#define SERVER_NONE 0
|
#define SERVER_NONE 0
|
||||||
#define UNIXLIKE_SERVER 1
|
#define UNIXLIKE_SERVER 1
|
||||||
@@ -392,12 +401,13 @@ openFTPStream(ParsedURL *pu, URLFile *uf)
|
|||||||
ftp_quit(¤t_ftp);
|
ftp_quit(¤t_ftp);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (pu->file == NULL || *pu->file == '\0')
|
if (pu->file == NULL || *pu->file == '\0' ||
|
||||||
goto ftp_dir;
|
pu->file[strlen(pu->file) - 1] == '/')
|
||||||
else
|
|
||||||
realpathname = file_unquote(pu->file);
|
|
||||||
if (pu->file[strlen(pu->file) - 1] == '/')
|
|
||||||
goto ftp_dir;
|
goto ftp_dir;
|
||||||
|
|
||||||
|
realpathname = file_unquote(pu->file);
|
||||||
|
if (*realpathname == '/' && *(realpathname + 1) == '~')
|
||||||
|
realpathname++;
|
||||||
/* Get file */
|
/* Get file */
|
||||||
uf->modtime = ftp_modtime(¤t_ftp, realpathname);
|
uf->modtime = ftp_modtime(¤t_ftp, realpathname);
|
||||||
ftp_command(¤t_ftp, "RETR", realpathname, &status);
|
ftp_command(¤t_ftp, "RETR", realpathname, &status);
|
||||||
@@ -414,10 +424,12 @@ loadFTPDir(ParsedURL *pu, char *code)
|
|||||||
{
|
{
|
||||||
Str FTPDIRtmp;
|
Str FTPDIRtmp;
|
||||||
Str tmp;
|
Str tmp;
|
||||||
int status, sv_type;
|
int status;
|
||||||
|
volatile int sv_type;
|
||||||
char *realpathname, *fn, *q;
|
char *realpathname, *fn, *q;
|
||||||
char **flist;
|
char **flist;
|
||||||
int i, nfile, nfile_max = 100;
|
int i, nfile, nfile_max;
|
||||||
|
MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL;
|
||||||
|
|
||||||
#ifdef JP_CHARSET
|
#ifdef JP_CHARSET
|
||||||
*code = DocumentCode;
|
*code = DocumentCode;
|
||||||
@@ -438,6 +450,8 @@ loadFTPDir(ParsedURL *pu, char *code)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
realpathname = file_unquote(pu->file);
|
realpathname = file_unquote(pu->file);
|
||||||
|
if (*realpathname == '/' && *(realpathname + 1) == '~')
|
||||||
|
realpathname++;
|
||||||
if (sv_type == UNIXLIKE_SERVER) {
|
if (sv_type == UNIXLIKE_SERVER) {
|
||||||
ftp_command(¤t_ftp, "CWD", realpathname, &status);
|
ftp_command(¤t_ftp, "CWD", realpathname, &status);
|
||||||
if (status == 250)
|
if (status == 250)
|
||||||
@@ -463,23 +477,34 @@ loadFTPDir(ParsedURL *pu, char *code)
|
|||||||
"\">\n<title>", q,
|
"\">\n<title>", q,
|
||||||
"</title>\n</head>\n<body>\n<h1>Index of ", q,
|
"</title>\n</head>\n<body>\n<h1>Index of ", q,
|
||||||
"</h1>\n", NULL);
|
"</h1>\n", NULL);
|
||||||
|
|
||||||
|
if (SETJMP(AbortLoading) != 0) {
|
||||||
|
if (sv_type == UNIXLIKE_SERVER)
|
||||||
|
Strcat_charp(FTPDIRtmp, "</a></pre>\n");
|
||||||
|
else
|
||||||
|
Strcat_charp(FTPDIRtmp, "</a></ul>\n");
|
||||||
|
Strcat_charp(FTPDIRtmp, "<p>Transfer Interrupted!\n");
|
||||||
|
goto ftp_end;
|
||||||
|
}
|
||||||
|
TRAP_ON;
|
||||||
|
|
||||||
if (sv_type == UNIXLIKE_SERVER)
|
if (sv_type == UNIXLIKE_SERVER)
|
||||||
Strcat_charp(FTPDIRtmp, "<pre>\n");
|
Strcat_charp(FTPDIRtmp, "<pre>\n");
|
||||||
else
|
else
|
||||||
Strcat_charp(FTPDIRtmp, "<ul>\n<li>");
|
Strcat_charp(FTPDIRtmp, "<ul>\n<li>");
|
||||||
Strcat_charp(FTPDIRtmp, "<a href=\"..\">[Upper Directory]</a>\n");
|
Strcat_charp(FTPDIRtmp, "<a href=\"..\">[Upper Directory]</a>\n");
|
||||||
|
|
||||||
|
nfile_max = 100;
|
||||||
flist = New_N(char *, nfile_max);
|
flist = New_N(char *, nfile_max);
|
||||||
nfile = 0;
|
nfile = 0;
|
||||||
if (sv_type == UNIXLIKE_SERVER) {
|
if (sv_type == UNIXLIKE_SERVER) {
|
||||||
char *name, *date, *size, *type_str;
|
char *name, *link, *date, *size, *type_str;
|
||||||
int ftype, max_len, len, j;
|
int ftype, max_len, len, j;
|
||||||
Str line_tmp;
|
|
||||||
|
|
||||||
max_len = 0;
|
max_len = 20;
|
||||||
while (tmp = Strfgets(current_ftp.data), tmp->length > 0) {
|
while (tmp = Strfgets(current_ftp.data), tmp->length > 0) {
|
||||||
Strchop(tmp);
|
Strchop(tmp);
|
||||||
if ((ftype = ex_ftpdir_name_size_date(tmp->ptr, &name, &date,
|
if ((ftype = ex_ftpdir_name_size_date(tmp->ptr, &name, &link, &date,
|
||||||
&size)) == FTPDIR_NONE)
|
&size)) == FTPDIR_NONE)
|
||||||
continue;
|
continue;
|
||||||
if (!strcmp(".", name) || !strcmp("..", name))
|
if (!strcmp(".", name) || !strcmp("..", name))
|
||||||
@@ -496,13 +521,12 @@ loadFTPDir(ParsedURL *pu, char *code)
|
|||||||
type_str = "@";
|
type_str = "@";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
type_str = "";
|
type_str = " ";
|
||||||
}
|
}
|
||||||
if (max_len < len)
|
if (max_len < len)
|
||||||
max_len = len;
|
max_len = len;
|
||||||
line_tmp =
|
flist[nfile++] = Sprintf("%s%s\n%s %5s%s", name, type_str, date,
|
||||||
Sprintf("%s%s %-12.12s %6.6s", name, type_str, date, size);
|
size, link)->ptr;
|
||||||
flist[nfile++] = line_tmp->ptr;
|
|
||||||
if (nfile == nfile_max) {
|
if (nfile == nfile_max) {
|
||||||
nfile_max *= 2;
|
nfile_max *= 2;
|
||||||
flist = New_Reuse(char *, flist, nfile_max);
|
flist = New_Reuse(char *, flist, nfile_max);
|
||||||
@@ -511,7 +535,7 @@ loadFTPDir(ParsedURL *pu, char *code)
|
|||||||
qsort(flist, nfile, sizeof(char *), strCmp);
|
qsort(flist, nfile, sizeof(char *), strCmp);
|
||||||
for (j = 0; j < nfile; j++) {
|
for (j = 0; j < nfile; j++) {
|
||||||
fn = flist[j];
|
fn = flist[j];
|
||||||
date = fn + strlen(fn) - 20;
|
date = strchr(fn, '\n');
|
||||||
if (*(date - 1) == '/') {
|
if (*(date - 1) == '/') {
|
||||||
ftype = FTPDIR_DIR;
|
ftype = FTPDIR_DIR;
|
||||||
*date = '\0';
|
*date = '\0';
|
||||||
@@ -522,27 +546,22 @@ loadFTPDir(ParsedURL *pu, char *code)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ftype = FTPDIR_FILE;
|
ftype = FTPDIR_FILE;
|
||||||
*date = '\0';
|
*(date - 1) = '\0';
|
||||||
}
|
}
|
||||||
date++;
|
date++;
|
||||||
len = strlen(fn);
|
|
||||||
tmp = convertLine(NULL, Strnew_charp(fn), code, RAW_MODE);
|
tmp = convertLine(NULL, Strnew_charp(fn), code, RAW_MODE);
|
||||||
|
if (ftype == FTPDIR_LINK)
|
||||||
|
Strcat_char(tmp, '@');
|
||||||
Strcat_m_charp(FTPDIRtmp, "<a href=\"", html_quote(file_quote(fn)),
|
Strcat_m_charp(FTPDIRtmp, "<a href=\"", html_quote(file_quote(fn)),
|
||||||
"\">", html_quote(tmp->ptr), NULL);
|
"\">", html_quote(tmp->ptr), "</a>", NULL);
|
||||||
if (ftype == FTPDIR_LINK) {
|
for (i = tmp->length; i <= max_len; i++) {
|
||||||
Strcat_charp(FTPDIRtmp, "@");
|
if ((max_len % 2 + i) % 2)
|
||||||
len++;
|
Strcat_char(FTPDIRtmp, '.');
|
||||||
|
else
|
||||||
|
Strcat_char(FTPDIRtmp, ' ');
|
||||||
}
|
}
|
||||||
Strcat_charp(FTPDIRtmp, "</a>");
|
tmp = convertLine(NULL, Strnew_charp(date), code, RAW_MODE);
|
||||||
for (i = len; i <= max_len; i++) {
|
Strcat_m_charp(FTPDIRtmp, html_quote(tmp->ptr), "\n", NULL);
|
||||||
if ((max_len % 2 + i) % 2) {
|
|
||||||
Strcat_charp(FTPDIRtmp, ".");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Strcat_charp(FTPDIRtmp, " ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Strcat_m_charp(FTPDIRtmp, date, "\n", NULL);
|
|
||||||
}
|
}
|
||||||
Strcat_charp(FTPDIRtmp, "</pre>\n");
|
Strcat_charp(FTPDIRtmp, "</pre>\n");
|
||||||
}
|
}
|
||||||
@@ -565,8 +584,10 @@ loadFTPDir(ParsedURL *pu, char *code)
|
|||||||
}
|
}
|
||||||
Strcat_charp(FTPDIRtmp, "</ul>\n");
|
Strcat_charp(FTPDIRtmp, "</ul>\n");
|
||||||
}
|
}
|
||||||
Strcat_charp(FTPDIRtmp, "</body>\n</html>\n");
|
|
||||||
|
|
||||||
|
ftp_end:
|
||||||
|
Strcat_charp(FTPDIRtmp, "</body>\n</html>\n");
|
||||||
|
TRAP_OFF;
|
||||||
closeFTPdata(current_ftp.data);
|
closeFTPdata(current_ftp.data);
|
||||||
return FTPDIRtmp;
|
return FTPDIRtmp;
|
||||||
}
|
}
|
||||||
@@ -577,119 +598,107 @@ disconnectFTP(void)
|
|||||||
ftp_quit(¤t_ftp);
|
ftp_quit(¤t_ftp);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define XD_CTOD(c) {\
|
|
||||||
if (c >= '0' && c <= '9') {\
|
|
||||||
c -= (unsigned char)'0';\
|
|
||||||
} else if (c >= 'a' && c <= 'f') {\
|
|
||||||
c = c - (unsigned char)'a' + (unsigned char)10;\
|
|
||||||
} else if (c >= 'A' && c <= 'F') {\
|
|
||||||
c = c - (unsigned char)'A' + (unsigned char)10;\
|
|
||||||
} else {\
|
|
||||||
goto skip;\
|
|
||||||
}\
|
|
||||||
}
|
|
||||||
|
|
||||||
#define EX_SKIP_SPACE(cp) {\
|
#define EX_SKIP_SPACE(cp) {\
|
||||||
while (IS_SPACE(*cp) && *cp != '\0') cp++;\
|
while (IS_SPACE(*cp) && *cp != '\0') cp++;\
|
||||||
if (*cp == '\0') {\
|
if (*cp == '\0')\
|
||||||
goto done;\
|
goto done;\
|
||||||
}\
|
|
||||||
}
|
}
|
||||||
#define EX_SKIP_NONE_SPACE(cp) {\
|
#define EX_SKIP_NONE_SPACE(cp) {\
|
||||||
while (!IS_SPACE(*cp) && *cp != '\0') cp++;\
|
while (!IS_SPACE(*cp) && *cp != '\0') cp++;\
|
||||||
if (*cp == '\0') {\
|
if (*cp == '\0')\
|
||||||
goto done;\
|
goto done;\
|
||||||
}\
|
}
|
||||||
|
#define EX_COUNT_DIGIT(cp) {\
|
||||||
|
size = 0;\
|
||||||
|
while (*cp && IS_DIGIT(*cp))\
|
||||||
|
size = size * 10 + *(cp++) - '0';\
|
||||||
|
if (*cp == '\0')\
|
||||||
|
goto done;\
|
||||||
}
|
}
|
||||||
|
|
||||||
static Str size_int2str(clen_t);
|
static Str size_int2str(clen_t);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ex_ftpdir_name_size_date(char *line, char **name, char **date, char **sizep)
|
ex_ftpdir_name_size_date(char *line, char **name, char **link, char **date,
|
||||||
|
char **sizep)
|
||||||
{
|
{
|
||||||
int ftype = FTPDIR_NONE;
|
int ftype = FTPDIR_NONE;
|
||||||
char *cp, *endp;
|
char *cp = line, *p;
|
||||||
Str date_str, name_str, size_str;
|
|
||||||
clen_t size;
|
clen_t size;
|
||||||
|
|
||||||
if (strlen(line) < 11) {
|
if (strlen(cp) < 11)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
|
||||||
/* skip permission */
|
/* skip permission */
|
||||||
if (!IS_SPACE(line[10])) {
|
cp += 10;
|
||||||
|
if (!IS_SPACE(*cp))
|
||||||
goto done;
|
goto done;
|
||||||
}
|
cp++;
|
||||||
cp = line + 11;
|
|
||||||
|
|
||||||
/* skip link count */
|
/* skip link count */
|
||||||
EX_SKIP_SPACE(cp)
|
EX_SKIP_SPACE(cp);
|
||||||
while (IS_DIGIT(*cp) && *cp != '\0')
|
EX_COUNT_DIGIT(cp);
|
||||||
cp++;
|
|
||||||
if (!IS_SPACE(*cp) || *cp == '\0') {
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
cp++;
|
cp++;
|
||||||
|
|
||||||
/* skip owner string */
|
/* skip owner string */
|
||||||
EX_SKIP_SPACE(cp)
|
EX_SKIP_SPACE(cp);
|
||||||
EX_SKIP_NONE_SPACE(cp)
|
EX_SKIP_NONE_SPACE(cp);
|
||||||
cp++;
|
cp++;
|
||||||
|
|
||||||
/* skip group string */
|
/* skip group string */
|
||||||
EX_SKIP_SPACE(cp)
|
EX_SKIP_SPACE(cp);
|
||||||
EX_SKIP_NONE_SPACE(cp)
|
EX_SKIP_NONE_SPACE(cp);
|
||||||
cp++;
|
cp++;
|
||||||
|
|
||||||
/* extract size */
|
/* extract size */
|
||||||
EX_SKIP_SPACE(cp)
|
EX_SKIP_SPACE(cp);
|
||||||
size = 0;
|
p = cp;
|
||||||
while (*cp && IS_DIGIT(*cp)) {
|
EX_COUNT_DIGIT(cp);
|
||||||
size = size * 10 + *(cp++) - '0';
|
if (*cp == ',') { /* device file ? */
|
||||||
|
cp++;
|
||||||
|
EX_SKIP_SPACE(cp);
|
||||||
|
EX_SKIP_NONE_SPACE(cp);
|
||||||
|
*sizep = allocStr(p, cp - p);
|
||||||
}
|
}
|
||||||
if (*cp == '\0') {
|
else {
|
||||||
goto done;
|
*sizep = size_int2str(size)->ptr;
|
||||||
}
|
}
|
||||||
|
cp++;
|
||||||
|
|
||||||
/* extract date */
|
/* extract date */
|
||||||
EX_SKIP_SPACE(cp)
|
/* loose check for i18n server */
|
||||||
if (IS_ALPHA(cp[0]) && IS_ALPHA(cp[1]) && IS_ALPHA(cp[2])
|
p = cp;
|
||||||
&& IS_SPACE(cp[3])
|
EX_SKIP_SPACE(cp);
|
||||||
&& (IS_SPACE(cp[4]) || IS_DIGIT(cp[4])) && IS_DIGIT(cp[5])
|
EX_SKIP_NONE_SPACE(cp); /* month ? */
|
||||||
&& IS_SPACE(cp[6])
|
EX_SKIP_SPACE(cp);
|
||||||
&& (IS_SPACE(cp[7]) || IS_DIGIT(cp[7])) && IS_DIGIT(cp[8])
|
EX_SKIP_NONE_SPACE(cp); /* day ? */
|
||||||
&& (cp[9] == ':' || IS_DIGIT(cp[9]))
|
EX_SKIP_SPACE(cp);
|
||||||
&& IS_DIGIT(cp[10]) && (IS_DIGIT(cp[11]) || IS_SPACE(cp[11]))
|
EX_SKIP_NONE_SPACE(cp); /* year or time ? */
|
||||||
&& IS_SPACE(cp[12])) {
|
*date = allocStr(p, cp - p);
|
||||||
cp[12] = '\0';
|
cp++;
|
||||||
date_str = Strnew_charp(cp);
|
|
||||||
cp += 13;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* extract file name */
|
/* extract file name */
|
||||||
EX_SKIP_SPACE(cp)
|
EX_SKIP_SPACE(cp);
|
||||||
if (line[0] == 'l') {
|
switch (line[0]) {
|
||||||
if ((endp = strstr(cp, " -> ")) == NULL) {
|
case 'l':
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
*endp = '\0';
|
|
||||||
size_str = Strnew_charp("-");
|
|
||||||
ftype = FTPDIR_LINK;
|
ftype = FTPDIR_LINK;
|
||||||
}
|
if ((p = strstr(cp, " -> ")) == NULL)
|
||||||
else if (line[0] == 'd') {
|
goto done;
|
||||||
size_str = Strnew_charp("-");
|
*name = allocStr(cp, p - cp);
|
||||||
|
*link = allocStr(p, - 1);
|
||||||
|
*sizep = "";
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
ftype = FTPDIR_DIR;
|
ftype = FTPDIR_DIR;
|
||||||
}
|
*name = allocStr(cp, -1);
|
||||||
else {
|
*link = "";
|
||||||
size_str = size_int2str(size);
|
*sizep = "";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
ftype = FTPDIR_FILE;
|
ftype = FTPDIR_FILE;
|
||||||
|
*name = allocStr(cp, -1);
|
||||||
|
*link = "";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
name_str = Strnew_charp(cp);
|
|
||||||
*date = date_str->ptr;
|
|
||||||
*name = name_str->ptr;
|
|
||||||
*sizep = size_str->ptr;
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
return (ftype);
|
return (ftype);
|
||||||
|
|||||||
Reference in New Issue
Block a user