#endif
#include <fcntl.h>
#include <assert.h>
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
#include "wget.h"
#include "utils.h"
#endif /* DEBUG_MALLOC */
\f
+/* Utility function: like xstrdup(), but also lowercases S. */
+
+char *
+xstrdup_lower (const char *s)
+{
+ char *copy = xstrdup (s);
+ char *p = copy;
+ for (; *p; p++)
+ *p = TOLOWER (*p);
+ return copy;
+}
+
+/* Return a count of how many times CHR occurs in STRING. */
+
+int
+count_char (const char *string, char chr)
+{
+ const char *p;
+ int count = 0;
+ for (p = string; *p; p++)
+ if (*p == chr)
+ ++count;
+ return count;
+}
+
/* Copy the string formed by two pointers (one on the beginning, other
on the char after the last char) to a new, malloc-ed location.
0-terminate it. */
}
#endif /* not WINDOWS */
\f
+#if 0
+/* debug */
char *
ps (char *orig)
{
path_simplify (r);
return r;
}
+#endif
/* Canonicalize PATH, and return a new path. The new path differs from PATH
in that:
Change the original string instead of strdup-ing.
React correctly when beginning with `./' and `../'.
Don't zip out trailing slashes. */
-void
+int
path_simplify (char *path)
{
- register int i, start, ddot;
+ register int i, start;
+ int changes = 0;
char stub_char;
if (!*path)
- return;
+ return 0;
- /*stub_char = (*path == '/') ? '/' : '.';*/
stub_char = '/';
- /* Addition: Remove all `./'-s preceding the string. If `../'-s
- precede, put `/' in front and remove them too. */
- i = 0;
- ddot = 0;
- while (1)
- {
- if (path[i] == '.' && path[i + 1] == '/')
- i += 2;
- else if (path[i] == '.' && path[i + 1] == '.' && path[i + 2] == '/')
- {
- i += 3;
- ddot = 1;
- }
- else
- break;
- }
- if (i)
- strcpy (path, path + i - ddot);
+ if (path[0] == '/')
+ /* Preserve initial '/'. */
+ ++path;
- /* Replace single `.' or `..' with `/'. */
+ /* Nix out leading `.' or `..' with. */
if ((path[0] == '.' && path[1] == '\0')
|| (path[0] == '.' && path[1] == '.' && path[2] == '\0'))
{
- path[0] = stub_char;
- path[1] = '\0';
- return;
+ path[0] = '\0';
+ changes = 1;
+ return changes;
}
+
/* Walk along PATH looking for things to compact. */
i = 0;
while (1)
{
strcpy (path + start + 1, path + i);
i = start + 1;
+ changes = 1;
}
/* Check for `../', `./' or trailing `.' by itself. */
if (!path[i + 1])
{
path[--i] = '\0';
+ changes = 1;
break;
}
{
strcpy (path + i, path + i + 1);
i = (start < 0) ? 0 : start;
+ changes = 1;
continue;
}
(path[i + 2] == '/' || !path[i + 2]))
{
while (--start > -1 && path[start] != '/');
- strcpy (path + start + 1, path + i + 2);
+ strcpy (path + start + 1, path + i + 2 + (start == -1 && path[i + 2]));
i = (start < 0) ? 0 : start;
+ changes = 1;
continue;
}
} /* path == '.' */
} /* while */
+
+ /* Addition: Remove all `./'-s and `../'-s preceding the string. */
+ i = 0;
+ while (1)
+ {
+ if (path[i] == '.' && path[i + 1] == '/')
+ i += 2;
+ else if (path[i] == '.' && path[i + 1] == '.' && path[i + 2] == '/')
+ i += 3;
+ else
+ break;
+ }
+ if (i)
+ {
+ strcpy (path, path + i - 0);
+ changes = 1;
+ }
+
+ return changes;
}
\f
/* "Touch" FILE, i.e. make its atime and mtime equal to the time
match_backwards ("abc", "bc") -> 1
match_backwards ("abc", "ab") -> 0
match_backwards ("abc", "abc") -> 1 */
-static int
-match_backwards (const char *string, const char *pattern)
+int
+match_tail (const char *string, const char *pattern)
{
int i, j;
}
/* Checks whether string S matches each element of ACCEPTS. A list
- element are matched either with fnmatch() or match_backwards(),
+ element are matched either with fnmatch() or match_tail(),
according to whether the element contains wildcards or not.
If the BACKWARD is 0, don't do backward comparison -- just compare
{
if (backward)
{
- if (match_backwards (s, *accepts))
+ if (match_tail (s, *accepts))
return 1;
}
else
return 0;
}
-/* Return the malloc-ed suffix of STR. For instance:
+/* Return the location of STR's suffix (file extension). Examples:
suffix ("foo.bar") -> "bar"
suffix ("foo.bar.baz") -> "baz"
suffix ("/foo/bar") -> NULL
{
int i;
- for (i = strlen (str); i && str[i] != '/' && str[i] != '.'; i--);
+ for (i = strlen (str); i && str[i] != '/' && str[i] != '.'; i--)
+ ;
+
if (str[i++] == '.')
- return xstrdup (str + i);
+ return (char *)str + i;
else
return NULL;
}
*p = '\0';
return res;
}
+
+/* Determine the width of the terminal we're running on. If that's
+ not possible, return 0. */
+
+int
+determine_screen_width (void)
+{
+ /* If there's a way to get the terminal size using POSIX
+ tcgetattr(), somebody please tell me. */
+#ifndef TIOCGWINSZ
+ return 0;
+#else /* TIOCGWINSZ */
+ int fd;
+ struct winsize wsz;
+
+ if (opt.lfilename != NULL)
+ return 0;
+
+ fd = fileno (stderr);
+ if (ioctl (fd, TIOCGWINSZ, &wsz) < 0)
+ return 0; /* most likely ENOTTY */
+
+ return wsz.ws_col;
+#endif /* TIOCGWINSZ */
+}
+
+#if 1
+/* A debugging function for checking whether an MD5 library works. */
+
+#include "gen-md5.h"
+
+char *
+debug_test_md5 (char *buf)
+{
+ unsigned char raw[16];
+ static char res[33];
+ unsigned char *p1;
+ char *p2;
+ int cnt;
+ ALLOCA_MD5_CONTEXT (ctx);
+
+ gen_md5_init (ctx);
+ gen_md5_update ((unsigned char *)buf, strlen (buf), ctx);
+ gen_md5_finish (ctx, raw);
+
+ p1 = raw;
+ p2 = res;
+ cnt = 16;
+ while (cnt--)
+ {
+ *p2++ = XDIGIT_TO_xchar (*p1 >> 4);
+ *p2++ = XDIGIT_TO_xchar (*p1 & 0xf);
+ ++p1;
+ }
+ *p2 = '\0';
+
+ return res;
+}
+#endif