diff options
author | Panu Matilainen <pmatilai@redhat.com> | 2007-11-22 16:28:30 +0200 |
---|---|---|
committer | Panu Matilainen <pmatilai@redhat.com> | 2007-11-22 16:28:30 +0200 |
commit | d10acc7c2a280bd8e0aea3610d9a8767521a5f40 (patch) | |
tree | f7aeffa417332f6d81021aef3b2db26ff05174d2 /rpmio | |
parent | d8cd2b6b1139a81b819e66817e22d814fe25a9e7 (diff) | |
download | rpm-d10acc7c2a280bd8e0aea3610d9a8767521a5f40.tar.gz rpm-d10acc7c2a280bd8e0aea3610d9a8767521a5f40.tar.bz2 rpm-d10acc7c2a280bd8e0aea3610d9a8767521a5f40.zip |
Move makeTempFile() from misc.h to rpmfileutil.h
- probably not very useful outside rpm but used all over the tree,
- rename to rpmMkTempFile() for namespacing since we're exporting it now
Diffstat (limited to 'rpmio')
-rw-r--r-- | rpmio/Makefile.am | 1 | ||||
-rw-r--r-- | rpmio/rpmfileutil.c | 100 | ||||
-rw-r--r-- | rpmio/rpmfileutil.h | 16 |
3 files changed, 117 insertions, 0 deletions
diff --git a/rpmio/Makefile.am b/rpmio/Makefile.am index 0510be0e6..9b4b17a80 100644 --- a/rpmio/Makefile.am +++ b/rpmio/Makefile.am @@ -7,6 +7,7 @@ AM_CPPFLAGS += @WITH_LUA_INCLUDE@ AM_CPPFLAGS += @WITH_POPT_INCLUDE@ AM_CPPFLAGS += -I$(top_srcdir)/misc AM_CPPFLAGS += -DRPMCONFIGDIR="\"@RPMCONFIGDIR@\"" +AM_CPPFLAGS += -DLOCALSTATEDIR="\"$(localstatedir)\"" usrlibdir = $(libdir) usrlib_LTLIBRARIES = librpmio.la diff --git a/rpmio/rpmfileutil.c b/rpmio/rpmfileutil.c index e79a65ad3..30047dadc 100644 --- a/rpmio/rpmfileutil.c +++ b/rpmio/rpmfileutil.c @@ -17,6 +17,7 @@ #include <rpmfileutil.h> #include <rpmurl.h> #include <rpmmacro.h> +#include <rpmlog.h> #include <argv.h> static int open_dso(const char * path, pid_t * pidp, size_t *fsizep) @@ -219,3 +220,102 @@ exit: return rc; } +int rpmMkTempFile(const char * prefix, const char ** fnptr, FD_t * fdptr) +{ + const char * tpmacro = "%{?_tmppath:%{_tmppath}}%{!?_tmppath:" LOCALSTATEDIR "/tmp}"; + const char * tempfn = NULL; + const char * tfn = NULL; + static int _initialized = 0; + int temput; + FD_t fd = NULL; + int ran; + + if (!prefix) prefix = ""; + + /* Create the temp directory if it doesn't already exist. */ + if (!_initialized) { + _initialized = 1; + tempfn = rpmGenPath(prefix, tpmacro, NULL); + if (rpmioMkpath(tempfn, 0755, (uid_t) -1, (gid_t) -1)) + goto errxit; + } + + /* XXX should probably use mkstemp here */ + srand(time(NULL)); + ran = rand() % 100000; + + /* maybe this should use link/stat? */ + + do { + char tfnbuf[64]; +#ifndef NOTYET + sprintf(tfnbuf, "rpm-tmp.%d", ran++); + tempfn = _free(tempfn); + tempfn = rpmGenPath(prefix, tpmacro, tfnbuf); +#else + strcpy(tfnbuf, "rpm-tmp.XXXXXX"); + tempfn = _free(tempfn); + tempfn = rpmGenPath(prefix, tpmacro, mktemp(tfnbuf)); +#endif + + temput = urlPath(tempfn, &tfn); + if (*tfn == '\0') goto errxit; + + switch (temput) { + case URL_IS_DASH: + case URL_IS_HKP: + goto errxit; + break; + case URL_IS_HTTPS: + case URL_IS_HTTP: + case URL_IS_FTP: + default: + break; + } + + fd = Fopen(tempfn, "w+x.ufdio"); + /* XXX FIXME: errno may not be correct for ufdio */ + } while ((fd == NULL || Ferror(fd)) && errno == EEXIST); + + if (fd == NULL || Ferror(fd)) + goto errxit; + + switch(temput) { + case URL_IS_PATH: + case URL_IS_UNKNOWN: + { struct stat sb, sb2; + if (!stat(tfn, &sb) && S_ISLNK(sb.st_mode)) { + rpmlog(RPMLOG_ERR, _("error creating temporary file %s\n"), tfn); + goto errxit; + } + + if (sb.st_nlink != 1) { + rpmlog(RPMLOG_ERR, _("error creating temporary file %s\n"), tfn); + goto errxit; + } + + if (fstat(Fileno(fd), &sb2) == 0) { + if (sb2.st_ino != sb.st_ino || sb2.st_dev != sb.st_dev) { + rpmlog(RPMLOG_ERR, _("error creating temporary file %s\n"), tfn); + goto errxit; + } + } + } break; + default: + break; + } + + if (fnptr) + *fnptr = tempfn; + else + tempfn = _free(tempfn); + *fdptr = fd; + + return 0; + +errxit: + tempfn = _free(tempfn); + if (fd != NULL) (void) Fclose(fd); + return 1; +} + diff --git a/rpmio/rpmfileutil.h b/rpmio/rpmfileutil.h index b2f72f518..0022e5d03 100644 --- a/rpmio/rpmfileutil.h +++ b/rpmio/rpmfileutil.h @@ -15,4 +15,20 @@ int rpmDoDigest(pgpHashAlgo algo, const char * fn,int asAscii, unsigned char * digest, size_t * fsizep); + +/** + * Return file handle for a temporaray file. + * A unique temporaray file path will be generated using + * rpmGenPath(prefix, "%{_tmppath}/", "rpm-tmp.XXXXX") + * where "XXXXXX" is filled in using rand(3). The file is opened, and + * the link count and (dev,ino) location are verified after opening. + * The file name and the open file handle are returned. + * + * @param prefix leading part of temp file path + * @retval fnptr temp file name (or NULL) + * @retval fdptr temp file handle + * @return 0 on success + */ +int rpmMkTempFile(const char * prefix, const char ** fnptr, FD_t * fdptr); + #endif /* _RPMFILEUTIL_H */ |