version 1.33, 2011/12/28 01:17:01 |
version 1.34, 2012/01/05 22:48:52 |
|
|
#include <assert.h> |
#include <assert.h> |
#include <ctype.h> |
#include <ctype.h> |
#include <dirent.h> |
#include <dirent.h> |
|
#include <errno.h> |
#include <fcntl.h> |
#include <fcntl.h> |
#include <getopt.h> |
#include <getopt.h> |
#include <stdio.h> |
#include <stdio.h> |
|
|
buf.cp = mandoc_malloc(buf.size); |
buf.cp = mandoc_malloc(buf.size); |
dbuf.cp = mandoc_malloc(dbuf.size); |
dbuf.cp = mandoc_malloc(dbuf.size); |
|
|
flags = O_CREAT | O_RDWR; |
|
if (OP_DEFAULT == op || OP_CONFFILE == op) |
|
flags |= O_TRUNC; |
|
|
|
if (OP_TEST == op) { |
if (OP_TEST == op) { |
ofile_argbuild(argc, argv, &of); |
ofile_argbuild(argc, argv, &of); |
if (NULL == of) |
if (NULL == of) |
|
|
exit((int)MANDOCLEVEL_BADARG); |
exit((int)MANDOCLEVEL_BADARG); |
} |
} |
|
|
|
flags = O_CREAT | O_RDWR; |
mdb.db = dbopen(mdb.dbn, flags, 0644, DB_BTREE, &info); |
mdb.db = dbopen(mdb.dbn, flags, 0644, DB_BTREE, &info); |
mdb.idx = dbopen(mdb.idxn, flags, 0644, DB_RECNO, NULL); |
mdb.idx = dbopen(mdb.idxn, flags, 0644, DB_RECNO, NULL); |
|
|
|
|
manpath_parse(&dirs, dir, NULL, NULL); |
manpath_parse(&dirs, dir, NULL, NULL); |
|
|
for (i = 0; i < dirs.sz; i++) { |
for (i = 0; i < dirs.sz; i++) { |
mdb.idxn[0] = mdb.dbn[0] = '\0'; |
|
|
|
strlcat(mdb.dbn, dirs.paths[i], MAXPATHLEN); |
/* |
strlcat(mdb.dbn, "/", MAXPATHLEN); |
* Go to the root of the respective manual tree. |
sz1 = strlcat(mdb.dbn, MANDOC_DB, MAXPATHLEN); |
* This must work or no manuals may be found: |
|
* They are indexed relative to the root. |
|
*/ |
|
|
strlcat(mdb.idxn, dirs.paths[i], MAXPATHLEN); |
if (-1 == chdir(dirs.paths[i])) { |
strlcat(mdb.idxn, "/", MAXPATHLEN); |
perror(dirs.paths[i]); |
sz2 = strlcat(mdb.idxn, MANDOC_IDX, MAXPATHLEN); |
exit((int)MANDOCLEVEL_SYSERR); |
|
|
if (sz1 >= MAXPATHLEN || sz2 >= MAXPATHLEN) { |
|
fprintf(stderr, "%s: path too long\n", |
|
dirs.paths[i]); |
|
exit((int)MANDOCLEVEL_BADARG); |
|
} |
} |
|
|
if (mdb.db) |
/* Create a new database in two temporary files. */ |
(*mdb.db->close)(mdb.db); |
|
if (mdb.idx) |
|
(*mdb.idx->close)(mdb.idx); |
|
|
|
mdb.db = dbopen(mdb.dbn, flags, 0644, DB_BTREE, &info); |
flags = O_CREAT | O_EXCL | O_RDWR; |
mdb.idx = dbopen(mdb.idxn, flags, 0644, DB_RECNO, NULL); |
while (NULL == mdb.db) { |
|
strlcpy(mdb.dbn, MANDOC_DB, MAXPATHLEN); |
if (NULL == mdb.db) { |
strlcat(mdb.dbn, ".XXXXXXXXXX", MAXPATHLEN); |
perror(mdb.dbn); |
if (NULL == mktemp(mdb.dbn)) { |
exit((int)MANDOCLEVEL_SYSERR); |
perror(mdb.dbn); |
} else if (NULL == mdb.idx) { |
exit((int)MANDOCLEVEL_SYSERR); |
perror(mdb.idxn); |
} |
exit((int)MANDOCLEVEL_SYSERR); |
mdb.db = dbopen(mdb.dbn, flags, 0644, |
|
DB_BTREE, &info); |
|
if (NULL == mdb.db && EEXIST != errno) { |
|
perror(mdb.dbn); |
|
exit((int)MANDOCLEVEL_SYSERR); |
|
} |
} |
} |
|
while (NULL == mdb.idx) { |
|
strlcpy(mdb.idxn, MANDOC_IDX, MAXPATHLEN); |
|
strlcat(mdb.idxn, ".XXXXXXXXXX", MAXPATHLEN); |
|
if (NULL == mktemp(mdb.idxn)) { |
|
perror(mdb.idxn); |
|
unlink(mdb.dbn); |
|
exit((int)MANDOCLEVEL_SYSERR); |
|
} |
|
mdb.idx = dbopen(mdb.idxn, flags, 0644, |
|
DB_RECNO, NULL); |
|
if (NULL == mdb.idx && EEXIST != errno) { |
|
perror(mdb.idxn); |
|
unlink(mdb.dbn); |
|
exit((int)MANDOCLEVEL_SYSERR); |
|
} |
|
} |
|
|
ofile_free(of); |
/* |
of = NULL; |
* Search for manuals and fill the new database. |
|
*/ |
|
|
if (-1 == chdir(dirs.paths[i])) { |
ofile_dirbuild(".", "", "", 0, &of); |
perror(dirs.paths[i]); |
|
exit((int)MANDOCLEVEL_SYSERR); |
if (NULL != of) { |
|
index_merge(of, mp, &dbuf, &buf, hash, |
|
&mdb, &recs); |
|
ofile_free(of); |
|
of = NULL; |
} |
} |
|
|
ofile_dirbuild(".", "", "", 0, &of); |
(*mdb.db->close)(mdb.db); |
if (NULL == of) |
(*mdb.idx->close)(mdb.idx); |
continue; |
mdb.db = NULL; |
|
mdb.idx = NULL; |
|
|
/* |
/* |
* Go to the root of the respective manual tree. |
* Replace the old database with the new one. |
* This must work or no manuals may be found (they're |
* This is not perfectly atomic, |
* indexed relative to the root). |
* but i cannot think of a better way. |
*/ |
*/ |
|
|
if (-1 == chdir(dirs.paths[i])) { |
if (-1 == rename(mdb.dbn, MANDOC_DB)) { |
perror(dirs.paths[i]); |
perror(MANDOC_DB); |
|
unlink(mdb.dbn); |
|
unlink(mdb.idxn); |
exit((int)MANDOCLEVEL_SYSERR); |
exit((int)MANDOCLEVEL_SYSERR); |
} |
} |
|
if (-1 == rename(mdb.idxn, MANDOC_IDX)) { |
index_merge(of, mp, &dbuf, &buf, hash, &mdb, &recs); |
perror(MANDOC_IDX); |
|
unlink(MANDOC_DB); |
|
unlink(MANDOC_IDX); |
|
unlink(mdb.idxn); |
|
exit((int)MANDOCLEVEL_SYSERR); |
|
} |
} |
} |
|
|
out: |
out: |
|
|
} |
} |
if (ch < 0) { |
if (ch < 0) { |
perror("hash"); |
perror("hash"); |
|
unlink(mdb->dbn); |
|
unlink(mdb->idxn); |
exit((int)MANDOCLEVEL_SYSERR); |
exit((int)MANDOCLEVEL_SYSERR); |
} |
} |
|
|