d4608eb1cb198f0c5426d90270e202d441c7da82
   1/* By carefully stacking #includes here (even if WE don't really need them)
   2 * we strive to make the thing actually compile. Git header files aren't very
   3 * nice. Perl headers are one of the signs of the coming apocalypse. */
   4#include <ctype.h>
   5/* Ok, it hasn't been so bad so far. */
   6
   7/* libgit interface */
   8#include "../cache.h"
   9#include "../exec_cmd.h"
  10
  11/* XS and Perl interface */
  12#include "EXTERN.h"
  13#include "perl.h"
  14#include "XSUB.h"
  15
  16#include "ppport.h"
  17
  18
  19MODULE = Git            PACKAGE = Git
  20
  21PROTOTYPES: DISABLE
  22
  23# /* TODO: xs_call_gate(). See Git.pm. */
  24
  25
  26const char *
  27xs_version()
  28CODE:
  29{
  30        RETVAL = GIT_VERSION;
  31}
  32OUTPUT:
  33        RETVAL
  34
  35
  36const char *
  37xs_exec_path()
  38CODE:
  39{
  40        RETVAL = git_exec_path();
  41}
  42OUTPUT:
  43        RETVAL
  44
  45
  46void
  47xs__execv_git_cmd(...)
  48CODE:
  49{
  50        const char **argv;
  51        int i;
  52
  53        argv = malloc(sizeof(const char *) * (items + 1));
  54        if (!argv)
  55                croak("malloc failed");
  56        for (i = 0; i < items; i++)
  57                argv[i] = strdup(SvPV_nolen(ST(i)));
  58        argv[i] = NULL;
  59
  60        execv_git_cmd(argv);
  61
  62        for (i = 0; i < items; i++)
  63                if (argv[i])
  64                        free((char *) argv[i]);
  65        free((char **) argv);
  66}
  67
  68char *
  69xs_hash_object(file, type = "blob")
  70        SV *file;
  71        char *type;
  72CODE:
  73{
  74        unsigned char sha1[20];
  75
  76        if (SvTYPE(file) == SVt_RV)
  77                file = SvRV(file);
  78
  79        if (SvTYPE(file) == SVt_PVGV) {
  80                /* Filehandle */
  81                PerlIO *pio;
  82
  83                pio = IoIFP(sv_2io(file));
  84                if (!pio)
  85                        croak("You passed me something weird - a dir glob?");
  86                /* XXX: I just hope PerlIO didn't read anything from it yet.
  87                 * --pasky */
  88                if (index_pipe(sha1, PerlIO_fileno(pio), type, 0))
  89                        croak("Unable to hash given filehandle");
  90                /* Avoid any nasty surprises. */
  91                PerlIO_close(pio);
  92
  93        } else {
  94                /* String */
  95                char *path = SvPV_nolen(file);
  96                int fd = open(path, O_RDONLY);
  97                struct stat st;
  98
  99                if (fd < 0 ||
 100                    fstat(fd, &st) < 0 ||
 101                    index_fd(sha1, fd, &st, 0, type))
 102                        croak("Unable to hash %s", path);
 103                close(fd);
 104        }
 105        RETVAL = sha1_to_hex(sha1);
 106}
 107OUTPUT:
 108        RETVAL