replaced read_whole_file() by getline()

This commit is contained in:
Tim Ruehsen 2013-05-09 22:37:17 +02:00 committed by Giuseppe Scrivano
parent e976d4f3dc
commit 099d8ee3da
8 changed files with 170 additions and 268 deletions

View File

@ -1,3 +1,18 @@
2013-05-14 Tim Ruehsen <tim.ruehsen@gmx.de>
* cookies.c (cookie_jar_load): Replaced read_whole_file() by getline().
* init.c (run_wgetrc): Likewise.
* netrc.c (parse_netrc): Likewise.
* utils.c: Likewise.
* ftp.c (getftp): Likewise.
* ftp-ls.c (ftp_parse_unix_ls, ftp_parse_winnt_ls, ftp_parse_vms_ls): Likewise.
* ftp-ls.c (clean_line): Accept the string length as parameter.
* ftp-ls.c: Replaced indent tabs by spaces.
* ftp.c: Likewise.
* utils.c: Removed read_whole_file() definition.
* netrc.c: Removed read_whole_file() definition for STANDALONE.
* utils.h: Removed read_whole_file() declaration.
2013-05-09 Tim Ruehsen <tim.ruehsen@gmx.de>
* utils.c (acceptable): use standard string functions instead of

View File

@ -1129,7 +1129,9 @@ domain_port (const char *domain_b, const char *domain_e,
void
cookie_jar_load (struct cookie_jar *jar, const char *file)
{
char *line;
char *line = NULL;
size_t bufsize = 0;
FILE *fp = fopen (file, "r");
if (!fp)
{
@ -1137,9 +1139,10 @@ cookie_jar_load (struct cookie_jar *jar, const char *file)
quote (file), strerror (errno));
return;
}
cookies_now = time (NULL);
for (; ((line = read_whole_line (fp)) != NULL); xfree (line))
while (getline (&line, &bufsize, fp) > 0)
{
struct cookie *cookie;
char *p = line;
@ -1233,6 +1236,8 @@ cookie_jar_load (struct cookie_jar *jar, const char *file)
abort_cookie:
delete_cookie (cookie);
}
xfree(line);
fclose (fp);
}

View File

@ -68,16 +68,17 @@ symperms (const char *s)
replaces all <TAB> character with <SPACE>. Returns the length of the
modified line. */
static int
clean_line(char *line)
clean_line (char *line, int len)
{
int len = strlen (line);
if (!len) return 0;
if (line[len - 1] == '\n')
if (len <= 0) return 0;
while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r'))
line[--len] = '\0';
if (!len) return 0;
if (line[len - 1] == '\r')
line[--len] = '\0';
for ( ; *line ; line++ ) if (*line == '\t') *line = ' ';
return len;
}
@ -102,8 +103,9 @@ ftp_parse_unix_ls (const char *file, int ignore_perms)
int hour, min, sec, ptype;
struct tm timestruct, *tnow;
time_t timenow;
size_t bufsize = 0;
char *line, *tok, *ptok; /* tokenizer */
char *line = NULL, *tok, *ptok; /* tokenizer */
struct fileinfo *dir, *l, cur; /* list creation */
fp = fopen (file, "rb");
@ -115,22 +117,16 @@ ftp_parse_unix_ls (const char *file, int ignore_perms)
dir = l = NULL;
/* Line loop to end of file: */
while ((line = read_whole_line (fp)) != NULL)
while ((len = getline (&line, &bufsize, fp)) > 0)
{
len = clean_line (line);
len = clean_line (line, len);
/* Skip if total... */
if (!strncasecmp (line, "total", 5))
{
xfree (line);
continue;
}
continue;
/* Get the first token (permissions). */
tok = strtok (line, " ");
if (!tok)
{
xfree (line);
continue;
}
continue;
cur.name = NULL;
cur.linkto = NULL;
@ -368,7 +364,6 @@ ftp_parse_unix_ls (const char *file, int ignore_perms)
DEBUGP (("Skipping.\n"));
xfree_null (cur.name);
xfree_null (cur.linkto);
xfree (line);
continue;
}
@ -416,10 +411,9 @@ ftp_parse_unix_ls (const char *file, int ignore_perms)
timestruct.tm_isdst = -1;
l->tstamp = mktime (&timestruct); /* store the time-stamp */
l->ptype = ptype;
xfree (line);
}
xfree (line);
fclose (fp);
return dir;
}
@ -431,9 +425,10 @@ ftp_parse_winnt_ls (const char *file)
int len;
int year, month, day; /* for time analysis */
int hour, min;
size_t bufsize = 0;
struct tm timestruct;
char *line, *tok; /* tokenizer */
char *line = NULL, *tok; /* tokenizer */
char *filename;
struct fileinfo *dir, *l, cur; /* list creation */
@ -446,42 +441,42 @@ ftp_parse_winnt_ls (const char *file)
dir = l = NULL;
/* Line loop to end of file: */
while ((line = read_whole_line (fp)) != NULL)
while ((len = getline (&line, &bufsize, fp)) > 0)
{
len = clean_line (line);
len = clean_line (line, len);
/* Name begins at 39 column of the listing if date presented in `mm-dd-yy'
format or at 41 column if date presented in `mm-dd-yyyy' format. Thus,
we cannot extract name before we parse date. Using this information we
also can recognize filenames that begin with a series of space
characters (but who really wants to use such filenames anyway?). */
if (len < 40) goto continue_loop;
if (len < 40) continue;
filename = line + 39;
/* First column: mm-dd-yy or mm-dd-yyyy. Should atoi() on the month fail,
january will be assumed. */
tok = strtok(line, "-");
if (tok == NULL) goto continue_loop;
if (tok == NULL) continue;
month = atoi(tok) - 1;
if (month < 0) month = 0;
tok = strtok(NULL, "-");
if (tok == NULL) goto continue_loop;
if (tok == NULL) continue;
day = atoi(tok);
tok = strtok(NULL, " ");
if (tok == NULL) goto continue_loop;
if (tok == NULL) continue;
year = atoi(tok);
/* Assuming the epoch starting at 1.1.1970 */
if (year <= 70)
{
year += 100;
}
{
year += 100;
}
else if (year >= 1900)
{
year -= 1900;
filename += 2;
}
{
year -= 1900;
filename += 2;
}
/* Now it is possible to determine the position of the first symbol in
filename. */
filename. */
cur.name = xstrdup(filename);
DEBUGP (("Name: '%s'\n", cur.name));
@ -489,10 +484,10 @@ ftp_parse_winnt_ls (const char *file)
/* Second column: hh:mm[AP]M, listing does not contain value for
seconds */
tok = strtok(NULL, ":");
if (tok == NULL) goto continue_loop;
if (tok == NULL) continue;
hour = atoi(tok);
tok = strtok(NULL, "M");
if (tok == NULL) goto continue_loop;
if (tok == NULL) continue;
min = atoi(tok);
/* Adjust hour from AM/PM. Just for the record, the sequence goes
11:00AM, 12:00PM, 01:00PM ... 11:00PM, 12:00AM, 01:00AM . */
@ -523,9 +518,9 @@ ftp_parse_winnt_ls (const char *file)
directories as the listing does not give us a clue) and filetype
here. */
tok = strtok(NULL, " ");
if (tok == NULL) goto continue_loop;
if (tok == NULL) continue;
while ((tok != NULL) && (*tok == '\0')) tok = strtok(NULL, " ");
if (tok == NULL) goto continue_loop;
if (tok == NULL) continue;
if (*tok == '<')
{
cur.type = FT_DIRECTORY;
@ -564,11 +559,9 @@ ftp_parse_winnt_ls (const char *file)
memcpy (l, &cur, sizeof (cur));
l->next = NULL;
}
continue_loop:
xfree (line);
}
xfree (line);
fclose(fp);
return dir;
}
@ -689,11 +682,12 @@ ftp_parse_vms_ls (const char *file)
FILE *fp;
int dt, i, j, len;
int perms;
size_t bufsize = 0;
time_t timenow;
struct tm *timestruct;
char date_str[ 32];
char *line, *tok; /* tokenizer */
char *line = NULL, *tok; /* tokenizer */
struct fileinfo *dir, *l, cur; /* list creation */
fp = fopen (file, "r");
@ -706,52 +700,34 @@ ftp_parse_vms_ls (const char *file)
/* Skip blank lines, Directory heading, and more blank lines. */
j = 0; /* Expecting initial blank line(s). */
while (1)
for (j = 0; (i = getline (&line, &bufsize, fp)) > 0; )
{
line = read_whole_line (fp);
if (line == NULL)
i = clean_line (line, i);
if (i <= 0)
continue; /* Ignore blank line. */
if ((j == 0) && (line[i - 1] == ']'))
{
break;
/* Found Directory heading line. Next non-blank line
is significant. */
j = 1;
}
else if (!strncmp (line, "Total of ", 9))
{
/* Found "Total of ..." footing line. No valid data
will follow (empty directory). */
i = 0; /* Arrange for early exit. */
break;
}
else
{
i = clean_line (line);
if (i <= 0)
{
xfree (line); /* Free useless line storage. */
continue; /* Blank line. Keep looking. */
}
else
{
if ((j == 0) && (line[ i- 1] == ']'))
{
/* Found Directory heading line. Next non-blank line
is significant.
*/
j = 1;
}
else if (!strncmp (line, "Total of ", 9))
{
/* Found "Total of ..." footing line. No valid data
will follow (empty directory).
*/
xfree (line); /* Free useless line storage. */
line = NULL; /* Arrange for early exit. */
break;
}
else
{
break; /* Must be significant data. */
}
}
xfree (line); /* Free useless line storage. */
break; /* Must be significant data. */
}
}
/* Read remainder of file until the next blank line or EOF. */
while (line != NULL)
while (i > 0)
{
char *p;
@ -842,9 +818,8 @@ ftp_parse_vms_ls (const char *file)
if (tok == NULL)
{
DEBUGP (("Getting additional line.\n"));
xfree (line);
line = read_whole_line (fp);
if (!line)
i = getline (&line, &bufsize, fp);
if (i <= 0)
{
DEBUGP (("EOF. Leaving listing parser.\n"));
break;
@ -853,14 +828,14 @@ ftp_parse_vms_ls (const char *file)
/* Second line must begin with " ". Otherwise, it's a first
line (and we may be confused).
*/
i = clean_line (line, i);
if (i <= 0)
{
/* Blank line. End of significant file listing. */
DEBUGP (("Blank line. Leaving listing parser.\n"));
xfree (line); /* Free useless line storage. */
break;
}
else if (line[ 0] != ' ')
else if (line[0] != ' ')
{
DEBUGP (("Non-blank in column 1. Must be a new file name?\n"));
continue;
@ -872,7 +847,6 @@ ftp_parse_vms_ls (const char *file)
{
/* Unexpected non-empty but apparently blank line. */
DEBUGP (("Null token. Leaving listing parser.\n"));
xfree (line); /* Free useless line storage. */
break;
}
}
@ -911,7 +885,7 @@ ftp_parse_vms_ls (const char *file)
(sizeof( date_str)- strlen (date_str) - 1));
DEBUGP (("Date time: >%s<\n", date_str));
}
else if (strchr ( tok, '[') != NULL)
else if (strchr (tok, '[') != NULL)
{
/* Owner. (Ignore.) */
DEBUGP (("Owner.\n"));
@ -921,7 +895,7 @@ ftp_parse_vms_ls (const char *file)
/* Protections (permissions). */
perms = 0;
j = 0;
for (i = 0; i < strlen( tok); i++)
for (i = 0; i < strlen(tok); i++)
{
switch (tok[ i])
{
@ -1015,21 +989,19 @@ ftp_parse_vms_ls (const char *file)
l->next = NULL;
}
/* Free old line storage. Read a new line. */
xfree (line);
line = read_whole_line (fp);
if (line != NULL)
i = getline (&line, &bufsize, fp);
if (i > 0)
{
i = clean_line (line);
i = clean_line (line, i);
if (i <= 0)
{
{
/* Blank line. End of significant file listing. */
xfree (line); /* Free useless line storage. */
break;
}
break;
}
}
}
xfree (line);
fclose (fp);
return dir;
}

142
src/ftp.c
View File

@ -616,16 +616,16 @@ Error in server response, closing control connection.\n"));
The VMS restriction may be relaxed when the squirrely code
above is reformed.
*/
if ((con->rs == ST_VMS) && (target[0] != '/'))
{
cwd_start = 0;
DEBUGP (("Using two-step CWD for relative path.\n"));
}
else
{
if ((con->rs == ST_VMS) && (target[0] != '/'))
{
cwd_start = 0;
DEBUGP (("Using two-step CWD for relative path.\n"));
}
else
{
/* Go straight to the target. */
cwd_start = 1;
}
cwd_start = 1;
}
/* At least one VMS FTP server (TCPware V5.6-2) can switch to
a UNIX emulation mode when given a UNIX-like directory
@ -643,10 +643,10 @@ Error in server response, closing control connection.\n"));
Unlike the rest of this block, this particular behavior
_is_ VMS-specific, so it gets its own VMS test.
*/
if ((con->rs == ST_VMS) && (strchr( target, '/') != NULL))
if ((con->rs == ST_VMS) && (strchr( target, '/') != NULL))
{
cwd_end = 3;
DEBUGP (("Using extra \"CWD []\" step for VMS server.\n"));
DEBUGP (("Using extra \"CWD []\" step for VMS server.\n"));
}
else
{
@ -656,22 +656,22 @@ Error in server response, closing control connection.\n"));
/* 2004-09-20 SMS. */
/* Sorry about the deviant indenting. Laziness. */
for (cwd_count = cwd_start; cwd_count < cwd_end; cwd_count++)
{
for (cwd_count = cwd_start; cwd_count < cwd_end; cwd_count++)
{
switch (cwd_count)
{
case 0:
/* Step one (optional): Go to the initial directory,
exactly as reported by the server.
*/
targ = con->id;
/* Step one (optional): Go to the initial directory,
exactly as reported by the server.
*/
targ = con->id;
break;
case 1:
/* Step two: Go to the target directory. (Absolute or
relative will work now.)
*/
targ = target;
/* Step two: Go to the target directory. (Absolute or
relative will work now.)
*/
targ = target;
break;
case 2:
@ -684,7 +684,7 @@ Error in server response, closing control connection.\n"));
default:
/* Can't happen. */
assert (1);
}
}
if (!opt.server_response)
logprintf (LOG_VERBOSE, "==> CWD (%d) %s ... ", cwd_count,
@ -938,42 +938,42 @@ Error in server response, closing control connection.\n"));
if (cmd & DO_RETR)
{
/* If we're in spider mode, don't really retrieve anything except
the directory listing and verify whether the given "file" exists. */
the directory listing and verify whether the given "file" exists. */
if (opt.spider)
{
bool exists = false;
uerr_t res;
struct fileinfo *f;
res = ftp_get_listing (u, con, &f);
/* Set the DO_RETR command flag again, because it gets unset when
calling ftp_get_listing() and would otherwise cause an assertion
failure earlier on when this function gets repeatedly called
(e.g., when recursing). */
con->cmd |= DO_RETR;
if (res == RETROK)
{
while (f)
{
if (!strcmp (f->name, u->file))
{
exists = true;
break;
}
f = f->next;
}
bool exists = false;
uerr_t res;
struct fileinfo *f;
res = ftp_get_listing (u, con, &f);
/* Set the DO_RETR command flag again, because it gets unset when
calling ftp_get_listing() and would otherwise cause an assertion
failure earlier on when this function gets repeatedly called
(e.g., when recursing). */
con->cmd |= DO_RETR;
if (res == RETROK)
{
while (f)
{
if (!strcmp (f->name, u->file))
{
exists = true;
break;
}
f = f->next;
}
if (exists)
{
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET, _("File %s exists.\n"),
quote (u->file));
}
else
else
{
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET, _("No such file %s.\n"),
quote (u->file));
}
}
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET, _("No such file %s.\n"),
quote (u->file));
}
}
fd_close (csock);
con->csock = -1;
fd_close (dtsock);
@ -1184,20 +1184,20 @@ Error in server response, closing control connection.\n"));
else if (opt.noclobber || opt.always_rest || opt.timestamping || opt.dirstruct
|| opt.output_document || count > 0)
{
if (opt.unlink && file_exists_p (con->target))
{
int res = unlink (con->target);
if (res < 0)
{
logprintf (LOG_NOTQUIET, "%s: %s\n", con->target,
strerror (errno));
fd_close (csock);
con->csock = -1;
fd_close (dtsock);
fd_close (local_sock);
return UNLINKERR;
}
}
if (opt.unlink && file_exists_p (con->target))
{
int res = unlink (con->target);
if (res < 0)
{
logprintf (LOG_NOTQUIET, "%s: %s\n", con->target,
strerror (errno));
fd_close (csock);
con->csock = -1;
fd_close (dtsock);
fd_close (local_sock);
return UNLINKERR;
}
}
#ifdef __VMS
int open_id;
@ -1367,18 +1367,20 @@ Error in server response, closing control connection.\n"));
logprintf (LOG_ALWAYS, "%s: %s\n", con->target, strerror (errno));
else
{
char *line;
/* The lines are being read with read_whole_line because of
char *line = NULL;
size_t bufsize = 0;
ssize_t len;
/* The lines are being read with getline because of
no-buffering on opt.lfile. */
while ((line = read_whole_line (fp)) != NULL)
while ((len = getline (&line, &bufsize, fp)) > 0)
{
char *p = strchr (line, '\0');
while (p > line && (p[-1] == '\n' || p[-1] == '\r'))
*--p = '\0';
while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r'))
line[--len] = '\0';
logprintf (LOG_ALWAYS, "%s\n",
quotearg_style (escape_quoting_style, line));
xfree (line);
}
xfree (line);
fclose (fp);
}
} /* con->cmd & DO_LIST && server_response */

View File

@ -574,7 +574,8 @@ bool
run_wgetrc (const char *file)
{
FILE *fp;
char *line;
char *line = NULL;
size_t bufsize = 0;
int ln;
int errcnt = 0;
@ -586,7 +587,7 @@ run_wgetrc (const char *file)
return true; /* not a fatal error */
}
ln = 1;
while ((line = read_whole_line (fp)) != NULL)
while (getline (&line, &bufsize, fp) > 0)
{
char *com = NULL, *val = NULL;
int comind;
@ -620,9 +621,9 @@ run_wgetrc (const char *file)
}
xfree_null (com);
xfree_null (val);
xfree (line);
++ln;
}
xfree (line);
fclose (fp);
return errcnt == 0;

View File

@ -164,48 +164,6 @@ search_netrc (const char *host, const char **acc, const char **passwd,
# define xrealloc realloc
/* Read a line from FP. The function reallocs the storage as needed
to accomodate for any length of the line. Reallocs are done
storage exponentially, doubling the storage after each overflow to
minimize the number of calls to realloc() and fgets(). The newline
character at the end of line is retained.
After end-of-file is encountered without anything being read, NULL
is returned. NULL is also returned on error. To distinguish
between these two cases, use the stdio function ferror(). */
char *
read_whole_line (FILE *fp)
{
int length = 0;
int bufsize = 81;
char *line = xmalloc (bufsize);
while (fgets (line + length, bufsize - length, fp))
{
length += strlen (line + length);
assert (length > 0);
if (line[length - 1] == '\n')
break;
/* fgets() guarantees to read the whole line, or to use up the
space we've given it. We can double the buffer
unconditionally. */
bufsize <<= 1;
line = xrealloc (line, bufsize);
}
if (length == 0 || ferror (fp))
{
xfree (line);
return NULL;
}
if (length + 1 < bufsize)
/* Relieve the memory from our exponential greediness. We say
`length + 1' because the terminating \0 is not included in
LENGTH. We don't need to zero-terminate the string ourselves,
though, because fgets() does that. */
line = xrealloc (line, length + 1);
return line;
}
#endif /* STANDALONE */
/* Maybe add NEWENTRY to the account information list, LIST. NEWENTRY is
@ -264,10 +222,11 @@ static acc_t *
parse_netrc (const char *path)
{
FILE *fp;
char *line, *p, *tok;
char *line = NULL, *p, *tok;
const char *premature_token;
acc_t *current, *retval;
int ln, qmark;
size_t bufsize = 0;
/* The latest token we've seen in the file. */
enum
@ -290,7 +249,7 @@ parse_netrc (const char *path)
premature_token = NULL;
/* While there are lines in the file... */
while ((line = read_whole_line (fp)) != NULL)
while (getline (&line, &bufsize, fp) > 0)
{
ln ++;
@ -423,10 +382,9 @@ parse_netrc (const char *path)
exec_name, path, ln, tok);
}
}
xfree (line);
}
xfree (line);
fclose (fp);
/* Finalize the last machine entry we found. */

View File

@ -1118,56 +1118,6 @@ has_html_suffix_p (const char *fname)
return false;
}
/* Read a line from FP and return the pointer to freshly allocated
storage. The storage space is obtained through malloc() and should
be freed with free() when it is no longer needed.
The length of the line is not limited, except by available memory.
The newline character at the end of line is retained. The line is
terminated with a zero character.
After end-of-file is encountered without anything being read, NULL
is returned. NULL is also returned on error. To distinguish
between these two cases, use the stdio function ferror(). */
char *
read_whole_line (FILE *fp)
{
int length = 0;
int bufsize = 82;
char *line = xmalloc (bufsize);
while (fgets (line + length, bufsize - length, fp))
{
length += strlen (line + length);
if (length == 0)
/* Possible for example when reading from a binary file where
a line begins with \0. */
continue;
if (line[length - 1] == '\n')
break;
/* fgets() guarantees to read the whole line, or to use up the
space we've given it. We can double the buffer
unconditionally. */
bufsize <<= 1;
line = xrealloc (line, bufsize);
}
if (length == 0 || ferror (fp))
{
xfree (line);
return NULL;
}
if (length + 1 < bufsize)
/* Relieve the memory from our exponential greediness. We say
`length + 1' because the terminating \0 is not included in
LENGTH. We don't need to zero-terminate the string ourselves,
though, because fgets() does that. */
line = xrealloc (line, length + 1);
return line;
}
/* Read FILE into memory. A pointer to `struct file_memory' are
returned; use struct element `content' to access file contents, and
the element `length' to know the file length. `content' is *not*

View File

@ -98,7 +98,6 @@ bool has_wildcards_p (const char *);
bool has_html_suffix_p (const char *);
char *read_whole_line (FILE *);
struct file_memory *wget_read_file (const char *);
void wget_read_file_free (struct file_memory *);