=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/mandoc/mandocdb.c,v retrieving revision 1.71 retrieving revision 1.72 diff -c -r1.71 -r1.72 *** src/usr.bin/mandoc/mandocdb.c 2014/01/22 20:58:35 1.71 --- src/usr.bin/mandoc/mandocdb.c 2014/03/18 16:56:06 1.72 *************** *** 1,4 **** ! /* $Id: mandocdb.c,v 1.71 2014/01/22 20:58:35 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze --- 1,4 ---- ! /* $Id: mandocdb.c,v 1.72 2014/03/18 16:56:06 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze *************** *** 16,21 **** --- 16,22 ---- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include + #include #include #include *************** *** 160,165 **** --- 161,167 ---- static int treescan(void); static size_t utf8(unsigned int, char [7]); + static char tempfilename[32]; static char *progname; static int nodb; /* no database changes */ static int quick; /* abort the parse early */ *************** *** 1866,1871 **** --- 1868,1875 ---- dbclose(int real) { size_t i; + int status; + pid_t child; if (nodb) return; *************** *** 1881,1890 **** if (real) return; ! if (-1 == rename(MANDOC_DB "~", MANDOC_DB)) { exitcode = (int)MANDOCLEVEL_SYSERR; ! say(MANDOC_DB, NULL); } } /* --- 1885,1944 ---- if (real) return; ! if ('\0' == *tempfilename) { ! if (-1 == rename(MANDOC_DB "~", MANDOC_DB)) { ! exitcode = (int)MANDOCLEVEL_SYSERR; ! say(MANDOC_DB, "%s", strerror(errno)); ! } ! return; ! } ! ! switch (child = fork()) { ! case (-1): exitcode = (int)MANDOCLEVEL_SYSERR; ! say("fork cmp", "%s", strerror(errno)); ! return; ! case (0): ! execlp("cmp", "cmp", "-s", ! tempfilename, MANDOC_DB, NULL); ! say("exec cmp", "%s", strerror(errno)); ! exit(0); ! default: ! break; } + if (-1 == waitpid(child, &status, 0)) { + exitcode = (int)MANDOCLEVEL_SYSERR; + say("wait cmp", "%s", strerror(errno)); + } else if (WIFSIGNALED(status)) { + exitcode = (int)MANDOCLEVEL_SYSERR; + say("cmp", "Died from a signal"); + } else if (WEXITSTATUS(status)) { + exitcode = (int)MANDOCLEVEL_SYSERR; + say(MANDOC_DB, + "Data changed, but cannot replace database"); + } + + *strrchr(tempfilename, '/') = '\0'; + switch (child = fork()) { + case (-1): + exitcode = (int)MANDOCLEVEL_SYSERR; + say("fork rm", "%s", strerror(errno)); + return; + case (0): + execlp("rm", "rm", "-rf", tempfilename, NULL); + say("exec rm", "%s", strerror(errno)); + exit((int)MANDOCLEVEL_SYSERR); + default: + break; + } + if (-1 == waitpid(child, &status, 0)) { + exitcode = (int)MANDOCLEVEL_SYSERR; + say("wait rm", "%s", strerror(errno)); + } else if (WIFSIGNALED(status) || WEXITSTATUS(status)) { + exitcode = (int)MANDOCLEVEL_SYSERR; + say(tempfilename, + "Cannot remove temporary directory"); + } } /* *************** *** 1898,1939 **** static int dbopen(int real) { ! const char *file, *sql; int rc, ofl; if (nodb) return(1); ofl = SQLITE_OPEN_READWRITE; ! if (0 == real) { ! file = MANDOC_DB "~"; ! if (-1 == remove(file) && ENOENT != errno) { exitcode = (int)MANDOCLEVEL_SYSERR; ! say(file, NULL); return(0); } ! ofl |= SQLITE_OPEN_EXCLUSIVE; ! } else ! file = MANDOC_DB; ! rc = sqlite3_open_v2(file, &db, ofl, NULL); if (SQLITE_OK == rc) ! goto prepare_statements; ! if (SQLITE_CANTOPEN != rc) { exitcode = (int)MANDOCLEVEL_SYSERR; ! say(file, NULL); return(0); } ! sqlite3_close(db); ! db = NULL; ! ! if (SQLITE_OK != (rc = sqlite3_open(file, &db))) { exitcode = (int)MANDOCLEVEL_SYSERR; ! say(file, NULL); return(0); } sql = "CREATE TABLE \"mpages\" (\n" " \"form\" INTEGER NOT NULL,\n" " \"id\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL\n" --- 1952,2013 ---- static int dbopen(int real) { ! const char *sql; int rc, ofl; if (nodb) return(1); + *tempfilename = '\0'; ofl = SQLITE_OPEN_READWRITE; ! ! if (real) { ! rc = sqlite3_open_v2(MANDOC_DB, &db, ofl, NULL); ! if (SQLITE_OK != rc) { exitcode = (int)MANDOCLEVEL_SYSERR; ! say(MANDOC_DB, "%s", sqlite3_errmsg(db)); return(0); } ! goto prepare_statements; ! } ! ofl |= SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE; ! ! remove(MANDOC_DB "~"); ! rc = sqlite3_open_v2(MANDOC_DB "~", &db, ofl, NULL); if (SQLITE_OK == rc) ! goto create_tables; ! if (quick) { exitcode = (int)MANDOCLEVEL_SYSERR; ! say(MANDOC_DB "~", "%s", sqlite3_errmsg(db)); return(0); } ! if (strlcpy(tempfilename, "/tmp/mandocdb.XXXXXX", ! sizeof(tempfilename)) >= sizeof(tempfilename)) { exitcode = (int)MANDOCLEVEL_SYSERR; ! say("/tmp/mandocdb.XXXXXX", "Filename too long"); return(0); } + if (NULL == mkdtemp(tempfilename)) { + exitcode = (int)MANDOCLEVEL_SYSERR; + say(tempfilename, "%s", strerror(errno)); + return(0); + } + if (strlcat(tempfilename, "/" MANDOC_DB, + sizeof(tempfilename)) >= sizeof(tempfilename)) { + exitcode = (int)MANDOCLEVEL_SYSERR; + say(tempfilename, "Filename too long"); + return(0); + } + rc = sqlite3_open_v2(tempfilename, &db, ofl, NULL); + if (SQLITE_OK != rc) { + exitcode = (int)MANDOCLEVEL_SYSERR; + say(tempfilename, "%s", sqlite3_errmsg(db)); + return(0); + } + create_tables: sql = "CREATE TABLE \"mpages\" (\n" " \"form\" INTEGER NOT NULL,\n" " \"id\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL\n" *************** *** 1956,1962 **** if (SQLITE_OK != sqlite3_exec(db, sql, NULL, NULL, NULL)) { exitcode = (int)MANDOCLEVEL_SYSERR; ! say(file, "%s", sqlite3_errmsg(db)); return(0); } --- 2030,2036 ---- if (SQLITE_OK != sqlite3_exec(db, sql, NULL, NULL, NULL)) { exitcode = (int)MANDOCLEVEL_SYSERR; ! say(MANDOC_DB, "%s", sqlite3_errmsg(db)); return(0); }