[prev in list] [next in list] [prev in thread] [next in thread]
List: rpm-devel
Subject: Re: [CVS] RPM: rpm/ CHANGES rpm/misc/ Makefile.am librpmmisc.c
From: devzero2000 <pinto.elia () gmail ! com>
Date: 2009-03-17 17:02:31
Message-ID: b086760e0903171002m344847cpb0f8689dfcdf8c64 () mail ! gmail ! com
[Download RAW message or body]
On Tue, Mar 17, 2009 at 5:36 PM, Jeff Johnson <n3npq@mac.com> wrote:
> Oooh, thank you! I keep meaning to do this ...
>
> BTW, perhaps its time to switch RPM to using Gnulib
> for portability issues as suggested (for popt) here:
>
> http://rpm5.org/community/rpm-devel/3161.html
>
> (aside)
> I plain and simply __CANNOT__ justify Gnulib for popt
> for the two dinky portability problems that were reported.
>
> But RPM might benefit from Gnulib even if Gnulib is way overkill for POPT.
>
> Opinions?
>
I was also my thought.
Regards
>
> 73 de Jeff
>
>
> On Mar 17, 2009, at 12:30 PM, Pinto Elia wrote:
>
> RPM Package Manager, CVS Repository
>> http://rpm5.org/cvs/
>>
>> ____________________________________________________________________________
>>
>> Server: rpm5.org Name: Pinto Elia
>> Root: /v/rpm/cvs Email: devzero2000@rpm5.org
>> Module: rpm Date: 17-Mar-2009 17:30:16
>> Branch: HEAD Handle: 2009031716301600
>>
>> Added files:
>> rpm/misc mkdtemp.c tempname.h
>> Modified files:
>> rpm CHANGES
>> rpm/misc Makefile.am librpmmisc.c
>>
>> Log:
>> add mkdtemp portability function to -lrpmmisc
>>
>> Summary:
>> Revision Changes Path
>> 1.2827 +1 -0 rpm/CHANGES
>> 1.42 +4 -2 rpm/misc/Makefile.am
>> 1.4 +4 -0 rpm/misc/librpmmisc.c
>> 1.1 +349 -0 rpm/misc/mkdtemp.c
>> 1.1 +38 -0 rpm/misc/tempname.h
>>
>> ____________________________________________________________________________
>>
>> patch -p0 <<'@@ .'
>> Index: rpm/CHANGES
>>
>> ============================================================================
>> $ cvs diff -u -r1.2826 -r1.2827 CHANGES
>> --- rpm/CHANGES 16 Mar 2009 22:30:39 -0000 1.2826
>> +++ rpm/CHANGES 17 Mar 2009 16:30:16 -0000 1.2827
>> @@ -1,5 +1,6 @@
>>
>> 5.2a3 -> 5.2a4:
>> + - devzero2000: add mkdtemp portability function to -lrpmmisc
>> - proyvind: do lazy mkdir of %_builddir, %_rpmdir & %_srcrpmdir when
>> doing
>> --install for src.rpms as well.
>> - jbj: yarn: convert Header refcount to usage mutex.
>> @@ .
>> patch -p0 <<'@@ .'
>> Index: rpm/misc/Makefile.am
>>
>> ============================================================================
>> $ cvs diff -u -r1.41 -r1.42 Makefile.am
>> --- rpm/misc/Makefile.am 15 Feb 2009 13:55:32 -0000 1.41
>> +++ rpm/misc/Makefile.am 17 Mar 2009 16:30:16 -0000 1.42
>> @@ -15,10 +15,12 @@
>> setenv.c stpcpy.c stpncpy.c \
>> strcspn.c strdup.c strerror.c \
>> strftime.c strcspn.c strstr.c strtol.c \
>> - strtoul.c
>> + strtoul.c \
>> + tempname.h \
>> + mkdtemp.c
>>
>> noinst_HEADERS = \
>> - asprintf.h err.h error.h
>> + asprintf.h err.h error.h tempname.h
>>
>> usrlibdir = $(libdir)
>> usrlib_LTLIBRARIES = librpmmisc.la
>> @@ .
>> patch -p0 <<'@@ .'
>> Index: rpm/misc/librpmmisc.c
>>
>> ============================================================================
>> $ cvs diff -u -r1.3 -r1.4 librpmmisc.c
>> --- rpm/misc/librpmmisc.c 31 Jul 2008 16:58:55 -0000 1.3
>> +++ rpm/misc/librpmmisc.c 17 Mar 2009 16:30:16 -0000 1.4
>> @@ -67,3 +67,7 @@
>> #if !defined(HAVE_STRSTR)
>> #include "strstr.c"
>> #endif
>> +
>> +#if !defined(HAVE_MKDTEMP)
>> +#include "mkdtemp.c"
>> +#endif
>> @@ .
>> patch -p0 <<'@@ .'
>> Index: rpm/misc/mkdtemp.c
>>
>> ============================================================================
>> $ cvs diff -u -r0 -r1.1 mkdtemp.c
>> --- /dev/null 2009-03-17 17:30:15 +0100
>> +++ mkdtemp.c 2009-03-17 17:30:16 +0100
>> @@ -0,0 +1,349 @@
>> +/* Copyright (C) 1999, 2001-2003, 2006-2007 Free Software Foundation,
>> Inc.
>> + This file is part of the GNU C Library.
>> +
>> + This program is free software: you can redistribute it and/or modify
>> + it under the terms of the GNU General Public License as published by
>> + the Free Software Foundation; either version 3 of the License, or
>> + (at your option) any later version.
>> +
>> + This program is distributed in the hope that it will be useful,
>> + but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + GNU General Public License for more details.
>> +
>> + You should have received a copy of the GNU General Public License
>> + along with this program. If not, see <http://www.gnu.org/licenses/>.
>> */
>> +
>> +/* Extracted from misc/mkdtemp.c. */
>> +#include "system.h"
>> +
>> +
>> +/* tempname.c - generate the name of a temporary file.
>> +
>> + Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
>> + 2000, 2001, 2002, 2003, 2005, 2006, 2007 Free Software Foundation,
>> + Inc.
>> +
>> + This program is free software: you can redistribute it and/or modify
>> + it under the terms of the GNU General Public License as published by
>> + the Free Software Foundation; either version 3 of the License, or
>> + (at your option) any later version.
>> +
>> + This program is distributed in the hope that it will be useful,
>> + but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + GNU General Public License for more details.
>> +
>> + You should have received a copy of the GNU General Public License
>> + along with this program. If not, see <http://www.gnu.org/licenses/>.
>> */
>> +
>> +/* Extracted from glibc sysdeps/posix/tempname.c. See also tmpdir.c.
>> */
>> +
>> +#if !_LIBC
>> +# include <config.h>
>> +# include "tempname.h"
>> +#endif
>> +
>> +#include <sys/types.h>
>> +#include <assert.h>
>> +
>> +#include <errno.h>
>> +#ifndef __set_errno
>> +# define __set_errno(Val) errno = (Val)
>> +#endif
>> +
>> +#include <stdio.h>
>> +#ifndef P_tmpdir
>> +# define P_tmpdir "/tmp"
>> +#endif
>> +#ifndef TMP_MAX
>> +# define TMP_MAX 238328
>> +#endif
>> +#ifndef __GT_FILE
>> +# define __GT_FILE 0
>> +# define __GT_BIGFILE 1
>> +# define __GT_DIR 2
>> +# define __GT_NOCREATE 3
>> +#endif
>> +
>> +#include <stddef.h>
>> +#include <stdlib.h>
>> +#include <string.h>
>> +
>> +#include <fcntl.h>
>> +#include <sys/time.h>
>> +#include <stdint.h>
>> +#include <unistd.h>
>> +
>> +#include <sys/stat.h>
>> +
>> +#if _LIBC
>> +# define struct_stat64 struct stat64
>> +# define small_open __open
>> +# define large_open __open64
>> +#else
>> +# define struct_stat64 struct stat
>> +# define small_open open
>> +# define large_open open
>> +# define __gen_tempname gen_tempname
>> +# define __getpid getpid
>> +# define __gettimeofday gettimeofday
>> +# define __mkdir mkdir
>> +# define __lxstat64(version, file, buf) lstat (file, buf)
>> +# define __xstat64(version, file, buf) stat (file, buf)
>> +#endif
>> +
>> +#if ! (HAVE___SECURE_GETENV || _LIBC)
>> +# define __secure_getenv getenv
>> +#endif
>> +
>> +#ifdef _LIBC
>> +# include <hp-timing.h>
>> +# if HP_TIMING_AVAIL
>> +# define RANDOM_BITS(Var) \
>> + if (__builtin_expect (value == UINT64_C (0), 0))
>> \
>> + {
>> \
>> + /* If this is the first time this function is used initialize
>> \
>> + the variable we accumulate the value in to some somewhat
>> \
>> + random value. If we'd not do this programs at startup time
>> \
>> + might have a reduced set of possible names, at least on slow
>> \
>> + machines. */
>> \
>> + struct timeval tv;
>> \
>> + __gettimeofday (&tv, NULL);
>> \
>> + value = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;
>> \
>> + }
>> \
>> + HP_TIMING_NOW (Var)
>> +# endif
>> +#endif
>> +
>> +/* Use the widest available unsigned type if uint64_t is not
>> + available. The algorithm below extracts a number less than 62**6
>> + (approximately 2**35.725) from uint64_t, so ancient hosts where
>> + uintmax_t is only 32 bits lose about 3.725 bits of randomness,
>> + which is better than not having mkstemp at all. */
>> +#if !defined UINT64_MAX && !defined uint64_t
>> +# define uint64_t uintmax_t
>> +#endif
>> +
>> +#if _LIBC
>> +/* Return nonzero if DIR is an existent directory. */
>> +static int
>> +direxists (const char *dir)
>> +{
>> + struct_stat64 buf;
>> + return __xstat64 (_STAT_VER, dir, &buf) == 0 && S_ISDIR (buf.st_mode);
>> +}
>> +
>> +/* Path search algorithm, for tmpnam, tmpfile, etc. If DIR is
>> + non-null and exists, uses it; otherwise uses the first of $TMPDIR,
>> + P_tmpdir, /tmp that exists. Copies into TMPL a template suitable
>> + for use with mk[s]temp. Will fail (-1) if DIR is non-null and
>> + doesn't exist, none of the searched dirs exists, or there's not
>> + enough space in TMPL. */
>> +int
>> +__path_search (char *tmpl, size_t tmpl_len, const char *dir, const char
>> *pfx,
>> + int try_tmpdir)
>> +{
>> + const char *d;
>> + size_t dlen, plen;
>> +
>> + if (!pfx || !pfx[0])
>> + {
>> + pfx = "file";
>> + plen = 4;
>> + }
>> + else
>> + {
>> + plen = strlen (pfx);
>> + if (plen > 5)
>> + plen = 5;
>> + }
>> +
>> + if (try_tmpdir)
>> + {
>> + d = __secure_getenv ("TMPDIR");
>> + if (d != NULL && direxists (d))
>> + dir = d;
>> + else if (dir != NULL && direxists (dir))
>> + /* nothing */ ;
>> + else
>> + dir = NULL;
>> + }
>> + if (dir == NULL)
>> + {
>> + if (direxists (P_tmpdir))
>> + dir = P_tmpdir;
>> + else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists ("/tmp"))
>> + dir = "/tmp";
>> + else
>> + {
>> + __set_errno (ENOENT);
>> + return -1;
>> + }
>> + }
>> +
>> + dlen = strlen (dir);
>> + while (dlen > 1 && dir[dlen - 1] == '/')
>> + dlen--; /* remove trailing slashes */
>> +
>> + /* check we have room for "${dir}/${pfx}XXXXXX\0" */
>> + if (tmpl_len < dlen + 1 + plen + 6 + 1)
>> + {
>> + __set_errno (EINVAL);
>> + return -1;
>> + }
>> +
>> + sprintf (tmpl, "%.*s/%.*sXXXXXX", (int) dlen, dir, (int) plen, pfx);
>> + return 0;
>> +}
>> +#endif /* _LIBC */
>> +
>> +/* These are the characters used in temporary file names. */
>> +static const char letters[] =
>> +"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
>> +
>> +/* Generate a temporary file name based on TMPL. TMPL must match the
>> + rules for mk[s]temp (i.e. end in "XXXXXX"). The name constructed
>> + does not exist at the time of the call to __gen_tempname. TMPL is
>> + overwritten with the result.
>> +
>> + KIND may be one of:
>> + __GT_NOCREATE: simply verify that the name does not exist
>> + at the time of the call.
>> + __GT_FILE: create the file using open(O_CREAT|O_EXCL)
>> + and return a read-write fd. The file is mode
>> 0600.
>> + __GT_BIGFILE: same as __GT_FILE but use open64().
>> + __GT_DIR: create a directory, which will be mode 0700.
>> +
>> + We use a clever algorithm to get hard-to-predict names. */
>> +int
>> +__gen_tempname (char *tmpl, int kind)
>> +{
>> + int len;
>> + char *XXXXXX;
>> + static uint64_t value;
>> + uint64_t random_time_bits;
>> + unsigned int count;
>> + int fd = -1;
>> + int save_errno = errno;
>> + struct_stat64 st;
>> +
>> + /* A lower bound on the number of temporary files to attempt to
>> + generate. The maximum total number of temporary file names that
>> + can exist for a given template is 62**6. It should never be
>> + necessary to try all these combinations. Instead if a reasonable
>> + number of names is tried (we define reasonable as 62**3) fail to
>> + give the system administrator the chance to remove the problems.
>> */
>> +#define ATTEMPTS_MIN (62 * 62 * 62)
>> +
>> + /* The number of times to attempt to generate a temporary file. To
>> + conform to POSIX, this must be no smaller than TMP_MAX. */
>> +#if ATTEMPTS_MIN < TMP_MAX
>> + unsigned int attempts = TMP_MAX;
>> +#else
>> + unsigned int attempts = ATTEMPTS_MIN;
>> +#endif
>> +
>> + len = strlen (tmpl);
>> + if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
>> + {
>> + __set_errno (EINVAL);
>> + return -1;
>> + }
>> +
>> + /* This is where the Xs start. */
>> + XXXXXX = &tmpl[len - 6];
>> +
>> + /* Get some more or less random data. */
>> +#ifdef RANDOM_BITS
>> + RANDOM_BITS (random_time_bits);
>> +#else
>> + {
>> + struct timeval tv;
>> + __gettimeofday (&tv, NULL);
>> + random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;
>> + }
>> +#endif
>> + value += random_time_bits ^ __getpid ();
>> +
>> + for (count = 0; count < attempts; value += 7777, ++count)
>> + {
>> + uint64_t v = value;
>> +
>> + /* Fill in the random bits. */
>> + XXXXXX[0] = letters[v % 62];
>> + v /= 62;
>> + XXXXXX[1] = letters[v % 62];
>> + v /= 62;
>> + XXXXXX[2] = letters[v % 62];
>> + v /= 62;
>> + XXXXXX[3] = letters[v % 62];
>> + v /= 62;
>> + XXXXXX[4] = letters[v % 62];
>> + v /= 62;
>> + XXXXXX[5] = letters[v % 62];
>> +
>> + switch (kind)
>> + {
>> + case __GT_FILE:
>> + fd = small_open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR |
>> S_IWUSR);
>> + break;
>> +
>> + case __GT_BIGFILE:
>> + fd = large_open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR |
>> S_IWUSR);
>> + break;
>> +
>> + case __GT_DIR:
>> + fd = __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
>> + break;
>> +
>> + case __GT_NOCREATE:
>> + /* This case is backward from the other three. __gen_tempname
>> + succeeds if __xstat fails because the name does not exist.
>> + Note the continue to bypass the common logic at the bottom
>> + of the loop. */
>> + if (__lxstat64 (_STAT_VER, tmpl, &st) < 0)
>> + {
>> + if (errno == ENOENT)
>> + {
>> + __set_errno (save_errno);
>> + return 0;
>> + }
>> + else
>> + /* Give up now. */
>> + return -1;
>> + }
>> + continue;
>> +
>> + default:
>> + assert (! "invalid KIND in __gen_tempname");
>> + }
>> +
>> + if (fd >= 0)
>> + {
>> + __set_errno (save_errno);
>> + return fd;
>> + }
>> + else if (errno != EEXIST)
>> + return -1;
>> + }
>> +
>> + /* We got out of the loop because we ran out of combinations to try.
>> */
>> + __set_errno (EEXIST);
>> + return -1;
>> +}
>> +
>> +
>> +/* Generate a unique temporary directory from TEMPLATE.
>> + The last six characters of TEMPLATE must be "XXXXXX";
>> + they are replaced with a string that makes the filename unique.
>> + The directory is created, mode 700, and its name is returned.
>> + (This function comes from OpenBSD.) */
>> +char *
>> +mkdtemp (char *template)
>> +{
>> + if (gen_tempname (template, GT_DIR))
>> + return NULL;
>> + else
>> + return template;
>> +}
>> @@ .
>> patch -p0 <<'@@ .'
>> Index: rpm/misc/tempname.h
>>
>> ============================================================================
>> $ cvs diff -u -r0 -r1.1 tempname.h
>> --- /dev/null 2009-03-17 17:30:15 +0100
>> +++ tempname.h 2009-03-17 17:30:16 +0100
>> @@ -0,0 +1,38 @@
>> +/* Create a temporary file or directory.
>> +
>> + Copyright (C) 2006 Free Software Foundation, Inc.
>> +
>> + This program is free software: you can redistribute it and/or modify
>> + it under the terms of the GNU General Public License as published by
>> + the Free Software Foundation; either version 3 of the License, or
>> + (at your option) any later version.
>> +
>> + This program is distributed in the hope that it will be useful,
>> + but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + GNU General Public License for more details.
>> +
>> + You should have received a copy of the GNU General Public License
>> + along with this program. If not, see <http://www.gnu.org/licenses/>.
>> */
>> +
>> +/* header written by Eric Blake */
>> +
>> +/* In gnulib, always prefer large files. GT_FILE maps to
>> + __GT_BIGFILE, not __GT_FILE, for a reason. */
>> +#define GT_FILE 1
>> +#define GT_DIR 2
>> +#define GT_NOCREATE 3
>> +
>> +/* Generate a temporary file name based on TMPL. TMPL must match the
>> + rules for mk[s]temp (i.e. end in "XXXXXX"). The name constructed
>> + does not exist at the time of the call to gen_tempname. TMPL is
>> + overwritten with the result.
>> +
>> + KIND may be one of:
>> + GT_NOCREATE: simply verify that the name does not exist
>> + at the time of the call.
>> + GT_FILE: create a large file using open(O_CREAT|O_EXCL)
>> + and return a read-write fd. The file is mode
>> 0600.
>> + GT_DIR: create a directory, which will be mode 0700.
>> +
>> + We use a clever algorithm to get hard-to-predict names. */
>> @@ .
>> ______________________________________________________________________
>> RPM Package Manager http://rpm5.org
>> CVS Sources Repository rpm-cvs@rpm5.org
>>
>
> ______________________________________________________________________
> RPM Package Manager http://rpm5.org
> Developer Communication List rpm-devel@rpm5.org
>
[Attachment #3 (text/html)]
<div class="gmail_quote">On Tue, Mar 17, 2009 at 5:36 PM, Jeff Johnson <span \
dir="ltr"><<a href="mailto:n3npq@mac.com">n3npq@mac.com</a>></span> \
wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, \
204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"> Oooh, thank you! I keep meaning \
to do this ...<br> <br>
BTW, perhaps its time to switch RPM to using Gnulib<br>
for portability issues as suggested (for popt) here:<br>
<br>
<a href="http://rpm5.org/community/rpm-devel/3161.html" \
target="_blank">http://rpm5.org/community/rpm-devel/3161.html</a><br> <br>
(aside)<br>
I plain and simply __CANNOT__ justify Gnulib for popt<br>
for the two dinky portability problems that were reported.<br>
<br>
But RPM might benefit from Gnulib even if Gnulib is way overkill for POPT.<br>
<br>
Opinions?<br>
</blockquote><div><br>I was also my thought. <br><br>Regards<br> </div><blockquote \
class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt \
0pt 0.8ex; padding-left: 1ex;"><br> 73 de Jeff<div><div></div><div class="h5"><br>
<br>
On Mar 17, 2009, at 12:30 PM, Pinto Elia wrote:<br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); \
margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"> RPM Package Manager, CVS \
Repository<br> <a href="http://rpm5.org/cvs/" \
target="_blank">http://rpm5.org/cvs/</a><br> \
____________________________________________________________________________<br> <br>
Server: <a href="http://rpm5.org" target="_blank">rpm5.org</a> \
Name: Pinto Elia<br> Root: /v/rpm/cvs Email: <a \
href="mailto:devzero2000@rpm5.org" target="_blank">devzero2000@rpm5.org</a><br> \
Module: rpm Date: 17-Mar-2009 17:30:16<br> Branch: \
HEAD Handle: 2009031716301600<br> <br>
Added files:<br>
rpm/misc mkdtemp.c tempname.h<br>
Modified files:<br>
rpm CHANGES<br>
rpm/misc Makefile.am librpmmisc.c<br>
<br>
Log:<br>
add mkdtemp portability function to -lrpmmisc<br>
<br>
Summary:<br>
Revision Changes Path<br>
1.2827 +1 -0 rpm/CHANGES<br>
1.42 +4 -2 rpm/misc/Makefile.am<br>
1.4 +4 -0 rpm/misc/librpmmisc.c<br>
1.1 +349 -0 rpm/misc/mkdtemp.c<br>
1.1 +38 -0 rpm/misc/tempname.h<br>
____________________________________________________________________________<br>
<br>
patch -p0 <<'@@ .'<br>
Index: rpm/CHANGES<br>
============================================================================<br>
$ cvs diff -u -r1.2826 -r1.2827 CHANGES<br>
--- rpm/CHANGES 16 Mar 2009 22:30:39 -0000 1.2826<br>
+++ rpm/CHANGES 17 Mar 2009 16:30:16 -0000 1.2827<br>
@@ -1,5 +1,6 @@<br>
<br>
5.2a3 -> 5.2a4:<br>
+ - devzero2000: add mkdtemp portability function to -lrpmmisc<br>
- proyvind: do lazy mkdir of %_builddir, %_rpmdir & %_srcrpmdir when \
doing<br>
--install for src.rpms as well.<br>
- jbj: yarn: convert Header refcount to usage mutex.<br>
@@ .<br>
patch -p0 <<'@@ .'<br>
Index: rpm/misc/Makefile.am<br>
============================================================================<br>
$ cvs diff -u -r1.41 -r1.42 Makefile.am<br>
--- rpm/misc/Makefile.am 15 Feb 2009 13:55:32 -0000 1.41<br>
+++ rpm/misc/Makefile.am 17 Mar 2009 16:30:16 -0000 1.42<br>
@@ -15,10 +15,12 @@<br>
setenv.c stpcpy.c stpncpy.c \<br>
strcspn.c strdup.c strerror.c \<br>
strftime.c strcspn.c strstr.c strtol.c \<br>
- strtoul.c<br>
+ strtoul.c \<br>
+ tempname.h \<br>
+ mkdtemp.c<br>
<br>
noinst_HEADERS = \<br>
- asprintf.h err.h error.h<br>
+ asprintf.h err.h error.h tempname.h<br>
<br>
usrlibdir = $(libdir)<br>
usrlib_LTLIBRARIES = <a href="http://librpmmisc.la" \
target="_blank">librpmmisc.la</a><br> @@ .<br>
patch -p0 <<'@@ .'<br>
Index: rpm/misc/librpmmisc.c<br>
============================================================================<br>
$ cvs diff -u -r1.3 -r1.4 librpmmisc.c<br>
--- rpm/misc/librpmmisc.c 31 Jul 2008 16:58:55 -0000 1.3<br>
+++ rpm/misc/librpmmisc.c 17 Mar 2009 16:30:16 -0000 1.4<br>
@@ -67,3 +67,7 @@<br>
#if !defined(HAVE_STRSTR)<br>
#include "strstr.c"<br>
#endif<br>
+<br>
+#if !defined(HAVE_MKDTEMP)<br>
+#include "mkdtemp.c"<br>
+#endif<br>
@@ .<br>
patch -p0 <<'@@ .'<br>
Index: rpm/misc/mkdtemp.c<br>
============================================================================<br>
$ cvs diff -u -r0 -r1.1 mkdtemp.c<br>
--- /dev/null 2009-03-17 17:30:15 +0100<br>
+++ mkdtemp.c 2009-03-17 17:30:16 +0100<br>
@@ -0,0 +1,349 @@<br>
+/* Copyright (C) 1999, 2001-2003, 2006-2007 Free Software Foundation, Inc.<br>
+ This file is part of the GNU C Library.<br>
+<br>
+ This program is free software: you can redistribute it and/or modify<br>
+ it under the terms of the GNU General Public License as published by<br>
+ the Free Software Foundation; either version 3 of the License, or<br>
+ (at your option) any later version.<br>
+<br>
+ This program is distributed in the hope that it will be useful,<br>
+ but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br>
+ GNU General Public License for more details.<br>
+<br>
+ You should have received a copy of the GNU General Public License<br>
+ along with this program. If not, see <<a href="http://www.gnu.org/licenses/" \
target="_blank">http://www.gnu.org/licenses/</a>>. */<br> +<br>
+/* Extracted from misc/mkdtemp.c. */<br>
+#include "system.h"<br>
+<br>
+<br>
+/* tempname.c - generate the name of a temporary file.<br>
+<br>
+ Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,<br>
+ 2000, 2001, 2002, 2003, 2005, 2006, 2007 Free Software Foundation,<br>
+ Inc.<br>
+<br>
+ This program is free software: you can redistribute it and/or modify<br>
+ it under the terms of the GNU General Public License as published by<br>
+ the Free Software Foundation; either version 3 of the License, or<br>
+ (at your option) any later version.<br>
+<br>
+ This program is distributed in the hope that it will be useful,<br>
+ but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br>
+ GNU General Public License for more details.<br>
+<br>
+ You should have received a copy of the GNU General Public License<br>
+ along with this program. If not, see <<a href="http://www.gnu.org/licenses/" \
target="_blank">http://www.gnu.org/licenses/</a>>. */<br> +<br>
+/* Extracted from glibc sysdeps/posix/tempname.c. See also tmpdir.c. */<br>
+<br>
+#if !_LIBC<br>
+# include <config.h><br>
+# include "tempname.h"<br>
+#endif<br>
+<br>
+#include <sys/types.h><br>
+#include <assert.h><br>
+<br>
+#include <errno.h><br>
+#ifndef __set_errno<br>
+# define __set_errno(Val) errno = (Val)<br>
+#endif<br>
+<br>
+#include <stdio.h><br>
+#ifndef P_tmpdir<br>
+# define P_tmpdir "/tmp"<br>
+#endif<br>
+#ifndef TMP_MAX<br>
+# define TMP_MAX 238328<br>
+#endif<br>
+#ifndef __GT_FILE<br>
+# define __GT_FILE 0<br>
+# define __GT_BIGFILE 1<br>
+# define __GT_DIR 2<br>
+# define __GT_NOCREATE 3<br>
+#endif<br>
+<br>
+#include <stddef.h><br>
+#include <stdlib.h><br>
+#include <string.h><br>
+<br>
+#include <fcntl.h><br>
+#include <sys/time.h><br>
+#include <stdint.h><br>
+#include <unistd.h><br>
+<br>
+#include <sys/stat.h><br>
+<br>
+#if _LIBC<br>
+# define struct_stat64 struct stat64<br>
+# define small_open __open<br>
+# define large_open __open64<br>
+#else<br>
+# define struct_stat64 struct stat<br>
+# define small_open open<br>
+# define large_open open<br>
+# define __gen_tempname gen_tempname<br>
+# define __getpid getpid<br>
+# define __gettimeofday gettimeofday<br>
+# define __mkdir mkdir<br>
+# define __lxstat64(version, file, buf) lstat (file, buf)<br>
+# define __xstat64(version, file, buf) stat (file, buf)<br>
+#endif<br>
+<br>
+#if ! (HAVE___SECURE_GETENV || _LIBC)<br>
+# define __secure_getenv getenv<br>
+#endif<br>
+<br>
+#ifdef _LIBC<br>
+# include <hp-timing.h><br>
+# if HP_TIMING_AVAIL<br>
+# define RANDOM_BITS(Var) \<br>
+ if (__builtin_expect (value == UINT64_C (0), 0)) \<br>
+ { \<br>
+ /* If this is the first time this function is used initialize \
\<br> + the variable we accumulate the value in to some somewhat \
\<br> + random value. If we'd not do this programs at startup time \
\<br> + might have a reduced set of possible names, at least on slow \
\<br> + machines. */ \
\<br> + struct timeval tv; \
\<br> + __gettimeofday (&tv, NULL); \
\<br> + value = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; \
\<br> + } \
\<br> + HP_TIMING_NOW (Var)<br>
+# endif<br>
+#endif<br>
+<br>
+/* Use the widest available unsigned type if uint64_t is not<br>
+ available. The algorithm below extracts a number less than 62**6<br>
+ (approximately 2**35.725) from uint64_t, so ancient hosts where<br>
+ uintmax_t is only 32 bits lose about 3.725 bits of randomness,<br>
+ which is better than not having mkstemp at all. */<br>
+#if !defined UINT64_MAX && !defined uint64_t<br>
+# define uint64_t uintmax_t<br>
+#endif<br>
+<br>
+#if _LIBC<br>
+/* Return nonzero if DIR is an existent directory. */<br>
+static int<br>
+direxists (const char *dir)<br>
+{<br>
+ struct_stat64 buf;<br>
+ return __xstat64 (_STAT_VER, dir, &buf) == 0 && S_ISDIR \
(buf.st_mode);<br> +}<br>
+<br>
+/* Path search algorithm, for tmpnam, tmpfile, etc. If DIR is<br>
+ non-null and exists, uses it; otherwise uses the first of $TMPDIR,<br>
+ P_tmpdir, /tmp that exists. Copies into TMPL a template suitable<br>
+ for use with mk[s]temp. Will fail (-1) if DIR is non-null and<br>
+ doesn't exist, none of the searched dirs exists, or there's not<br>
+ enough space in TMPL. */<br>
+int<br>
+__path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,<br>
+ int try_tmpdir)<br>
+{<br>
+ const char *d;<br>
+ size_t dlen, plen;<br>
+<br>
+ if (!pfx || !pfx[0])<br>
+ {<br>
+ pfx = "file";<br>
+ plen = 4;<br>
+ }<br>
+ else<br>
+ {<br>
+ plen = strlen (pfx);<br>
+ if (plen > 5)<br>
+ plen = 5;<br>
+ }<br>
+<br>
+ if (try_tmpdir)<br>
+ {<br>
+ d = __secure_getenv ("TMPDIR");<br>
+ if (d != NULL && direxists (d))<br>
+ dir = d;<br>
+ else if (dir != NULL && direxists (dir))<br>
+ /* nothing */ ;<br>
+ else<br>
+ dir = NULL;<br>
+ }<br>
+ if (dir == NULL)<br>
+ {<br>
+ if (direxists (P_tmpdir))<br>
+ dir = P_tmpdir;<br>
+ else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists \
("/tmp"))<br> + dir = "/tmp";<br>
+ else<br>
+ {<br>
+ __set_errno (ENOENT);<br>
+ return -1;<br>
+ }<br>
+ }<br>
+<br>
+ dlen = strlen (dir);<br>
+ while (dlen > 1 && dir[dlen - 1] == '/')<br>
+ dlen--; /* remove trailing slashes */<br>
+<br>
+ /* check we have room for "${dir}/${pfx}XXXXXX\0" */<br>
+ if (tmpl_len < dlen + 1 + plen + 6 + 1)<br>
+ {<br>
+ __set_errno (EINVAL);<br>
+ return -1;<br>
+ }<br>
+<br>
+ sprintf (tmpl, "%.*s/%.*sXXXXXX", (int) dlen, dir, (int) plen, \
pfx);<br> + return 0;<br>
+}<br>
+#endif /* _LIBC */<br>
+<br>
+/* These are the characters used in temporary file names. */<br>
+static const char letters[] =<br>
+"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";<br>
+<br>
+/* Generate a temporary file name based on TMPL. TMPL must match the<br>
+ rules for mk[s]temp (i.e. end in "XXXXXX"). The name constructed<br>
+ does not exist at the time of the call to __gen_tempname. TMPL is<br>
+ overwritten with the result.<br>
+<br>
+ KIND may be one of:<br>
+ __GT_NOCREATE: simply verify that the name does not exist<br>
+ at the time of the call.<br>
+ __GT_FILE: create the file using open(O_CREAT|O_EXCL)<br>
+ and return a read-write fd. The file is mode 0600.<br>
+ __GT_BIGFILE: same as __GT_FILE but use open64().<br>
+ __GT_DIR: create a directory, which will be mode 0700.<br>
+<br>
+ We use a clever algorithm to get hard-to-predict names. */<br>
+int<br>
+__gen_tempname (char *tmpl, int kind)<br>
+{<br>
+ int len;<br>
+ char *XXXXXX;<br>
+ static uint64_t value;<br>
+ uint64_t random_time_bits;<br>
+ unsigned int count;<br>
+ int fd = -1;<br>
+ int save_errno = errno;<br>
+ struct_stat64 st;<br>
+<br>
+ /* A lower bound on the number of temporary files to attempt to<br>
+ generate. The maximum total number of temporary file names that<br>
+ can exist for a given template is 62**6. It should never be<br>
+ necessary to try all these combinations. Instead if a reasonable<br>
+ number of names is tried (we define reasonable as 62**3) fail to<br>
+ give the system administrator the chance to remove the problems. */<br>
+#define ATTEMPTS_MIN (62 * 62 * 62)<br>
+<br>
+ /* The number of times to attempt to generate a temporary file. To<br>
+ conform to POSIX, this must be no smaller than TMP_MAX. */<br>
+#if ATTEMPTS_MIN < TMP_MAX<br>
+ unsigned int attempts = TMP_MAX;<br>
+#else<br>
+ unsigned int attempts = ATTEMPTS_MIN;<br>
+#endif<br>
+<br>
+ len = strlen (tmpl);<br>
+ if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))<br>
+ {<br>
+ __set_errno (EINVAL);<br>
+ return -1;<br>
+ }<br>
+<br>
+ /* This is where the Xs start. */<br>
+ XXXXXX = &tmpl[len - 6];<br>
+<br>
+ /* Get some more or less random data. */<br>
+#ifdef RANDOM_BITS<br>
+ RANDOM_BITS (random_time_bits);<br>
+#else<br>
+ {<br>
+ struct timeval tv;<br>
+ __gettimeofday (&tv, NULL);<br>
+ random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;<br>
+ }<br>
+#endif<br>
+ value += random_time_bits ^ __getpid ();<br>
+<br>
+ for (count = 0; count < attempts; value += 7777, ++count)<br>
+ {<br>
+ uint64_t v = value;<br>
+<br>
+ /* Fill in the random bits. */<br>
+ XXXXXX[0] = letters[v % 62];<br>
+ v /= 62;<br>
+ XXXXXX[1] = letters[v % 62];<br>
+ v /= 62;<br>
+ XXXXXX[2] = letters[v % 62];<br>
+ v /= 62;<br>
+ XXXXXX[3] = letters[v % 62];<br>
+ v /= 62;<br>
+ XXXXXX[4] = letters[v % 62];<br>
+ v /= 62;<br>
+ XXXXXX[5] = letters[v % 62];<br>
+<br>
+ switch (kind)<br>
+ {<br>
+ case __GT_FILE:<br>
+ fd = small_open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);<br>
+ break;<br>
+<br>
+ case __GT_BIGFILE:<br>
+ fd = large_open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);<br>
+ break;<br>
+<br>
+ case __GT_DIR:<br>
+ fd = __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR);<br>
+ break;<br>
+<br>
+ case __GT_NOCREATE:<br>
+ /* This case is backward from the other three. __gen_tempname<br>
+ succeeds if __xstat fails because the name does not exist.<br>
+ Note the continue to bypass the common logic at the bottom<br>
+ of the loop. */<br>
+ if (__lxstat64 (_STAT_VER, tmpl, &st) < 0)<br>
+ {<br>
+ if (errno == ENOENT)<br>
+ {<br>
+ __set_errno (save_errno);<br>
+ return 0;<br>
+ }<br>
+ else<br>
+ /* Give up now. */<br>
+ return -1;<br>
+ }<br>
+ continue;<br>
+<br>
+ default:<br>
+ assert (! "invalid KIND in __gen_tempname");<br>
+ }<br>
+<br>
+ if (fd >= 0)<br>
+ {<br>
+ __set_errno (save_errno);<br>
+ return fd;<br>
+ }<br>
+ else if (errno != EEXIST)<br>
+ return -1;<br>
+ }<br>
+<br>
+ /* We got out of the loop because we ran out of combinations to try. */<br>
+ __set_errno (EEXIST);<br>
+ return -1;<br>
+}<br>
+<br>
+<br>
+/* Generate a unique temporary directory from TEMPLATE.<br>
+ The last six characters of TEMPLATE must be "XXXXXX";<br>
+ they are replaced with a string that makes the filename unique.<br>
+ The directory is created, mode 700, and its name is returned.<br>
+ (This function comes from OpenBSD.) */<br>
+char *<br>
+mkdtemp (char *template)<br>
+{<br>
+ if (gen_tempname (template, GT_DIR))<br>
+ return NULL;<br>
+ else<br>
+ return template;<br>
+}<br>
@@ .<br>
patch -p0 <<'@@ .'<br>
Index: rpm/misc/tempname.h<br>
============================================================================<br>
$ cvs diff -u -r0 -r1.1 tempname.h<br>
--- /dev/null 2009-03-17 17:30:15 +0100<br>
+++ tempname.h 2009-03-17 17:30:16 +0100<br>
@@ -0,0 +1,38 @@<br>
+/* Create a temporary file or directory.<br>
+<br>
+ Copyright (C) 2006 Free Software Foundation, Inc.<br>
+<br>
+ This program is free software: you can redistribute it and/or modify<br>
+ it under the terms of the GNU General Public License as published by<br>
+ the Free Software Foundation; either version 3 of the License, or<br>
+ (at your option) any later version.<br>
+<br>
+ This program is distributed in the hope that it will be useful,<br>
+ but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br>
+ GNU General Public License for more details.<br>
+<br>
+ You should have received a copy of the GNU General Public License<br>
+ along with this program. If not, see <<a href="http://www.gnu.org/licenses/" \
target="_blank">http://www.gnu.org/licenses/</a>>. */<br> +<br>
+/* header written by Eric Blake */<br>
+<br>
+/* In gnulib, always prefer large files. GT_FILE maps to<br>
+ __GT_BIGFILE, not __GT_FILE, for a reason. */<br>
+#define GT_FILE 1<br>
+#define GT_DIR 2<br>
+#define GT_NOCREATE 3<br>
+<br>
+/* Generate a temporary file name based on TMPL. TMPL must match the<br>
+ rules for mk[s]temp (i.e. end in "XXXXXX"). The name constructed<br>
+ does not exist at the time of the call to gen_tempname. TMPL is<br>
+ overwritten with the result.<br>
+<br>
+ KIND may be one of:<br>
+ GT_NOCREATE: simply verify that the name does not exist<br>
+ at the time of the call.<br>
+ GT_FILE: create a large file using open(O_CREAT|O_EXCL)<br>
+ and return a read-write fd. The file is mode 0600.<br>
+ GT_DIR: create a directory, which will be mode 0700.<br>
+<br>
+ We use a clever algorithm to get hard-to-predict names. */<br>
@@ .<br>
______________________________________________________________________<br>
RPM Package Manager <a href="http://rpm5.org" \
target="_blank">http://rpm5.org</a><br> CVS Sources Repository \
<a href="mailto:rpm-cvs@rpm5.org" target="_blank">rpm-cvs@rpm5.org</a><br> \
</blockquote> <br>
______________________________________________________________________<br>
RPM Package Manager <a href="http://rpm5.org" \
target="_blank">http://rpm5.org</a><br></div></div> Developer Communication List \
<a href="mailto:rpm-devel@rpm5.org" target="_blank">rpm-devel@rpm5.org</a><br> \
</blockquote></div><br>
______________________________________________________________________
RPM Package Manager http://rpm5.org
Developer Communication List rpm-devel@rpm5.org
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic