summaryrefslogtreecommitdiff
path: root/rpmio
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2007-11-22 16:28:30 +0200
committerPanu Matilainen <pmatilai@redhat.com>2007-11-22 16:28:30 +0200
commitd10acc7c2a280bd8e0aea3610d9a8767521a5f40 (patch)
treef7aeffa417332f6d81021aef3b2db26ff05174d2 /rpmio
parentd8cd2b6b1139a81b819e66817e22d814fe25a9e7 (diff)
downloadrpm-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.am1
-rw-r--r--rpmio/rpmfileutil.c100
-rw-r--r--rpmio/rpmfileutil.h16
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 */