size <<= 1; /* twice the old size */
str = xrealloc (str, size);
}
- return NULL; /* unreached */
}
/* Concatenate the NULL-terminated list of string arguments into
}
#endif /* not WINDOWS */
\f
-/* "Touch" FILE, i.e. make its atime and mtime equal to the time
- specified with TM. */
+/* "Touch" FILE, i.e. make its mtime ("modified time") equal the time
+ specified with TM. The atime ("access time") is set to the current
+ time. */
+
void
touch (const char *file, time_t tm)
{
#ifdef HAVE_STRUCT_UTIMBUF
struct utimbuf times;
- times.actime = times.modtime = tm;
#else
- time_t times[2];
- times[0] = times[1] = tm;
+ struct {
+ time_t actime;
+ time_t modtime;
+ } times;
#endif
-
+ times.modtime = tm;
+ times.actime = time (NULL);
if (utime (file, ×) == -1)
logprintf (LOG_NOTQUIET, "utime(%s): %s\n", file, strerror (errno));
}
proclist (char **strlist, const char *s, enum accd flags)
{
char **x;
-
for (x = strlist; *x; x++)
- if (has_wildcards_p (*x))
- {
- if (fnmatch (*x, s, FNM_PATHNAME) == 0)
- break;
- }
- else
- {
- char *p = *x + ((flags & ALLABS) && (**x == '/')); /* Remove '/' */
- if (frontcmp (p, s))
- break;
- }
+ {
+ /* Remove leading '/' if ALLABS */
+ char *p = *x + ((flags & ALLABS) && (**x == '/'));
+ if (has_wildcards_p (p))
+ {
+ if (fnmatch (p, s, FNM_PATHNAME) == 0)
+ break;
+ }
+ else
+ {
+ if (frontcmp (p, s))
+ break;
+ }
+ }
return *x;
}
usually improves readability."
This intentionally uses kilobyte (KB), megabyte (MB), etc. in their
- original computer science meaning of "multiples of 1024".
- Multiples of 1000 would be useless since Wget already adds thousand
- separators for legibility. We don't use the "*bibyte" names
- invented in 1998, and seldom used in practice. Wikipedia's entry
- on kilobyte discusses this in some detail. */
+ original computer science meaning of "powers of 1024". Powers of
+ 1000 would be useless since Wget already displays sizes with
+ thousand separators. We don't use the "*bibyte" names invented in
+ 1998, and seldom used in practice. Wikipedia's entry on kilobyte
+ discusses this in some detail. */
char *
human_readable (wgint n)
return buf;
}
\f
-/* Support for timers. */
-
-#undef TIMER_WINDOWS
-#undef TIMER_GETTIMEOFDAY
-#undef TIMER_TIME
-
-/* Depending on the OS and availability of gettimeofday(), one and
- only one of the above constants will be defined. Virtually all
- modern Unix systems will define TIMER_GETTIMEOFDAY; Windows will
- use TIMER_WINDOWS. TIMER_TIME is a catch-all method for
- non-Windows systems without gettimeofday. */
-
-#ifdef WINDOWS
-# define TIMER_WINDOWS
-#else /* not WINDOWS */
-# ifdef HAVE_GETTIMEOFDAY
-# define TIMER_GETTIMEOFDAY
-# else
-# define TIMER_TIME
-# endif
-#endif /* not WINDOWS */
-
-#ifdef TIMER_GETTIMEOFDAY
-typedef struct timeval wget_sys_time;
-#endif
-
-#ifdef TIMER_TIME
-typedef time_t wget_sys_time;
-#endif
-
-#ifdef TIMER_WINDOWS
-typedef union {
- DWORD lores; /* In case GetTickCount is used */
- LARGE_INTEGER hires; /* In case high-resolution timer is used */
-} wget_sys_time;
-#endif
-
-struct wget_timer {
- /* Whether the start time has been initialized. */
- int initialized;
-
- /* The starting point in time which, subtracted from the current
- time, yields elapsed time. */
- wget_sys_time start;
-
- /* The most recent elapsed time, calculated by wtimer_update().
- Measured in milliseconds. */
- double elapsed_last;
-
- /* Approximately, the time elapsed between the true start of the
- measurement and the time represented by START. */
- double elapsed_pre_start;
-};
-
-#ifdef TIMER_WINDOWS
-
-/* Whether high-resolution timers are used. Set by wtimer_initialize_once
- the first time wtimer_allocate is called. */
-static int using_hires_timers;
-
-/* Frequency of high-resolution timers -- number of updates per
- millisecond. Calculated the first time wtimer_allocate is called
- provided that high-resolution timers are available. */
-static double hires_millisec_freq;
-
-/* The first time a timer is created, determine whether to use
- high-resolution timers. */
-
-static void
-wtimer_initialize_once (void)
-{
- static int init_done;
- if (!init_done)
- {
- LARGE_INTEGER freq;
- init_done = 1;
- freq.QuadPart = 0;
- QueryPerformanceFrequency (&freq);
- if (freq.QuadPart != 0)
- {
- using_hires_timers = 1;
- hires_millisec_freq = (double) freq.QuadPart / 1000.0;
- }
- }
-}
-#endif /* TIMER_WINDOWS */
-
-/* Allocate a timer. Calling wtimer_read on the timer will return
- zero. It is not legal to call wtimer_update with a freshly
- allocated timer -- use wtimer_reset first. */
-
-struct wget_timer *
-wtimer_allocate (void)
-{
- struct wget_timer *wt = xnew (struct wget_timer);
- xzero (*wt);
-
-#ifdef TIMER_WINDOWS
- wtimer_initialize_once ();
-#endif
-
- return wt;
-}
-
-/* Allocate a new timer and reset it. Return the new timer. */
-
-struct wget_timer *
-wtimer_new (void)
-{
- struct wget_timer *wt = wtimer_allocate ();
- wtimer_reset (wt);
- return wt;
-}
-
-/* Free the resources associated with the timer. Its further use is
- prohibited. */
-
-void
-wtimer_delete (struct wget_timer *wt)
-{
- xfree (wt);
-}
-
-/* Store system time to WST. */
-
-static void
-wtimer_sys_set (wget_sys_time *wst)
-{
-#ifdef TIMER_GETTIMEOFDAY
- gettimeofday (wst, NULL);
-#endif
-
-#ifdef TIMER_TIME
- time (wst);
-#endif
-
-#ifdef TIMER_WINDOWS
- if (using_hires_timers)
- {
- QueryPerformanceCounter (&wst->hires);
- }
- else
- {
- /* Where hires counters are not available, use GetTickCount rather
- GetSystemTime, because it is unaffected by clock skew and simpler
- to use. Note that overflows don't affect us because we never use
- absolute values of the ticker, only the differences. */
- wst->lores = GetTickCount ();
- }
-#endif
-}
-
-/* Reset timer WT. This establishes the starting point from which
- wtimer_read() will return the number of elapsed milliseconds.
- It is allowed to reset a previously used timer. */
-
-void
-wtimer_reset (struct wget_timer *wt)
-{
- /* Set the start time to the current time. */
- wtimer_sys_set (&wt->start);
- wt->elapsed_last = 0;
- wt->elapsed_pre_start = 0;
- wt->initialized = 1;
-}
-
-static double
-wtimer_sys_diff (wget_sys_time *wst1, wget_sys_time *wst2)
-{
-#ifdef TIMER_GETTIMEOFDAY
- return ((double)(wst1->tv_sec - wst2->tv_sec) * 1000
- + (double)(wst1->tv_usec - wst2->tv_usec) / 1000);
-#endif
-
-#ifdef TIMER_TIME
- return 1000 * (*wst1 - *wst2);
-#endif
-
-#ifdef WINDOWS
- if (using_hires_timers)
- return (wst1->hires.QuadPart - wst2->hires.QuadPart) / hires_millisec_freq;
- else
- return wst1->lores - wst2->lores;
-#endif
-}
-
-/* Update the timer's elapsed interval. This function causes the
- timer to call gettimeofday (or time(), etc.) to update its idea of
- current time. To get the elapsed interval in milliseconds, use
- wtimer_read.
-
- This function handles clock skew, i.e. time that moves backwards is
- ignored. */
-
-void
-wtimer_update (struct wget_timer *wt)
-{
- wget_sys_time now;
- double elapsed;
-
- assert (wt->initialized != 0);
-
- wtimer_sys_set (&now);
- elapsed = wt->elapsed_pre_start + wtimer_sys_diff (&now, &wt->start);
-
- /* Ideally we'd just return the difference between NOW and
- wt->start. However, the system timer can be set back, and we
- could return a value smaller than when we were last called, even
- a negative value. Both of these would confuse the callers, which
- expect us to return monotonically nondecreasing values.
-
- Therefore: if ELAPSED is smaller than its previous known value,
- we reset wt->start to the current time and effectively start
- measuring from this point. But since we don't want the elapsed
- value to start from zero, we set elapsed_pre_start to the last
- elapsed time and increment all future calculations by that
- amount. */
-
- if (elapsed < wt->elapsed_last)
- {
- wt->start = now;
- wt->elapsed_pre_start = wt->elapsed_last;
- elapsed = wt->elapsed_last;
- }
-
- wt->elapsed_last = elapsed;
-}
-
-/* Return the elapsed time in milliseconds between the last call to
- wtimer_reset and the last call to wtimer_update.
-
- A typical use of the timer interface would be:
-
- struct wtimer *timer = wtimer_new ();
- ... do something that takes a while ...
- wtimer_update ();
- double msecs = wtimer_read (); */
-
-double
-wtimer_read (const struct wget_timer *wt)
-{
- return wt->elapsed_last;
-}
-
-/* Return the assessed granularity of the timer implementation, in
- milliseconds. This is used by code that tries to substitute a
- better value for timers that have returned zero. */
-
-double
-wtimer_granularity (void)
-{
-#ifdef TIMER_GETTIMEOFDAY
- /* Granularity of gettimeofday varies wildly between architectures.
- However, it appears that on modern machines it tends to be better
- than 1ms. Assume 100 usecs. (Perhaps the configure process
- could actually measure this?) */
- return 0.1;
-#endif
-
-#ifdef TIMER_TIME
- return 1000;
-#endif
-
-#ifdef TIMER_WINDOWS
- if (using_hires_timers)
- return 1.0 / hires_millisec_freq;
- else
- return 10; /* according to MSDN */
-#endif
-}
-\f
-/* This should probably be at a better place, but it doesn't really
- fit into html-parse.c. */
-
-/* The function returns the pointer to the malloc-ed quoted version of
- string s. It will recognize and quote numeric and special graphic
- entities, as per RFC1866:
-
- `&' -> `&'
- `<' -> `<'
- `>' -> `>'
- `"' -> `"'
- SP -> ` '
-
- No other entities are recognized or replaced. */
-char *
-html_quote_string (const char *s)
-{
- const char *b = s;
- char *p, *res;
- int i;
-
- /* Pass through the string, and count the new size. */
- for (i = 0; *s; s++, i++)
- {
- if (*s == '&')
- i += 4; /* `amp;' */
- else if (*s == '<' || *s == '>')
- i += 3; /* `lt;' and `gt;' */
- else if (*s == '\"')
- i += 5; /* `quot;' */
- else if (*s == ' ')
- i += 4; /* #32; */
- }
- res = (char *)xmalloc (i + 1);
- s = b;
- for (p = res; *s; s++)
- {
- switch (*s)
- {
- case '&':
- *p++ = '&';
- *p++ = 'a';
- *p++ = 'm';
- *p++ = 'p';
- *p++ = ';';
- break;
- case '<': case '>':
- *p++ = '&';
- *p++ = (*s == '<' ? 'l' : 'g');
- *p++ = 't';
- *p++ = ';';
- break;
- case '\"':
- *p++ = '&';
- *p++ = 'q';
- *p++ = 'u';
- *p++ = 'o';
- *p++ = 't';
- *p++ = ';';
- break;
- case ' ':
- *p++ = '&';
- *p++ = '#';
- *p++ = '3';
- *p++ = '2';
- *p++ = ';';
- break;
- default:
- *p++ = *s;
- }
- }
- *p = '\0';
- return res;
-}
-
/* Determine the width of the terminal we're running on. If that's
not possible, return 0. */
#endif /* not WINDOWS */
-/* Encode the string S of length LENGTH to base64 format and place it
- to STORE. STORE will be 0-terminated, and must point to a writable
- buffer of at least 1+BASE64_LENGTH(length) bytes. */
+/* Encode the string STR of length LENGTH to base64 format and place it
+ to B64STORE. The output will be \0-terminated, and must point to a
+ writable buffer of at least 1+BASE64_LENGTH(length) bytes. It
+ returns the length of the resulting base64 data, not counting the
+ terminating zero.
-void
-base64_encode (const char *s, char *store, int length)
+ This implementation will not emit newlines after 76 characters of
+ base64 data. */
+
+int
+base64_encode (const char *str, int length, char *b64store)
{
/* Conversion table. */
static char tbl[64] = {
'4','5','6','7','8','9','+','/'
};
int i;
- unsigned char *p = (unsigned char *)store;
+ const unsigned char *s = (const unsigned char *) str;
+ char *p = b64store;
/* Transform the 3x8 bits to 4x6 bits, as required by base64. */
for (i = 0; i < length; i += 3)
*p++ = tbl[s[2] & 0x3f];
s += 3;
}
+
/* Pad the result if necessary... */
if (i == length + 1)
*(p - 1) = '=';
else if (i == length + 2)
*(p - 1) = *(p - 2) = '=';
+
/* ...and zero-terminate it. */
*p = '\0';
+
+ return p - b64store;
}
#define IS_ASCII(c) (((c) & 0x80) == 0)
int
base64_decode (const char *base64, char *to)
{
- /* Table of base64 values for first 128 characters. */
+ /* Table of base64 values for first 128 characters. Note that this
+ assumes ASCII (but so does Wget in other places). */
static short base64_char_to_value[128] =
{
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0- 9 */
{
NEXT_BASE64_CHAR (c, p);
if (!c)
- return -1; /* premature EOF while dcoding base64 */
+ return -1; /* premature EOF while decoding base64 */
if (c != '=')
return -1; /* padding `=' expected but not found */
continue;
/* Process fourth byte of a quadruplet. */
NEXT_BASE64_CHAR (c, p);
if (!c)
- return -1; /* premature EOF while dcoding base64 */
+ return -1; /* premature EOF while decoding base64 */
if (c == '=')
continue;
#undef IS_ASCII
#undef IS_BASE64
#undef NEXT_BASE64_CHAR
+\f
+/* Simple merge sort for use by stable_sort. Implementation courtesy
+ Zeljko Vrba with additional debugging by Nenad Barbutov. */
+
+static void
+mergesort_internal (void *base, void *temp, size_t size, size_t from, size_t to,
+ int (*cmpfun) PARAMS ((const void *, const void *)))
+{
+#define ELT(array, pos) ((char *)(array) + (pos) * size)
+ if (from < to)
+ {
+ size_t i, j, k;
+ size_t mid = (to + from) / 2;
+ mergesort_internal (base, temp, size, from, mid, cmpfun);
+ mergesort_internal (base, temp, size, mid + 1, to, cmpfun);
+ i = from;
+ j = mid + 1;
+ for (k = from; (i <= mid) && (j <= to); k++)
+ if (cmpfun (ELT (base, i), ELT (base, j)) <= 0)
+ memcpy (ELT (temp, k), ELT (base, i++), size);
+ else
+ memcpy (ELT (temp, k), ELT (base, j++), size);
+ while (i <= mid)
+ memcpy (ELT (temp, k++), ELT (base, i++), size);
+ while (j <= to)
+ memcpy (ELT (temp, k++), ELT (base, j++), size);
+ for (k = from; k <= to; k++)
+ memcpy (ELT (base, k), ELT (temp, k), size);
+ }
+#undef ELT
+}
+
+/* Stable sort with interface exactly like standard library's qsort.
+ Uses mergesort internally, allocating temporary storage with
+ alloca. */
+
+void
+stable_sort (void *base, size_t nmemb, size_t size,
+ int (*cmpfun) PARAMS ((const void *, const void *)))
+{
+ if (size > 1)
+ {
+ void *temp = alloca (nmemb * size * sizeof (void *));
+ mergesort_internal (base, temp, size, 0, nmemb - 1, cmpfun);
+ }
+}