gitout

A static git page generator
git clone https://git.bracken.jp/gitout.git
Log | Files | Refs | Submodules | README | LICENSE

gitout_index.c (2618B)


      1 #include "gitout_index.h"
      2 
      3 #include <err.h>
      4 #include <stddef.h>
      5 #include <stdlib.h>
      6 
      7 #include "git/git.h"
      8 #include "git/repo.h"
      9 #include "security.h"
     10 #include "third_party/openbsd/reallocarray.h"
     11 #include "utils.h"
     12 #include "writer/index_writer.h"
     13 
     14 struct GitoutIndexOptions {
     15   const char** repo_dirs;
     16   size_t repo_dir_count;
     17   const char* me_url;
     18   IndexWriterType writer_type;
     19 };
     20 
     21 GitoutIndexOptions* gitout_index_options_create(int argc, const char* argv[]) {
     22   GitoutIndexOptions options = {
     23       .repo_dirs = NULL,
     24       .repo_dir_count = 0,
     25       .me_url = NULL,
     26       .writer_type = kIndexWriterTypeHtml,
     27   };
     28   for (int i = 1; i < argc; i++) {
     29     if (argv[i][0] != '-') {
     30       options.repo_dirs = reallocarray(
     31           options.repo_dirs, options.repo_dir_count + 1, sizeof(char*));
     32       if (!options.repo_dirs) {
     33         err(1, "reallocarray");
     34       }
     35       options.repo_dirs[options.repo_dir_count++] = argv[i];
     36     } else if (argv[i][1] == 'm') {
     37       // Requires 'me' URL argument.
     38       if (i + 1 >= argc) {
     39         return NULL;
     40       }
     41       options.me_url = argv[++i];
     42     } else if (argv[i][1] == 'H') {
     43       options.writer_type = kIndexWriterTypeHtml;
     44     } else if (argv[i][1] == 'G') {
     45       options.writer_type = kIndexWriterTypeGopher;
     46     }
     47   }
     48   GitoutIndexOptions* options_out = ecalloc(1, sizeof(GitoutIndexOptions));
     49   *options_out = options;
     50   return options_out;
     51 }
     52 
     53 void gitout_index_options_free(GitoutIndexOptions* options) {
     54   if (!options) {
     55     return;
     56   }
     57   if (options->repo_dirs) {
     58     free(options->repo_dirs);
     59     options->repo_dirs = NULL;
     60   }
     61   free(options);
     62 }
     63 
     64 void gitout_index_init(const GitoutIndexOptions* options) {
     65   const char** readonly_paths = options->repo_dirs;
     66   size_t readonly_paths_count = options->repo_dir_count;
     67   const char* readwrite_paths[2] = {".", NULL};
     68   size_t readwrite_paths_count = 1;
     69   restrict_filesystem_access(readonly_paths, readonly_paths_count,
     70                              readwrite_paths, readwrite_paths_count);
     71   restrict_system_operations(kGitoutIndex);
     72 
     73   gitout_git_initialize();
     74 }
     75 
     76 void gitout_index_run(const GitoutIndexOptions* options) {
     77   IndexWriter* writer = indexwriter_create(options->writer_type);
     78   if (options->me_url) {
     79     indexwriter_set_me_url(writer, options->me_url);
     80   }
     81   indexwriter_begin(writer);
     82   for (size_t i = 0; i < options->repo_dir_count; i++) {
     83     GitRepo* repo = gitrepo_create(options->repo_dirs[i]);
     84     indexwriter_add_repo(writer, repo);
     85     gitrepo_free(repo);
     86   }
     87   indexwriter_end(writer);
     88   indexwriter_free(writer);
     89 }
     90 
     91 void gitout_index_shutdown(void) {
     92   gitout_git_shutdown();
     93 }