ssh-push.con commit Add "git checkout" that does what the name suggests (303e5f4)
   1#include "cache.h"
   2#include "rsh.h"
   3#include "refs.h"
   4
   5unsigned char local_version = 1;
   6unsigned char remote_version = 0;
   7
   8int serve_object(int fd_in, int fd_out) {
   9        ssize_t size;
  10        int posn = 0;
  11        char sha1[20];
  12        unsigned long objsize;
  13        void *buf;
  14        signed char remote;
  15        do {
  16                size = read(fd_in, sha1 + posn, 20 - posn);
  17                if (size < 0) {
  18                        perror("git-ssh-push: read ");
  19                        return -1;
  20                }
  21                if (!size)
  22                        return -1;
  23                posn += size;
  24        } while (posn < 20);
  25        
  26        /* fprintf(stderr, "Serving %s\n", sha1_to_hex(sha1)); */
  27        remote = 0;
  28        
  29        buf = map_sha1_file(sha1, &objsize);
  30        
  31        if (!buf) {
  32                fprintf(stderr, "git-ssh-push: could not find %s\n", 
  33                        sha1_to_hex(sha1));
  34                remote = -1;
  35        }
  36        
  37        write(fd_out, &remote, 1);
  38        
  39        if (remote < 0)
  40                return 0;
  41        
  42        posn = 0;
  43        do {
  44                size = write(fd_out, buf + posn, objsize - posn);
  45                if (size <= 0) {
  46                        if (!size) {
  47                                fprintf(stderr, "git-ssh-push: write closed");
  48                        } else {
  49                                perror("git-ssh-push: write ");
  50                        }
  51                        return -1;
  52                }
  53                posn += size;
  54        } while (posn < objsize);
  55        return 0;
  56}
  57
  58int serve_version(int fd_in, int fd_out)
  59{
  60        if (read(fd_in, &remote_version, 1) < 1)
  61                return -1;
  62        write(fd_out, &local_version, 1);
  63        return 0;
  64}
  65
  66int serve_ref(int fd_in, int fd_out)
  67{
  68        char ref[PATH_MAX];
  69        unsigned char sha1[20];
  70        int posn = 0;
  71        signed char remote = 0;
  72        do {
  73                if (read(fd_in, ref + posn, 1) < 1)
  74                        return -1;
  75                posn++;
  76        } while (ref[posn - 1]);
  77        if (get_ref_sha1(ref, sha1))
  78                remote = -1;
  79        write(fd_out, &remote, 1);
  80        if (remote)
  81                return 0;
  82        write(fd_out, sha1, 20);
  83        return 0;
  84}
  85
  86
  87void service(int fd_in, int fd_out) {
  88        char type;
  89        int retval;
  90        do {
  91                retval = read(fd_in, &type, 1);
  92                if (retval < 1) {
  93                        if (retval < 0)
  94                                perror("git-ssh-push: read ");
  95                        return;
  96                }
  97                if (type == 'v' && serve_version(fd_in, fd_out))
  98                        return;
  99                if (type == 'o' && serve_object(fd_in, fd_out))
 100                        return;
 101                if (type == 'r' && serve_ref(fd_in, fd_out))
 102                        return;
 103        } while (1);
 104}
 105
 106int main(int argc, char **argv)
 107{
 108        int arg = 1;
 109        char *commit_id;
 110        char *url;
 111        int fd_in, fd_out;
 112        const char *prog = getenv("GIT_SSH_PULL") ? : "git-ssh-pull";
 113
 114        while (arg < argc && argv[arg][0] == '-') {
 115                if (argv[arg][1] == 'w')
 116                        arg++;
 117                arg++;
 118        }
 119        if (argc < arg + 2) {
 120                usage("git-ssh-push [-c] [-t] [-a] [-w ref] commit-id url");
 121                return 1;
 122        }
 123        commit_id = argv[arg];
 124        url = argv[arg + 1];
 125        if (setup_connection(&fd_in, &fd_out, prog, url, arg, argv + 1))
 126                return 1;
 127
 128        service(fd_in, fd_out);
 129        return 0;
 130}