add mtime support to ftpparse

This commit is contained in:
Mario Fetka 2010-09-18 12:55:05 +02:00
parent 267f5a2964
commit 7c3da640e1
13 changed files with 969 additions and 447 deletions

View File

@ -170,7 +170,7 @@ typedef int boolean;
/* Gettext */
#include "gettext.h"
#define _(String) dgettext (PACKAGE, String)
#define _(String) dgettext(PACKAGE, String)
/* Gettext */

View File

@ -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);

View 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 Pengs code
}
return FTPOK;
}

View File

@ -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 */
}
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 == '<') /* 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;
long long u = 0;
while (len-- > 0)
u = u * 10 + (*buf++ - '0');
return u;
}
uerr_t ftp_parse(ftpparse *fp, char *buf, int len)
int ftpparse(fp, buf, len)
struct 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;
else if ((j - i == 5) && (buf[i + 2] == ':'))
{
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;
case 8: /*
* twiddling thumbs
*/
break;
}
i = j + 1;
while ((i < len) && (buf[i] == ' '))
++i;
}
time_t parse_time(const char * str)
{
char * p;
struct tm tm;
time_t t;
if (!str)
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;
}

View File

@ -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 */

View File

@ -31,10 +31,10 @@
# ifdef DEFAULT_TEXT_DOMAIN
# undef gettext
# define gettext(Msgid) \
dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
dgettext(DEFAULT_TEXT_DOMAIN, Msgid)
# undef ngettext
# define ngettext(Msgid1, Msgid2, N) \
dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
dngettext(DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
# endif
#else
@ -65,31 +65,31 @@
On pre-ANSI systems without 'const', the config.h file is supposed to
contain "#define const". */
# undef gettext
# define gettext(Msgid) ((const char *) (Msgid))
# define gettext(Msgid) ((const char *)(Msgid))
# undef dgettext
# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid))
# define dgettext(Domainname, Msgid) ((void)(Domainname), gettext(Msgid))
# undef dcgettext
# define dcgettext(Domainname, Msgid, Category) \
((void) (Category), dgettext (Domainname, Msgid))
((void)(Category), dgettext(Domainname, Msgid))
# undef ngettext
# define ngettext(Msgid1, Msgid2, N) \
((N) == 1 \
? ((void) (Msgid2), (const char *) (Msgid1)) \
: ((void) (Msgid1), (const char *) (Msgid2)))
? ((void)(Msgid2), (const char *)(Msgid1)) \
: ((void)(Msgid1), (const char *)(Msgid2)))
# undef dngettext
# define dngettext(Domainname, Msgid1, Msgid2, N) \
((void) (Domainname), ngettext (Msgid1, Msgid2, N))
((void)(Domainname), ngettext(Msgid1, Msgid2, N))
# undef dcngettext
# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N))
((void)(Category), dngettext(Domainname, Msgid1, Msgid2, N))
# undef textdomain
# define textdomain(Domainname) ((const char *) (Domainname))
# define textdomain(Domainname) ((const char *)(Domainname))
# undef bindtextdomain
# define bindtextdomain(Domainname, Dirname) \
((void) (Domainname), (const char *) (Dirname))
((void)(Domainname), (const char *)(Dirname))
# undef bind_textdomain_codeset
# define bind_textdomain_codeset(Domainname, Codeset) \
((void) (Domainname), (const char *) (Codeset))
((void)(Domainname), (const char *)(Codeset))
#endif
@ -111,26 +111,26 @@
The letter 'p' stands for 'particular' or 'special'. */
#ifdef DEFAULT_TEXT_DOMAIN
# define pgettext(Msgctxt, Msgid) \
pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
pgettext_aux(DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#else
# define pgettext(Msgctxt, Msgid) \
pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
pgettext_aux(NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#endif
#define dpgettext(Domainname, Msgctxt, Msgid) \
pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
pgettext_aux(Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
pgettext_aux(Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
#ifdef DEFAULT_TEXT_DOMAIN
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
npgettext_aux(DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#else
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
npgettext_aux(NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#endif
#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
npgettext_aux(Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
npgettext_aux(Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
#ifdef __GNUC__
__inline
@ -140,11 +140,12 @@ inline
#endif
#endif
static const char *
pgettext_aux (const char *domain,
pgettext_aux(const char *domain,
const char *msg_ctxt_id, const char *msgid,
int category)
{
const char *translation = dcgettext (domain, msg_ctxt_id, category);
const char *translation = dcgettext(domain, msg_ctxt_id, category);
if (translation == msg_ctxt_id)
return msgid;
else
@ -159,15 +160,16 @@ inline
#endif
#endif
static const char *
npgettext_aux (const char *domain,
npgettext_aux(const char *domain,
const char *msg_ctxt_id, const char *msgid,
const char *msgid_plural, unsigned long int n,
int category)
{
const char *translation =
dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
dcngettext(domain, msg_ctxt_id, msgid_plural, n, category);
if (translation == msg_ctxt_id || translation == msgid_plural)
return (n == 1 ? msgid : msgid_plural);
return(n == 1 ? msgid : msgid_plural);
else
return translation;
}
@ -180,16 +182,16 @@ npgettext_aux (const char *domain,
#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
(((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \
/* || __STDC_VERSION__ >= 199901L */ )
/* || __STDC_VERSION__ >= 199901L */)
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
#include <stdlib.h>
#endif
#define pgettext_expr(Msgctxt, Msgid) \
dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
dcpgettext_expr(NULL, Msgctxt, Msgid, LC_MESSAGES)
#define dpgettext_expr(Domainname, Msgctxt, Msgid) \
dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
dcpgettext_expr(Domainname, Msgctxt, Msgid, LC_MESSAGES)
#ifdef __GNUC__
__inline
@ -199,31 +201,32 @@ inline
#endif
#endif
static const char *
dcpgettext_expr (const char *domain,
dcpgettext_expr(const char *domain,
const char *msgctxt, const char *msgid,
int category)
{
size_t msgctxt_len = strlen (msgctxt) + 1;
size_t msgid_len = strlen (msgid) + 1;
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
char buf[1024];
char *msg_ctxt_id =
(msgctxt_len + msgid_len <= sizeof (buf)
(msgctxt_len + msgid_len <= sizeof(buf)
? buf
: (char *) malloc (msgctxt_len + msgid_len));
: (char *)malloc(msgctxt_len + msgid_len));
if (msg_ctxt_id != NULL)
#endif
{
memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
memcpy(msg_ctxt_id, msgctxt, msgctxt_len - 1);
msg_ctxt_id[msgctxt_len - 1] = '\004';
memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
translation = dcgettext (domain, msg_ctxt_id, category);
memcpy(msg_ctxt_id + msgctxt_len, msgid, msgid_len);
translation = dcgettext(domain, msg_ctxt_id, category);
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
if (msg_ctxt_id != buf)
free (msg_ctxt_id);
free(msg_ctxt_id);
#endif
if (translation != msg_ctxt_id)
return translation;
@ -232,9 +235,9 @@ dcpgettext_expr (const char *domain,
}
#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
dcnpgettext_expr(NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
dcnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
#ifdef __GNUC__
__inline
@ -244,37 +247,38 @@ inline
#endif
#endif
static const char *
dcnpgettext_expr (const char *domain,
dcnpgettext_expr(const char *domain,
const char *msgctxt, const char *msgid,
const char *msgid_plural, unsigned long int n,
int category)
{
size_t msgctxt_len = strlen (msgctxt) + 1;
size_t msgid_len = strlen (msgid) + 1;
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
char buf[1024];
char *msg_ctxt_id =
(msgctxt_len + msgid_len <= sizeof (buf)
(msgctxt_len + msgid_len <= sizeof(buf)
? buf
: (char *) malloc (msgctxt_len + msgid_len));
: (char *)malloc(msgctxt_len + msgid_len));
if (msg_ctxt_id != NULL)
#endif
{
memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
memcpy(msg_ctxt_id, msgctxt, msgctxt_len - 1);
msg_ctxt_id[msgctxt_len - 1] = '\004';
memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
memcpy(msg_ctxt_id + msgctxt_len, msgid, msgid_len);
translation = dcngettext(domain, msg_ctxt_id, msgid_plural, n, category);
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
if (msg_ctxt_id != buf)
free (msg_ctxt_id);
free(msg_ctxt_id);
#endif
if (!(translation == msg_ctxt_id || translation == msgid_plural))
return translation;
}
return (n == 1 ? msgid : msgid_plural);
return(n == 1 ? msgid : msgid_plural);
}
#endif /* _LIBGETTEXT_H */

View File

@ -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;
}

View File

@ -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 {

View File

@ -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"

View File

@ -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, &times))
{
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)
@ -520,7 +544,7 @@ DL_Window::handle_download_thread()
if (err == DLLOCALFATAL)
{
PrintMessage("One connection of the download %s encountered a unrecoverable local error, usually lack of free space, or a write to bad medium, or a problem with permissions,so please fix this and retry\n",
PrintMessage(" One connection of the download % s encountered a unrecoverable local error, usually lack of free space, or a write to bad medium, or a problem with permissions, so please fix this and retry \ n ",
connection->u.url);
got_dl = FALSE;
status = DL_FATALERR;
@ -530,7 +554,7 @@ DL_Window::handle_download_thread()
if (err == DLREMOTEFATAL)
{
PrintMessage(_
("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"),
(" 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 "),
connection->u.url);
got_dl = FALSE;
status = DL_FATALERR;
@ -566,8 +590,8 @@ DL_Window::handle_joining_thread()
/*has the user pressed OK at the end of the download */
if (bDone == true)
{
PrintMessage("All Done.\n");
//curses_query_user_input("Press any key to exit.");
PrintMessage(" All Done.\ n ");
//curses_query_user_input(" Press any key to exit.");
proz_download_delete_dl_file(download);
proz_download_free_download(download, 0);
status = DL_IDLING;
@ -599,7 +623,7 @@ DL_Window::print_status(download_t *download, int quiet_mode)
for (int i = 0; i < download->num_connections; i++)
{
fprintf(stdout,
"%2.2d %-30.30s %15.15s %10zd\n",
" % 2.2d % -30.30s % 15.15s % 10zd \ n ",
i + 1, download->pconnections[i]->u.host,
proz_connection_get_status_string(download->
pconnections
@ -608,11 +632,11 @@ DL_Window::print_status(download_t *download, int quiet_mode)
(download->pconnections[i]));
}
fprintf(stdout, "Total Bytes received %zd Kb\n",
fprintf(stdout, " Total Bytes received % zd Kb \ n ",
proz_download_get_total_bytes_got(download) / 1024);
fprintf(stdout, "Average Speed = %.3f Kb/sec\n",
fprintf(stdout, " Average Speed = % .3f Kb / sec \ n ",
proz_download_get_average_speed(download) / 1024);
}
@ -625,23 +649,23 @@ DL_Window::print_status(download_t *download, int quiet_mode)
{
if (secs_left < 60)
{
snprintf(timeLeft, sizeof(timeLeft), "00:%.2d", secs_left);
snprintf(timeLeft, sizeof(timeLeft), " 00 : % .2d ", secs_left);
}
else if (secs_left < 3600)
{
snprintf(timeLeft, sizeof(timeLeft), "00:%.2d:%.2d",
snprintf(timeLeft, sizeof(timeLeft), " 00 : % .2d : % .2d ",
secs_left / 60, secs_left % 60);
}
else
{
snprintf(timeLeft, sizeof(timeLeft), "%.2d:%.2d:00",
snprintf(timeLeft, sizeof(timeLeft), " % .2d : % .2d : 00 ",
secs_left / 3600,
(secs_left % 3600) / 60);
}
}
else
{
sprintf(timeLeft, "??:??:??");
sprintf(timeLeft, " ? ? : ? ? : ? ? ");
}
off_t totalDownloaded = 0;
@ -656,7 +680,7 @@ DL_Window::print_status(download_t *download, int quiet_mode)
//WGET looks like this:
//xx% [=======> ] nnn,nnn,nnn XXXX.XXK/s ETA hh:mm:ss
fprintf(stdout, " %.2lf%% %zdKb/%zdkb %0.3fKb/s ETA %s \r",
fprintf(stdout, " % .2lf % % % zdKb / % zdkb % 0.3fKb / s ETA % s \ r ",
((float)totalDownloaded) / ((float)totalFile / 100),
totalDownloaded, totalFile, (float)aveSpeed, timeLeft);
fflush(stdout);
@ -667,8 +691,8 @@ DL_Window::print_status(download_t *download, int quiet_mode)
int DL_Window::askUserResume(connection_t *connection, boolean resumeSupported)
{
int ret = 0;
const char msg[] = "Previous download of %s exists, would you like to (R)esume it or (O)verwrite it?";
const char msg2[] = "Previous download of %s exists, would you like to (A)bort it or (O)verwrite it?";
const char msg[] = " Previous download of % s exists, would you like to(R) esume it or (O) verwrite it ? ";
const char msg2[] = " Previous download of % s exists, would you like to(A) bort it or (O) verwrite it ? ";
do
@ -679,7 +703,7 @@ int DL_Window::askUserResume(connection_t *connection, boolean resumeSupported)
}
else
{
fprintf(stdout, "\n");
fprintf(stdout, " \ n ");
fprintf(stdout, (resumeSupported == TRUE) ? msg : msg2, connection->u.file);
ret = getc(stdin);
ret = islower(ret) ? toupper(ret) : ret;
@ -717,7 +741,7 @@ int DL_Window::askUserResume(connection_t *connection, boolean resumeSupported)
int DL_Window::askUserOverwrite(connection_t *connectionb)
{
int ret = 0;
const char msg[] = "File %s already exists, would you like to (A)bort it or (O)verwrite it?";
const char msg[] = " File % s already exists, would you like to(A) bort it or (O) verwrite it ? ";
do
@ -728,7 +752,7 @@ int DL_Window::askUserOverwrite(connection_t *connectionb)
}
else
{
fprintf(stdout, "\n");
fprintf(stdout, " \ n ");
fprintf(stdout, msg, connection->u.file);
ret = getc(stdin);
ret = islower(ret) ? toupper(ret) : ret;

View File

@ -31,10 +31,10 @@
# ifdef DEFAULT_TEXT_DOMAIN
# undef gettext
# define gettext(Msgid) \
dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
dgettext(DEFAULT_TEXT_DOMAIN, Msgid)
# undef ngettext
# define ngettext(Msgid1, Msgid2, N) \
dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
dngettext(DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
# endif
#else
@ -65,31 +65,31 @@
On pre-ANSI systems without 'const', the config.h file is supposed to
contain "#define const". */
# undef gettext
# define gettext(Msgid) ((const char *) (Msgid))
# define gettext(Msgid) ((const char *)(Msgid))
# undef dgettext
# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid))
# define dgettext(Domainname, Msgid) ((void)(Domainname), gettext(Msgid))
# undef dcgettext
# define dcgettext(Domainname, Msgid, Category) \
((void) (Category), dgettext (Domainname, Msgid))
((void)(Category), dgettext(Domainname, Msgid))
# undef ngettext
# define ngettext(Msgid1, Msgid2, N) \
((N) == 1 \
? ((void) (Msgid2), (const char *) (Msgid1)) \
: ((void) (Msgid1), (const char *) (Msgid2)))
? ((void)(Msgid2), (const char *)(Msgid1)) \
: ((void)(Msgid1), (const char *)(Msgid2)))
# undef dngettext
# define dngettext(Domainname, Msgid1, Msgid2, N) \
((void) (Domainname), ngettext (Msgid1, Msgid2, N))
((void)(Domainname), ngettext(Msgid1, Msgid2, N))
# undef dcngettext
# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N))
((void)(Category), dngettext(Domainname, Msgid1, Msgid2, N))
# undef textdomain
# define textdomain(Domainname) ((const char *) (Domainname))
# define textdomain(Domainname) ((const char *)(Domainname))
# undef bindtextdomain
# define bindtextdomain(Domainname, Dirname) \
((void) (Domainname), (const char *) (Dirname))
((void)(Domainname), (const char *)(Dirname))
# undef bind_textdomain_codeset
# define bind_textdomain_codeset(Domainname, Codeset) \
((void) (Domainname), (const char *) (Codeset))
((void)(Domainname), (const char *)(Codeset))
#endif
@ -111,26 +111,26 @@
The letter 'p' stands for 'particular' or 'special'. */
#ifdef DEFAULT_TEXT_DOMAIN
# define pgettext(Msgctxt, Msgid) \
pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
pgettext_aux(DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#else
# define pgettext(Msgctxt, Msgid) \
pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
pgettext_aux(NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#endif
#define dpgettext(Domainname, Msgctxt, Msgid) \
pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
pgettext_aux(Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
pgettext_aux(Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
#ifdef DEFAULT_TEXT_DOMAIN
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
npgettext_aux(DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#else
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
npgettext_aux(NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#endif
#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
npgettext_aux(Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
npgettext_aux(Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
#ifdef __GNUC__
__inline
@ -140,11 +140,12 @@ inline
#endif
#endif
static const char *
pgettext_aux (const char *domain,
pgettext_aux(const char *domain,
const char *msg_ctxt_id, const char *msgid,
int category)
{
const char *translation = dcgettext (domain, msg_ctxt_id, category);
const char *translation = dcgettext(domain, msg_ctxt_id, category);
if (translation == msg_ctxt_id)
return msgid;
else
@ -159,15 +160,16 @@ inline
#endif
#endif
static const char *
npgettext_aux (const char *domain,
npgettext_aux(const char *domain,
const char *msg_ctxt_id, const char *msgid,
const char *msgid_plural, unsigned long int n,
int category)
{
const char *translation =
dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
dcngettext(domain, msg_ctxt_id, msgid_plural, n, category);
if (translation == msg_ctxt_id || translation == msgid_plural)
return (n == 1 ? msgid : msgid_plural);
return(n == 1 ? msgid : msgid_plural);
else
return translation;
}
@ -180,16 +182,16 @@ npgettext_aux (const char *domain,
#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
(((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \
/* || __STDC_VERSION__ >= 199901L */ )
/* || __STDC_VERSION__ >= 199901L */)
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
#include <stdlib.h>
#endif
#define pgettext_expr(Msgctxt, Msgid) \
dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
dcpgettext_expr(NULL, Msgctxt, Msgid, LC_MESSAGES)
#define dpgettext_expr(Domainname, Msgctxt, Msgid) \
dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
dcpgettext_expr(Domainname, Msgctxt, Msgid, LC_MESSAGES)
#ifdef __GNUC__
__inline
@ -199,31 +201,32 @@ inline
#endif
#endif
static const char *
dcpgettext_expr (const char *domain,
dcpgettext_expr(const char *domain,
const char *msgctxt, const char *msgid,
int category)
{
size_t msgctxt_len = strlen (msgctxt) + 1;
size_t msgid_len = strlen (msgid) + 1;
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
char buf[1024];
char *msg_ctxt_id =
(msgctxt_len + msgid_len <= sizeof (buf)
(msgctxt_len + msgid_len <= sizeof(buf)
? buf
: (char *) malloc (msgctxt_len + msgid_len));
: (char *)malloc(msgctxt_len + msgid_len));
if (msg_ctxt_id != NULL)
#endif
{
memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
memcpy(msg_ctxt_id, msgctxt, msgctxt_len - 1);
msg_ctxt_id[msgctxt_len - 1] = '\004';
memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
translation = dcgettext (domain, msg_ctxt_id, category);
memcpy(msg_ctxt_id + msgctxt_len, msgid, msgid_len);
translation = dcgettext(domain, msg_ctxt_id, category);
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
if (msg_ctxt_id != buf)
free (msg_ctxt_id);
free(msg_ctxt_id);
#endif
if (translation != msg_ctxt_id)
return translation;
@ -232,9 +235,9 @@ dcpgettext_expr (const char *domain,
}
#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
dcnpgettext_expr(NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
dcnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
#ifdef __GNUC__
__inline
@ -244,37 +247,38 @@ inline
#endif
#endif
static const char *
dcnpgettext_expr (const char *domain,
dcnpgettext_expr(const char *domain,
const char *msgctxt, const char *msgid,
const char *msgid_plural, unsigned long int n,
int category)
{
size_t msgctxt_len = strlen (msgctxt) + 1;
size_t msgid_len = strlen (msgid) + 1;
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
char buf[1024];
char *msg_ctxt_id =
(msgctxt_len + msgid_len <= sizeof (buf)
(msgctxt_len + msgid_len <= sizeof(buf)
? buf
: (char *) malloc (msgctxt_len + msgid_len));
: (char *)malloc(msgctxt_len + msgid_len));
if (msg_ctxt_id != NULL)
#endif
{
memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
memcpy(msg_ctxt_id, msgctxt, msgctxt_len - 1);
msg_ctxt_id[msgctxt_len - 1] = '\004';
memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
memcpy(msg_ctxt_id + msgctxt_len, msgid, msgid_len);
translation = dcngettext(domain, msg_ctxt_id, msgid_plural, n, category);
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
if (msg_ctxt_id != buf)
free (msg_ctxt_id);
free(msg_ctxt_id);
#endif
if (!(translation == msg_ctxt_id || translation == msgid_plural))
return translation;
}
return (n == 1 ? msgid : msgid_plural);
return(n == 1 ? msgid : msgid_plural);
}
#endif /* _LIBGETTEXT_H */

View File

@ -57,7 +57,7 @@
* CONREJECTED,
* REMOTEFATAL,
* LOCALFATAL
**} dl_status;
****} dl_status;
*
* And here are the texts for the above enums.
*/

View File

@ -9,7 +9,7 @@
/* Gettext */
#include "gettext.h"
#define _(String) dgettext (PACKAGE, String)
#define _(String) dgettext(PACKAGE, String)
/* Gettext */