]> sjero.net Git - wget/commitdiff
[svn] Allow unique_name to return the FILE argument unmodified.
authorhniksic <devnull@localhost>
Tue, 16 Sep 2003 21:47:49 +0000 (14:47 -0700)
committerhniksic <devnull@localhost>
Tue, 16 Sep 2003 21:47:49 +0000 (14:47 -0700)
Streamline and optimize unique_name_1.

src/ChangeLog
src/log.c
src/mswindows.c
src/url.c
src/utils.c
src/utils.h

index 6ec4e7c3f4894e0b83e88ad8fde126775e9bbeb6..b31cdc754635d2420b0ae9f63707da78a02b9ade 100644 (file)
@@ -1,3 +1,10 @@
+2003-09-16  Hrvoje Niksic  <hniksic@xemacs.org>
+
+       * url.c (url_file_name): Don't reallocate FNAME if the file
+       doesn't exist, as is usually the case.
+
+       * utils.c (unique_name): New flag allow_passthrough.
+
 2003-09-16  Hrvoje Niksic  <hniksic@xemacs.org>
 
        * utils.c (wtimer_sys_diff): Convert the time difference to signed
index 0ac45b76ece43822635b07f709a1b5e676dd0fbd..1f829e493da2a2945d47ef99769bf3b933a1f3bf 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -660,7 +660,7 @@ static const char *redirect_request_signal_name;
 static void
 redirect_output (void)
 {
-  char *logfile = unique_name (DEFAULT_LOGFILE);
+  char *logfile = unique_name (DEFAULT_LOGFILE, 0);
   fprintf (stderr, _("\n%s received, redirecting output to `%s'.\n"),
           redirect_request_signal_name, logfile);
   logfp = fopen (logfile, "w");
index 95a0099fac5d4708060049fc5a7a38b11cb7109f..53219812e332c93ea1480c67de83a075a0214624 100644 (file)
@@ -136,7 +136,7 @@ fork_to_background (void)
 
   if (!opt.lfilename)
     {
-      opt.lfilename = unique_name (DEFAULT_LOGFILE);
+      opt.lfilename = unique_name (DEFAULT_LOGFILE, 0);
       changedp = 1;
     }
   printf (_("Continuing in background.\n"));
index 9776cc3e0dbb8ab194e748e0f827ce5d04fd057f..57cec64c4c04ebe5580e089ce506b6260dcb4ba6 100644 (file)
--- a/src/url.c
+++ b/src/url.c
@@ -1694,15 +1694,15 @@ url_file_name (const struct url *u)
      4) Hierarchy is built.
 
      The exception is the case when file does exist and is a
-     directory (actually support for bad httpd-s).  */
+     directory (see `mkalldirs' for explanation).  */
 
   if ((opt.noclobber || opt.always_rest || opt.timestamping || opt.dirstruct)
       && !(file_exists_p (fname) && !file_non_directory_p (fname)))
-    return fnres.base;
+    return fname;
 
-  /* Find a unique name.  */
-  unique = unique_name (fname);
-  xfree (fname);
+  unique = unique_name (fname, 1);
+  if (unique != fname)
+    xfree (fname);
   return unique;
 }
 
index 0f443411f443ab1fd9a19d1771b4a0820ea2e088..481e5b78c8ea7b46e6cd77acb24693114d939864 100644 (file)
@@ -470,7 +470,7 @@ fork_to_background (void)
 
   if (!opt.lfilename)
     {
-      opt.lfilename = unique_name (DEFAULT_LOGFILE);
+      opt.lfilename = unique_name (DEFAULT_LOGFILE, 0);
       changedp = 1;
     }
   pid = fork ();
@@ -580,39 +580,55 @@ file_size (const char *filename)
   return size;
 }
 
-/* Return a unique filename, given a prefix and count */
+/* stat file names named PREFIX.1, PREFIX.2, etc., until one that
+   doesn't exist is found.  Return a freshly allocated copy of the
+   unused file name.  */
+
 static char *
-unique_name_1 (const char *fileprefix, int count)
+unique_name_1 (const char *prefix)
 {
-  char *filename;
+  int count = 1;
+  int plen = strlen (prefix);
+  char *template = (char *)alloca (plen + 1 + 24);
+  char *template_tail = template + plen;
 
-  if (count)
-    {
-      filename = (char *)xmalloc (strlen (fileprefix) + numdigit (count) + 2);
-      sprintf (filename, "%s.%d", fileprefix, count);
-    }
-  else
-    filename = xstrdup (fileprefix);
+  memcpy (template, prefix, plen);
+  *template_tail++ = '.';
 
-  if (!file_exists_p (filename))
-    return filename;
-  else
-    {
-      xfree (filename);
-      return NULL;
-    }
+  do
+    number_to_string (template_tail, count++);
+  while (file_exists_p (template));
+
+  return xstrdup (template);
 }
 
-/* Return a unique file name, based on PREFIX.  */
+/* Return a unique file name, based on FILE.
+
+   More precisely, if FILE doesn't exist, it is returned unmodified.
+   If not, FILE.1 is tried, then FILE.2, etc.  The first FILE.<number>
+   file name that doesn't exist is returned.
+
+   The resulting file is not created, only verified that it didn't
+   exist at the point in time when the function was called.
+   Therefore, where security matters, don't rely that the file created
+   by this function exists until you open it with O_EXCL or
+   something.
+
+   If ALLOW_PASSTHROUGH is 0, it always returns a freshly allocated
+   string.  Otherwise, it may return FILE if the file doesn't exist
+   (and therefore doesn't need changing).  */
+
 char *
-unique_name (const char *prefix)
+unique_name (const char *file, int allow_passthrough)
 {
-  char *file = NULL;
-  int count = 0;
+  /* If the FILE itself doesn't exist, return it without
+     modification. */
+  if (!file_exists_p (file))
+    return allow_passthrough ? (char *)file : xstrdup (file);
 
-  while (!file)
-    file = unique_name_1 (prefix, count++);
-  return file;
+  /* Otherwise, find a numeric suffix that results in unused file name
+     and return it.  */
+  return unique_name_1 (file);
 }
 \f
 /* Create DIRECTORY.  If some of the pathname components of DIRECTORY
index 3ae279cf341fee3b77b6aa383c7963b801a069a1..18752a5f015cee53501b3791af7dac46d0f5668d 100644 (file)
@@ -73,7 +73,7 @@ int file_exists_p PARAMS ((const char *));
 int file_non_directory_p PARAMS ((const char *));
 long file_size PARAMS ((const char *));
 int make_directory PARAMS ((const char *));
-char *unique_name PARAMS ((const char *));
+char *unique_name PARAMS ((const char *, int));
 char *file_merge PARAMS ((const char *, const char *));
 
 int acceptable PARAMS ((const char *));