ssh-upload.con commit Supplant the "while case ... break ;; esac" idiom (822f7c7)
   1#ifndef COUNTERPART_ENV_NAME
   2#define COUNTERPART_ENV_NAME "GIT_SSH_FETCH"
   3#endif
   4#ifndef COUNTERPART_PROGRAM_NAME
   5#define COUNTERPART_PROGRAM_NAME "git-ssh-fetch"
   6#endif
   7#ifndef MY_PROGRAM_NAME
   8#define MY_PROGRAM_NAME "git-ssh-upload"
   9#endif
  10
  11#include "cache.h"
  12#include "rsh.h"
  13#include "refs.h"
  14
  15static unsigned char local_version = 1;
  16static unsigned char remote_version;
  17
  18static int verbose;
  19
  20static int serve_object(int fd_in, int fd_out) {
  21        ssize_t size;
  22        unsigned char sha1[20];
  23        signed char remote;
  24
  25        size = read_in_full(fd_in, sha1, 20);
  26        if (size < 0) {
  27                perror("git-ssh-upload: read ");
  28                return -1;
  29        }
  30        if (!size)
  31                return -1;
  32
  33        if (verbose)
  34                fprintf(stderr, "Serving %s\n", sha1_to_hex(sha1));
  35
  36        remote = 0;
  37
  38        if (!has_sha1_file(sha1)) {
  39                fprintf(stderr, "git-ssh-upload: could not find %s\n",
  40                        sha1_to_hex(sha1));
  41                remote = -1;
  42        }
  43
  44        if (write_in_full(fd_out, &remote, 1) != 1)
  45                return 0;
  46
  47        if (remote < 0)
  48                return 0;
  49
  50        return write_sha1_to_fd(fd_out, sha1);
  51}
  52
  53static int serve_version(int fd_in, int fd_out)
  54{
  55        if (xread(fd_in, &remote_version, 1) < 1)
  56                return -1;
  57        write_in_full(fd_out, &local_version, 1);
  58        return 0;
  59}
  60
  61static int serve_ref(int fd_in, int fd_out)
  62{
  63        char ref[PATH_MAX];
  64        unsigned char sha1[20];
  65        int posn = 0;
  66        signed char remote = 0;
  67        do {
  68                if (posn >= PATH_MAX || xread(fd_in, ref + posn, 1) < 1)
  69                        return -1;
  70                posn++;
  71        } while (ref[posn - 1]);
  72
  73        if (verbose)
  74                fprintf(stderr, "Serving %s\n", ref);
  75
  76        if (get_ref_sha1(ref, sha1))
  77                remote = -1;
  78        if (write_in_full(fd_out, &remote, 1) != 1)
  79                return 0;
  80        if (remote)
  81                return 0;
  82        write_in_full(fd_out, sha1, 20);
  83        return 0;
  84}
  85
  86
  87static void service(int fd_in, int fd_out) {
  88        char type;
  89        ssize_t retval;
  90        do {
  91                retval = xread(fd_in, &type, 1);
  92                if (retval < 1) {
  93                        if (retval < 0)
  94                                perror("git-ssh-upload: 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
 106static const char ssh_push_usage[] =
 107        MY_PROGRAM_NAME " [-c] [-t] [-a] [-w ref] commit-id url";
 108
 109int main(int argc, char **argv)
 110{
 111        int arg = 1;
 112        char *commit_id;
 113        char *url;
 114        int fd_in, fd_out;
 115        const char *prog;
 116        unsigned char sha1[20];
 117        char hex[41];
 118
 119        prog = getenv(COUNTERPART_ENV_NAME);
 120        if (!prog) prog = COUNTERPART_PROGRAM_NAME;
 121
 122        setup_git_directory();
 123
 124        while (arg < argc && argv[arg][0] == '-') {
 125                if (argv[arg][1] == 'w')
 126                        arg++;
 127                arg++;
 128        }
 129        if (argc < arg + 2)
 130                usage(ssh_push_usage);
 131        commit_id = argv[arg];
 132        url = argv[arg + 1];
 133        if (get_sha1(commit_id, sha1))
 134                die("Not a valid object name %s", commit_id);
 135        memcpy(hex, sha1_to_hex(sha1), sizeof(hex));
 136        argv[arg] = hex;
 137
 138        if (setup_connection(&fd_in, &fd_out, prog, url, arg, argv + 1))
 139                return 1;
 140
 141        service(fd_in, fd_out);
 142        return 0;
 143}