summaryrefslogtreecommitdiffabout
path: root/shared.c
Unidiff
Diffstat (limited to 'shared.c') (more/less context) (ignore whitespace changes)
-rw-r--r--shared.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/shared.c b/shared.c
index 911a55a..4cb9573 100644
--- a/shared.c
+++ b/shared.c
@@ -300,96 +300,117 @@ void cgit_diff_tree(const unsigned char *old_sha1,
300 int ret; 300 int ret;
301 int prefixlen; 301 int prefixlen;
302 302
303 diff_setup(&opt); 303 diff_setup(&opt);
304 opt.output_format = DIFF_FORMAT_CALLBACK; 304 opt.output_format = DIFF_FORMAT_CALLBACK;
305 opt.detect_rename = 1; 305 opt.detect_rename = 1;
306 opt.rename_limit = ctx.cfg.renamelimit; 306 opt.rename_limit = ctx.cfg.renamelimit;
307 DIFF_OPT_SET(&opt, RECURSIVE); 307 DIFF_OPT_SET(&opt, RECURSIVE);
308 opt.format_callback = cgit_diff_tree_cb; 308 opt.format_callback = cgit_diff_tree_cb;
309 opt.format_callback_data = fn; 309 opt.format_callback_data = fn;
310 if (prefix) { 310 if (prefix) {
311 opt.nr_paths = 1; 311 opt.nr_paths = 1;
312 opt.paths = &prefix; 312 opt.paths = &prefix;
313 prefixlen = strlen(prefix); 313 prefixlen = strlen(prefix);
314 opt.pathlens = &prefixlen; 314 opt.pathlens = &prefixlen;
315 } 315 }
316 diff_setup_done(&opt); 316 diff_setup_done(&opt);
317 317
318 if (old_sha1 && !is_null_sha1(old_sha1)) 318 if (old_sha1 && !is_null_sha1(old_sha1))
319 ret = diff_tree_sha1(old_sha1, new_sha1, "", &opt); 319 ret = diff_tree_sha1(old_sha1, new_sha1, "", &opt);
320 else 320 else
321 ret = diff_root_tree_sha1(new_sha1, "", &opt); 321 ret = diff_root_tree_sha1(new_sha1, "", &opt);
322 diffcore_std(&opt); 322 diffcore_std(&opt);
323 diff_flush(&opt); 323 diff_flush(&opt);
324} 324}
325 325
326void cgit_diff_commit(struct commit *commit, filepair_fn fn) 326void cgit_diff_commit(struct commit *commit, filepair_fn fn)
327{ 327{
328 unsigned char *old_sha1 = NULL; 328 unsigned char *old_sha1 = NULL;
329 329
330 if (commit->parents) 330 if (commit->parents)
331 old_sha1 = commit->parents->item->object.sha1; 331 old_sha1 = commit->parents->item->object.sha1;
332 cgit_diff_tree(old_sha1, commit->object.sha1, fn, NULL); 332 cgit_diff_tree(old_sha1, commit->object.sha1, fn, NULL);
333} 333}
334 334
335int cgit_parse_snapshots_mask(const char *str) 335int cgit_parse_snapshots_mask(const char *str)
336{ 336{
337 const struct cgit_snapshot_format *f; 337 const struct cgit_snapshot_format *f;
338 static const char *delim = " \t,:/|;"; 338 static const char *delim = " \t,:/|;";
339 int tl, sl, rv = 0; 339 int tl, sl, rv = 0;
340 340
341 /* favor legacy setting */ 341 /* favor legacy setting */
342 if(atoi(str)) 342 if(atoi(str))
343 return 1; 343 return 1;
344 for(;;) { 344 for(;;) {
345 str += strspn(str,delim); 345 str += strspn(str,delim);
346 tl = strcspn(str,delim); 346 tl = strcspn(str,delim);
347 if (!tl) 347 if (!tl)
348 break; 348 break;
349 for (f = cgit_snapshot_formats; f->suffix; f++) { 349 for (f = cgit_snapshot_formats; f->suffix; f++) {
350 sl = strlen(f->suffix); 350 sl = strlen(f->suffix);
351 if((tl == sl && !strncmp(f->suffix, str, tl)) || 351 if((tl == sl && !strncmp(f->suffix, str, tl)) ||
352 (tl == sl-1 && !strncmp(f->suffix+1, str, tl-1))) { 352 (tl == sl-1 && !strncmp(f->suffix+1, str, tl-1))) {
353 rv |= f->bit; 353 rv |= f->bit;
354 break; 354 break;
355 } 355 }
356 } 356 }
357 str += tl; 357 str += tl;
358 } 358 }
359 return rv; 359 return rv;
360} 360}
361 361
362int cgit_open_filter(struct cgit_filter *filter) 362int cgit_open_filter(struct cgit_filter *filter)
363{ 363{
364 364
365 filter->old_stdout = chk_positive(dup(STDOUT_FILENO), 365 filter->old_stdout = chk_positive(dup(STDOUT_FILENO),
366 "Unable to duplicate STDOUT"); 366 "Unable to duplicate STDOUT");
367 chk_zero(pipe(filter->pipe_fh), "Unable to create pipe to subprocess"); 367 chk_zero(pipe(filter->pipe_fh), "Unable to create pipe to subprocess");
368 filter->pid = chk_non_negative(fork(), "Unable to create subprocess"); 368 filter->pid = chk_non_negative(fork(), "Unable to create subprocess");
369 if (filter->pid == 0) { 369 if (filter->pid == 0) {
370 close(filter->pipe_fh[1]); 370 close(filter->pipe_fh[1]);
371 chk_non_negative(dup2(filter->pipe_fh[0], STDIN_FILENO), 371 chk_non_negative(dup2(filter->pipe_fh[0], STDIN_FILENO),
372 "Unable to use pipe as STDIN"); 372 "Unable to use pipe as STDIN");
373 execvp(filter->cmd, filter->argv); 373 execvp(filter->cmd, filter->argv);
374 die("Unable to exec subprocess %s: %s (%d)", filter->cmd, 374 die("Unable to exec subprocess %s: %s (%d)", filter->cmd,
375 strerror(errno), errno); 375 strerror(errno), errno);
376 } 376 }
377 close(filter->pipe_fh[0]); 377 close(filter->pipe_fh[0]);
378 chk_non_negative(dup2(filter->pipe_fh[1], STDOUT_FILENO), 378 chk_non_negative(dup2(filter->pipe_fh[1], STDOUT_FILENO),
379 "Unable to use pipe as STDOUT"); 379 "Unable to use pipe as STDOUT");
380 close(filter->pipe_fh[1]); 380 close(filter->pipe_fh[1]);
381 return 0; 381 return 0;
382} 382}
383 383
384int cgit_close_filter(struct cgit_filter *filter) 384int cgit_close_filter(struct cgit_filter *filter)
385{ 385{
386 chk_non_negative(dup2(filter->old_stdout, STDOUT_FILENO), 386 chk_non_negative(dup2(filter->old_stdout, STDOUT_FILENO),
387 "Unable to restore STDOUT"); 387 "Unable to restore STDOUT");
388 close(filter->old_stdout); 388 close(filter->old_stdout);
389 if (filter->pid < 0) 389 if (filter->pid < 0)
390 return 0; 390 return 0;
391 waitpid(filter->pid, &filter->exitstatus, 0); 391 waitpid(filter->pid, &filter->exitstatus, 0);
392 if (WIFEXITED(filter->exitstatus) && !WEXITSTATUS(filter->exitstatus)) 392 if (WIFEXITED(filter->exitstatus) && !WEXITSTATUS(filter->exitstatus))
393 return 0; 393 return 0;
394 die("Subprocess %s exited abnormally", filter->cmd); 394 die("Subprocess %s exited abnormally", filter->cmd);
395} 395}
396
397/* Read the content of the specified file into a newly allocated buffer,
398 * zeroterminate the buffer and return 0 on success, errno otherwise.
399 */
400int readfile(const char *path, char **buf, size_t *size)
401{
402 int fd;
403 struct stat st;
404
405 fd = open(path, O_RDONLY);
406 if (fd == -1)
407 return errno;
408 if (fstat(fd, &st))
409 return errno;
410 if (!S_ISREG(st.st_mode))
411 return EISDIR;
412 *buf = xmalloc(st.st_size + 1);
413 *size = read_in_full(fd, *buf, st.st_size);
414 (*buf)[*size] = '\0';
415 return (*size == st.st_size ? 0 : errno);
416}