summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwtc%google.com <devnull@localhost>2012-12-07 01:59:38 +0000
committerwtc%google.com <devnull@localhost>2012-12-07 01:59:38 +0000
commit4cef7c531c4098642e8211b8a2be2cd25ae5e037 (patch)
tree3ceabb218562bcd36384fd461dabcdf48d768a75
parent6044db0799bfb61e51f6543a7adc6d5c469b6b61 (diff)
downloadnss-hg-4cef7c531c4098642e8211b8a2be2cd25ae5e037.tar.gz
Bug 578561: Remove the old sdb_getTempDir() code because it always fails
with current versions of SQLite. Reimplement sdb_getTempDir() to replicate how SQLite determines its temp directory. r=rrelyea.
-rw-r--r--security/nss/lib/softoken/sdb.c155
1 files changed, 60 insertions, 95 deletions
diff --git a/security/nss/lib/softoken/sdb.c b/security/nss/lib/softoken/sdb.c
index c6ff11037..8ab757c45 100644
--- a/security/nss/lib/softoken/sdb.c
+++ b/security/nss/lib/softoken/sdb.c
@@ -30,8 +30,11 @@
#include "prenv.h"
#include "prsystem.h" /* for PR_GetDirectorySeparator() */
#include "sys/stat.h"
-#if defined (_WIN32)
+#if defined(_WIN32)
#include <io.h>
+#include <windows.h>
+#elif defined(XP_UNIX)
+#include <unistd.h>
#endif
#ifdef SQLITE_UNSAFE_THREADS
@@ -187,106 +190,68 @@ sdb_done(int err, int *count)
}
/*
- *
- * strdup limited to 'n' bytes. (Note: len of file is assumed to be >= len)
- *
- * We don't have a PORT_ version of this function,
- * I suspect it's only normally available in glib,
+ * find out where sqlite stores the temp tables. We do this by replicating
+ * the logic from sqlite.
*/
+#if defined(_WIN32)
static char *
-sdb_strndup(const char *file, int len)
+sdb_getTempDir(void)
{
- char *result = PORT_Alloc(len+1);
-
- if (result == NULL) {
- return result;
- }
-
- PORT_Memcpy(result, file, len);
- result[len] = 0;
- return result;
-}
-
-/*
- * call back from sqlite3_exec("Pragma database_list"). Looks for the
- * temp directory, then return the file the temp directory is stored
- * at. */
-static int
-sdb_getTempDirCallback(void *arg, int columnCount, char **cval, char **cname)
-{
- int i;
- int found = 0;
- char *file = NULL;
- char *end, *dir;
- char dirsep;
-
- /* we've already found the temp directory, don't look at any more records*/
- if (*(char **)arg) {
- return SQLITE_OK;
- }
-
- /* look at the columns to see if this record is the temp database,
- * and does it say where it is stored */
- for (i=0; i < columnCount; i++) {
- if (PORT_Strcmp(cname[i],"name") == 0) {
- if (PORT_Strcmp(cval[i], "temp") == 0) {
- found++;
- continue;
- }
- }
- if (PORT_Strcmp(cname[i],"file") == 0) {
- if (cval[i] && (*cval[i] != 0)) {
- file = cval[i];
- }
- }
- }
-
- /* if we couldn't find it, ask for the next record */
- if (!found || !file) {
- return SQLITE_OK;
- }
-
- /* drop of the database file name and just return the directory */
- dirsep = PR_GetDirectorySeparator();
- end = PORT_Strrchr(file, dirsep);
- if (!end) {
- return SQLITE_OK;
- }
- dir = sdb_strndup(file, end-file);
-
- *(char **)arg = dir;
- return SQLITE_OK;
+ /* sqlite uses sqlite3_temp_directory if it is not NULL. We don't have
+ * access to sqlite3_temp_directory because it is not exported from
+ * sqlite3.dll. Assume sqlite3_win32_set_directory isn't called and
+ * sqlite3_temp_directory is NULL.
+ */
+ char path[MAX_PATH];
+ DWORD rv;
+ size_t len;
+
+ rv = GetTempPathA(MAX_PATH, path);
+ if (rv > MAX_PATH || rv == 0)
+ return NULL;
+ len = strlen(path);
+ if (len == 0)
+ return NULL;
+ /* The returned string ends with a backslash, for example, "C:\TEMP\". */
+ if (path[len - 1] == '\\')
+ path[len - 1] = '\0';
+ return PORT_Strdup(path);
}
-
-/*
- * find out where sqlite stores the temp tables. We do this by creating
- * a temp table, then looking for the database name that sqlite3 creates.
- */
+#elif defined(XP_UNIX)
static char *
-sdb_getTempDir(sqlite3 *sqlDB)
+sdb_getTempDir(void)
{
- char *tempDir = NULL;
- int sqlerr;
-
- /* create a temporary table */
- sqlerr = sqlite3_exec(sqlDB, "CREATE TEMPORARY TABLE myTemp (id)",
- NULL, 0, NULL);
- if (sqlerr != SQLITE_OK) {
- return NULL;
- }
- /* look for through the database list for the temp directory */
- sqlerr = sqlite3_exec(sqlDB, "PRAGMA database_list",
- sdb_getTempDirCallback, &tempDir, NULL);
-
- /* drop the temp table we created */
- sqlite3_exec(sqlDB, "DROP TABLE myTemp", NULL, 0, NULL);
-
- if (sqlerr != SQLITE_OK) {
- return NULL;
- }
- return tempDir;
+ const char *azDirs[] = {
+ NULL,
+ NULL,
+ "/var/tmp",
+ "/usr/tmp",
+ "/tmp",
+ NULL /* List terminator */
+ };
+ unsigned int i;
+ struct stat buf;
+ const char *zDir = NULL;
+
+ azDirs[0] = sqlite3_temp_directory;
+ azDirs[1] = getenv("TMPDIR");
+
+ for (i = 0; i < PR_ARRAY_SIZE(azDirs); i++) {
+ zDir = azDirs[i];
+ if (zDir == NULL) continue;
+ if (stat(zDir, &buf)) continue;
+ if (!S_ISDIR(buf.st_mode)) continue;
+ if (access(zDir, 07)) continue;
+ break;
+ }
+
+ if (zDir == NULL)
+ return NULL;
+ return PORT_Strdup(zDir);
}
-
+#else
+#error "sdb_getTempDir not implemented"
+#endif
/*
* Map SQL_LITE errors to PKCS #11 errors as best we can.
@@ -1827,7 +1792,7 @@ sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate,
* is to check for the existance of a local file compared to the same
* check in the temp directory. If the temp directory is faster, cache
* the database there. */
- tempDir = sdb_getTempDir(sqlDB);
+ tempDir = sdb_getTempDir();
if (tempDir) {
tempOps = sdb_measureAccess(tempDir);
PORT_Free(tempDir);