Use getopt_long(3) from <getopt.h> in order to parse command line
[gitlite/.git] / gitlite.c
CommitLineData
41465307 1#include <getopt.h>
a374efd8 2#include <libgen.h>
285daa47
SB
3#include <stdio.h>
4#include <stdlib.h>
a374efd8
SB
5#include <string.h>
6#include <sys/param.h>
41465307 7#include <sysexits.h>
a374efd8 8#include <unistd.h>
285daa47 9
285daa47
SB
10#include <git2/clone.h>
11#include <git2/errors.h>
41465307 12#include <git2/global.h>
285daa47
SB
13
14// Compile with:
15// clang90 -o gitlite gitlite.c -lgit2 -I/usr/local/include -L/usr/local/lib -g
16
41465307
SB
17extern char *__progname;
18
285daa47 19void
41465307
SB
20git_bail_error(int rc) {
21 const git_error *err = NULL;
285daa47
SB
22
23 if (rc < 0) {
24 err = git_error_last();
41465307
SB
25 if (err)
26 printf("ERROR %d: %s\n", err->klass, err->message);
27 else
28 printf("ERROR %d: cannot fetch error info\n", rc);
29 }
285daa47
SB
30}
31
a374efd8 32void
41465307 33util_stripext(char *path) {
a374efd8
SB
34 char *end = path + strlen(path);
35
36 while (end > path && *end != '.') {
37 --end;
38 }
39
40 if (end > path) {
41 *end = '\0';
42 }
43}
44
41465307
SB
45static
46void usage(void) {
47 fprintf(stderr, "usage: %s --<git-cmd> ...\n", __progname);
48 fprintf(stderr, "usage: %s --clone <git-url> [local-path]\n", __progname);
49}
50
285daa47 51int
41465307 52main(int argc, char *argv[]) {
285daa47 53 int rc;
41465307
SB
54 int ch = 0;
55 int opt_index = -1;
56 int do_clone, do_fetch, do_log = 0;
a374efd8 57 char buff[MAXPATHLEN];
41465307 58 char *url = NULL;
a374efd8
SB
59 char *ext = NULL;
60 char *local_path = NULL;
285daa47
SB
61 git_repository *cloned_repo = NULL;
62
41465307
SB
63 static struct option longopts[] = {
64 {"clone", required_argument, NULL, 'c'},
65 {"fetch", no_argument, NULL, 'f'},
66 {"log", no_argument, NULL, 'l'},
67 {NULL, 0, NULL, 0}
68 };
285daa47 69
a374efd8 70 if (argc == 1) {
41465307
SB
71 usage();
72 return (EX_USAGE);
a374efd8
SB
73 }
74
41465307
SB
75 while ((ch = getopt_long(argc, argv, "c:fl", longopts, &opt_index)) != -1) {
76 switch (ch) {
77 case 'c':
78 do_clone = 1;
79 url = optarg;
80 break;
81 case 'f':
82 do_fetch = 1;
83 break;
84 case 'l':
85 do_log = 1;
86 break;
87 default:
88 usage();
89 return (EX_USAGE);
90 }
91 }
92 argc -= optind;
93 argv += optind;
94
95 if (do_clone) {
96 printf("handle git clone command\n");
97
98 git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT;
99 git_checkout_options co_opts = GIT_CHECKOUT_OPTIONS_INIT;
100
101 co_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
102 co_opts.progress_cb = NULL;
103 co_opts.progress_payload = NULL;
104 clone_opts.checkout_opts = co_opts;
105 clone_opts.fetch_opts.callbacks.sideband_progress = NULL;
106 clone_opts.fetch_opts.callbacks.transfer_progress = NULL;
107 clone_opts.fetch_opts.callbacks.credentials = NULL;
108 clone_opts.fetch_opts.callbacks.payload = NULL;
109
110 rc = git_libgit2_init();
111 git_bail_error(rc);
112
113 local_path = argv[0];
114 if (local_path == NULL) {
115 ext = strdup(basename(__DECONST(char *, url)));
116 util_stripext(__DECONST(char *, ext));
117 asprintf(&local_path, "%s/%s", getwd(buff), ext);
118 }
119
120 rc = git_clone(&cloned_repo, url, local_path, &clone_opts);
121 git_bail_error(rc);
122
123 } else if (do_fetch) {
124 fprintf(stderr, "handle git fetch command\n");
125 return (-1);
126
127 } else if (do_log) {
128 fprintf(stderr, "handle git log command\n");
129 return (-1);
a374efd8 130 }
285daa47
SB
131
132 if (cloned_repo)
133 git_repository_free(cloned_repo);
134
135 rc = git_libgit2_shutdown();
136 git_bail_error(rc);
137
a374efd8
SB
138 if (ext != NULL)
139 free(ext);
140
41465307 141 return (rc);
285daa47 142}