]> git.proxmox.com Git - libgit2.git/blame - examples/common.c
Set upstream metadata fields: Bug-Database, Bug-Submit, Repository, Repository-Browse.
[libgit2.git] / examples / common.c
CommitLineData
66902d47 1/*
6cb831bd 2 * Utilities library for libgit2 examples
66902d47 3 *
6cb831bd
BS
4 * Written by the libgit2 contributors
5 *
6 * To the extent possible under law, the author(s) have dedicated all copyright
7 * and related and neighboring rights to this software to the public domain
8 * worldwide. This software is distributed without any warranty.
9 *
10 * You should have received a copy of the CC0 Public Domain Dedication along
11 * with this software. If not, see
12 * <http://creativecommons.org/publicdomain/zero/1.0/>.
66902d47
RB
13 */
14
ac3d33df 15
66902d47
RB
16#include "common.h"
17
0c9c969a
UG
18#ifndef _WIN32
19# include <unistd.h>
20#endif
21#include <errno.h>
22
66902d47
RB
23void check_lg2(int error, const char *message, const char *extra)
24{
25 const git_error *lg2err;
26 const char *lg2msg = "", *lg2spacer = "";
27
28 if (!error)
29 return;
30
ac3d33df 31 if ((lg2err = git_error_last()) != NULL && lg2err->message != NULL) {
66902d47
RB
32 lg2msg = lg2err->message;
33 lg2spacer = " - ";
34 }
35
36 if (extra)
37 fprintf(stderr, "%s '%s' [%d]%s%s\n",
38 message, extra, error, lg2spacer, lg2msg);
39 else
40 fprintf(stderr, "%s [%d]%s%s\n",
41 message, error, lg2spacer, lg2msg);
42
43 exit(1);
44}
45
46void fatal(const char *message, const char *extra)
47{
48 if (extra)
49 fprintf(stderr, "%s %s\n", message, extra);
50 else
51 fprintf(stderr, "%s\n", message);
52
53 exit(1);
54}
55
66902d47
RB
56int diff_output(
57 const git_diff_delta *d,
58 const git_diff_hunk *h,
59 const git_diff_line *l,
60 void *p)
61{
300f4412 62 FILE *fp = (FILE*)p;
66902d47
RB
63
64 (void)d; (void)h;
65
66 if (!fp)
67 fp = stdout;
68
69 if (l->origin == GIT_DIFF_LINE_CONTEXT ||
70 l->origin == GIT_DIFF_LINE_ADDITION ||
71 l->origin == GIT_DIFF_LINE_DELETION)
72 fputc(l->origin, fp);
73
74 fwrite(l->content, 1, l->content_len, fp);
75
76 return 0;
77}
78
79void treeish_to_tree(
80 git_tree **out, git_repository *repo, const char *treeish)
81{
82 git_object *obj = NULL;
83
84 check_lg2(
85 git_revparse_single(&obj, repo, treeish),
86 "looking up object", treeish);
87
88 check_lg2(
ac3d33df 89 git_object_peel((git_object **)out, obj, GIT_OBJECT_TREE),
66902d47
RB
90 "resolving object to tree", treeish);
91
92 git_object_free(obj);
93}
94
eae0bfdc
PP
95void *xrealloc(void *oldp, size_t newsz)
96{
97 void *p = realloc(oldp, newsz);
98 if (p == NULL) {
99 fprintf(stderr, "Cannot allocate memory, exiting.\n");
100 exit(1);
101 }
102 return p;
103}
104
ac3d33df
JK
105int resolve_refish(git_annotated_commit **commit, git_repository *repo, const char *refish)
106{
107 git_reference *ref;
108 git_object *obj;
109 int err = 0;
110
111 assert(commit != NULL);
112
113 err = git_reference_dwim(&ref, repo, refish);
114 if (err == GIT_OK) {
115 git_annotated_commit_from_ref(commit, repo, ref);
116 git_reference_free(ref);
117 return 0;
118 }
119
120 err = git_revparse_single(&obj, repo, refish);
121 if (err == GIT_OK) {
122 err = git_annotated_commit_lookup(commit, repo, git_object_id(obj));
123 git_object_free(obj);
124 }
125
126 return err;
127}
0c9c969a
UG
128
129static int readline(char **out)
130{
131 int c, error = 0, length = 0, allocated = 0;
132 char *line = NULL;
133
134 errno = 0;
135
136 while ((c = getchar()) != EOF) {
137 if (length == allocated) {
138 allocated += 16;
139
140 if ((line = realloc(line, allocated)) == NULL) {
141 error = -1;
142 goto error;
143 }
144 }
145
146 if (c == '\n')
147 break;
148
149 line[length++] = c;
150 }
151
152 if (errno != 0) {
153 error = -1;
154 goto error;
155 }
156
157 line[length] = '\0';
158 *out = line;
159 line = NULL;
160 error = length;
161error:
162 free(line);
163 return error;
164}
165
166static int ask(char **out, const char *prompt, char optional)
167{
168 printf("%s ", prompt);
169 fflush(stdout);
170
171 if (!readline(out) && !optional) {
172 fprintf(stderr, "Could not read response: %s", strerror(errno));
173 return -1;
174 }
175
176 return 0;
177}
178
179int cred_acquire_cb(git_credential **out,
180 const char *url,
181 const char *username_from_url,
182 unsigned int allowed_types,
183 void *payload)
184{
185 char *username = NULL, *password = NULL, *privkey = NULL, *pubkey = NULL;
186 int error = 1;
187
188 UNUSED(url);
189 UNUSED(payload);
190
191 if (username_from_url) {
192 if ((username = strdup(username_from_url)) == NULL)
193 goto out;
194 } else if ((error = ask(&username, "Username:", 0)) < 0) {
195 goto out;
196 }
197
198 if (allowed_types & GIT_CREDENTIAL_SSH_KEY) {
199 int n;
200
201 if ((error = ask(&privkey, "SSH Key:", 0)) < 0 ||
202 (error = ask(&password, "Password:", 1)) < 0)
203 goto out;
204
205 if ((n = snprintf(NULL, 0, "%s.pub", privkey)) < 0 ||
206 (pubkey = malloc(n + 1)) == NULL ||
207 (n = snprintf(pubkey, n + 1, "%s.pub", privkey)) < 0)
208 goto out;
209
210 error = git_credential_ssh_key_new(out, username, pubkey, privkey, password);
211 } else if (allowed_types & GIT_CREDENTIAL_USERPASS_PLAINTEXT) {
212 if ((error = ask(&password, "Password:", 1)) < 0)
213 goto out;
214
215 error = git_credential_userpass_plaintext_new(out, username, password);
216 } else if (allowed_types & GIT_CREDENTIAL_USERNAME) {
217 error = git_credential_username_new(out, username);
218 }
219
220out:
221 free(username);
222 free(password);
223 free(privkey);
224 free(pubkey);
225 return error;
226}
227
228char *read_file(const char *path)
229{
230 ssize_t total = 0;
231 char *buf = NULL;
232 struct stat st;
233 int fd = -1;
234
235 if ((fd = open(path, O_RDONLY)) < 0 || fstat(fd, &st) < 0)
236 goto out;
237
238 if ((buf = malloc(st.st_size + 1)) == NULL)
239 goto out;
240
241 while (total < st.st_size) {
242 ssize_t bytes = read(fd, buf + total, st.st_size - total);
243 if (bytes <= 0) {
244 if (errno == EAGAIN || errno == EINTR)
245 continue;
246 free(buf);
247 buf = NULL;
248 goto out;
249 }
250 total += bytes;
251 }
252
253 buf[total] = '\0';
254
255out:
256 if (fd >= 0)
257 close(fd);
258 return buf;
259}
260