⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 utils.c

📁 一个从网络上自动下载文件的自由工具
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Various utility functions.   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,   2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.This file is part of GNU Wget.GNU Wget is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 3 of the License, or(at your option) any later version.GNU Wget is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with Wget.  If not, see <http://www.gnu.org/licenses/>.Additional permission under GNU GPL version 3 section 7If you modify this program, or any covered work, by linking orcombining it with the OpenSSL project's OpenSSL library (or amodified version of that library), containing parts covered by theterms of the OpenSSL or SSLeay licenses, the Free Software Foundationgrants you additional permission to convey the resulting work.Corresponding Source for a non-source form of such a combinationshall include the source code for the parts of OpenSSL used as wellas that of the covered work.  */#include <config.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#ifdef HAVE_SYS_TIME_H# include <sys/time.h>#endif#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#ifdef HAVE_MMAP# include <sys/mman.h>#endif#ifdef HAVE_PROCESS_H# include <process.h>  /* getpid() */#endif#ifdef HAVE_UTIME_H# include <utime.h>#endif#ifdef HAVE_SYS_UTIME_H# include <sys/utime.h>#endif#include <errno.h>#include <fcntl.h>#include <assert.h>#include <stdarg.h>#include <locale.h>/* For TIOCGWINSZ and friends: */#ifdef HAVE_SYS_IOCTL_H# include <sys/ioctl.h>#endif#ifdef HAVE_TERMIOS_H# include <termios.h>#endif/* Needed for Unix version of run_with_timeout. */#include <signal.h>#include <setjmp.h>#ifndef HAVE_SIGSETJMP/* If sigsetjmp is a macro, configure won't pick it up. */# ifdef sigsetjmp#  define HAVE_SIGSETJMP# endif#endif#if defined HAVE_SIGSETJMP || defined HAVE_SIGBLOCK# define USE_SIGNAL_TIMEOUT#endif#include "wget.h"#include "utils.h"#include "hash.h"#ifdef TESTING#include "test.h"#endif /* 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;}/* 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.  */char *strdupdelim (const char *beg, const char *end){  char *res = xmalloc (end - beg + 1);  memcpy (res, beg, end - beg);  res[end - beg] = '\0';  return res;}/* Parse a string containing comma-separated elements, and return a   vector of char pointers with the elements.  Spaces following the   commas are ignored.  */char **sepstring (const char *s){  char **res;  const char *p;  int i = 0;  if (!s || !*s)    return NULL;  res = NULL;  p = s;  while (*s)    {      if (*s == ',')        {          res = xrealloc (res, (i + 2) * sizeof (char *));          res[i] = strdupdelim (p, s);          res[++i] = NULL;          ++s;          /* Skip the blanks following the ','.  */          while (ISSPACE (*s))            ++s;          p = s;        }      else        ++s;    }  res = xrealloc (res, (i + 2) * sizeof (char *));  res[i] = strdupdelim (p, s);  res[i + 1] = NULL;  return res;}/* Like sprintf, but prints into a string of sufficient size freshly   allocated with malloc, which is returned.  If unable to print due   to invalid format, returns NULL.  Inability to allocate needed   memory results in abort, as with xmalloc.  This is in spirit   similar to the GNU/BSD extension asprintf, but somewhat easier to   use.   Internally the function either calls vasprintf or loops around   vsnprintf until the correct size is found.  Since Wget also ships a   fallback implementation of vsnprintf, this should be portable.  */char *aprintf (const char *fmt, ...){#if defined HAVE_VASPRINTF && !defined DEBUG_MALLOC  /* Use vasprintf. */  int ret;  va_list args;  char *str;  va_start (args, fmt);  ret = vasprintf (&str, fmt, args);  va_end (args);  if (ret < 0 && errno == ENOMEM)    abort ();                   /* for consistency with xmalloc/xrealloc */  else if (ret < 0)    return NULL;  return str;#else  /* not HAVE_VASPRINTF */  /* vasprintf is unavailable.  snprintf into a small buffer and     resize it as necessary. */  int size = 32;  char *str = xmalloc (size);  /* #### This code will infloop and eventually abort in xrealloc if     passed a FMT that causes snprintf to consistently return -1.  */  while (1)    {      int n;      va_list args;      va_start (args, fmt);      n = vsnprintf (str, size, fmt, args);      va_end (args);      /* If the printing worked, return the string. */      if (n > -1 && n < size)        return str;      /* Else try again with a larger buffer. */      if (n > -1)               /* C99 */        size = n + 1;           /* precisely what is needed */      else        size <<= 1;             /* twice the old size */      str = xrealloc (str, size);    }#endif /* not HAVE_VASPRINTF */}/* Concatenate the NULL-terminated list of string arguments into   freshly allocated space.  */char *concat_strings (const char *str0, ...){  va_list args;  int saved_lengths[5];         /* inspired by Apache's apr_pstrcat */  char *ret, *p;  const char *next_str;  int total_length = 0;  int argcount;  /* Calculate the length of and allocate the resulting string. */  argcount = 0;  va_start (args, str0);  for (next_str = str0; next_str != NULL; next_str = va_arg (args, char *))    {      int len = strlen (next_str);      if (argcount < countof (saved_lengths))        saved_lengths[argcount++] = len;      total_length += len;    }  va_end (args);  p = ret = xmalloc (total_length + 1);  /* Copy the strings into the allocated space. */  argcount = 0;  va_start (args, str0);  for (next_str = str0; next_str != NULL; next_str = va_arg (args, char *))    {      int len;      if (argcount < countof (saved_lengths))        len = saved_lengths[argcount++];      else        len = strlen (next_str);      memcpy (p, next_str, len);      p += len;    }  va_end (args);  *p = '\0';  return ret;}/* Format the provided time according to the specified format.  The   format is a string with format elements supported by strftime.  */static char *fmttime (time_t t, const char *fmt){  static char output[32];  struct tm *tm = localtime(&t);  if (!tm)    abort ();  if (!strftime(output, sizeof(output), fmt, tm))    abort ();  return output;}/* Return pointer to a static char[] buffer in which zero-terminated   string-representation of TM (in form hh:mm:ss) is printed.   If TM is NULL, the current time will be used.  */char *time_str (time_t t){  return fmttime(t, "%H:%M:%S");}/* Like the above, but include the date: YYYY-MM-DD hh:mm:ss.  */char *datetime_str (time_t t){  return fmttime(t, "%Y-%m-%d %H:%M:%S");}/* The Windows versions of the following two functions are defined in   mswindows.c. On MSDOS this function should never be called. */#if !defined(WINDOWS) && !defined(MSDOS)voidfork_to_background (void){  pid_t pid;  /* Whether we arrange our own version of opt.lfilename here.  */  bool logfile_changed = false;  if (!opt.lfilename)    {      /* We must create the file immediately to avoid either a race         condition (which arises from using unique_name and failing to         use fopen_excl) or lying to the user about the log file name         (which arises from using unique_name, printing the name, and         using fopen_excl later on.)  */      FILE *new_log_fp = unique_create (DEFAULT_LOGFILE, false, &opt.lfilename);      if (new_log_fp)        {          logfile_changed = true;          fclose (new_log_fp);        }    }  pid = fork ();  if (pid < 0)    {      /* parent, error */      perror ("fork");      exit (1);    }  else if (pid != 0)    {      /* parent, no error */      printf (_("Continuing in background, pid %d.\n"), (int) pid);      if (logfile_changed)        printf (_("Output will be written to `%s'.\n"), opt.lfilename);      exit (0);                 /* #### should we use _exit()? */    }  /* child: give up the privileges and keep running. */  setsid ();  freopen ("/dev/null", "r", stdin);  freopen ("/dev/null", "w", stdout);  freopen ("/dev/null", "w", stderr);}#endif /* !WINDOWS && !MSDOS *//* "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.  */voidtouch (const char *file, time_t tm){#ifdef HAVE_STRUCT_UTIMBUF  struct utimbuf times;#else  struct {    time_t actime;    time_t modtime;  } times;#endif  times.modtime = tm;  times.actime = time (NULL);  if (utime (file, &times) == -1)    logprintf (LOG_NOTQUIET, "utime(%s): %s\n", file, strerror (errno));}/* Checks if FILE is a symbolic link, and removes it if it is.  Does   nothing under MS-Windows.  */intremove_link (const char *file){  int err = 0;  struct_stat st;  if (lstat (file, &st) == 0 && S_ISLNK (st.st_mode))    {      DEBUGP (("Unlinking %s (symlink).\n", file));      err = unlink (file);      if (err != 0)        logprintf (LOG_VERBOSE, _("Failed to unlink symlink `%s': %s\n"),                   file, strerror (errno));    }  return err;}/* Does FILENAME exist?  This is quite a lousy implementation, since   it supplies no error codes -- only a yes-or-no answer.  Thus it   will return that a file does not exist if, e.g., the directory is   unreadable.  I don't mind it too much currently, though.  The   proper way should, of course, be to have a third, error state,   other than true/false, but that would introduce uncalled-for   additional complexity to the callers.  */boolfile_exists_p (const char *filename){#ifdef HAVE_ACCESS  return access (filename, F_OK) >= 0;#else  struct_stat buf;  return stat (filename, &buf) >= 0;#endif}/* Returns 0 if PATH is a directory, 1 otherwise (any kind of file).   Returns 0 on error.  */boolfile_non_directory_p (const char *path){  struct_stat buf;  /* Use lstat() rather than stat() so that symbolic links pointing to     directories can be identified correctly.  */  if (lstat (path, &buf) != 0)    return false;  return S_ISDIR (buf.st_mode) ? false : true;}/* Return the size of file named by FILENAME, or -1 if it cannot be   opened or seeked into. */wgintfile_size (const char *filename){#if defined(HAVE_FSEEKO) && defined(HAVE_FTELLO)  wgint size;  /* We use fseek rather than stat to determine the file size because     that way we can also verify that the file is readable without     explicitly checking for permissions.  Inspired by the POST patch     by Arnaud Wylie.  */  FILE *fp = fopen (filename, "rb");  if (!fp)    return -1;  fseeko (fp, 0, SEEK_END);  size = ftello (fp);  fclose (fp);  return size;#else  struct_stat st;  if (stat (filename, &st) < 0)    return -1;  return st.st_size;#endif}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -