Sophie

Sophie

distrib > Mandriva > 10.2 > x86_64 > by-pkgid > b7174078f84d42f033df4938ce3efa9e > files > 3

cdrdao-1.1.9-7.1.102mdk.src.rpm

diff -ruN cdrdao-1.1.9.org/config.h.in cdrdao-1.1.9/config.h.in
--- cdrdao-1.1.9.org/config.h.in	2004-06-06 17:58:04.000000000 -0600
+++ cdrdao-1.1.9/config.h.in	2005-05-17 13:25:41.806583811 -0600
@@ -60,6 +60,18 @@
 /* Define to 1 if you have the `seteuid' function. */
 #undef HAVE_SETEUID
 
+/* Define to 1 if you have the etgid' function. */
+#undef HAVE_SETGID
+
+/* Define to 1 if you have the etregid' function. */
+#undef HAVE_SETREGID
+
+/* Define to 1 if you have the etreuid' function. */
+#undef HAVE_SETREUID
+
+/* Define to 1 if you have the etuid' function. */
+#undef HAVE_SETUID
+
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
diff -ruN cdrdao-1.1.9.org/dao/CdrDriver.cc cdrdao-1.1.9/dao/CdrDriver.cc
--- cdrdao-1.1.9.org/dao/CdrDriver.cc	2004-06-05 13:40:52.000000000 -0600
+++ cdrdao-1.1.9/dao/CdrDriver.cc	2005-05-17 13:26:58.934670625 -0600
@@ -36,6 +36,7 @@
 #include "util.h"
 #include "CdTextItem.h"
 #include "data.h"
+#include "port.h"
 
 // all drivers
 #include "CDD2600.h"
@@ -3301,6 +3302,9 @@
     fp = onTheFlyFd_;
   }
   else {
+
+    giveUpRootPrivileges();
+
 #ifdef __CYGWIN__
     if ((fp = open(dataFilename, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,
 		   0666)) < 0)
diff -ruN cdrdao-1.1.9.org/dao/dao.cc cdrdao-1.1.9/dao/dao.cc
--- cdrdao-1.1.9.org/dao/dao.cc	2004-05-17 16:52:05.000000000 -0600
+++ cdrdao-1.1.9/dao/dao.cc	2005-05-17 13:28:50.365570012 -0600
@@ -457,6 +457,8 @@
 
   setRealTimeScheduling(4);
 
+  giveUpRootPrivileges();
+
   if (cdr != NULL) {
     if (cdr->bigEndianSamples() == 0) {
       // swap samples for little endian recorders
@@ -746,6 +748,8 @@
   }
 #endif
 
+  giveUpRootPrivileges();
+
   switch (writer(toc, cdr, header, startLba, speed)) {
   case 1: // error, reader process terminated abnormally
 #ifndef USE_POSIX_THREADS
diff -ruN cdrdao-1.1.9.org/dao/main.cc cdrdao-1.1.9/dao/main.cc
--- cdrdao-1.1.9.org/dao/main.cc	2004-06-05 14:57:34.000000000 -0600
+++ cdrdao-1.1.9/dao/main.cc	2005-05-17 13:39:35.867121735 -0600
@@ -40,8 +40,10 @@
 #include "ScsiIf.h"
 #include "CdrDriver.h"
 #include "dao.h"
+#include "port.h"
 #include "Settings.h"
 #include "Cddb.h"
+#include "TempFileManager.h"
 
 
 #ifdef UNIXWARE
@@ -64,6 +66,7 @@
 static const char *DATA_FILENAME = NULL;
 static const char *CDDB_SERVER_LIST = "freedb.freedb.org freedb.freedb.org:/~cddb/cddb.cgi uk.freedb.org uk.freedb.org:/~cddb/cddb.cgi cz.freedb.org cz.freedb.org:/~cddb/cddb.cgi";
 static const char *CDDB_LOCAL_DB_DIR = NULL;
+static const char *TMP_FILE_DIR = NULL;
 static int WRITING_SPEED = -1;
 static int EJECT = 0;
 static int SWAP = 0;
@@ -92,6 +95,7 @@
 static int OVERBURN = 0;
 static int BUFFER_UNDER_RUN_PROTECTION = 1;
 static int WRITE_SPEED_CONTROL = 1;
+static bool KEEP = false;
 static bool PRINT_QUERY = false;
 
 static CdrDriver::BlankingMode BLANKING_MODE = CdrDriver::BLANK_MINIMAL;
@@ -206,7 +210,12 @@
     break;
     
   case SHOW_TOC:
-    message(0, "\nUsage: %s show-toc [-v #] toc-file\n", PRGNAME);
+    message(0, "\nUsage: %s show-toc [options] toc-file", PRGNAME);
+    message(0, 
+"options:\n"   
+"  --tmpdir <path>         - sets directory for temporary wav files\n"
+"  --keep                  - keep generated temp wav files after exit\n"
+"  -v #                    - sets verbose level\n");
     break;
     
   case SHOW_DATA:
@@ -238,6 +247,8 @@
 "  --buffers #             - sets fifo buffer size (min. 10)\n"
 "  --reload                - reload the disk if necessary for writing\n"
 "  --force                 - force execution of operation\n"
+"  --tmpdir <path>         - sets directory for temporary wav files\n"
+"  --keep                  - keep generated temp wav files after exit\n"
 "  -v #                    - sets verbose level\n"
 "  -n                      - no pause before writing\n",
 	    SCSI_DEVICE);
@@ -270,6 +281,8 @@
 "  --buffers #             - sets fifo buffer size (min. 10)\n"
 "  --reload                - reload the disk if necessary for writing\n"
 "  --force                 - force execution of operation\n"
+"  --tmpdir <path>         - sets directory for temporary wav files\n"
+"  --keep                  - keep generated temp wav files after exit\n"
 "  -v #                    - sets verbose level\n"
 "  -n                      - no pause before writing\n",
 	    SCSI_DEVICE);
@@ -350,11 +363,22 @@
     break;
     
   case TOC_INFO:
-    message(0, "\nUsage: %s toc-info [-v #] toc-file\n", PRGNAME);
+    message(0, "\nUsage: %s toc-info [options] toc-file", PRGNAME);
+    message(0, 
+"options:\n"   
+"  --tmpdir <path>         - sets directory for temporary wav files\n"
+"  --keep                  - keep generated temp wav files after exit\n"
+"  -v #                    - sets verbose level\n");
     break;
     
   case TOC_SIZE:
-    message(0, "\nUsage: %s toc-size [-v #] toc-file\n", PRGNAME);
+    message(0, "\nUsage: %s toc-size [options] toc-file", PRGNAME);
+    message(0, 
+"options:\n"   
+"  --tmpdir <path>         - sets directory for temporary wav files\n"
+"  --keep                  - keep generated temp wav files after exit\n"
+"  -v #                    - sets verbose level\n");
+    break;
 
   case BLANK:
     message(0, "\nUsage: %s blank [options]", PRGNAME);
@@ -554,6 +578,9 @@
 	*ival > 0) {
       CDDB_TIMEOUT = *ival;
     }
+    if ((sval = SETTINGS->getString(SET_TMP_FILE_DIR)) != NULL) {
+        TMP_FILE_DIR = strdupCC(sval);
+    }
   }
 }
 
@@ -859,6 +886,9 @@
       else if (strcmp((*argv) + 2, "force") == 0) {
 	FORCE = 1;
       }
+      else if (strcmp((*argv) + 2, "keep") == 0) {
+       KEEP = true;
+      }
       else if (strcmp((*argv) + 2, "on-the-fly") == 0) {
 	ON_THE_FLY = 1;
       }
@@ -954,6 +984,16 @@
 	  argc--, argv++;
 	}
       }
+      else if (strcmp((*argv) + 2, "tmpdir") == 0) {
+          if (argc < 2) {
+              message(-2, "Missing argument after: %s", *argv);
+              return 1;
+          } else {
+              TMP_FILE_DIR = argv[1];
+              SETTINGS->set(SET_TMP_FILE_DIR, TMP_FILE_DIR);
+              argc--, argv++;
+          }
+      }
       else if (strcmp((*argv) + 2, "cddb-timeout") == 0) {
 	if (argc < 2) {
 	  message(-2, "Missing argument after: %s", *argv);
@@ -1062,6 +1102,26 @@
   return 0;
 }
 
+// Commit settings to overall system. Export them.
+static void commitSettings(Settings* SETTINGS, const char* settingsPath)
+{
+  if (TMP_FILE_DIR)
+    tempFileManager.setTempDirectory(TMP_FILE_DIR);
+
+  tempFileManager.setKeepTemps(KEEP);
+
+  if (SAVE_SETTINGS && settingsPath != NULL) {
+    // If we're saving our settings, give up root privileges and
+    // exit. The --save option is only compiled in if setreuid() is
+    // available (because it could be used for a local root exploit).
+    if (giveUpRootPrivileges()) {
+      exportSettings(COMMAND);
+      SETTINGS->write(settingsPath);
+    }
+    exit(0);
+  }
+}
+
 // Selects driver for device of 'scsiIf'.
 static CdrDriver *selectDriver(Command cmd, ScsiIf *scsiIf,
 			       const char *driverId)
@@ -2104,13 +2164,9 @@
     exit(1);
   }
 
-  printVersion();
-
-  if (SAVE_SETTINGS && settingsPath != NULL) {
-    exportSettings(COMMAND);
-    SETTINGS->write(settingsPath);
-  }
+  commitSettings(SETTINGS, settingsPath);
 
+  printVersion();
 
   if (COMMAND != READ_TOC && COMMAND != DISK_INFO && COMMAND != READ_CD &&
       COMMAND != BLANK && COMMAND != SCAN_BUS && COMMAND != UNLOCK &&
@@ -2339,11 +2395,6 @@
     else {
       cdr->rezeroUnit(0);
 
-#if defined(HAVE_SETEUID) && defined(HAVE_SETEGID)
-      seteuid(getuid());
-      setegid(getgid());
-#endif
-
       if (WITH_CDDB) {
 	if (readCddb(toc) == 0) {
 	  message(2, "CD-TEXT data was added to toc-file.");
diff -ruN cdrdao-1.1.9.org/dao/port.cc cdrdao-1.1.9/dao/port.cc
--- cdrdao-1.1.9.org/dao/port.cc	2002-06-29 11:22:08.000000000 -0600
+++ cdrdao-1.1.9/dao/port.cc	2005-05-17 13:41:01.809615514 -0600
@@ -287,3 +287,41 @@
 
   return 0;
 }
+
+// Give up root privileges. Returns true if succeeded or no action was
+// taken.
+
+bool giveUpRootPrivileges()
+{
+    if (geteuid() != getuid()) { 
+#if defined(HAVE_SETREUID)
+        if (setreuid((uid_t)-1, getuid()) != 0)
+            return false;
+#elif defined(HAVE_SETEUID)
+        if (seteuid(getuid()) != 0)
+            return false;
+#elif defined(HAVE_SETUID)
+        if (setuid(getuid()) != 0)
+            return false;
+#else
+        return false;
+#endif
+    }
+
+    if (getegid() != getgid()) {
+#if defined(HAVE_SETREGID)
+        if (setregid((gid_t)-1, getgid()) != 0)
+            return false;
+#elif defined(HAVE_SETEGID)
+        if (setegid(getgid()) != 0)
+            return false;
+#elif defined(HAVE_SETGID)
+        if (setgid(getgid()) != 0)
+            return false;
+#else
+        return false;
+#endif
+    }
+
+    return true;
+}
diff -ruN cdrdao-1.1.9.org/dao/port.h cdrdao-1.1.9/dao/port.h
--- cdrdao-1.1.9.org/dao/port.h	2001-04-08 02:51:51.000000000 -0600
+++ cdrdao-1.1.9/dao/port.h	2005-05-17 13:41:18.129671004 -0600
@@ -29,5 +29,6 @@
 void blockSignal(int sig);
 void unblockSignal(int sig);
 int setRealTimeScheduling(int priority);
+bool giveUpRootPrivileges();
 
 #endif
diff -ruN cdrdao-1.1.9.org/dao/Settings.cc cdrdao-1.1.9/dao/Settings.cc
--- cdrdao-1.1.9.org/dao/Settings.cc	2004-06-05 13:40:52.000000000 -0600
+++ cdrdao-1.1.9/dao/Settings.cc	2005-05-17 13:42:37.425364454 -0600
@@ -55,6 +55,8 @@
 const char *SET_CDDB_TIMEOUT     = "cddb_timeout";
 const char *SET_CDDB_DB_DIR      = "cddb_directory";
 
+const char *SET_TMP_FILE_DIR = "tmp_file_dir";
+
 class SettingEntry {
 public:
   SettingEntry(const char *, int);
diff -ruN cdrdao-1.1.9.org/dao/Settings.h cdrdao-1.1.9/dao/Settings.h
--- cdrdao-1.1.9.org/dao/Settings.h	2004-06-05 13:40:52.000000000 -0600
+++ cdrdao-1.1.9/dao/Settings.h	2005-05-17 13:46:38.311905687 -0600
@@ -32,6 +32,7 @@
 extern const char *SET_CDDB_SERVER_LIST;
 extern const char *SET_CDDB_TIMEOUT;
 extern const char *SET_CDDB_DB_DIR;
+extern const char *SET_TMP_FILE_DIR;
 
 class Settings {
 public:
diff -ruN cdrdao-1.1.9.org/scsilib/librscg/scsi-remote.c cdrdao-1.1.9/scsilib/librscg/scsi-remote.c
--- cdrdao-1.1.9.org/scsilib/librscg/scsi-remote.c	2004-06-03 20:17:08.000000000 -0600
+++ cdrdao-1.1.9/scsilib/librscg/scsi-remote.c	2005-05-17 13:47:31.072387464 -0600
@@ -1,8 +1,8 @@
 #define	USE_REMOTE
-/* @(#)scsi-remote.c	1.15 04/01/15 Copyright 1990,2000-2003 J. Schilling */
+/* @(#)scsi-remote.c	1.16 04/08/24 Copyright 1990,2000-2003 J. Schilling */
 #ifndef lint
 static	char __sccsid[] =
-	"@(#)scsi-remote.c	1.15 04/01/15 Copyright 1990,2000-2003 J. Schilling";
+	"@(#)scsi-remote.c	1.16 04/08/24 Copyright 1990,2000-2003 J. Schilling";
 #endif
 /*
  *	Remote SCSI user level command transport routines
@@ -94,7 +94,7 @@
 /*extern	BOOL	debug;*/
 LOCAL	BOOL	debug = 1;
 
-LOCAL	char	_scg_trans_version[] = "remote-1.15";	/* The version for remote SCSI	*/
+LOCAL	char	_scg_trans_version[] = "remote-1.16";	/* The version for remote SCSI	*/
 LOCAL	char	_scg_auth_schily[]	= "schily";	/* The author for this module	*/
 
 LOCAL	int	scgo_rsend		__PR((SCSI *scgp));
@@ -1078,6 +1078,13 @@
 			_exit(EX_BAD);
 			/* NOTREACHED */
 		}
+		if (getuid() != geteuid() &&
+		    seteuid(pw->pw_uid) == -1) {
+			errmsg("seteuid(%lld) failed.\n",
+							(Llong)pw->pw_uid);
+			_exit(EX_BAD);
+			/* NOTREACHED */
+		}
 
 		/*
 		 * Fork again to completely detach from parent
diff -ruN cdrdao-1.1.9.org/trackdb/Makefile.am cdrdao-1.1.9/trackdb/Makefile.am
--- cdrdao-1.1.9.org/trackdb/Makefile.am	2004-05-10 14:14:50.000000000 -0600
+++ cdrdao-1.1.9/trackdb/Makefile.am	2005-05-17 14:08:18.362425987 -0600
@@ -1,6 +1,6 @@
 noinst_LIBRARIES = libtrackdb.a
 
-libtrackdb_a_SOURCES = Cddb.cc lec.cc Toc.cc TrackDataList.cc CdTextContainer.cc Msf.cc Track.cc util.cc CdTextItem.cc SubTrack.cc TrackData.cc Cddb.h CdTextContainer.h CdTextItem.h lec.h Msf.h Sample.h SubTrack.h Toc.h TrackData.h TrackDataList.h Track.h util.h CueParser.g TocParser.g
+libtrackdb_a_SOURCES = Cddb.cc lec.cc Toc.cc TrackDataList.cc CdTextContainer.cc Msf.cc Track.cc util.cc CdTextItem.cc SubTrack.cc TrackData.cc Cddb.h CdTextContainer.h CdTextItem.h lec.h Msf.h Sample.h SubTrack.h Toc.h TrackData.h TrackDataList.h Track.h util.h CueParser.g TocParser.g TempFileManager.cc TempFileManager.h
 
 PCCTS_GEN_FILES = TocParser.cpp TocParserGram.cpp TocLexerBase.cpp CueParser.cpp CueParserGram.cpp CueLexerBase.cpp CueLexerBase.h CueParserGram.h CueParserTokens.h TocLexerBase.h TocParserGram.h TocParserTokens.h
 
diff -ruN cdrdao-1.1.9.org/trackdb/Makefile.in cdrdao-1.1.9/trackdb/Makefile.in
--- cdrdao-1.1.9.org/trackdb/Makefile.in	2004-06-06 17:57:21.000000000 -0600
+++ cdrdao-1.1.9/trackdb/Makefile.in	2005-05-17 14:22:09.766481053 -0600
@@ -54,7 +54,8 @@
 am_libtrackdb_a_OBJECTS = Cddb.$(OBJEXT) lec.$(OBJEXT) Toc.$(OBJEXT) \
 	TrackDataList.$(OBJEXT) CdTextContainer.$(OBJEXT) \
 	Msf.$(OBJEXT) Track.$(OBJEXT) util.$(OBJEXT) \
-	CdTextItem.$(OBJEXT) SubTrack.$(OBJEXT) TrackData.$(OBJEXT)
+	CdTextItem.$(OBJEXT) SubTrack.$(OBJEXT) TrackData.$(OBJEXT) \
+	TempFileManager.$(OBJEXT)
 am__objects_1 = TocParser.$(OBJEXT) TocParserGram.$(OBJEXT) \
 	TocLexerBase.$(OBJEXT) CueParser.$(OBJEXT) \
 	CueParserGram.$(OBJEXT) CueLexerBase.$(OBJEXT)
@@ -212,7 +213,7 @@
 target_alias = @target_alias@
 thread_libs = @thread_libs@
 noinst_LIBRARIES = libtrackdb.a
-libtrackdb_a_SOURCES = Cddb.cc lec.cc Toc.cc TrackDataList.cc CdTextContainer.cc Msf.cc Track.cc util.cc CdTextItem.cc SubTrack.cc TrackData.cc Cddb.h CdTextContainer.h CdTextItem.h lec.h Msf.h Sample.h SubTrack.h Toc.h TrackData.h TrackDataList.h Track.h util.h CueParser.g TocParser.g
+libtrackdb_a_SOURCES = Cddb.cc lec.cc Toc.cc TrackDataList.cc CdTextContainer.cc Msf.cc Track.cc util.cc CdTextItem.cc SubTrack.cc TrackData.cc Cddb.h CdTextContainer.h CdTextItem.h lec.h Msf.h Sample.h SubTrack.h Toc.h TrackData.h TrackDataList.h Track.h util.h CueParser.g TocParser.g TempFileManager.cc TempFileManager.h
 PCCTS_GEN_FILES = TocParser.cpp TocParserGram.cpp TocLexerBase.cpp CueParser.cpp CueParserGram.cpp CueLexerBase.cpp CueLexerBase.h CueParserGram.h CueParserTokens.h TocLexerBase.h TocParserGram.h TocParserTokens.h
 nodist_libtrackdb_a_SOURCES = ${PCCTS_GEN_FILES} @pcctsinc@/AParser.cpp @pcctsinc@/DLexerBase.cpp @pcctsinc@/ATokenBuffer.cpp 
 INCLUDES = -I@pcctsinc@
diff -ruN cdrdao-1.1.9.org/trackdb/TempFileManager.cc cdrdao-1.1.9/trackdb/TempFileManager.cc
--- cdrdao-1.1.9.org/trackdb/TempFileManager.cc	1969-12-31 17:00:00.000000000 -0700
+++ cdrdao-1.1.9/trackdb/TempFileManager.cc	2005-05-17 13:59:56.773883057 -0600
@@ -0,0 +1,130 @@
+/*  cdrdao - write audio CD-Rs in disc-at-once mode
+ *
+ *  Copyright (C) 1998-2004  Denis Leroy <denis@poolshark.org>
+ *
+ *  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 2 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, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "TempFileManager.h"
+#include "util.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#define DEFAULT_TEMP_PATH "/tmp/"
+
+TempFileManager::TempFileManager()
+{
+  path_ = DEFAULT_TEMP_PATH;
+  keepTemps_ = false;
+  prefix_ = "cdrdao.";
+}
+
+TempFileManager::~TempFileManager()
+{
+    if (!keepTemps_) {
+        std::map<std::string, std::string>::const_iterator i = map_.begin();
+
+        for (;i != map_.end(); i++) {
+            std::string tmpFile = (*i).second;
+            message(3, "Removing temp file \"%s\"", tmpFile.c_str());
+            unlink(tmpFile.c_str());
+        }
+    }
+}
+
+bool TempFileManager::setTempDirectory(const char* path)
+{
+  struct stat st;
+
+  int ret = stat(path, &st);
+
+  if (ret != 0) {
+    message(-2, "Could not find temporary directory %s.",
+            path);
+    return false;
+  }
+
+  if (!S_ISDIR(st.st_mode) || !(st.st_mode & S_IWUSR)) {
+    message(-2, "No permission for temp directory %s.",
+            path);
+    return false;
+  }
+
+  path_ = path;
+
+  if (path[path_.size() - 1] != '/')
+    path_ += '/';
+
+  return true;
+}
+
+bool TempFileManager::getTempFile(std::string& tempname, const char* key,
+                                  const char* extension)
+{
+  if (!map_[key].empty()) {
+    tempname = map_[key];
+    return true;
+  }
+
+  const char* shortname = strrchr(key, '/');
+  if (shortname)
+    shortname++;
+  else
+    shortname = key;
+
+  std::string fname = path_;
+  fname += prefix_;
+  fname += shortname;
+
+  int id = 1;
+  int fd;
+  do {
+    char tmpbuf[12];
+    std::string uniqnm = fname;
+    sprintf(tmpbuf, ".%d", id);
+    uniqnm += tmpbuf;
+    if (extension) {
+      uniqnm += ".";
+      uniqnm += extension;
+    }
+    fd = open(uniqnm.c_str(), O_CREAT|O_EXCL,
+              S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+    if (fd > 0) {
+      fname = uniqnm;
+      break;
+    }
+    id++;
+
+    if (id > 100) {
+      message(-2, "Unable to create temp file in directory %s.",
+              path_.c_str());
+      tempname = "";
+      return false;
+    }
+  } while(1);
+
+  close(fd);
+  map_[key] = fname;
+  tempname = map_[key];
+
+  message(3, "Created temp file \"%s\" for file \"%s\"", fname.c_str(), key);
+    
+  return false;
+}
+
+TempFileManager tempFileManager;
diff -ruN cdrdao-1.1.9.org/trackdb/TempFileManager.h cdrdao-1.1.9/trackdb/TempFileManager.h
--- cdrdao-1.1.9.org/trackdb/TempFileManager.h	1969-12-31 17:00:00.000000000 -0700
+++ cdrdao-1.1.9/trackdb/TempFileManager.h	2005-05-17 13:59:56.773883057 -0600
@@ -0,0 +1,54 @@
+/*  cdrdao - write audio CD-Rs in disc-at-once mode
+ *
+ *  Copyright (C) 1998-2004  Denis Leroy <denis@poolshark.org>
+ *
+ *  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 2 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, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __TEMPFILEMANAGER_H__
+#define __TEMPFILEMANAGER_H__
+
+#include <string>
+#include <map>
+
+class TempFileManager {
+ public:
+    TempFileManager();
+
+    // The destructor will delete all temp files (unless keepTemps is
+    // set) that have not expired yet.
+    virtual ~TempFileManager();
+
+    bool setTempDirectory(const char* path);
+    void setKeepTemps(bool b) { keepTemps_ = b; }
+    void setPrefix(const char* prefix) { prefix_ = prefix; }
+
+    // Create a new temporary file, associated with given 'key'. The
+    // given name string is set to the temporaty file. Returns false
+    // is a new file was created, returns true if a temporary file
+    // already exists.
+    bool getTempFile(std::string& name, const char* key,
+                     const char* extension = NULL);
+
+ private:
+    std::string path_;
+    std::string prefix_;
+    std::map<std::string, std::string> map_;
+    bool keepTemps_;
+};
+
+extern TempFileManager tempFileManager;
+
+#endif