add mtime support to ftpparse
This commit is contained in:
parent
267f5a2964
commit
7c3da640e1
@ -104,6 +104,43 @@ int proz_download_setup_connections_no_ftpsearch(download_t * download,
|
||||
download->pconnections = kmalloc(sizeof(connection_t *) * num_connections);
|
||||
download->num_connections = num_connections;
|
||||
|
||||
// Compare file size and modification time
|
||||
char * final_file = kmalloc(PATH_MAX);
|
||||
struct stat final_stat_buf;
|
||||
snprintf(final_file, PATH_MAX, "%s/%s", download->dl_dir, connection->u.file);
|
||||
proz_debug("final file %s", final_file);
|
||||
if (stat(final_file, &final_stat_buf) == -1)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
proz_debug("final file does not exist, perfect!");
|
||||
else
|
||||
{
|
||||
proz_debug("something else happened %d", errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else // there is such file, compare size and mdate
|
||||
{
|
||||
proz_debug("final file exists, check size and mdate");
|
||||
proz_debug("local file is %lld byte, last mod at %s",
|
||||
final_stat_buf.st_size, ctime(&(final_stat_buf.st_mtime)));
|
||||
proz_debug("remotefile is %lld byte, last mod at %s",
|
||||
connection->main_file_size, ctime(&(connection->u.remote_time)));
|
||||
// not download again if same mod time and same size
|
||||
if (final_stat_buf.st_size == connection->main_file_size &&
|
||||
final_stat_buf.st_mtime == connection->u.remote_time)
|
||||
{
|
||||
proz_debug("same file size and modification time, skip this file");
|
||||
return -2; // -2 will be handler seperately in DL_Window::start_download
|
||||
}
|
||||
else
|
||||
{
|
||||
proz_debug("file size of mod time differs, go ahead with downloading");
|
||||
}
|
||||
}
|
||||
kfree(final_file);
|
||||
// end of new code
|
||||
|
||||
out_file = kmalloc(PATH_MAX);
|
||||
snprintf(out_file, PATH_MAX, "%s/%s.prozilla",
|
||||
download->dl_dir, connection->u.file);
|
||||
|
@ -1111,23 +1111,36 @@ uerr_t proz_ftp_get_url_info(connection_t * connection)
|
||||
close_sock(&connection->ctrl_sock);
|
||||
|
||||
// size_rt = size_returner(buffer, strlen(buffer));
|
||||
err = ftp_parse(&fp, buffer, strlen(buffer));
|
||||
// use old ftpparse
|
||||
// err =ftp_parse(&fp, buffer, strlen(buffer));
|
||||
int parse_ret;
|
||||
parse_ret = ftpparse(&fp, buffer, strlen(buffer));
|
||||
if (parse_ret == 1)
|
||||
err = FTPPARSEOK;
|
||||
else
|
||||
err = FTPPARSEFAIL;
|
||||
// end of use old ftpparse
|
||||
if (err != FTPPARSEOK)
|
||||
{
|
||||
connection_show_message(connection,
|
||||
_
|
||||
("Unable to parse the line the FTP server returned:please report URL to prozilla-dev@disconnected-by-peer.at "));
|
||||
_("Unable to parse the line the FTP server returned:please report URL to prozilla-dev@disconnected-by-peer.at "));
|
||||
}
|
||||
|
||||
if (err == FTPPARSEOK)
|
||||
{
|
||||
proz_debug("size returned from LIST %ld", fp.filesize);
|
||||
// use old ftpparse
|
||||
//proz_debug("size returned from LIST %ld", fp.filesize);
|
||||
proz_debug("size returned from LIST %ld", fp.size);
|
||||
//SEC size_rt off_t?
|
||||
if (size_ok == FALSE)
|
||||
{
|
||||
proz_debug("SIZE failed, setting file size based on LIST");
|
||||
connection->main_file_size = fp.filesize;
|
||||
}
|
||||
//if (size_ok == FALSE)
|
||||
//{
|
||||
//proz_debug("SIZE failed, setting file size based on LIST");
|
||||
//connection->main_file_size = fp.filesize;
|
||||
connection->main_file_size = fp.size;
|
||||
//}
|
||||
// set the mtime, only obtainable using ftpparse.c from prozilla-1.3.x
|
||||
connection->u.remote_time = fp.mtime;
|
||||
// end of Chen Peng’s code
|
||||
}
|
||||
return FTPOK;
|
||||
}
|
||||
|
@ -1,161 +1,381 @@
|
||||
/******************************************************************************
|
||||
libprozilla - a download accelerator library
|
||||
Copyright (C) 2001 Kalum Somaratna
|
||||
/* ftpparse.c, ftpparse.h: library for parsing FTP LIST responses
|
||||
D. J. Bernstein, djb@pobox.com
|
||||
19970712 (doc updated 19970810)
|
||||
Commercial use is fine, if you let me know what programs you're using this in.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
Currently covered:
|
||||
EPLF.
|
||||
UNIX ls, with or without gid.
|
||||
Microsoft FTP Service.
|
||||
Windows NT FTP Server.
|
||||
VMS.
|
||||
WFTPD (DOS).
|
||||
NetPresenz (Mac).
|
||||
NetWare.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
Definitely not covered:
|
||||
Long VMS filenames, with information split across two lines.
|
||||
NCSA Telnet FTP server. Has LIST = NLST (and bad NLST for directories).
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
******************************************************************************/
|
||||
Written for maximum portability, but tested only under UNIX so far.
|
||||
*/
|
||||
|
||||
//Rewrite of the ftp parsing code as we needed to extract the date of
|
||||
//the file to save it when the downloading is complete.
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /*
|
||||
* HAVE_CONFIG_H
|
||||
*/
|
||||
|
||||
|
||||
#include "common.h"
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include "ftpparse.h"
|
||||
#include "prozilla.h"
|
||||
|
||||
static long totai(year, month, mday)
|
||||
long year;
|
||||
long month;
|
||||
long mday;
|
||||
{
|
||||
/*
|
||||
* adapted from datetime_untai()
|
||||
*/
|
||||
/*
|
||||
* about 100x faster than typical mktime()
|
||||
*/
|
||||
long result;
|
||||
if (month >= 2)
|
||||
month -= 2;
|
||||
else
|
||||
{
|
||||
month += 10;
|
||||
--year;
|
||||
}
|
||||
result = (mday - 1) * 10 + 5 + 306 * month;
|
||||
result /= 10;
|
||||
if (result == 365)
|
||||
{
|
||||
year -= 3;
|
||||
result = 1460;
|
||||
}
|
||||
else
|
||||
result += 365 * (year % 4);
|
||||
year /= 4;
|
||||
result += 1461 * (year % 25);
|
||||
year /= 25;
|
||||
if (result == 36524)
|
||||
{
|
||||
year -= 3;
|
||||
result = 146096;
|
||||
}
|
||||
else
|
||||
{
|
||||
result += 36524 * (year % 4);
|
||||
}
|
||||
year /= 4;
|
||||
result += 146097 * (year - 5);
|
||||
result += 11017;
|
||||
return result * 86400;
|
||||
}
|
||||
|
||||
static int flagneedbase = 1;
|
||||
static time_t base; /*
|
||||
* time() value on this OS at the beginning of 1970 TAI
|
||||
*/
|
||||
static long now; /*
|
||||
* current time
|
||||
*/
|
||||
static int flagneedcurrentyear = 1;
|
||||
static long currentyear; /*
|
||||
* approximation to current year
|
||||
*/
|
||||
|
||||
static void initbase()
|
||||
{
|
||||
struct tm *t;
|
||||
|
||||
/* MultiNet (some spaces removed from examples) */
|
||||
/* "00README.TXT;1 2 30-DEC-1996 17:44 [SYSTEM] (RWED,RWED,RE,RE)" */
|
||||
/* "CORE.DIR;1 1 8-SEP-1996 16:09 [SYSTEM] (RWE,RWE,RE,RE)" */
|
||||
/* and non-MutliNet VMS: */
|
||||
/* "CII-MANUAL.TEX;1 213/216 29-JAN-1996 03:33:12 [ANONYMOU,ANONYMOUS] (RWED,RWED,,)" */
|
||||
if (!flagneedbase)
|
||||
return;
|
||||
|
||||
/* MSDOS format */
|
||||
/* 04-27-00 09:09PM <DIR> licensed */
|
||||
/* 07-18-00 10:16AM <DIR> pub */
|
||||
/* 04-14-00 03:47PM 589 readme.htm */
|
||||
base = 0;
|
||||
t = gmtime(&base);
|
||||
base =
|
||||
-(totai(t->tm_year + 1900, t->tm_mon, t->tm_mday) +
|
||||
t->tm_hour * 3600 + t->tm_min * 60 + t->tm_sec);
|
||||
/*
|
||||
* time_t is assumed to be measured in TAI seconds.
|
||||
*/
|
||||
/*
|
||||
* base may be slightly off if time_t is measured in UTC seconds.
|
||||
*/
|
||||
/*
|
||||
* Typical software naively claims to use UTC but actually uses TAI.
|
||||
*/
|
||||
flagneedbase = 0;
|
||||
}
|
||||
|
||||
static void initnow()
|
||||
{
|
||||
long day;
|
||||
long year;
|
||||
|
||||
initbase();
|
||||
now = time((time_t *)0) - base;
|
||||
|
||||
long getlong(char *buf, int len)
|
||||
if (flagneedcurrentyear)
|
||||
{
|
||||
/*
|
||||
* adapted from datetime_tai()
|
||||
*/
|
||||
day = now / 86400;
|
||||
if ((now % 86400) < 0)
|
||||
--day;
|
||||
day -= 11017;
|
||||
year = 5 + day / 146097;
|
||||
day = day % 146097;
|
||||
if (day < 0)
|
||||
{
|
||||
day += 146097;
|
||||
--year;
|
||||
}
|
||||
year *= 4;
|
||||
if (day == 146096)
|
||||
{
|
||||
year += 3;
|
||||
day = 36524;
|
||||
}
|
||||
else
|
||||
{
|
||||
year += day / 36524;
|
||||
day %= 36524;
|
||||
}
|
||||
year *= 25;
|
||||
year += day / 1461;
|
||||
day %= 1461;
|
||||
year *= 4;
|
||||
if (day == 1460)
|
||||
{
|
||||
year += 3;
|
||||
day = 365;
|
||||
}
|
||||
else
|
||||
{
|
||||
year += day / 365;
|
||||
day %= 365;
|
||||
}
|
||||
day *= 10;
|
||||
if ((day + 5) / 306 >= 10)
|
||||
++year;
|
||||
currentyear = year;
|
||||
flagneedcurrentyear = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* UNIX ls does not show the year for dates in the last six months. */
|
||||
/* So we have to guess the year. */
|
||||
/* Apparently NetWare uses ``twelve months'' instead of ``six months''; ugh. */
|
||||
/* Some versions of ls also fail to show the year for future dates. */
|
||||
static long guesstai(month, mday)
|
||||
long month;
|
||||
long mday;
|
||||
{
|
||||
long year;
|
||||
long t;
|
||||
|
||||
initnow();
|
||||
|
||||
for (year = currentyear - 1; year < currentyear + 100; ++year)
|
||||
{
|
||||
t = totai(year, month, mday);
|
||||
if (now - t < 350 * 86400)
|
||||
return t;
|
||||
}
|
||||
/* Added by Grendel */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check(buf, monthname)
|
||||
char *buf;
|
||||
char *monthname;
|
||||
{
|
||||
if ((buf[0] != monthname[0]) && (buf[0] != monthname[0] - 32))
|
||||
return 0;
|
||||
if ((buf[1] != monthname[1]) && (buf[1] != monthname[1] - 32))
|
||||
return 0;
|
||||
if ((buf[2] != monthname[2]) && (buf[2] != monthname[2] - 32))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char *months[12] = {
|
||||
"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct",
|
||||
"nov", "dec"
|
||||
};
|
||||
|
||||
static int getmonth(buf, len)
|
||||
char *buf;
|
||||
int len;
|
||||
{
|
||||
int i;
|
||||
if (len == 3)
|
||||
for (i = 0; i < 12; ++i)
|
||||
if (check(buf, months[i]))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static long getlong(buf, len)
|
||||
char *buf;
|
||||
int len;
|
||||
{
|
||||
long u = 0;
|
||||
|
||||
while (len-- > 0)
|
||||
u = u * 10 + (*buf++ - '0');
|
||||
return u;
|
||||
}
|
||||
|
||||
|
||||
/* Find next Field
|
||||
** ---------------
|
||||
** Finds the next RFC822 token in a string
|
||||
** On entry,
|
||||
** *pstr points to a string containing a word separated
|
||||
** by white white space "," ";" or "=". The word
|
||||
** can optionally be quoted using <"> or "<" ">"
|
||||
** Comments surrrounded by '(' ')' are filtered out
|
||||
**
|
||||
** On exit,
|
||||
** *pstr has been moved to the first delimiter past the
|
||||
** field
|
||||
** THE STRING HAS BEEN MUTILATED by a 0 terminator
|
||||
**
|
||||
** Returns a pointer to the first word or NULL on error
|
||||
*/
|
||||
char * get_nextfield(char ** pstr)
|
||||
static long long getlonglong(buf, len)
|
||||
char *buf;
|
||||
int len;
|
||||
{
|
||||
char * p = *pstr;
|
||||
|
||||
char * start = NULL;
|
||||
|
||||
if (!pstr || !*pstr)
|
||||
return NULL;
|
||||
while (1)
|
||||
{
|
||||
/* Strip white space and other delimiters */
|
||||
while (*p && (isspace((int)*p) || *p == ',' || *p == ';' || *p == '='))
|
||||
p++;
|
||||
if (!*p)
|
||||
{
|
||||
*pstr = p;
|
||||
return NULL; /* No field */
|
||||
long long u = 0;
|
||||
while (len-- > 0)
|
||||
u = u * 10 + (*buf++ - '0');
|
||||
return u;
|
||||
}
|
||||
|
||||
if (*p == '"') /* quoted field */
|
||||
int ftpparse(fp, buf, len)
|
||||
struct ftpparse *fp;
|
||||
char *buf;
|
||||
int len;
|
||||
{
|
||||
start = ++p;
|
||||
for (; *p && *p != '"'; p++)
|
||||
if (*p == '\\' && *(p + 1))
|
||||
p++;
|
||||
/* Skip escaped chars */
|
||||
break; /* kr95-10-9: needs to stop here */
|
||||
}
|
||||
else if (*p == '<') /* quoted field */
|
||||
{
|
||||
start = ++p;
|
||||
for (; *p && *p != '>'; p++)
|
||||
if (*p == '\\' && *(p + 1))
|
||||
p++;
|
||||
/* Skip escaped chars */
|
||||
break; /* kr95-10-9: needs to stop here */
|
||||
}
|
||||
else if (*p == '(') /* Comment */
|
||||
{
|
||||
for (; *p && *p != ')'; p++)
|
||||
if (*p == '\\' && *(p + 1))
|
||||
p++;
|
||||
/* Skip escaped chars */
|
||||
p++;
|
||||
}
|
||||
else /* Spool field */
|
||||
{
|
||||
start = p;
|
||||
while (*p && !isspace((int)*p) && *p != ',' && *p != ';' && *p != '=')
|
||||
p++;
|
||||
break; /* Got it */
|
||||
}
|
||||
}
|
||||
if (*p)
|
||||
*p++ = '\0';
|
||||
*pstr = p;
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uerr_t ftp_parse(ftpparse *fp, char *buf, int len)
|
||||
{
|
||||
char *cp;
|
||||
char *token;
|
||||
char *ptr;
|
||||
char *date;
|
||||
int i;
|
||||
int j;
|
||||
int state;
|
||||
off_t size = -1;
|
||||
long year;
|
||||
long month = -1;
|
||||
long mday = -1;
|
||||
long hour;
|
||||
long minute;
|
||||
|
||||
fp->filename = 0;
|
||||
fp->name = 0;
|
||||
fp->namelen = 0;
|
||||
// fp->flagtrycwd = 0;
|
||||
// fp->flagtryretr = 0;
|
||||
//fp->sizetype = FTPPARSE_SIZE_UNKNOWN;
|
||||
fp->filesize = 0;
|
||||
// fp->mtimetype = FTPPARSE_MTIME_UNKNOWN;
|
||||
fp->flagtrycwd = 0;
|
||||
fp->flagtryretr = 0;
|
||||
fp->sizetype = FTPPARSE_SIZE_UNKNOWN;
|
||||
fp->size = 0;
|
||||
fp->mtimetype = FTPPARSE_MTIME_UNKNOWN;
|
||||
fp->mtime = 0;
|
||||
// fp->idtype = FTPPARSE_ID_UNKNOWN;
|
||||
fp->idtype = FTPPARSE_ID_UNKNOWN;
|
||||
fp->id = 0;
|
||||
// fp->idlen = 0;
|
||||
fp->idlen = 0;
|
||||
|
||||
proz_debug("FTP LIST to be parsed is %s", cp = strdup(buf));
|
||||
free(cp);
|
||||
|
||||
if (len < 2) /* an empty name in EPLF, with no info, could be 2 chars */
|
||||
return FTPPARSENOTEXIST;
|
||||
if (len < 2) /*
|
||||
* an empty name in EPLF, with no info, could be 2 chars
|
||||
*/
|
||||
return 0;
|
||||
|
||||
switch (*buf)
|
||||
{
|
||||
/*
|
||||
* see http://pobox.com/~djb/proto/eplf.txt
|
||||
*/
|
||||
/*
|
||||
* "+i8388621.29609,m824255902,/,\tdev"
|
||||
*/
|
||||
/*
|
||||
* "+i8388621.44468,m839956783,r,s10376,\tRFCEPLF"
|
||||
*/
|
||||
case '+':
|
||||
i = 1;
|
||||
for (j = 1; j < len; ++j)
|
||||
{
|
||||
if (buf[j] == 9)
|
||||
{
|
||||
fp->name = buf + j + 1;
|
||||
fp->namelen = len - j - 1;
|
||||
return 1;
|
||||
}
|
||||
if (buf[j] == ',')
|
||||
{
|
||||
switch (buf[i])
|
||||
{
|
||||
case '/':
|
||||
fp->flagtrycwd = 1;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
fp->flagtryretr = 1;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
fp->sizetype = FTPPARSE_SIZE_BINARY;
|
||||
fp->size = getlonglong(buf + i + 1, j - i - 1);
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
fp->mtimetype = FTPPARSE_MTIME_LOCAL;
|
||||
initbase();
|
||||
fp->mtime = base + getlong(buf + i + 1, j - i - 1);
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
fp->idtype = FTPPARSE_ID_FULL;
|
||||
fp->id = buf + i + 1;
|
||||
fp->idlen = j - i - 1;
|
||||
}
|
||||
i = j + 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* UNIX-style listing, without inum and without blocks
|
||||
*/
|
||||
/*
|
||||
* "-rw-r--r-- 1 root other 531 Jan 29 03:26 README"
|
||||
*/
|
||||
/*
|
||||
* "dr-xr-xr-x 2 root other 512 Apr 8 1994 etc"
|
||||
*/
|
||||
/*
|
||||
* "dr-xr-xr-x 2 root 512 Apr 8 1994 etc"
|
||||
*/
|
||||
/*
|
||||
* "lrwxrwxrwx 1 root other 7 Jan 25 00:17 bin -> usr/bin"
|
||||
*/
|
||||
/*
|
||||
* Also produced by Microsoft's FTP servers for Windows:
|
||||
*/
|
||||
/*
|
||||
* "---------- 1 owner group 1803128 Jul 10 10:18 ls-lR.Z"
|
||||
*/
|
||||
/*
|
||||
* "d--------- 1 owner group 0 May 9 19:45 Softlib"
|
||||
*/
|
||||
/*
|
||||
* Also WFTPD for MSDOS:
|
||||
*/
|
||||
/*
|
||||
* "-rwxrwxrwx 1 noone nogroup 322 Aug 19 1996 message.ftp"
|
||||
*/
|
||||
/*
|
||||
* Also NetWare:
|
||||
*/
|
||||
/*
|
||||
* "d [R----F--] supervisor 512 Jan 16 18:53 login"
|
||||
*/
|
||||
/*
|
||||
* "- [R----F--] rhesus 214059 Oct 20 15:27 cx.exe"
|
||||
*/
|
||||
/*
|
||||
* Also NetPresenz for the Mac:
|
||||
*/
|
||||
/*
|
||||
* "-------r-- 326 1391972 1392298 Nov 22 1995 MegaPhone.sit"
|
||||
*/
|
||||
/*
|
||||
* "drwxrwxr-x folder 2 May 10 1996 network"
|
||||
*/
|
||||
case 'b':
|
||||
case 'c':
|
||||
case 'd':
|
||||
@ -163,88 +383,257 @@ uerr_t ftp_parse(ftpparse *fp, char *buf, int len)
|
||||
case 'p':
|
||||
case 's':
|
||||
case '-':
|
||||
/* UNIX-style listing, without inum and without blocks */
|
||||
/* "-rw-r--r-- 1 root other 531 Jan 29 03:26 README" */
|
||||
/* "dr-xr-xr-x 2 root other 512 Apr 8 1994 etc" */
|
||||
/* "dr-xr-xr-x 2 root 512 Apr 8 1994 etc" */
|
||||
/* "lrwxrwxrwx 1 root other 7 Jan 25 00:17 bin -> usr/bin" */
|
||||
/* Also produced by Microsoft's FTP servers for Windows: */
|
||||
/* "---------- 1 owner group 1803128 Jul 10 10:18 ls-lR.Z" */
|
||||
/* "d--------- 1 owner group 0 May 9 19:45 Softlib" */
|
||||
/* Also WFTPD for MSDOS: */
|
||||
/* "-rwxrwxrwx 1 noone nogroup 322 Aug 19 1996 message.ftp" */
|
||||
/* Also NetWare: */
|
||||
/* "d [R----F--] supervisor 512 Jan 16 18:53 login" */
|
||||
/* "- [R----F--] rhesus 214059 Oct 20 15:27 cx.exe" */
|
||||
/* Also NetPresenz for the Mac: */
|
||||
/* "-------r-- 326 1391972 1392298 Nov 22 1995 MegaPhone.sit" */
|
||||
/* "drwxrwxr-x folder 2 May 10 1996 network"
|
||||
*/
|
||||
|
||||
if (*buf == 'd')
|
||||
fp->filetype = DIRECTORY;
|
||||
fp->flagtrycwd = 1;
|
||||
if (*buf == '-')
|
||||
fp->filetype = DIRECTORY;
|
||||
fp->flagtryretr = 1;
|
||||
if (*buf == 'l')
|
||||
fp->filetype = SYMBOLIC_LINK;
|
||||
ptr = cp = strdup(buf);
|
||||
fp->flagtrycwd = fp->flagtryretr = 1;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
state = 1;
|
||||
i = 0;
|
||||
for (j = 1; j < len; ++j)
|
||||
if ((buf[j] == ' ') && (buf[j - 1] != ' '))
|
||||
{
|
||||
//add checking
|
||||
token = get_nextfield(&cp);
|
||||
if (token == NULL) //failed to parse
|
||||
return FTPPARSEFAIL;
|
||||
}
|
||||
/*
|
||||
** This field can either be group or size. We find out by looking at the
|
||||
** next field. If this is a non-digit then this field is the size.
|
||||
switch (state)
|
||||
{
|
||||
case 1: /*
|
||||
* skipping perm
|
||||
*/
|
||||
while (*cp && isspace((int)*cp))
|
||||
cp++;
|
||||
if (isdigit((int)*cp))
|
||||
state = 2;
|
||||
break;
|
||||
|
||||
case 2: /*
|
||||
* skipping nlink
|
||||
*/
|
||||
state = 3;
|
||||
if ((j - i == 6) && (buf[i] == 'f')) /*
|
||||
* for NetPresenz
|
||||
*/
|
||||
state = 4;
|
||||
break;
|
||||
|
||||
case 3: /*
|
||||
* skipping uid
|
||||
*/
|
||||
state = 4;
|
||||
break;
|
||||
|
||||
case 4: /*
|
||||
* getting tentative size
|
||||
*/
|
||||
size = getlonglong(buf + i, j - i);
|
||||
state = 5;
|
||||
break;
|
||||
|
||||
case 5: /*
|
||||
* searching for month, otherwise getting tentative size
|
||||
*/
|
||||
month = getmonth(buf + i, j - i);
|
||||
if (month >= 0)
|
||||
state = 6;
|
||||
else
|
||||
size = getlonglong(buf + i, j - i);
|
||||
break;
|
||||
|
||||
case 6: /*
|
||||
* have size and month
|
||||
*/
|
||||
mday = getlong(buf + i, j - i);
|
||||
state = 7;
|
||||
break;
|
||||
|
||||
case 7: /*
|
||||
* have size, month, mday
|
||||
*/
|
||||
if ((j - i == 4) && (buf[i + 1] == ':'))
|
||||
{
|
||||
token = get_nextfield(&cp);
|
||||
while (*cp && isspace((int)*cp))
|
||||
cp++;
|
||||
hour = getlong(buf + i, 1);
|
||||
minute = getlong(buf + i + 2, 2);
|
||||
fp->mtimetype = FTPPARSE_MTIME_REMOTEMINUTE;
|
||||
initbase();
|
||||
fp->mtime =
|
||||
base + guesstai(month,
|
||||
mday) + hour * 3600 +
|
||||
minute * 60;
|
||||
}
|
||||
//if it is a filename
|
||||
fp->filesize = strtol(token, NULL, 10);
|
||||
proz_debug("FTP file size is %ld", fp->filesize);
|
||||
|
||||
|
||||
while (*cp && isspace((int)*cp))
|
||||
cp++;
|
||||
assert(cp + 12 < ptr + len);
|
||||
date = cp;
|
||||
cp += 12;
|
||||
*cp++ = '\0';
|
||||
fp->date_str = strdup(date);
|
||||
|
||||
proz_debug("LIST date is %s", fp->date_str);
|
||||
|
||||
return FTPPARSEOK;
|
||||
|
||||
default:
|
||||
return FTPPARSEFAIL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
time_t parse_time(const char * str)
|
||||
else if ((j - i == 5) && (buf[i + 2] == ':'))
|
||||
{
|
||||
char * p;
|
||||
struct tm tm;
|
||||
time_t t;
|
||||
hour = getlong(buf + i, 2);
|
||||
minute = getlong(buf + i + 3, 2);
|
||||
fp->mtimetype = FTPPARSE_MTIME_REMOTEMINUTE;
|
||||
initbase();
|
||||
fp->mtime =
|
||||
base + guesstai(month,
|
||||
mday) + hour * 3600 +
|
||||
minute * 60;
|
||||
}
|
||||
else if (j - i >= 4)
|
||||
{
|
||||
year = getlong(buf + i, j - i);
|
||||
fp->mtimetype = FTPPARSE_MTIME_REMOTEDAY;
|
||||
initbase();
|
||||
fp->mtime = base + totai(year, month, mday);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
fp->name = buf + j + 1;
|
||||
fp->namelen = len - j - 1;
|
||||
state = 8;
|
||||
break;
|
||||
|
||||
if (!str)
|
||||
case 8: /*
|
||||
* twiddling thumbs
|
||||
*/
|
||||
break;
|
||||
}
|
||||
i = j + 1;
|
||||
while ((i < len) && (buf[i] == ' '))
|
||||
++i;
|
||||
}
|
||||
|
||||
if (state != 8)
|
||||
return 0;
|
||||
|
||||
if ((p = strchr(str, ',')))
|
||||
fp->size = size;
|
||||
fp->sizetype = FTPPARSE_SIZE_ASCII;
|
||||
|
||||
if (*buf == 'l')
|
||||
for (i = 0; i + 3 < fp->namelen; ++i)
|
||||
if (fp->name[i] == ' ')
|
||||
if (fp->name[i + 1] == '-')
|
||||
if (fp->name[i + 2] == '>')
|
||||
if (fp->name[i + 3] == ' ')
|
||||
{
|
||||
fp->namelen = i;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* eliminate extra NetWare spaces
|
||||
*/
|
||||
if ((buf[1] == ' ') || (buf[1] == '['))
|
||||
if (fp->namelen > 3)
|
||||
if (fp->name[0] == ' ')
|
||||
if (fp->name[1] == ' ')
|
||||
if (fp->name[2] == ' ')
|
||||
{
|
||||
fp->name += 3;
|
||||
fp->namelen -= 3;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* MultiNet (some spaces removed from examples)
|
||||
*/
|
||||
/*
|
||||
* "00README.TXT;1 2 30-DEC-1996 17:44 [SYSTEM] (RWED,RWED,RE,RE)"
|
||||
*/
|
||||
/*
|
||||
* "CORE.DIR;1 1 8-SEP-1996 16:09 [SYSTEM] (RWE,RWE,RE,RE)"
|
||||
*/
|
||||
/*
|
||||
* and non-MutliNet VMS:
|
||||
*/
|
||||
/*
|
||||
* "CII-MANUAL.TEX;1 213/216 29-JAN-1996 03:33:12 [ANONYMOU,ANONYMOUS] (RWED,RWED,,)"
|
||||
*/
|
||||
for (i = 0; i < len; ++i)
|
||||
if (buf[i] == ';')
|
||||
break;
|
||||
if (i < len)
|
||||
{
|
||||
fp->name = buf;
|
||||
fp->namelen = i;
|
||||
if (i > 4)
|
||||
if (buf[i - 4] == '.')
|
||||
if (buf[i - 3] == 'D')
|
||||
if (buf[i - 2] == 'I')
|
||||
if (buf[i - 1] == 'R')
|
||||
{
|
||||
fp->namelen -= 4;
|
||||
fp->flagtrycwd = 1;
|
||||
}
|
||||
if (!fp->flagtrycwd)
|
||||
fp->flagtryretr = 1;
|
||||
while (buf[i] != ' ')
|
||||
if (++i == len)
|
||||
return 0;
|
||||
while (buf[i] == ' ')
|
||||
if (++i == len)
|
||||
return 0;
|
||||
while (buf[i] != ' ')
|
||||
if (++i == len)
|
||||
return 0;
|
||||
while (buf[i] == ' ')
|
||||
if (++i == len)
|
||||
return 0;
|
||||
j = i;
|
||||
while (buf[j] != '-')
|
||||
if (++j == len)
|
||||
return 0;
|
||||
mday = getlong(buf + i, j - i);
|
||||
while (buf[j] == '-')
|
||||
if (++j == len)
|
||||
return 0;
|
||||
i = j;
|
||||
while (buf[j] != '-')
|
||||
if (++j == len)
|
||||
return 0;
|
||||
month = getmonth(buf + i, j - i);
|
||||
if (month < 0)
|
||||
return 0;
|
||||
while (buf[j] == '-')
|
||||
if (++j == len)
|
||||
return 0;
|
||||
i = j;
|
||||
while (buf[j] != ' ')
|
||||
if (++j == len)
|
||||
return 0;
|
||||
year = getlong(buf + i, j - i);
|
||||
while (buf[j] == ' ')
|
||||
if (++j == len)
|
||||
return 0;
|
||||
i = j;
|
||||
while (buf[j] != ':')
|
||||
if (++j == len)
|
||||
return 0;
|
||||
hour = getlong(buf + i, j - i);
|
||||
while (buf[j] == ':')
|
||||
if (++j == len)
|
||||
return 0;
|
||||
i = j;
|
||||
while ((buf[j] != ':') && (buf[j] != ' '))
|
||||
if (++j == len)
|
||||
return 0;
|
||||
minute = getlong(buf + i, j - i);
|
||||
|
||||
fp->mtimetype = FTPPARSE_MTIME_REMOTEMINUTE;
|
||||
initbase();
|
||||
fp->mtime =
|
||||
base + totai(year, month, mday) + hour * 3600 + minute * 60;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some useless lines, safely ignored:
|
||||
*/
|
||||
/*
|
||||
* "Total of 11 Files, 10966 Blocks." (VMS)
|
||||
*/
|
||||
/*
|
||||
* "total 14786" (UNIX)
|
||||
*/
|
||||
/*
|
||||
* "DISK$ANONFTP:[ANONYMOUS]" (VMS)
|
||||
*/
|
||||
/*
|
||||
* "Directory DISK$PCSA:[ANONYM]" (VMS)
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,53 +1,75 @@
|
||||
/******************************************************************************
|
||||
libprozilla - a download accelerator library
|
||||
Copyright (C) 2001 Kalum Somaratna
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
******************************************************************************/
|
||||
|
||||
/* FTP LIST command parsing code. */
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
|
||||
#ifndef FTPPARSE_H
|
||||
#define FTPPARSE_H
|
||||
|
||||
/*
|
||||
ftpparse(&fp,buf,len) tries to parse one line of LIST output.
|
||||
|
||||
#include "common.h"
|
||||
#include "prozilla.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
The line is an array of len characters stored in buf.
|
||||
It should not include the terminating CR LF; so buf[len] is typically CR.
|
||||
|
||||
If ftpparse() can't find a filename, it returns 0.
|
||||
|
||||
typedef struct ftpparse {
|
||||
char *filename;
|
||||
If ftpparse() can find a filename, it fills in fp and returns 1.
|
||||
fp is a struct ftpparse, defined below.
|
||||
The name is an array of fp.namelen characters stored in fp.name;
|
||||
fp.name points somewhere within buf.
|
||||
*/
|
||||
|
||||
struct ftpparse {
|
||||
char *name; /*
|
||||
* not necessarily 0-terminated
|
||||
*/
|
||||
int namelen;
|
||||
off_t filesize; /* number of octets */
|
||||
// int mtimetype;
|
||||
time_t mtime; /* modification time */
|
||||
file_type_t filetype;
|
||||
char *id; /* not necessarily 0-terminated */
|
||||
char *date_str;
|
||||
}ftpparse;
|
||||
int flagtrycwd; /*
|
||||
* 0 if cwd is definitely pointless, 1 otherwise
|
||||
*/
|
||||
int flagtryretr; /*
|
||||
* 0 if retr is definitely pointless, 1 otherwise
|
||||
*/
|
||||
int sizetype;
|
||||
off_t size; /*
|
||||
* number of octets
|
||||
*/
|
||||
int mtimetype;
|
||||
time_t mtime; /*
|
||||
* modification time
|
||||
*/
|
||||
int idtype;
|
||||
char *id; /*
|
||||
* not necessarily 0-terminated
|
||||
*/
|
||||
int idlen;
|
||||
};
|
||||
|
||||
#define FTPPARSE_SIZE_UNKNOWN 0
|
||||
#define FTPPARSE_SIZE_BINARY 1 /*
|
||||
* size is the number of octets in TYPE I
|
||||
*/
|
||||
#define FTPPARSE_SIZE_ASCII 2 /*
|
||||
* size is the number of octets in TYPE A
|
||||
*/
|
||||
|
||||
uerr_t ftp_parse(ftpparse *fp, char *buf, int len);
|
||||
#define FTPPARSE_MTIME_UNKNOWN 0
|
||||
#define FTPPARSE_MTIME_LOCAL 1 /*
|
||||
* time is correct
|
||||
*/
|
||||
#define FTPPARSE_MTIME_REMOTEMINUTE 2 /*
|
||||
* time zone and secs are unknown
|
||||
*/
|
||||
#define FTPPARSE_MTIME_REMOTEDAY 3 /*
|
||||
* time zone and time of day are unknown
|
||||
*/
|
||||
/*
|
||||
When a time zone is unknown, it is assumed to be GMT. You may want
|
||||
to use localtime() for LOCAL times, along with an indication that the
|
||||
time is correct in the local time zone, and gmtime() for REMOTE* times.
|
||||
*/
|
||||
|
||||
#define FTPPARSE_ID_UNKNOWN 0
|
||||
#define FTPPARSE_ID_FULL 1 /*
|
||||
* unique identifier for files on this FTP server
|
||||
*/
|
||||
|
||||
extern int ftpparse();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* FTPPARSE_H */
|
||||
|
@ -145,6 +145,7 @@ pgettext_aux (const char *domain,
|
||||
int category)
|
||||
{
|
||||
const char *translation = dcgettext(domain, msg_ctxt_id, category);
|
||||
|
||||
if (translation == msg_ctxt_id)
|
||||
return msgid;
|
||||
else
|
||||
@ -166,6 +167,7 @@ npgettext_aux (const char *domain,
|
||||
{
|
||||
const char *translation =
|
||||
dcngettext(domain, msg_ctxt_id, msgid_plural, n, category);
|
||||
|
||||
if (translation == msg_ctxt_id || translation == msgid_plural)
|
||||
return(n == 1 ? msgid : msgid_plural);
|
||||
else
|
||||
@ -206,6 +208,7 @@ dcpgettext_expr (const char *domain,
|
||||
size_t msgctxt_len = strlen(msgctxt) + 1;
|
||||
size_t msgid_len = strlen(msgid) + 1;
|
||||
const char *translation;
|
||||
|
||||
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
|
||||
char msg_ctxt_id[msgctxt_len + msgid_len];
|
||||
#else
|
||||
@ -252,6 +255,7 @@ dcnpgettext_expr (const char *domain,
|
||||
size_t msgctxt_len = strlen(msgctxt) + 1;
|
||||
size_t msgid_len = strlen(msgid) + 1;
|
||||
const char *translation;
|
||||
|
||||
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
|
||||
char msg_ctxt_id[msgctxt_len + msgid_len];
|
||||
#else
|
||||
|
@ -67,6 +67,30 @@
|
||||
#define DYNAMIC_LINE_BUFFER 40
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
...
|
||||
******************************************************************************/
|
||||
// Chen Peng, added to convert time string to unix time
|
||||
time_t parse_date(const char * input)
|
||||
{
|
||||
const char *cp;
|
||||
time_t ret_t = 0;
|
||||
struct tm *t = (struct tm *)kmalloc(sizeof(struct tm));
|
||||
|
||||
memset(t, , sizeof(*t));
|
||||
// apache format, other server may diff... todo
|
||||
cp = strptime(input, "%a, %d %b %Y %T %Z", t);
|
||||
if (cp == NULL)
|
||||
{
|
||||
t->tm_year += 100; // somehow it misses 100 years. maybe a bug
|
||||
ret_t = mktime(t);
|
||||
}
|
||||
else
|
||||
proz_debug("Fail to parse time %s, unparsed part is %s", input, cp);
|
||||
kfree(t);
|
||||
return ret_t;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
...
|
||||
******************************************************************************/
|
||||
@ -261,7 +285,7 @@ off_t hgetlen(const char *hdr)
|
||||
for (len = 0; isdigit(*hdr); hdr++)
|
||||
len = 10 * len + (*hdr - '0');
|
||||
|
||||
proz_debug("contenlen %s contentlen %lld", *hdr, len);
|
||||
proz_debug("contenlen %s contentlen %lld", hdr, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -700,6 +724,17 @@ uerr_t proz_http_get_url_info(connection_t * connection)
|
||||
connection->resume_support = TRUE;
|
||||
else if (connection->hs.accept_ranges == -1)
|
||||
connection->resume_support = FALSE;
|
||||
// parse date and put it to urlinfo
|
||||
time_t remote_time;
|
||||
remote_time = parse_date(connection->hs.remote_time);
|
||||
if (remote_time)
|
||||
{
|
||||
/ parse date ok
|
||||
connection->u.remote_time = remote_time;
|
||||
proz_debug("Remote unix time is %lld", connection->u.remote_time);
|
||||
proz_debug("Remote time is %s", ctime(&(connection->u.remote_time)));
|
||||
}
|
||||
// end of parse date and put it to urlinfo
|
||||
}
|
||||
|
||||
|
||||
@ -888,6 +923,15 @@ uerr_t ftp_get_url_info_from_http_proxy(connection_t * connection)
|
||||
connection->resume_support = TRUE;
|
||||
else if (connection->hs.accept_ranges == -1)
|
||||
connection->resume_support = FALSE;
|
||||
// parse date and put it to urlinfo
|
||||
time_t remote_time;
|
||||
remote_time = parse_date(connection->hs.remote_time);
|
||||
if (remote_time) // parse date ok
|
||||
{
|
||||
connection->u.remote_time = remote_time;
|
||||
proz_debug("Remote mod time is %s", ctime(&(connection->u.remote_time)));
|
||||
}
|
||||
// end of parse date and put it to urlinfo
|
||||
return FTPOK;
|
||||
}
|
||||
|
||||
|
@ -120,9 +120,8 @@ typedef struct _urlinfo {
|
||||
char ftp_type;
|
||||
char *path, *dir, *file; /* Path, dir and file (properly decoded). */
|
||||
char *user, *passwd; /* For FTP. */
|
||||
|
||||
char *referer; /* The source from which the request
|
||||
URI was obtained. */
|
||||
char *referer; /* The source from which the request URI was obtained. */
|
||||
time_t mtime; /* modification time, added by Chen Peng */
|
||||
} urlinfo;
|
||||
|
||||
typedef enum {
|
||||
|
42
po/de.po
42
po/de.po
@ -8,7 +8,7 @@ msgstr ""
|
||||
"Project-Id-Version: prozilla 2.0.5\n"
|
||||
"Report-Msgid-Bugs-To: prozilla-dev@disconnected-by-peer.at\n"
|
||||
"POT-Creation-Date: 2010-09-01 18:53+0200\n"
|
||||
"PO-Revision-Date: 2010-09-01 19:02+0100\n"
|
||||
"PO-Revision-Date: 2010-09-01 19:58+0100\n"
|
||||
"Last-Translator: Mario Fetka <mario.fetka@gmail.com>\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: de\n"
|
||||
@ -22,15 +22,8 @@ msgstr ""
|
||||
|
||||
#: src/download_win.cpp:533
|
||||
#, c-format
|
||||
msgid ""
|
||||
"A connection(s) of the download %s encountered a unrecoverable remote error, "
|
||||
"usually the file not being present in the remote server, therefore the "
|
||||
"download had to be aborted!\n"
|
||||
msgstr ""
|
||||
"Bei der Verbindung des Downloads %s ist ein nicht behebbarer "
|
||||
"Verbindungsfehler aufgetreten. In der Regel bedäutet dies das die Datei auf "
|
||||
"dem Remote-Server nicht vorhanden ist. Der Download musste abgeprochen "
|
||||
"werden!\n"
|
||||
msgid "A connection(s) of the download %s encountered a unrecoverable remote error, usually the file not being present in the remote server, therefore the download had to be aborted!\n"
|
||||
msgstr "Bei der Verbindung des Downloads %s ist ein nicht behebbarer Verbindungsfehler aufgetreten. In der Regel bedäutet dies das die Datei auf dem Remote-Server nicht vorhanden ist. Der Download musste abgeprochen werden!\n"
|
||||
|
||||
#: src/init.cpp:83
|
||||
msgid "unable to create the directory to store the config info in"
|
||||
@ -102,15 +95,14 @@ msgstr ""
|
||||
#: src/main.cpp:394
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Hey! Does waiting for a server response for Zero(0) seconds make and sense "
|
||||
"to you!?\n"
|
||||
"Hey! Does waiting for a server response for Zero(0) seconds make and sense to you!?\n"
|
||||
"Please type proz --help for help\n"
|
||||
msgstr ""
|
||||
"Hey! Macht das Warten auf eine Antwort des Servers für Null (0) Sekunden "
|
||||
"irgendeinen Sinn für dich!?\n"
|
||||
"Hey! Macht das Warten auf eine Antwort des Servers für Null (0) Sekunden irgendeinen Sinn für dich!?\n"
|
||||
"Bitte geben sie proz --help für die Hilfe ein\n"
|
||||
|
||||
#: src/main.cpp:407 src/main.cpp:426
|
||||
#: src/main.cpp:407
|
||||
#: src/main.cpp:426
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Error: Invalid arguments for the --pao option\n"
|
||||
@ -125,19 +117,16 @@ msgid ""
|
||||
"Hey you! Will pinging Zero(0) servers at once achive anything for me!?\n"
|
||||
"Please type proz --help for help\n"
|
||||
msgstr ""
|
||||
"Hey du! Keine (0) Server auf einmal zu erreichen hat für mich keine "
|
||||
"Bedeutung!?\n"
|
||||
"Hey du! Keine (0) Server auf einmal zu erreichen hat für mich keine Bedeutung!?\n"
|
||||
"Bitte geben sie proz --help für die Hilfe ein\n"
|
||||
|
||||
#: src/main.cpp:432
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Hey! Will requesting Zero(0) servers at oncefrom the ftpearch achive "
|
||||
"anything!?\n"
|
||||
"Hey! Will requesting Zero(0) servers at oncefrom the ftpearch achive anything!?\n"
|
||||
"Please type proz --help for help\n"
|
||||
msgstr ""
|
||||
"Hey! Keine (0) Servern von der FTP-Suche auf einmal zu erreichen hat für "
|
||||
"mich keine Bedeutung!?\n"
|
||||
"Hey! Keine (0) Servern von der FTP-Suche auf einmal zu erreichen hat für mich keine Bedeutung!?\n"
|
||||
"Bitte geben sie proz --help für die Hilfe ein\n"
|
||||
|
||||
#: src/main.cpp:445
|
||||
@ -170,12 +159,10 @@ msgstr ""
|
||||
#: src/main.cpp:480
|
||||
#, c-format
|
||||
msgid ""
|
||||
"The available servers are (0) filesearching.com and (1) ftpsearch.elmundo."
|
||||
"es\n"
|
||||
"The available servers are (0) filesearching.com and (1) ftpsearch.elmundo.es\n"
|
||||
"Please type proz --help for help\n"
|
||||
msgstr ""
|
||||
"Die Server sind verfügbar Server sind (0) filesearching.com und (1) "
|
||||
"ftpsearch.elmundo.es\n"
|
||||
"Die Server sind verfügbar Server sind (0) filesearching.com und (1) ftpsearch.elmundo.es\n"
|
||||
"Bitte geben sie proz --help für die Hilfe ein\n"
|
||||
|
||||
#: src/main.cpp:489
|
||||
@ -219,9 +206,7 @@ msgstr "Gesamt Bytes empfangen %lld Kb (%.2f%%)"
|
||||
#: src/interface.c:335
|
||||
#, c-format
|
||||
msgid "Current speed = %1.2fKb/s, Average D/L speed = %1.2fKb/s"
|
||||
msgstr ""
|
||||
"Aktuelle Geschwindigkeit = %1.2f Kb/s, Durchschnittliche D/L Geschwindigkeit "
|
||||
"= %1.2f Kb/s"
|
||||
msgstr "Aktuelle Geschwindigkeit = %1.2f Kb/s, Durchschnittliche D/L Geschwindigkeit = %1.2f Kb/s"
|
||||
|
||||
#: src/interface.c:343
|
||||
#, c-format
|
||||
@ -245,3 +230,4 @@ msgstr "Wiederaufnehmen Unterstützte"
|
||||
#: src/interface.c:359
|
||||
msgid "Resume NOT Supported"
|
||||
msgstr "Wiederaufnehmen NICHT unterstützt"
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <utime.h>
|
||||
#ifdef HAVE_NCURSES_H
|
||||
#include <ncurses.h>
|
||||
#else
|
||||
@ -326,6 +327,15 @@ DL_Window::start_download()
|
||||
status = DL_ABORTED;
|
||||
return;
|
||||
}
|
||||
// handle skipped files
|
||||
if (ret == -2)
|
||||
{
|
||||
PrintMessage("Remote file is the same as local, skip it\n");
|
||||
status = DL_ABORTED;
|
||||
return;
|
||||
}
|
||||
// end of handle skipped files
|
||||
|
||||
|
||||
/*Display resume status */
|
||||
if (download->resume_support)
|
||||
@ -507,6 +517,20 @@ DL_Window::handle_download_thread()
|
||||
status = DL_JOINING;
|
||||
proz_download_join_downloads(download);
|
||||
joining_thread_running = TRUE;
|
||||
|
||||
// set correct mtime to server time
|
||||
struct utimbuf times;
|
||||
times.actime = times.modtime = download->u.remote_time;
|
||||
if (!utime(download->u.file, ×))
|
||||
{
|
||||
proz_debug("update mtime for file %s as %s",
|
||||
download->u.file, ctime(&(download->u.remote_time)));
|
||||
}
|
||||
else
|
||||
{
|
||||
proz_debug("fail to update mtime for file %s, errno=%d", download->u.file, errno);
|
||||
}
|
||||
// end of set correct mtime to server time
|
||||
}
|
||||
|
||||
if (err == CANTRESUME)
|
||||
|
@ -145,6 +145,7 @@ pgettext_aux (const char *domain,
|
||||
int category)
|
||||
{
|
||||
const char *translation = dcgettext(domain, msg_ctxt_id, category);
|
||||
|
||||
if (translation == msg_ctxt_id)
|
||||
return msgid;
|
||||
else
|
||||
@ -166,6 +167,7 @@ npgettext_aux (const char *domain,
|
||||
{
|
||||
const char *translation =
|
||||
dcngettext(domain, msg_ctxt_id, msgid_plural, n, category);
|
||||
|
||||
if (translation == msg_ctxt_id || translation == msgid_plural)
|
||||
return(n == 1 ? msgid : msgid_plural);
|
||||
else
|
||||
@ -206,6 +208,7 @@ dcpgettext_expr (const char *domain,
|
||||
size_t msgctxt_len = strlen(msgctxt) + 1;
|
||||
size_t msgid_len = strlen(msgid) + 1;
|
||||
const char *translation;
|
||||
|
||||
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
|
||||
char msg_ctxt_id[msgctxt_len + msgid_len];
|
||||
#else
|
||||
@ -252,6 +255,7 @@ dcnpgettext_expr (const char *domain,
|
||||
size_t msgctxt_len = strlen(msgctxt) + 1;
|
||||
size_t msgid_len = strlen(msgid) + 1;
|
||||
const char *translation;
|
||||
|
||||
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
|
||||
char msg_ctxt_id[msgctxt_len + msgid_len];
|
||||
#else
|
||||
|
@ -57,7 +57,7 @@
|
||||
* CONREJECTED,
|
||||
* REMOTEFATAL,
|
||||
* LOCALFATAL
|
||||
**} dl_status;
|
||||
****} dl_status;
|
||||
*
|
||||
* And here are the texts for the above enums.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user