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 }