[BACK]Return to mandocdb.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Diff for /mandoc/mandocdb.c between version 1.136 and 1.140

version 1.136, 2014/04/16 18:59:43 version 1.140, 2014/04/19 02:56:54
Line 100  struct inodev {
Line 100  struct inodev {
   
 struct  mpage {  struct  mpage {
         struct inodev    inodev;  /* used for hashing routine */          struct inodev    inodev;  /* used for hashing routine */
         int64_t          recno;   /* id in mpages SQL table */          int64_t          pageid;  /* pageid in mpages SQL table */
         enum form        form;    /* format from file content */          enum form        form;    /* format from file content */
         char            *sec;     /* section from file content */          char            *sec;     /* section from file content */
         char            *arch;    /* architecture from file content */          char            *arch;    /* architecture from file content */
Line 430  main(int argc, char *argv[])
Line 430  main(int argc, char *argv[])
         ohash_init(&mlinks, 6, &mlinks_info);          ohash_init(&mlinks, 6, &mlinks_info);
   
         if (OP_UPDATE == op || OP_DELETE == op || OP_TEST == op) {          if (OP_UPDATE == op || OP_DELETE == op || OP_TEST == op) {
                 /*  
                  * Force processing all files.  
                  */  
                 use_all = 1;  
   
                 /*                  /*
                  * All of these deal with a specific directory.                   * All of these deal with a specific directory.
                  * Jump into that directory then collect files specified                   * Jump into that directory first.
                  * on the command-line.  
                  */                   */
                 if (0 == set_basedir(path_arg))                  if (0 == set_basedir(path_arg))
                         goto out;                          goto out;
                 for (i = 0; i < argc; i++)  
                         filescan(argv[i]);                  if (dbopen(1)) {
                 if (0 == dbopen(1))                          /*
                         goto out;                           * The existing database is usable.  Process
                 if (OP_TEST != op)                           * all files specified on the command-line.
                         dbprune();                           */
                           use_all = 1;
                           for (i = 0; i < argc; i++)
                                   filescan(argv[i]);
                           if (OP_TEST != op)
                                   dbprune();
                   } else {
                           /*
                            * Database missing or corrupt.
                            * Recreate from scratch.
                            */
                           exitcode = (int)MANDOCLEVEL_OK;
                           op = OP_DEFAULT;
                           if (0 == treescan())
                                   goto out;
                           if (0 == dbopen(0))
                                   goto out;
                   }
                 if (OP_DELETE != op)                  if (OP_DELETE != op)
                         mpages_merge(mc, mp);                          mpages_merge(mc, mp);
                 dbclose(1);                  dbclose(OP_DEFAULT == op ? 0 : 1);
         } else {          } else {
                 /*                  /*
                  * If we have arguments, use them as our manpaths.                   * If we have arguments, use them as our manpaths.
Line 549  usage:
Line 561  usage:
 static int  static int
 treescan(void)  treescan(void)
 {  {
           char             buf[PATH_MAX];
         FTS             *f;          FTS             *f;
         FTSENT          *ff;          FTSENT          *ff;
         struct mlink    *mlink;          struct mlink    *mlink;
Line 560  treescan(void)
Line 573  treescan(void)
         argv[0] = ".";          argv[0] = ".";
         argv[1] = (char *)NULL;          argv[1] = (char *)NULL;
   
         /*          f = fts_open((char * const *)argv,
          * Walk through all components under the directory, using the              FTS_PHYSICAL | FTS_NOCHDIR, NULL);
          * logical descent of files.  
          */  
         f = fts_open((char * const *)argv, FTS_LOGICAL, NULL);  
         if (NULL == f) {          if (NULL == f) {
                 exitcode = (int)MANDOCLEVEL_SYSERR;                  exitcode = (int)MANDOCLEVEL_SYSERR;
                 say("", "&fts_open");                  say("", "&fts_open");
Line 576  treescan(void)
Line 586  treescan(void)
   
         while (NULL != (ff = fts_read(f))) {          while (NULL != (ff = fts_read(f))) {
                 path = ff->fts_path + 2;                  path = ff->fts_path + 2;
                   switch (ff->fts_info) {
   
                 /*                  /*
                    * Symbolic links require various sanity checks,
                    * then get handled just like regular files.
                    */
                   case (FTS_SL):
                           if (NULL == realpath(path, buf)) {
                                   if (warnings)
                                           say(path, "&realpath");
                                   continue;
                           }
                           if (strstr(buf, basedir) != buf) {
                                   if (warnings) say("",
                                       "%s: outside base directory", buf);
                                   continue;
                           }
                           /* Use logical inode to avoid mpages dupe. */
                           if (-1 == stat(path, ff->fts_statp)) {
                                   if (warnings)
                                           say(path, "&stat");
                                   continue;
                           }
                           /* FALLTHROUGH */
   
                   /*
                  * If we're a regular file, add an mlink by using the                   * If we're a regular file, add an mlink by using the
                  * stored directory data and handling the filename.                   * stored directory data and handling the filename.
                  */                   */
                 if (FTS_F == ff->fts_info) {                  case (FTS_F):
                         if (0 == strcmp(path, MANDOC_DB))                          if (0 == strcmp(path, MANDOC_DB))
                                 continue;                                  continue;
                         if ( ! use_all && ff->fts_level < 2) {                          if ( ! use_all && ff->fts_level < 2) {
Line 636  treescan(void)
Line 671  treescan(void)
                         mlink->gzip = gzip;                          mlink->gzip = gzip;
                         mlink_add(mlink, ff->fts_statp);                          mlink_add(mlink, ff->fts_statp);
                         continue;                          continue;
                 } else if (FTS_D != ff->fts_info &&  
                                 FTS_DP != ff->fts_info) {                  case (FTS_D):
                           /* FALLTHROUGH */
                   case (FTS_DP):
                           break;
   
                   default:
                         if (warnings)                          if (warnings)
                                 say(path, "Not a regular file");                                  say(path, "Not a regular file");
                         continue;                          continue;
Line 726  filescan(const char *file)
Line 766  filescan(const char *file)
         if (0 == strncmp(file, "./", 2))          if (0 == strncmp(file, "./", 2))
                 file += 2;                  file += 2;
   
           /*
            * We have to do lstat(2) before realpath(3) loses
            * the information whether this is a symbolic link.
            * We need to know that because for symbolic links,
            * we want to use the orginal file name, while for
            * regular files, we want to use the real path.
            */
           if (-1 == lstat(file, &st)) {
                   exitcode = (int)MANDOCLEVEL_BADARG;
                   say(file, "&lstat");
                   return;
           } else if (0 == ((S_IFREG | S_IFLNK) & st.st_mode)) {
                   exitcode = (int)MANDOCLEVEL_BADARG;
                   say(file, "Not a regular file");
                   return;
           }
   
           /*
            * We have to resolve the file name to the real path
            * in any case for the base directory check.
            */
         if (NULL == realpath(file, buf)) {          if (NULL == realpath(file, buf)) {
                 exitcode = (int)MANDOCLEVEL_BADARG;                  exitcode = (int)MANDOCLEVEL_BADARG;
                 say(file, "&realpath");                  say(file, "&realpath");
Line 742  filescan(const char *file)
Line 803  filescan(const char *file)
                 return;                  return;
         }          }
   
         if (-1 == stat(buf, &st)) {          /*
                 exitcode = (int)MANDOCLEVEL_BADARG;           * Now we are sure the file is inside our tree.
                 say(file, "&stat");           * If it is a symbolic link, ignore the real path
                 return;           * and use the original name.
         } else if ( ! (S_IFREG & st.st_mode)) {           * This implies passing stuff like "cat1/../man1/foo.1"
                 exitcode = (int)MANDOCLEVEL_BADARG;           * on the command line won't work.  So don't do that.
                 say(file, "Not a regular file");           * Note the stat(2) can still fail if the link target
                 return;           * doesn't exist.
            */
           if (S_IFLNK & st.st_mode) {
                   if (-1 == stat(buf, &st)) {
                           exitcode = (int)MANDOCLEVEL_BADARG;
                           say(file, "&stat");
                           return;
                   }
                   strlcpy(buf, file, sizeof(buf));
                   start = strstr(buf, basedir) == buf ?
                       buf + strlen(basedir) + 1 : buf;
         }          }
   
         mlink = mandoc_calloc(1, sizeof(struct mlink));          mlink = mandoc_calloc(1, sizeof(struct mlink));
Line 1099  mpages_merge(struct mchars *mc, struct mparse *mp)
Line 1170  mpages_merge(struct mchars *mc, struct mparse *mp)
                                          * to the target.                                           * to the target.
                                          */                                           */
   
                                         if (mpage_dest->recno)                                          if (mpage_dest->pageid)
                                                 dbadd_mlink(mlink);                                                  dbadd_mlink(mlink);
   
                                         if (NULL == mlink->next)                                          if (NULL == mlink->next)
Line 1892  dbadd_mlink(const struct mlink *mlink)
Line 1963  dbadd_mlink(const struct mlink *mlink)
         SQL_BIND_TEXT(stmts[STMT_INSERT_LINK], i, mlink->dsec);          SQL_BIND_TEXT(stmts[STMT_INSERT_LINK], i, mlink->dsec);
         SQL_BIND_TEXT(stmts[STMT_INSERT_LINK], i, mlink->arch);          SQL_BIND_TEXT(stmts[STMT_INSERT_LINK], i, mlink->arch);
         SQL_BIND_TEXT(stmts[STMT_INSERT_LINK], i, mlink->name);          SQL_BIND_TEXT(stmts[STMT_INSERT_LINK], i, mlink->name);
         SQL_BIND_INT64(stmts[STMT_INSERT_LINK], i, mlink->mpage->recno);          SQL_BIND_INT64(stmts[STMT_INSERT_LINK], i, mlink->mpage->pageid);
         SQL_STEP(stmts[STMT_INSERT_LINK]);          SQL_STEP(stmts[STMT_INSERT_LINK]);
         sqlite3_reset(stmts[STMT_INSERT_LINK]);          sqlite3_reset(stmts[STMT_INSERT_LINK]);
 }  }
Line 1944  dbadd(struct mpage *mpage, struct mchars *mc)
Line 2015  dbadd(struct mpage *mpage, struct mchars *mc)
         SQL_BIND_TEXT(stmts[STMT_INSERT_PAGE], i, mpage->desc);          SQL_BIND_TEXT(stmts[STMT_INSERT_PAGE], i, mpage->desc);
         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->recno = sqlite3_last_insert_rowid(db);          mpage->pageid = sqlite3_last_insert_rowid(db);
         sqlite3_reset(stmts[STMT_INSERT_PAGE]);          sqlite3_reset(stmts[STMT_INSERT_PAGE]);
   
         while (NULL != mlink) {          while (NULL != mlink) {
Line 1961  dbadd(struct mpage *mpage, struct mchars *mc)
Line 2032  dbadd(struct mpage *mpage, struct mchars *mc)
                 i = 1;                  i = 1;
                 SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, key->mask);                  SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, key->mask);
                 SQL_BIND_TEXT(stmts[STMT_INSERT_NAME], i, key->rendered);                  SQL_BIND_TEXT(stmts[STMT_INSERT_NAME], i, key->rendered);
                 SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, mpage->recno);                  SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, mpage->pageid);
                 SQL_STEP(stmts[STMT_INSERT_NAME]);                  SQL_STEP(stmts[STMT_INSERT_NAME]);
                 sqlite3_reset(stmts[STMT_INSERT_NAME]);                  sqlite3_reset(stmts[STMT_INSERT_NAME]);
                 if (key->rendered != key->key)                  if (key->rendered != key->key)
Line 1976  dbadd(struct mpage *mpage, struct mchars *mc)
Line 2047  dbadd(struct mpage *mpage, struct mchars *mc)
                 i = 1;                  i = 1;
                 SQL_BIND_INT64(stmts[STMT_INSERT_KEY], i, key->mask);                  SQL_BIND_INT64(stmts[STMT_INSERT_KEY], i, key->mask);
                 SQL_BIND_TEXT(stmts[STMT_INSERT_KEY], i, key->rendered);                  SQL_BIND_TEXT(stmts[STMT_INSERT_KEY], i, key->rendered);
                 SQL_BIND_INT64(stmts[STMT_INSERT_KEY], i, mpage->recno);                  SQL_BIND_INT64(stmts[STMT_INSERT_KEY], i, mpage->pageid);
                 SQL_STEP(stmts[STMT_INSERT_KEY]);                  SQL_STEP(stmts[STMT_INSERT_KEY]);
                 sqlite3_reset(stmts[STMT_INSERT_KEY]);                  sqlite3_reset(stmts[STMT_INSERT_KEY]);
                 if (key->rendered != key->key)                  if (key->rendered != key->key)
Line 2172  create_tables:
Line 2243  create_tables:
         sql = "CREATE TABLE \"mpages\" (\n"          sql = "CREATE TABLE \"mpages\" (\n"
               " \"desc\" TEXT NOT NULL,\n"                " \"desc\" TEXT NOT NULL,\n"
               " \"form\" INTEGER NOT NULL,\n"                " \"form\" INTEGER NOT NULL,\n"
               " \"id\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL\n"                " \"pageid\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL\n"
               ");\n"                ");\n"
               "\n"                "\n"
               "CREATE TABLE \"mlinks\" (\n"                "CREATE TABLE \"mlinks\" (\n"
               " \"sec\" TEXT NOT NULL,\n"                " \"sec\" TEXT NOT NULL,\n"
               " \"arch\" TEXT NOT NULL,\n"                " \"arch\" TEXT NOT NULL,\n"
               " \"name\" TEXT NOT NULL,\n"                " \"name\" TEXT NOT NULL,\n"
               " \"pageid\" INTEGER NOT NULL REFERENCES mpages(id) "                " \"pageid\" INTEGER NOT NULL REFERENCES mpages(pageid) "
                 "ON DELETE CASCADE\n"                  "ON DELETE CASCADE\n"
               ");\n"                ");\n"
               "CREATE INDEX mlinks_pageid_idx ON mlinks (pageid);\n"                "CREATE INDEX mlinks_pageid_idx ON mlinks (pageid);\n"
Line 2187  create_tables:
Line 2258  create_tables:
               "CREATE TABLE \"names\" (\n"                "CREATE TABLE \"names\" (\n"
               " \"bits\" INTEGER NOT NULL,\n"                " \"bits\" INTEGER NOT NULL,\n"
               " \"name\" TEXT NOT NULL,\n"                " \"name\" TEXT NOT NULL,\n"
               " \"pageid\" INTEGER NOT NULL REFERENCES mpages(id) "                " \"pageid\" INTEGER NOT NULL REFERENCES mpages(pageid) "
                 "ON DELETE CASCADE\n"                  "ON DELETE CASCADE\n"
               ");\n"                ");\n"
               "\n"                "\n"
               "CREATE TABLE \"keys\" (\n"                "CREATE TABLE \"keys\" (\n"
               " \"bits\" INTEGER NOT NULL,\n"                " \"bits\" INTEGER NOT NULL,\n"
               " \"key\" TEXT NOT NULL,\n"                " \"key\" TEXT NOT NULL,\n"
               " \"pageid\" INTEGER NOT NULL REFERENCES mpages(id) "                " \"pageid\" INTEGER NOT NULL REFERENCES mpages(pageid) "
                 "ON DELETE CASCADE\n"                  "ON DELETE CASCADE\n"
               ");\n"                ");\n"
               "CREATE INDEX keys_pageid_idx ON keys (pageid);\n";                "CREATE INDEX keys_pageid_idx ON keys (pageid);\n";
Line 2207  create_tables:
Line 2278  create_tables:
   
 prepare_statements:  prepare_statements:
         SQL_EXEC("PRAGMA foreign_keys = ON");          SQL_EXEC("PRAGMA foreign_keys = ON");
         sql = "DELETE FROM mpages WHERE id 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=?)";
         sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_DELETE_PAGE], NULL);          sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_DELETE_PAGE], NULL);

Legend:
Removed from v.1.136  
changed lines
  Added in v.1.140

CVSweb