1 /* Various functions of utilitarian nature.
2 Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
4 This file is part of Wget.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
26 #else /* not HAVE_STRING_H */
28 #endif /* not HAVE_STRING_H */
30 #include <sys/types.h>
41 #ifdef HAVE_SYS_UTIME_H
42 # include <sys/utime.h>
46 # include <libc.h> /* for access() */
58 /* Croak the fatal memory error and bail out with non-zero exit
61 memfatal (const char *s)
63 /* HACK: expose save_log_p from log.c, so we can turn it off in
64 order to prevent saving the log. Saving the log is dangerous
65 because logprintf() and logputs() can call malloc(), so this
66 could infloop. When logging is turned off, infloop can no longer
68 extern int save_log_p;
71 logprintf (LOG_ALWAYS, _("%s: %s: Not enough memory.\n"), exec_name, s);
75 /* xmalloc, xrealloc and xstrdup exit the program if there is not
76 enough memory. xstrdup also implements strdup on systems that do
90 xrealloc (void *obj, size_t size)
94 /* Not all Un*xes have the feature of realloc() that calling it with
95 a NULL-pointer is the same as malloc(), but it is easy to
98 res = realloc (obj, size);
102 memfatal ("realloc");
107 xstrdup (const char *s)
111 char *s1 = malloc (l + 1);
114 memcpy (s1, s, l + 1);
116 #else /* HAVE_STRDUP */
117 char *s1 = strdup (s);
121 #endif /* HAVE_STRDUP */
124 /* Copy the string formed by two pointers (one on the beginning, other
125 on the char after the last char) to a new, malloc-ed location.
128 strdupdelim (const char *beg, const char *end)
130 char *res = (char *)xmalloc (end - beg + 1);
131 memcpy (res, beg, end - beg);
132 res[end - beg] = '\0';
136 /* Parse a string containing comma-separated elements, and return a
137 vector of char pointers with the elements. Spaces following the
138 commas are ignored. */
140 sepstring (const char *s)
154 res = (char **)xrealloc (res, (i + 2) * sizeof (char *));
155 res[i] = strdupdelim (p, s);
158 /* Skip the blanks following the ','. */
166 res = (char **)xrealloc (res, (i + 2) * sizeof (char *));
167 res[i] = strdupdelim (p, s);
172 /* Return pointer to a static char[] buffer in which zero-terminated
173 string-representation of TM (in form hh:mm:ss) is printed. It is
174 shamelessly non-reentrant, but it doesn't matter, really.
176 If TM is non-NULL, the time_t of the current time will be stored
179 time_str (time_t *tm)
189 ptm = localtime (&tim);
190 sprintf (tms, "%02d:%02d:%02d", ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
194 /* Returns an error message for ERRNUM. #### This requires more work.
195 This function, as well as the whole error system, is very
198 uerrmsg (uerr_t errnum)
203 return _("Unknown/unsupported protocol");
206 return _("Invalid port specification");
209 return _("Invalid host name");
213 /* $@#@#$ compiler. */
218 /* The Windows versions of the following two functions are defined in
221 /* A cuserid() immitation using getpwuid(), to avoid hassling with
222 utmp. Besides, not all systems have cuesrid(). Under Windows, it
223 is defined in mswindows.c.
225 If WHERE is non-NULL, the username will be stored there.
226 Otherwise, it will be returned as a static buffer (as returned by
227 getpwuid()). In the latter case, the buffer should be copied
228 before calling getpwuid() or pwd_cuserid() again. */
231 pwd_cuserid (char *where)
235 if (!(pwd = getpwuid (getuid ())) || !pwd->pw_name)
239 strcpy (where, pwd->pw_name);
247 fork_to_background (void)
250 /* Whether we arrange our own version of opt.lfilename here. */
255 opt.lfilename = unique_name (DEFAULT_LOGFILE);
267 /* parent, no error */
268 printf (_("Continuing in background.\n"));
270 printf (_("Output will be written to `%s'.\n"), opt.lfilename);
273 /* child: keep running */
275 #endif /* not WINDOWS */
277 /* Canonicalize PATH, and return a new path. The new path differs from PATH
279 Multple `/'s are collapsed to a single `/'.
280 Leading `./'s and trailing `/.'s are removed.
281 Trailing `/'s are removed.
282 Non-leading `../'s and trailing `..'s are handled by removing
283 portions of the path.
285 E.g. "a/b/c/./../d/.." will yield "a/b". This function originates
289 Always use '/' as stub_char.
290 Don't check for local things using canon_stat.
291 Change the original string instead of strdup-ing.
292 React correctly when beginning with `./' and `../'. */
294 path_simplify (char *path)
296 register int i, start, ddot;
302 /*stub_char = (*path == '/') ? '/' : '.';*/
305 /* Addition: Remove all `./'-s preceding the string. If `../'-s
306 precede, put `/' in front and remove them too. */
311 if (path[i] == '.' && path[i + 1] == '/')
313 else if (path[i] == '.' && path[i + 1] == '.' && path[i + 2] == '/')
322 strcpy (path, path + i - ddot);
324 /* Replace single `.' or `..' with `/'. */
325 if ((path[0] == '.' && path[1] == '\0')
326 || (path[0] == '.' && path[1] == '.' && path[2] == '\0'))
332 /* Walk along PATH looking for things to compact. */
339 while (path[i] && path[i] != '/')
344 /* If we didn't find any slashes, then there is nothing left to do. */
348 /* Handle multiple `/'s in a row. */
349 while (path[i] == '/')
352 if ((start + 1) != i)
354 strcpy (path + start + 1, path + i);
358 /* Check for trailing `/'. */
359 if (start && !path[i])
366 /* Check for `../', `./' or trailing `.' by itself. */
369 /* Handle trailing `.' by itself. */
374 if (path[i + 1] == '/')
376 strcpy (path + i, path + i + 1);
377 i = (start < 0) ? 0 : start;
381 /* Handle `../' or trailing `..' by itself. */
382 if (path[i + 1] == '.' &&
383 (path[i + 2] == '/' || !path[i + 2]))
385 while (--start > -1 && path[start] != '/');
386 strcpy (path + start + 1, path + i + 2);
387 i = (start < 0) ? 0 : start;
400 /* "Touch" FILE, i.e. make its atime and mtime equal to the time
401 specified with TM. */
403 touch (const char *file, time_t tm)
405 #ifdef HAVE_STRUCT_UTIMBUF
406 struct utimbuf times;
407 times.actime = times.modtime = tm;
410 times[0] = times[1] = tm;
413 if (utime (file, ×) == -1)
414 logprintf (LOG_NOTQUIET, "utime: %s\n", strerror (errno));
417 /* Checks if FILE is a symbolic link, and removes it if it is. Does
418 nothing under MS-Windows. */
420 remove_link (const char *file)
425 if (lstat (file, &st) == 0 && S_ISLNK (st.st_mode))
427 DEBUGP (("Unlinking %s (symlink).\n", file));
430 logprintf (LOG_VERBOSE, _("Failed to unlink symlink `%s': %s\n"),
431 file, strerror (errno));
436 /* Does FILENAME exist? This is quite a lousy implementation, since
437 it supplies no error codes -- only a yes-or-no answer. Thus it
438 will return that a file does not exist if, e.g., the directory is
439 unreadable. I don't mind it too much currently, though. The
440 proper way should, of course, be to have a third, error state,
441 other than true/false, but that would introduce uncalled-for
442 additional complexity to the callers. */
444 file_exists_p (const char *filename)
447 return access (filename, F_OK) >= 0;
450 return stat (filename, &buf) >= 0;
454 /* Returns 0 if PATH is a directory, 1 otherwise (any kind of file).
455 Returns 0 on error. */
457 file_non_directory_p (const char *path)
460 /* Use lstat() rather than stat() so that symbolic links pointing to
461 directories can be identified correctly. */
462 if (lstat (path, &buf) != 0)
464 return S_ISDIR (buf.st_mode) ? 0 : 1;
467 /* Return a unique filename, given a prefix and count */
469 unique_name_1 (const char *fileprefix, int count)
475 filename = (char *)xmalloc (strlen (fileprefix) + numdigit (count) + 2);
476 sprintf (filename, "%s.%d", fileprefix, count);
479 filename = xstrdup (fileprefix);
481 if (!file_exists_p (filename))
490 /* Return a unique file name, based on PREFIX. */
492 unique_name (const char *prefix)
498 file = unique_name_1 (prefix, count++);
502 /* Create DIRECTORY. If some of the pathname components of DIRECTORY
503 are missing, create them first. In case any mkdir() call fails,
504 return its error status. Returns 0 on successful completion.
506 The behaviour of this function should be identical to the behaviour
507 of `mkdir -p' on systems where mkdir supports the `-p' option. */
509 make_directory (const char *directory)
515 /* Make a copy of dir, to be able to write to it. Otherwise, the
516 function is unsafe if called with a read-only char *argument. */
517 STRDUP_ALLOCA (dir, directory);
519 /* If the first character of dir is '/', skip it (and thus enable
520 creation of absolute-pathname directories. */
521 for (i = (*dir == '/'); 1; ++i)
523 for (; dir[i] && dir[i] != '/'; i++)
528 /* Check whether the directory already exists. */
529 if (!file_exists_p (dir))
531 if (mkdir (dir, 0777) < 0)
542 static int in_acclist PARAMS ((const char *const *, const char *, int));
544 /* Determine whether a file is acceptable to be followed, according to
545 lists of patterns to accept/reject. */
547 acceptable (const char *s)
551 while (l && s[l] != '/')
558 return (in_acclist ((const char *const *)opt.accepts, s, 1)
559 && !in_acclist ((const char *const *)opt.rejects, s, 1));
561 return in_acclist ((const char *const *)opt.accepts, s, 1);
563 else if (opt.rejects)
564 return !in_acclist ((const char *const *)opt.rejects, s, 1);
568 /* Compare S1 and S2 frontally; S2 must begin with S1. E.g. if S1 is
569 `/something', frontcmp() will return 1 only if S2 begins with
570 `/something'. Otherwise, 0 is returned. */
572 frontcmp (const char *s1, const char *s2)
574 for (; *s1 && *s2 && (*s1 == *s2); ++s1, ++s2);
578 /* Iterate through STRLIST, and return the first element that matches
579 S, through wildcards or front comparison (as appropriate). */
581 proclist (char **strlist, const char *s, enum accd flags)
585 for (x = strlist; *x; x++)
586 if (has_wildcards_p (*x))
588 if (fnmatch (*x, s, FNM_PATHNAME) == 0)
593 char *p = *x + ((flags & ALLABS) && (**x == '/')); /* Remove '/' */
600 /* Returns whether DIRECTORY is acceptable for download, wrt the
601 include/exclude lists.
603 If FLAGS is ALLABS, the leading `/' is ignored in paths; relative
604 and absolute paths may be freely intermixed. */
606 accdir (const char *directory, enum accd flags)
608 /* Remove starting '/'. */
609 if (flags & ALLABS && *directory == '/')
613 if (!proclist (opt.includes, directory, flags))
618 if (proclist (opt.excludes, directory, flags))
624 /* Match the end of STRING against PATTERN. For instance:
626 match_backwards ("abc", "bc") -> 1
627 match_backwards ("abc", "ab") -> 0
628 match_backwards ("abc", "abc") -> 1 */
630 match_backwards (const char *string, const char *pattern)
634 for (i = strlen (string), j = strlen (pattern); i >= 0 && j >= 0; i--, j--)
635 if (string[i] != pattern[j])
637 /* If the pattern was exhausted, the match was succesful. */
644 /* Checks whether string S matches each element of ACCEPTS. A list
645 element are matched either with fnmatch() or match_backwards(),
646 according to whether the element contains wildcards or not.
648 If the BACKWARD is 0, don't do backward comparison -- just compare
651 in_acclist (const char *const *accepts, const char *s, int backward)
653 for (; *accepts; accepts++)
655 if (has_wildcards_p (*accepts))
657 /* fnmatch returns 0 if the pattern *does* match the
659 if (fnmatch (*accepts, s, 0) == 0)
666 if (match_backwards (s, *accepts))
671 if (!strcmp (s, *accepts))
679 /* Return the malloc-ed suffix of STR. For instance:
680 suffix ("foo.bar") -> "bar"
681 suffix ("foo.bar.baz") -> "baz"
682 suffix ("/foo/bar") -> NULL
683 suffix ("/foo.bar/baz") -> NULL */
685 suffix (const char *str)
689 for (i = strlen (str); i && str[i] != '/' && str[i] != '.'; i--);
691 return xstrdup (str + i);
696 /* Read a line from FP. The function reallocs the storage as needed
697 to accomodate for any length of the line. Reallocs are done
698 storage exponentially, doubling the storage after each overflow to
699 minimize the number of calls to realloc().
701 It is not an exemplary of correctness, since it kills off the
702 newline (and no, there is no way to know if there was a newline at
705 read_whole_line (FILE *fp)
712 line = (char *)xmalloc (bufsize);
713 /* Construct the line. */
714 while ((c = getc (fp)) != EOF && c != '\n')
717 line = (char *)xrealloc (line, (bufsize <<= 1));
725 /* Check for overflow at zero-termination (no need to double the
726 buffer in this case. */
728 line = (char *)xrealloc (line, i + 1);
733 /* Load file pointed to by FP to memory and return the malloc-ed
734 buffer with the contents. *NREAD will contain the number of read
735 bytes. The file is loaded in chunks, allocated exponentially,
736 starting with FILE_BUFFER_SIZE bytes. */
738 load_file (FILE *fp, char **buf, long *nread)
745 while (!feof (fp) && !ferror (fp))
747 *buf = (char *)xrealloc (*buf, bufsize + *nread);
748 *nread += fread (*buf + *nread, sizeof (char), bufsize, fp);
751 /* #### No indication of encountered error?? */
754 /* Free the pointers in a NULL-terminated vector of pointers, then
755 free the pointer itself. */
757 free_vec (char **vec)
768 /* Append vector V2 to vector V1. The function frees V2 and
769 reallocates V1 (thus you may not use the contents of neither
770 pointer after the call). If V1 is NULL, V2 is returned. */
772 merge_vecs (char **v1, char **v2)
782 /* To avoid j == 0 */
787 for (i = 0; v1[i]; i++);
789 for (j = 0; v2[j]; j++);
791 v1 = (char **)xrealloc (v1, (i + j + 1) * sizeof (char **));
792 memcpy (v1 + i, v2, (j + 1) * sizeof (char *));
797 /* A set of simple-minded routines to store and search for strings in
798 a linked list. You may add a string to the slist, and peek whether
799 it's still in there at any time later. */
801 /* Add an element to the list. If flags is NOSORT, the list will not
804 add_slist (slist *l, const char *s, int flags)
806 slist *t, *old, *beg;
813 t = (slist *)xmalloc (sizeof (slist));
814 t->string = xstrdup (s);
819 /* Find the last element. */
822 t = (slist *)xmalloc (sizeof (slist));
824 t->string = xstrdup (s);
828 /* Empty list or changing the first element. */
829 if (!l || (cmp = strcmp (l->string, s)) > 0)
831 t = (slist *)xmalloc (sizeof (slist));
832 t->string = xstrdup (s);
841 /* Second two one-before-the-last element. */
846 cmp = strcmp (s, l->string);
847 if (cmp == 0) /* no repeating in the list */
851 /* If the next list element is greater than s, put s between the
852 current and the next list element. */
853 t = (slist *)xmalloc (sizeof (slist));
856 t->string = xstrdup (s);
859 t = (slist *)xmalloc (sizeof (slist));
860 t->string = xstrdup (s);
861 /* Insert the new element after the last element. */
867 /* Is there a specific entry in the list? */
869 in_slist (slist *l, const char *s)
875 cmp = strcmp (l->string, s);
878 else if (cmp > 0) /* the list is ordered! */
885 /* Free the whole slist. */
887 free_slist (slist *l)
900 /* Legible -- return a static pointer to the legibly printed long. */
904 static char outbuf[20];
907 char *outptr, *inptr;
909 /* Print the number into the buffer. */
910 long_to_string (inbuf, l);
911 /* Reset the pointers. */
914 /* If the number is negative, shift the pointers. */
920 /* How many digits before the first separator? */
921 mod = strlen (inptr) % 3;
923 for (i = 0; i < mod; i++)
924 *outptr++ = inptr[i];
925 /* Now insert the rest of them, putting separator before every
927 for (i1 = i, i = 0; inptr[i1]; i++, i1++)
929 if (i % 3 == 0 && i1 != 0)
931 *outptr++ = inptr[i1];
933 /* Zero-terminate the string. */
938 /* Count the digits in a (long) integer. */
943 while ((a /= 10) != 0)
948 /* Print NUMBER to BUFFER. The digits are first written in reverse
949 order (the least significant digit first), and are then reversed. */
951 long_to_string (char *buffer, long number)
962 /* Print the digits to the string. */
965 *p++ = number % 10 + '0';
969 /* And reverse them. */
971 for (i = l/2; i >= 0; i--)
974 buffer[i] = buffer[l - i];
977 buffer[l + 1] = '\0';