version 1.141, 2014/04/20 16:46:04 |
version 1.150, 2014/06/19 00:45:37 |
Line 433 main(int argc, char *argv[]) |
|
Line 433 main(int argc, char *argv[]) |
|
if (OP_UPDATE == op || OP_DELETE == op || OP_TEST == op) { |
if (OP_UPDATE == op || OP_DELETE == op || OP_TEST == op) { |
|
|
/* |
/* |
* All of these deal with a specific directory. |
* Most of these deal with a specific directory. |
* Jump into that directory first. |
* Jump into that directory first. |
*/ |
*/ |
if (0 == set_basedir(path_arg)) |
if (OP_TEST != op && 0 == set_basedir(path_arg)) |
goto out; |
goto out; |
|
|
if (dbopen(1)) { |
if (dbopen(1)) { |
Line 471 main(int argc, char *argv[]) |
|
Line 471 main(int argc, char *argv[]) |
|
* manpath_parse() wants to do it. |
* manpath_parse() wants to do it. |
*/ |
*/ |
if (argc > 0) { |
if (argc > 0) { |
dirs.paths = mandoc_calloc(argc, |
dirs.paths = mandoc_reallocarray(NULL, |
sizeof(char *)); |
argc, sizeof(char *)); |
dirs.sz = (size_t)argc; |
dirs.sz = (size_t)argc; |
for (i = 0; i < argc; i++) |
for (i = 0; i < argc; i++) |
dirs.paths[i] = mandoc_strdup(argv[i]); |
dirs.paths[i] = mandoc_strdup(argv[i]); |
Line 512 main(int argc, char *argv[]) |
|
Line 512 main(int argc, char *argv[]) |
|
goto out; |
goto out; |
|
|
mpages_merge(mc, mp); |
mpages_merge(mc, mp); |
if (warnings && |
if (warnings && !nodb && |
! (MPARSE_QUICK & mparse_options)) |
! (MPARSE_QUICK & mparse_options)) |
names_check(); |
names_check(); |
dbclose(0); |
dbclose(0); |
Line 525 main(int argc, char *argv[]) |
|
Line 525 main(int argc, char *argv[]) |
|
} |
} |
} |
} |
out: |
out: |
set_basedir(NULL); |
|
manpath_free(&dirs); |
manpath_free(&dirs); |
mchars_free(mc); |
mchars_free(mc); |
mparse_free(mp); |
mparse_free(mp); |
|
|
fsec[-1] = '\0'; |
fsec[-1] = '\0'; |
|
|
mlink = mandoc_calloc(1, sizeof(struct mlink)); |
mlink = mandoc_calloc(1, sizeof(struct mlink)); |
strlcpy(mlink->file, path, sizeof(mlink->file)); |
if (strlcpy(mlink->file, path, |
|
sizeof(mlink->file)) >= |
|
sizeof(mlink->file)) { |
|
say(path, "Filename too long"); |
|
free(mlink); |
|
continue; |
|
} |
mlink->dform = dform; |
mlink->dform = dform; |
mlink->dsec = dsec; |
mlink->dsec = dsec; |
mlink->arch = arch; |
mlink->arch = arch; |
Line 794 filescan(const char *file) |
|
Line 799 filescan(const char *file) |
|
return; |
return; |
} |
} |
|
|
if (strstr(buf, basedir) == buf) |
if (OP_TEST == op) |
start = buf + strlen(basedir) + 1; |
|
else if (OP_TEST == op) |
|
start = buf; |
start = buf; |
|
else if (strstr(buf, basedir) == buf) |
|
start = buf + strlen(basedir); |
else { |
else { |
exitcode = (int)MANDOCLEVEL_BADARG; |
exitcode = (int)MANDOCLEVEL_BADARG; |
say("", "%s: outside base directory", buf); |
say("", "%s: outside base directory", buf); |
Line 819 filescan(const char *file) |
|
Line 824 filescan(const char *file) |
|
say(file, "&stat"); |
say(file, "&stat"); |
return; |
return; |
} |
} |
strlcpy(buf, file, sizeof(buf)); |
if (strlcpy(buf, file, sizeof(buf)) >= sizeof(buf)) { |
start = strstr(buf, basedir) == buf ? |
say(file, "Filename too long"); |
buf + strlen(basedir) + 1 : buf; |
return; |
|
} |
|
start = buf; |
|
if (OP_TEST != op && strstr(buf, basedir) == buf) |
|
start += strlen(basedir); |
} |
} |
|
|
mlink = mandoc_calloc(1, sizeof(struct mlink)); |
mlink = mandoc_calloc(1, sizeof(struct mlink)); |
strlcpy(mlink->file, start, sizeof(mlink->file)); |
if (strlcpy(mlink->file, start, sizeof(mlink->file)) >= |
|
sizeof(mlink->file)) { |
|
say(start, "Filename too long"); |
|
return; |
|
} |
|
|
/* |
/* |
* First try to guess our directory structure. |
* First try to guess our directory structure. |
Line 973 mlinks_undupe(struct mpage *mpage) |
|
Line 986 mlinks_undupe(struct mpage *mpage) |
|
mpage->form = FORM_NONE; |
mpage->form = FORM_NONE; |
goto nextlink; |
goto nextlink; |
} |
} |
if (strlcpy(buf, mlink->file, PATH_MAX) >= PATH_MAX) { |
(void)strlcpy(buf, mlink->file, sizeof(buf)); |
if (warnings) |
|
say(mlink->file, "Filename too long"); |
|
goto nextlink; |
|
} |
|
bufp = strstr(buf, "cat"); |
bufp = strstr(buf, "cat"); |
assert(NULL != bufp); |
assert(NULL != bufp); |
memcpy(bufp, "man", 3); |
memcpy(bufp, "man", 3); |
if (NULL != (bufp = strrchr(buf, '.'))) |
if (NULL != (bufp = strrchr(buf, '.'))) |
*++bufp = '\0'; |
*++bufp = '\0'; |
strlcat(buf, mlink->dsec, PATH_MAX); |
(void)strlcat(buf, mlink->dsec, sizeof(buf)); |
if (NULL == ohash_find(&mlinks, |
if (NULL == ohash_find(&mlinks, |
ohash_qlookup(&mlinks, buf))) |
ohash_qlookup(&mlinks, buf))) |
goto nextlink; |
goto nextlink; |
Line 1287 names_check(void) |
|
Line 1296 names_check(void) |
|
"AND mlinks.name == names.name" |
"AND mlinks.name == names.name" |
")" |
")" |
") JOIN (" |
") JOIN (" |
"SELECT * FROM mlinks GROUP BY pageid" |
"SELECT sec, arch, name, pageid FROM mlinks " |
|
"GROUP BY pageid" |
") USING (pageid);", |
") USING (pageid);", |
-1, &stmt, NULL); |
-1, &stmt, NULL); |
|
|
Line 1774 putkeys(const struct mpage *mpage, |
|
Line 1784 putkeys(const struct mpage *mpage, |
|
s->mask |= v; |
s->mask |= v; |
return; |
return; |
} else if (NULL == s) { |
} else if (NULL == s) { |
s = mandoc_calloc(sizeof(struct str) + sz + 1, 1); |
s = mandoc_calloc(1, sizeof(struct str) + sz + 1); |
memcpy(s->key, cp, sz); |
memcpy(s->key, cp, sz); |
ohash_insert(htab, slot, s); |
ohash_insert(htab, slot, s); |
} |
} |
Line 1986 dbadd(struct mpage *mpage, struct mchars *mc) |
|
Line 1996 dbadd(struct mpage *mpage, struct mchars *mc) |
|
mlink = mpage->mlinks; |
mlink = mpage->mlinks; |
|
|
if (nodb) { |
if (nodb) { |
|
for (key = ohash_first(&names, &slot); NULL != key; |
|
key = ohash_next(&names, &slot)) { |
|
if (key->rendered != key->key) |
|
free(key->rendered); |
|
free(key); |
|
} |
|
for (key = ohash_first(&strings, &slot); NULL != key; |
|
key = ohash_next(&strings, &slot)) { |
|
if (key->rendered != key->key) |
|
free(key->rendered); |
|
free(key); |
|
} |
|
if (0 == debug) |
|
return; |
while (NULL != mlink) { |
while (NULL != mlink) { |
fputs(mlink->name, stdout); |
fputs(mlink->name, stdout); |
if (NULL == mlink->next || |
if (NULL == mlink->next || |
Line 2012 dbadd(struct mpage *mpage, struct mchars *mc) |
|
Line 2036 dbadd(struct mpage *mpage, struct mchars *mc) |
|
if (debug) |
if (debug) |
say(mlink->file, "Adding to database"); |
say(mlink->file, "Adding to database"); |
|
|
|
i = strlen(mpage->desc) + 1; |
|
key = mandoc_calloc(1, sizeof(struct str) + i); |
|
memcpy(key->key, mpage->desc, i); |
|
render_key(mc, key); |
|
|
i = 1; |
i = 1; |
SQL_BIND_TEXT(stmts[STMT_INSERT_PAGE], i, mpage->desc); |
SQL_BIND_TEXT(stmts[STMT_INSERT_PAGE], i, key->rendered); |
SQL_BIND_INT(stmts[STMT_INSERT_PAGE], i, FORM_SRC == mpage->form); |
SQL_BIND_INT(stmts[STMT_INSERT_PAGE], i, FORM_SRC == mpage->form); |
SQL_STEP(stmts[STMT_INSERT_PAGE]); |
SQL_STEP(stmts[STMT_INSERT_PAGE]); |
mpage->pageid = sqlite3_last_insert_rowid(db); |
mpage->pageid = sqlite3_last_insert_rowid(db); |
sqlite3_reset(stmts[STMT_INSERT_PAGE]); |
sqlite3_reset(stmts[STMT_INSERT_PAGE]); |
|
|
|
if (key->rendered != key->key) |
|
free(key->rendered); |
|
free(key); |
|
|
while (NULL != mlink) { |
while (NULL != mlink) { |
dbadd_mlink(mlink); |
dbadd_mlink(mlink); |
mlink = mlink->next; |
mlink = mlink->next; |
Line 2197 dbopen(int real) |
|
Line 2230 dbopen(int real) |
|
rc = sqlite3_open_v2(MANDOC_DB, &db, ofl, NULL); |
rc = sqlite3_open_v2(MANDOC_DB, &db, ofl, NULL); |
if (SQLITE_OK != rc) { |
if (SQLITE_OK != rc) { |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say(MANDOC_DB, "%s", sqlite3_errmsg(db)); |
if (SQLITE_CANTOPEN != rc) |
|
say(MANDOC_DB, "%s", sqlite3_errstr(rc)); |
return(0); |
return(0); |
} |
} |
goto prepare_statements; |
goto prepare_statements; |
Line 2211 dbopen(int real) |
|
Line 2245 dbopen(int real) |
|
goto create_tables; |
goto create_tables; |
if (MPARSE_QUICK & mparse_options) { |
if (MPARSE_QUICK & mparse_options) { |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say(MANDOC_DB "~", "%s", sqlite3_errmsg(db)); |
say(MANDOC_DB "~", "%s", sqlite3_errstr(rc)); |
return(0); |
return(0); |
} |
} |
|
|
if (strlcpy(tempfilename, "/tmp/mandocdb.XXXXXX", |
(void)strlcpy(tempfilename, "/tmp/mandocdb.XXXXXX", |
sizeof(tempfilename)) >= sizeof(tempfilename)) { |
sizeof(tempfilename)); |
exitcode = (int)MANDOCLEVEL_SYSERR; |
|
say("", "/tmp/mandocdb.XXXXXX: Filename too long"); |
|
return(0); |
|
} |
|
if (NULL == mkdtemp(tempfilename)) { |
if (NULL == mkdtemp(tempfilename)) { |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say("", "&%s", tempfilename); |
say("", "&%s", tempfilename); |
return(0); |
return(0); |
} |
} |
if (strlcat(tempfilename, "/" MANDOC_DB, |
(void)strlcat(tempfilename, "/" MANDOC_DB, |
sizeof(tempfilename)) >= sizeof(tempfilename)) { |
sizeof(tempfilename)); |
exitcode = (int)MANDOCLEVEL_SYSERR; |
|
say("", "%s/" MANDOC_DB ": Filename too long", |
|
tempfilename); |
|
return(0); |
|
} |
|
rc = sqlite3_open_v2(tempfilename, &db, ofl, NULL); |
rc = sqlite3_open_v2(tempfilename, &db, ofl, NULL); |
if (SQLITE_OK != rc) { |
if (SQLITE_OK != rc) { |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say("", "%s: %s", tempfilename, sqlite3_errmsg(db)); |
say("", "%s: %s", tempfilename, sqlite3_errstr(rc)); |
return(0); |
return(0); |
} |
} |
|
|
|
|
if (SQLITE_OK != sqlite3_exec(db, sql, NULL, NULL, NULL)) { |
if (SQLITE_OK != sqlite3_exec(db, sql, NULL, NULL, NULL)) { |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say(MANDOC_DB, "%s", sqlite3_errmsg(db)); |
say(MANDOC_DB, "%s", sqlite3_errmsg(db)); |
|
sqlite3_close(db); |
return(0); |
return(0); |
} |
} |
|
|
prepare_statements: |
prepare_statements: |
SQL_EXEC("PRAGMA foreign_keys = ON"); |
if (SQLITE_OK != sqlite3_exec(db, |
|
"PRAGMA foreign_keys = ON", NULL, NULL, NULL)) { |
|
exitcode = (int)MANDOCLEVEL_SYSERR; |
|
say(MANDOC_DB, "PRAGMA foreign_keys: %s", |
|
sqlite3_errmsg(db)); |
|
sqlite3_close(db); |
|
return(0); |
|
} |
|
|
sql = "DELETE FROM mpages WHERE pageid IN " |
sql = "DELETE FROM mpages WHERE pageid IN " |
"(SELECT pageid FROM mlinks WHERE " |
"(SELECT pageid FROM mlinks WHERE " |
"sec=? AND arch=? AND name=?)"; |
"sec=? AND arch=? AND name=?)"; |
Line 2302 prepare_statements: |
|
Line 2336 prepare_statements: |
|
* synchronous mode for much better performance. |
* synchronous mode for much better performance. |
*/ |
*/ |
|
|
if (real) |
if (real && SQLITE_OK != sqlite3_exec(db, |
SQL_EXEC("PRAGMA synchronous = OFF"); |
"PRAGMA synchronous = OFF", NULL, NULL, NULL)) { |
|
exitcode = (int)MANDOCLEVEL_SYSERR; |
|
say(MANDOC_DB, "PRAGMA synchronous: %s", |
|
sqlite3_errmsg(db)); |
|
sqlite3_close(db); |
|
return(0); |
|
} |
#endif |
#endif |
|
|
return(1); |
return(1); |
|
|
hash_halloc(size_t sz, void *arg) |
hash_halloc(size_t sz, void *arg) |
{ |
{ |
|
|
return(mandoc_calloc(sz, 1)); |
return(mandoc_calloc(1, sz)); |
} |
} |
|
|
static void * |
static void * |
Line 2335 set_basedir(const char *targetdir) |
|
Line 2375 set_basedir(const char *targetdir) |
|
{ |
{ |
static char startdir[PATH_MAX]; |
static char startdir[PATH_MAX]; |
static int fd; |
static int fd; |
|
char *cp; |
|
|
/* |
/* |
* Remember where we started by keeping a fd open to the origin |
* Remember where we started by keeping a fd open to the origin |
Line 2345 set_basedir(const char *targetdir) |
|
Line 2386 set_basedir(const char *targetdir) |
|
if ('\0' == *startdir) { |
if ('\0' == *startdir) { |
if (NULL == getcwd(startdir, PATH_MAX)) { |
if (NULL == getcwd(startdir, PATH_MAX)) { |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
if (NULL != targetdir) |
say("", "&getcwd"); |
say("", "&getcwd"); |
|
return(0); |
return(0); |
} |
} |
if (-1 == (fd = open(startdir, O_RDONLY, 0))) { |
if (-1 == (fd = open(startdir, O_RDONLY, 0))) { |
Line 2354 set_basedir(const char *targetdir) |
|
Line 2394 set_basedir(const char *targetdir) |
|
say("", "&open %s", startdir); |
say("", "&open %s", startdir); |
return(0); |
return(0); |
} |
} |
if (NULL == targetdir) |
|
targetdir = startdir; |
|
} else { |
} else { |
if (-1 == fd) |
if (-1 == fd) |
return(0); |
return(0); |
Line 2366 set_basedir(const char *targetdir) |
|
Line 2404 set_basedir(const char *targetdir) |
|
say("", "&chdir %s", startdir); |
say("", "&chdir %s", startdir); |
return(0); |
return(0); |
} |
} |
if (NULL == targetdir) { |
|
close(fd); |
|
return(1); |
|
} |
|
} |
} |
if (NULL == realpath(targetdir, basedir)) { |
if (NULL == realpath(targetdir, basedir)) { |
basedir[0] = '\0'; |
basedir[0] = '\0'; |
Line 2380 set_basedir(const char *targetdir) |
|
Line 2414 set_basedir(const char *targetdir) |
|
exitcode = (int)MANDOCLEVEL_BADARG; |
exitcode = (int)MANDOCLEVEL_BADARG; |
say("", "&chdir"); |
say("", "&chdir"); |
return(0); |
return(0); |
|
} |
|
cp = strchr(basedir, '\0'); |
|
if ('/' != cp[-1]) { |
|
if (cp - basedir >= PATH_MAX - 1) { |
|
exitcode = (int)MANDOCLEVEL_SYSERR; |
|
say("", "Filename too long"); |
|
return(0); |
|
} |
|
*cp++ = '/'; |
|
*cp = '\0'; |
} |
} |
return(1); |
return(1); |
} |
} |