summaryrefslogtreecommitdiff
path: root/vcs-svn
diff options
context:
space:
mode:
authorLibravatar Jeff King <peff@peff.net>2020-08-13 11:00:17 -0400
committerLibravatar Junio C Hamano <gitster@pobox.com>2020-08-13 11:02:15 -0700
commitfc47391e2478b26d33cae033f13405b6ee6af97b (patch)
tree9cebfb9d4bbbcee8feea178c17976ec28652145c /vcs-svn
parentmake git-fast-import a builtin (diff)
downloadtgif-fc47391e2478b26d33cae033f13405b6ee6af97b.tar.xz
drop vcs-svn experiment
The code in vcs-svn was started in 2010 as an attempt to build a remote-helper for interacting with svn repositories (as opposed to git-svn). However, we never got as far as shipping a mature remote helper, and the last substantive commit was e99d012a6bc in 2012. We do have a git-remote-testsvn, and it is even installed as part of "make install". But given the name, it seems unlikely to be used by anybody (you'd have to explicitly "git clone testsvn::$url", and there have been zero mentions of that on the mailing list since 2013, and even that includes the phrase "you might need to hack a bit to get it working properly"[1]). We also ship contrib/svn-fe, which builds on the vcs-svn work. However, it does not seem to build out of the box for me, as the link step misses some required libraries for using libgit.a. Curiously, the original build breakage bisects for me to eff80a9fd9 (Allow custom "comment char", 2013-01-16), which seems unrelated. There was an attempt to fix it in da011cb0e7 (contrib/svn-fe: fix Makefile, 2014-08-28), but on my system that only switches the error message. So it seems like the result is not really usable by anybody in practice. It would be wonderful if somebody wanted to pick up the topic again, and potentially it's worth carrying around for that reason. But the flip side is that people doing tree-wide operations have to deal with this code. And you can see the list with (replace "HEAD" with this commit as appropriate): { echo "--" git diff-tree --diff-filter=D -r --name-only HEAD^ HEAD } | git log --no-merges --oneline e99d012a6bc.. --stdin which shows 58 times somebody had to deal with the code, generally due to a compile or test failure, or a tree-wide style fix or API change. Let's drop it and let anybody who wants to pick it up do so by resurrecting it from the git history. As a bonus, this also reduces the size of a stripped installation of Git from 21MB to 19MB. [1] https://lore.kernel.org/git/CALkWK0mPHzKfzFKKpZkfAus3YVC9NFYDbFnt+5JQYVKipk3bQQ@mail.gmail.com/ Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'vcs-svn')
-rw-r--r--vcs-svn/LICENSE32
-rw-r--r--vcs-svn/fast_export.c365
-rw-r--r--vcs-svn/line_buffer.c126
-rw-r--r--vcs-svn/line_buffer.txt77
-rw-r--r--vcs-svn/sliding_window.c79
-rw-r--r--vcs-svn/svndiff.c309
-rw-r--r--vcs-svn/svndump.c540
7 files changed, 0 insertions, 1528 deletions
diff --git a/vcs-svn/LICENSE b/vcs-svn/LICENSE
deleted file mode 100644
index eb91858b82..0000000000
--- a/vcs-svn/LICENSE
+++ /dev/null
@@ -1,32 +0,0 @@
-Copyright (C) 2010 David Barr <david.barr@cordelta.com>.
-All rights reserved.
-
-Copyright (C) 2010 Jonathan Nieder <jrnieder@gmail.com>.
-
-Copyright (C) 2005 Stefan Hegny, hydrografix Consulting GmbH,
-Frankfurt/Main, Germany
-and others, see http://svn2cc.sarovar.org
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice(s), this list of conditions and the following disclaimer
- unmodified other than the allowable addition of one or more
- copyright notices.
-2. Redistributions in binary form must reproduce the above copyright
- notice(s), this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
-EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c
deleted file mode 100644
index b5b8913cb0..0000000000
--- a/vcs-svn/fast_export.c
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Licensed under a two-clause BSD-style license.
- * See LICENSE for details.
- */
-
-#include "cache.h"
-#include "quote.h"
-#include "fast_export.h"
-#include "strbuf.h"
-#include "svndiff.h"
-#include "sliding_window.h"
-#include "line_buffer.h"
-
-#define MAX_GITSVN_LINE_LEN 4096
-
-static uint32_t first_commit_done;
-static struct line_buffer postimage = LINE_BUFFER_INIT;
-static struct line_buffer report_buffer = LINE_BUFFER_INIT;
-
-/* NEEDSWORK: move to fast_export_init() */
-static int init_postimage(void)
-{
- static int postimage_initialized;
- if (postimage_initialized)
- return 0;
- postimage_initialized = 1;
- return buffer_tmpfile_init(&postimage);
-}
-
-void fast_export_init(int fd)
-{
- first_commit_done = 0;
- if (buffer_fdinit(&report_buffer, fd))
- die_errno("cannot read from file descriptor %d", fd);
-}
-
-void fast_export_deinit(void)
-{
- if (buffer_deinit(&report_buffer))
- die_errno("error closing fast-import feedback stream");
-}
-
-void fast_export_delete(const char *path)
-{
- putchar('D');
- putchar(' ');
- quote_c_style(path, NULL, stdout, 0);
- putchar('\n');
-}
-
-static void fast_export_truncate(const char *path, uint32_t mode)
-{
- fast_export_modify(path, mode, "inline");
- printf("data 0\n\n");
-}
-
-void fast_export_modify(const char *path, uint32_t mode, const char *dataref)
-{
- /* Mode must be 100644, 100755, 120000, or 160000. */
- if (!dataref) {
- fast_export_truncate(path, mode);
- return;
- }
- printf("M %06"PRIo32" %s ", mode, dataref);
- quote_c_style(path, NULL, stdout, 0);
- putchar('\n');
-}
-
-void fast_export_begin_note(uint32_t revision, const char *author,
- const char *log, timestamp_t timestamp, const char *note_ref)
-{
- static int firstnote = 1;
- size_t loglen = strlen(log);
- printf("commit %s\n", note_ref);
- printf("committer %s <%s@%s> %"PRItime" +0000\n", author, author, "local", timestamp);
- printf("data %"PRIuMAX"\n", (uintmax_t)loglen);
- fwrite(log, loglen, 1, stdout);
- if (firstnote) {
- if (revision > 1)
- printf("from %s^0", note_ref);
- firstnote = 0;
- }
- fputc('\n', stdout);
-}
-
-void fast_export_note(const char *committish, const char *dataref)
-{
- printf("N %s %s\n", dataref, committish);
-}
-
-static char gitsvnline[MAX_GITSVN_LINE_LEN];
-void fast_export_begin_commit(uint32_t revision, const char *author,
- const struct strbuf *log,
- const char *uuid, const char *url,
- timestamp_t timestamp, const char *local_ref)
-{
- static const struct strbuf empty = STRBUF_INIT;
- if (!log)
- log = &empty;
- if (*uuid && *url) {
- snprintf(gitsvnline, MAX_GITSVN_LINE_LEN,
- "\n\ngit-svn-id: %s@%"PRIu32" %s\n",
- url, revision, uuid);
- } else {
- *gitsvnline = '\0';
- }
- printf("commit %s\n", local_ref);
- printf("mark :%"PRIu32"\n", revision);
- printf("committer %s <%s@%s> %"PRItime" +0000\n",
- *author ? author : "nobody",
- *author ? author : "nobody",
- *uuid ? uuid : "local", timestamp);
- printf("data %"PRIuMAX"\n",
- (uintmax_t) (log->len + strlen(gitsvnline)));
- fwrite(log->buf, log->len, 1, stdout);
- printf("%s\n", gitsvnline);
- if (!first_commit_done) {
- if (revision > 1)
- printf("from :%"PRIu32"\n", revision - 1);
- first_commit_done = 1;
- }
-}
-
-void fast_export_end_commit(uint32_t revision)
-{
- printf("progress Imported commit %"PRIu32".\n\n", revision);
-}
-
-static void ls_from_rev(uint32_t rev, const char *path)
-{
- /* ls :5 path/to/old/file */
- printf("ls :%"PRIu32" ", rev);
- quote_c_style(path, NULL, stdout, 0);
- putchar('\n');
- fflush(stdout);
-}
-
-static void ls_from_active_commit(const char *path)
-{
- /* ls "path/to/file" */
- printf("ls \"");
- quote_c_style(path, NULL, stdout, 1);
- printf("\"\n");
- fflush(stdout);
-}
-
-static const char *get_response_line(void)
-{
- const char *line = buffer_read_line(&report_buffer);
- if (line)
- return line;
- if (buffer_ferror(&report_buffer))
- die_errno("error reading from fast-import");
- die("unexpected end of fast-import feedback");
-}
-
-static void die_short_read(struct line_buffer *input)
-{
- if (buffer_ferror(input))
- die_errno("error reading dump file");
- die("invalid dump: unexpected end of file");
-}
-
-static int parse_cat_response_line(const char *header, off_t *len)
-{
- uintmax_t n;
- const char *type;
- const char *end;
-
- if (ends_with(header, " missing"))
- return error("cat-blob reports missing blob: %s", header);
- type = strstr(header, " blob ");
- if (!type)
- return error("cat-blob header has wrong object type: %s", header);
- n = strtoumax(type + strlen(" blob "), (char **) &end, 10);
- if (end == type + strlen(" blob "))
- return error("cat-blob header does not contain length: %s", header);
- if (memchr(type + strlen(" blob "), '-', end - type - strlen(" blob ")))
- return error("cat-blob header contains negative length: %s", header);
- if (n == UINTMAX_MAX || n > maximum_signed_value_of_type(off_t))
- return error("blob too large for current definition of off_t");
- *len = n;
- if (*end)
- return error("cat-blob header contains garbage after length: %s", header);
- return 0;
-}
-
-static void check_preimage_overflow(off_t a, off_t b)
-{
- if (signed_add_overflows(a, b))
- die("blob too large for current definition of off_t");
-}
-
-static long apply_delta(off_t len, struct line_buffer *input,
- const char *old_data, uint32_t old_mode)
-{
- long ret;
- struct sliding_view preimage = SLIDING_VIEW_INIT(&report_buffer, 0);
- FILE *out;
-
- if (init_postimage() || !(out = buffer_tmpfile_rewind(&postimage)))
- die("cannot open temporary file for blob retrieval");
- if (old_data) {
- const char *response;
- printf("cat-blob %s\n", old_data);
- fflush(stdout);
- response = get_response_line();
- if (parse_cat_response_line(response, &preimage.max_off))
- die("invalid cat-blob response: %s", response);
- check_preimage_overflow(preimage.max_off, 1);
- }
- if (old_mode == S_IFLNK) {
- strbuf_addstr(&preimage.buf, "link ");
- check_preimage_overflow(preimage.max_off, strlen("link "));
- preimage.max_off += strlen("link ");
- check_preimage_overflow(preimage.max_off, 1);
- }
- if (svndiff0_apply(input, len, &preimage, out))
- die("cannot apply delta");
- if (old_data) {
- /* Read the remainder of preimage and trailing newline. */
- assert(!signed_add_overflows(preimage.max_off, 1));
- preimage.max_off++; /* room for newline */
- if (move_window(&preimage, preimage.max_off - 1, 1))
- die("cannot seek to end of input");
- if (preimage.buf.buf[0] != '\n')
- die("missing newline after cat-blob response");
- }
- ret = buffer_tmpfile_prepare_to_read(&postimage);
- if (ret < 0)
- die("cannot read temporary file for blob retrieval");
- strbuf_release(&preimage.buf);
- return ret;
-}
-
-void fast_export_buf_to_data(const struct strbuf *data)
-{
- printf("data %"PRIuMAX"\n", (uintmax_t)data->len);
- fwrite(data->buf, data->len, 1, stdout);
- fputc('\n', stdout);
-}
-
-void fast_export_data(uint32_t mode, off_t len, struct line_buffer *input)
-{
- assert(len >= 0);
- if (mode == S_IFLNK) {
- /* svn symlink blobs start with "link " */
- if (len < 5)
- die("invalid dump: symlink too short for \"link\" prefix");
- len -= 5;
- if (buffer_skip_bytes(input, 5) != 5)
- die_short_read(input);
- }
- printf("data %"PRIuMAX"\n", (uintmax_t) len);
- if (buffer_copy_bytes(input, len) != len)
- die_short_read(input);
- fputc('\n', stdout);
-}
-
-static int parse_ls_response(const char *response, uint32_t *mode,
- struct strbuf *dataref)
-{
- const char *tab;
- const char *response_end;
-
- assert(response);
- response_end = response + strlen(response);
-
- if (*response == 'm') { /* Missing. */
- errno = ENOENT;
- return -1;
- }
-
- /* Mode. */
- if (response_end - response < (signed) strlen("100644") ||
- response[strlen("100644")] != ' ')
- die("invalid ls response: missing mode: %s", response);
- *mode = 0;
- for (; *response != ' '; response++) {
- char ch = *response;
- if (ch < '0' || ch > '7')
- die("invalid ls response: mode is not octal: %s", response);
- *mode *= 8;
- *mode += ch - '0';
- }
-
- /* ' blob ' or ' tree ' */
- if (response_end - response < (signed) strlen(" blob ") ||
- (response[1] != 'b' && response[1] != 't'))
- die("unexpected ls response: not a tree or blob: %s", response);
- response += strlen(" blob ");
-
- /* Dataref. */
- tab = memchr(response, '\t', response_end - response);
- if (!tab)
- die("invalid ls response: missing tab: %s", response);
- strbuf_add(dataref, response, tab - response);
- return 0;
-}
-
-int fast_export_ls_rev(uint32_t rev, const char *path,
- uint32_t *mode, struct strbuf *dataref)
-{
- ls_from_rev(rev, path);
- return parse_ls_response(get_response_line(), mode, dataref);
-}
-
-int fast_export_ls(const char *path, uint32_t *mode, struct strbuf *dataref)
-{
- ls_from_active_commit(path);
- return parse_ls_response(get_response_line(), mode, dataref);
-}
-
-const char *fast_export_read_path(const char *path, uint32_t *mode_out)
-{
- int err;
- static struct strbuf buf = STRBUF_INIT;
-
- strbuf_reset(&buf);
- err = fast_export_ls(path, mode_out, &buf);
- if (err) {
- if (errno != ENOENT)
- BUG("unexpected fast_export_ls error: %s",
- strerror(errno));
- /* Treat missing paths as directories. */
- *mode_out = S_IFDIR;
- return NULL;
- }
- return buf.buf;
-}
-
-void fast_export_copy(uint32_t revision, const char *src, const char *dst)
-{
- int err;
- uint32_t mode;
- static struct strbuf data = STRBUF_INIT;
-
- strbuf_reset(&data);
- err = fast_export_ls_rev(revision, src, &mode, &data);
- if (err) {
- if (errno != ENOENT)
- BUG("unexpected fast_export_ls_rev error: %s",
- strerror(errno));
- fast_export_delete(dst);
- return;
- }
- fast_export_modify(dst, mode, data.buf);
-}
-
-void fast_export_blob_delta(uint32_t mode,
- uint32_t old_mode, const char *old_data,
- off_t len, struct line_buffer *input)
-{
- long postimage_len;
-
- assert(len >= 0);
- postimage_len = apply_delta(len, input, old_data, old_mode);
- if (mode == S_IFLNK) {
- buffer_skip_bytes(&postimage, strlen("link "));
- postimage_len -= strlen("link ");
- }
- printf("data %ld\n", postimage_len);
- buffer_copy_bytes(&postimage, postimage_len);
- fputc('\n', stdout);
-}
diff --git a/vcs-svn/line_buffer.c b/vcs-svn/line_buffer.c
deleted file mode 100644
index e416caf8a4..0000000000
--- a/vcs-svn/line_buffer.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Licensed under a two-clause BSD-style license.
- * See LICENSE for details.
- */
-
-#include "git-compat-util.h"
-#include "line_buffer.h"
-#include "strbuf.h"
-
-#define COPY_BUFFER_LEN 4096
-
-int buffer_init(struct line_buffer *buf, const char *filename)
-{
- buf->infile = filename ? fopen(filename, "r") : stdin;
- if (!buf->infile)
- return -1;
- return 0;
-}
-
-int buffer_fdinit(struct line_buffer *buf, int fd)
-{
- buf->infile = fdopen(fd, "r");
- if (!buf->infile)
- return -1;
- return 0;
-}
-
-int buffer_tmpfile_init(struct line_buffer *buf)
-{
- buf->infile = tmpfile();
- if (!buf->infile)
- return -1;
- return 0;
-}
-
-int buffer_deinit(struct line_buffer *buf)
-{
- int err;
- if (buf->infile == stdin)
- return ferror(buf->infile);
- err = ferror(buf->infile);
- err |= fclose(buf->infile);
- return err;
-}
-
-FILE *buffer_tmpfile_rewind(struct line_buffer *buf)
-{
- rewind(buf->infile);
- return buf->infile;
-}
-
-long buffer_tmpfile_prepare_to_read(struct line_buffer *buf)
-{
- long pos = ftell(buf->infile);
- if (pos < 0)
- return error_errno("ftell error");
- if (fseek(buf->infile, 0, SEEK_SET))
- return error_errno("seek error");
- return pos;
-}
-
-int buffer_ferror(struct line_buffer *buf)
-{
- return ferror(buf->infile);
-}
-
-int buffer_read_char(struct line_buffer *buf)
-{
- return fgetc(buf->infile);
-}
-
-/* Read a line without trailing newline. */
-char *buffer_read_line(struct line_buffer *buf)
-{
- char *end;
- if (!fgets(buf->line_buffer, sizeof(buf->line_buffer), buf->infile))
- /* Error or data exhausted. */
- return NULL;
- end = buf->line_buffer + strlen(buf->line_buffer);
- if (end[-1] == '\n')
- end[-1] = '\0';
- else if (feof(buf->infile))
- ; /* No newline at end of file. That's fine. */
- else
- /*
- * Line was too long.
- * There is probably a saner way to deal with this,
- * but for now let's return an error.
- */
- return NULL;
- return buf->line_buffer;
-}
-
-size_t buffer_read_binary(struct line_buffer *buf,
- struct strbuf *sb, size_t size)
-{
- return strbuf_fread(sb, size, buf->infile);
-}
-
-off_t buffer_copy_bytes(struct line_buffer *buf, off_t nbytes)
-{
- char byte_buffer[COPY_BUFFER_LEN];
- off_t done = 0;
- while (done < nbytes && !feof(buf->infile) && !ferror(buf->infile)) {
- off_t len = nbytes - done;
- size_t in = len < COPY_BUFFER_LEN ? len : COPY_BUFFER_LEN;
- in = fread(byte_buffer, 1, in, buf->infile);
- done += in;
- fwrite(byte_buffer, 1, in, stdout);
- if (ferror(stdout))
- return done + buffer_skip_bytes(buf, nbytes - done);
- }
- return done;
-}
-
-off_t buffer_skip_bytes(struct line_buffer *buf, off_t nbytes)
-{
- char byte_buffer[COPY_BUFFER_LEN];
- off_t done = 0;
- while (done < nbytes && !feof(buf->infile) && !ferror(buf->infile)) {
- off_t len = nbytes - done;
- size_t in = len < COPY_BUFFER_LEN ? len : COPY_BUFFER_LEN;
- done += fread(byte_buffer, 1, in, buf->infile);
- }
- return done;
-}
diff --git a/vcs-svn/line_buffer.txt b/vcs-svn/line_buffer.txt
deleted file mode 100644
index 8e139eb22d..0000000000
--- a/vcs-svn/line_buffer.txt
+++ /dev/null
@@ -1,77 +0,0 @@
-line_buffer API
-===============
-
-The line_buffer library provides a convenient interface for
-mostly-line-oriented input.
-
-Each line is not permitted to exceed 10000 bytes. The provided
-functions are not thread-safe or async-signal-safe, and like
-`fgets()`, they generally do not function correctly if interrupted
-by a signal without SA_RESTART set.
-
-Calling sequence
-----------------
-
-The calling program:
-
- - initializes a `struct line_buffer` to LINE_BUFFER_INIT
- - specifies a file to read with `buffer_init`
- - processes input with `buffer_read_line`, `buffer_skip_bytes`,
- and `buffer_copy_bytes`
- - closes the file with `buffer_deinit`, perhaps to start over and
- read another file.
-
-When finished, the caller can use `buffer_reset` to deallocate
-resources.
-
-Using temporary files
----------------------
-
-Temporary files provide a place to store data that should not outlive
-the calling program. A program
-
- - initializes a `struct line_buffer` to LINE_BUFFER_INIT
- - requests a temporary file with `buffer_tmpfile_init`
- - acquires an output handle by calling `buffer_tmpfile_rewind`
- - uses standard I/O functions like `fprintf` and `fwrite` to fill
- the temporary file
- - declares writing is over with `buffer_tmpfile_prepare_to_read`
- - can re-read what was written with `buffer_read_line`,
- `buffer_copy_bytes`, and so on
- - can reuse the temporary file by calling `buffer_tmpfile_rewind`
- again
- - removes the temporary file with `buffer_deinit`, perhaps to
- reuse the line_buffer for some other file.
-
-When finished, the calling program can use `buffer_reset` to deallocate
-resources.
-
-Functions
----------
-
-`buffer_init`, `buffer_fdinit`::
- Open the named file or file descriptor for input.
- buffer_init(buf, NULL) prepares to read from stdin.
- On failure, returns -1 (with errno indicating the nature
- of the failure).
-
-`buffer_deinit`::
- Stop reading from the current file (closing it unless
- it was stdin). Returns nonzero if `fclose` fails or
- the error indicator was set.
-
-`buffer_read_line`::
- Read a line and strip off the trailing newline.
- On failure or end of file, returns NULL.
-
-`buffer_copy_bytes`::
- Read `len` bytes of input and dump them to the standard output
- stream. Returns early for error or end of file.
-
-`buffer_skip_bytes`::
- Discards `len` bytes from the input stream (stopping early
- if necessary because of an error or eof). Return value is
- the number of bytes successfully read.
-
-`buffer_reset`::
- Deallocates non-static buffers.
diff --git a/vcs-svn/sliding_window.c b/vcs-svn/sliding_window.c
deleted file mode 100644
index 06d273c9e8..0000000000
--- a/vcs-svn/sliding_window.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed under a two-clause BSD-style license.
- * See LICENSE for details.
- */
-
-#include "git-compat-util.h"
-#include "sliding_window.h"
-#include "line_buffer.h"
-#include "strbuf.h"
-
-static int input_error(struct line_buffer *file)
-{
- if (!buffer_ferror(file))
- return error("delta preimage ends early");
- return error_errno("cannot read delta preimage");
-}
-
-static int skip_or_whine(struct line_buffer *file, off_t gap)
-{
- if (buffer_skip_bytes(file, gap) != gap)
- return input_error(file);
- return 0;
-}
-
-static int read_to_fill_or_whine(struct line_buffer *file,
- struct strbuf *buf, size_t width)
-{
- buffer_read_binary(file, buf, width - buf->len);
- if (buf->len != width)
- return input_error(file);
- return 0;
-}
-
-static int check_offset_overflow(off_t offset, uintmax_t len)
-{
- if (len > maximum_signed_value_of_type(off_t))
- return error("unrepresentable length in delta: "
- "%"PRIuMAX" > OFF_MAX", len);
- if (signed_add_overflows(offset, (off_t) len))
- return error("unrepresentable offset in delta: "
- "%"PRIuMAX" + %"PRIuMAX" > OFF_MAX",
- (uintmax_t) offset, len);
- return 0;
-}
-
-int move_window(struct sliding_view *view, off_t off, size_t width)
-{
- off_t file_offset;
- assert(view);
- assert(view->width <= view->buf.len);
- assert(!check_offset_overflow(view->off, view->buf.len));
-
- if (check_offset_overflow(off, width))
- return -1;
- if (off < view->off || off + width < view->off + view->width)
- return error("invalid delta: window slides left");
- if (view->max_off >= 0 && view->max_off < off + (off_t) width)
- return error("delta preimage ends early");
-
- file_offset = view->off + view->buf.len;
- if (off < file_offset) {
- /* Move the overlapping region into place. */
- strbuf_remove(&view->buf, 0, off - view->off);
- } else {
- /* Seek ahead to skip the gap. */
- if (skip_or_whine(view->file, off - file_offset))
- return -1;
- strbuf_setlen(&view->buf, 0);
- }
-
- if (view->buf.len > width)
- ; /* Already read. */
- else if (read_to_fill_or_whine(view->file, &view->buf, width))
- return -1;
-
- view->off = off;
- view->width = width;
- return 0;
-}
diff --git a/vcs-svn/svndiff.c b/vcs-svn/svndiff.c
deleted file mode 100644
index 75c753162a..0000000000
--- a/vcs-svn/svndiff.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Licensed under a two-clause BSD-style license.
- * See LICENSE for details.
- */
-
-#include "git-compat-util.h"
-#include "sliding_window.h"
-#include "line_buffer.h"
-#include "svndiff.h"
-
-/*
- * svndiff0 applier
- *
- * See http://svn.apache.org/repos/asf/subversion/trunk/notes/svndiff.
- *
- * svndiff0 ::= 'SVN\0' window*
- * window ::= int int int int int instructions inline_data;
- * instructions ::= instruction*;
- * instruction ::= view_selector int int
- * | copyfrom_data int
- * | packed_view_selector int
- * | packed_copyfrom_data
- * ;
- * view_selector ::= copyfrom_source
- * | copyfrom_target
- * ;
- * copyfrom_source ::= # binary 00 000000;
- * copyfrom_target ::= # binary 01 000000;
- * copyfrom_data ::= # binary 10 000000;
- * packed_view_selector ::= # view_selector OR-ed with 6 bit value;
- * packed_copyfrom_data ::= # copyfrom_data OR-ed with 6 bit value;
- * int ::= highdigit* lowdigit;
- * highdigit ::= # binary 1000 0000 OR-ed with 7 bit value;
- * lowdigit ::= # 7 bit value;
- */
-
-#define INSN_MASK 0xc0
-#define INSN_COPYFROM_SOURCE 0x00
-#define INSN_COPYFROM_TARGET 0x40
-#define INSN_COPYFROM_DATA 0x80
-#define OPERAND_MASK 0x3f
-
-#define VLI_CONTINUE 0x80
-#define VLI_DIGIT_MASK 0x7f
-#define VLI_BITS_PER_DIGIT 7
-
-struct window {
- struct sliding_view *in;
- struct strbuf out;
- struct strbuf instructions;
- struct strbuf data;
-};
-
-#define WINDOW_INIT(w) { (w), STRBUF_INIT, STRBUF_INIT, STRBUF_INIT }
-
-static void window_release(struct window *ctx)
-{
- strbuf_release(&ctx->out);
- strbuf_release(&ctx->instructions);
- strbuf_release(&ctx->data);
-}
-
-static int write_strbuf(struct strbuf *sb, FILE *out)
-{
- if (fwrite(sb->buf, 1, sb->len, out) == sb->len) /* Success. */
- return 0;
- return error_errno("cannot write delta postimage");
-}
-
-static int error_short_read(struct line_buffer *input)
-{
- if (buffer_ferror(input))
- return error_errno("error reading delta");
- return error("invalid delta: unexpected end of file");
-}
-
-static int read_chunk(struct line_buffer *delta, off_t *delta_len,
- struct strbuf *buf, size_t len)
-{
- assert(*delta_len >= 0);
- strbuf_reset(buf);
- if (len > (uintmax_t) *delta_len ||
- buffer_read_binary(delta, buf, len) != len)
- return error_short_read(delta);
- *delta_len -= buf->len;
- return 0;
-}
-
-static int read_magic(struct line_buffer *in, off_t *len)
-{
- static const char magic[] = {'S', 'V', 'N', '\0'};
- struct strbuf sb = STRBUF_INIT;
-
- if (read_chunk(in, len, &sb, sizeof(magic))) {
- strbuf_release(&sb);
- return -1;
- }
- if (memcmp(sb.buf, magic, sizeof(magic))) {
- strbuf_release(&sb);
- return error("invalid delta: unrecognized file type");
- }
- strbuf_release(&sb);
- return 0;
-}
-
-static int read_int(struct line_buffer *in, uintmax_t *result, off_t *len)
-{
- uintmax_t rv = 0;
- off_t sz;
- for (sz = *len; sz; sz--) {
- const int ch = buffer_read_char(in);
- if (ch == EOF)
- break;
-
- rv <<= VLI_BITS_PER_DIGIT;
- rv += (ch & VLI_DIGIT_MASK);
- if (ch & VLI_CONTINUE)
- continue;
-
- *result = rv;
- *len = sz - 1;
- return 0;
- }
- return error_short_read(in);
-}
-
-static int parse_int(const char **buf, size_t *result, const char *end)
-{
- size_t rv = 0;
- const char *pos;
- for (pos = *buf; pos != end; pos++) {
- unsigned char ch = *pos;
-
- rv <<= VLI_BITS_PER_DIGIT;
- rv += (ch & VLI_DIGIT_MASK);
- if (ch & VLI_CONTINUE)
- continue;
-
- *result = rv;
- *buf = pos + 1;
- return 0;
- }
- return error("invalid delta: unexpected end of instructions section");
-}
-
-static int read_offset(struct line_buffer *in, off_t *result, off_t *len)
-{
- uintmax_t val;
- if (read_int(in, &val, len))
- return -1;
- if (val > maximum_signed_value_of_type(off_t))
- return error("unrepresentable offset in delta: %"PRIuMAX"", val);
- *result = val;
- return 0;
-}
-
-static int read_length(struct line_buffer *in, size_t *result, off_t *len)
-{
- uintmax_t val;
- if (read_int(in, &val, len))
- return -1;
- if (val > SIZE_MAX)
- return error("unrepresentable length in delta: %"PRIuMAX"", val);
- *result = val;
- return 0;
-}
-
-static int copyfrom_source(struct window *ctx, const char **instructions,
- size_t nbytes, const char *insns_end)
-{
- size_t offset;
- if (parse_int(instructions, &offset, insns_end))
- return -1;
- if (unsigned_add_overflows(offset, nbytes) ||
- offset + nbytes > ctx->in->width)
- return error("invalid delta: copies source data outside view");
- strbuf_add(&ctx->out, ctx->in->buf.buf + offset, nbytes);
- return 0;
-}
-
-static int copyfrom_target(struct window *ctx, const char **instructions,
- size_t nbytes, const char *instructions_end)
-{
- size_t offset;
- if (parse_int(instructions, &offset, instructions_end))
- return -1;
- if (offset >= ctx->out.len)
- return error("invalid delta: copies from the future");
- for (; nbytes > 0; nbytes--)
- strbuf_addch(&ctx->out, ctx->out.buf[offset++]);
- return 0;
-}
-
-static int copyfrom_data(struct window *ctx, size_t *data_pos, size_t nbytes)
-{
- const size_t pos = *data_pos;
- if (unsigned_add_overflows(pos, nbytes) ||
- pos + nbytes > ctx->data.len)
- return error("invalid delta: copies unavailable inline data");
- strbuf_add(&ctx->out, ctx->data.buf + pos, nbytes);
- *data_pos += nbytes;
- return 0;
-}
-
-static int parse_first_operand(const char **buf, size_t *out, const char *end)
-{
- size_t result = (unsigned char) *(*buf)++ & OPERAND_MASK;
- if (result) { /* immediate operand */
- *out = result;
- return 0;
- }
- return parse_int(buf, out, end);
-}
-
-static int execute_one_instruction(struct window *ctx,
- const char **instructions, size_t *data_pos)
-{
- unsigned int instruction;
- const char *insns_end = ctx->instructions.buf + ctx->instructions.len;
- size_t nbytes;
- assert(ctx);
- assert(instructions && *instructions);
- assert(data_pos);
-
- instruction = (unsigned char) **instructions;
- if (parse_first_operand(instructions, &nbytes, insns_end))
- return -1;
- switch (instruction & INSN_MASK) {
- case INSN_COPYFROM_SOURCE:
- return copyfrom_source(ctx, instructions, nbytes, insns_end);
- case INSN_COPYFROM_TARGET:
- return copyfrom_target(ctx, instructions, nbytes, insns_end);
- case INSN_COPYFROM_DATA:
- return copyfrom_data(ctx, data_pos, nbytes);
- default:
- return error("invalid delta: unrecognized instruction");
- }
-}
-
-static int apply_window_in_core(struct window *ctx)
-{
- const char *instructions;
- size_t data_pos = 0;
-
- /*
- * Fill ctx->out.buf using data from the source, target,
- * and inline data views.
- */
- for (instructions = ctx->instructions.buf;
- instructions != ctx->instructions.buf + ctx->instructions.len;
- )
- if (execute_one_instruction(ctx, &instructions, &data_pos))
- return -1;
- if (data_pos != ctx->data.len)
- return error("invalid delta: does not copy all inline data");
- return 0;
-}
-
-static int apply_one_window(struct line_buffer *delta, off_t *delta_len,
- struct sliding_view *preimage, FILE *out)
-{
- int rv = -1;
- struct window ctx = WINDOW_INIT(preimage);
- size_t out_len;
- size_t instructions_len;
- size_t data_len;
- assert(delta_len);
-
- /* "source view" offset and length already handled; */
- if (read_length(delta, &out_len, delta_len) ||
- read_length(delta, &instructions_len, delta_len) ||
- read_length(delta, &data_len, delta_len) ||
- read_chunk(delta, delta_len, &ctx.instructions, instructions_len) ||
- read_chunk(delta, delta_len, &ctx.data, data_len))
- goto error_out;
- strbuf_grow(&ctx.out, out_len);
- if (apply_window_in_core(&ctx))
- goto error_out;
- if (ctx.out.len != out_len) {
- rv = error("invalid delta: incorrect postimage length");
- goto error_out;
- }
- if (write_strbuf(&ctx.out, out))
- goto error_out;
- rv = 0;
-error_out:
- window_release(&ctx);
- return rv;
-}
-
-int svndiff0_apply(struct line_buffer *delta, off_t delta_len,
- struct sliding_view *preimage, FILE *postimage)
-{
- assert(delta && preimage && postimage && delta_len >= 0);
-
- if (read_magic(delta, &delta_len))
- return -1;
- while (delta_len) { /* For each window: */
- off_t pre_off = -1;
- size_t pre_len;
-
- if (read_offset(delta, &pre_off, &delta_len) ||
- read_length(delta, &pre_len, &delta_len) ||
- move_window(preimage, pre_off, pre_len) ||
- apply_one_window(delta, &delta_len, preimage, postimage))
- return -1;
- }
- return 0;
-}
diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c
deleted file mode 100644
index 08d136b8cc..0000000000
--- a/vcs-svn/svndump.c
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
- * Parse and rearrange a svnadmin dump.
- * Create the dump with:
- * svnadmin dump --incremental -r<startrev>:<endrev> <repository> >outfile
- *
- * Licensed under a two-clause BSD-style license.
- * See LICENSE for details.
- */
-
-#include "cache.h"
-#include "fast_export.h"
-#include "line_buffer.h"
-#include "strbuf.h"
-#include "svndump.h"
-
-/*
- * Compare start of string to literal of equal length;
- * must be guarded by length test.
- */
-#define constcmp(s, ref) memcmp(s, ref, sizeof(ref) - 1)
-
-#define REPORT_FILENO 3
-
-#define NODEACT_REPLACE 4
-#define NODEACT_DELETE 3
-#define NODEACT_ADD 2
-#define NODEACT_CHANGE 1
-#define NODEACT_UNKNOWN 0
-
-/* States: */
-#define DUMP_CTX 0 /* dump metadata */
-#define REV_CTX 1 /* revision metadata */
-#define NODE_CTX 2 /* node metadata */
-#define INTERNODE_CTX 3 /* between nodes */
-
-#define DATE_RFC2822_LEN 31
-
-static struct line_buffer input = LINE_BUFFER_INIT;
-
-static struct {
- uint32_t action, srcRev, type;
- off_t prop_length, text_length;
- struct strbuf src, dst;
- uint32_t text_delta, prop_delta;
-} node_ctx;
-
-static struct {
- uint32_t revision;
- timestamp_t timestamp;
- struct strbuf log, author, note;
-} rev_ctx;
-
-static struct {
- uint32_t version;
- struct strbuf uuid, url;
-} dump_ctx;
-
-static void reset_node_ctx(char *fname)
-{
- node_ctx.type = 0;
- node_ctx.action = NODEACT_UNKNOWN;
- node_ctx.prop_length = -1;
- node_ctx.text_length = -1;
- strbuf_reset(&node_ctx.src);
- node_ctx.srcRev = 0;
- strbuf_reset(&node_ctx.dst);
- if (fname)
- strbuf_addstr(&node_ctx.dst, fname);
- node_ctx.text_delta = 0;
- node_ctx.prop_delta = 0;
-}
-
-static void reset_rev_ctx(uint32_t revision)
-{
- rev_ctx.revision = revision;
- rev_ctx.timestamp = 0;
- strbuf_reset(&rev_ctx.log);
- strbuf_reset(&rev_ctx.author);
- strbuf_reset(&rev_ctx.note);
-}
-
-static void reset_dump_ctx(const char *url)
-{
- strbuf_reset(&dump_ctx.url);
- if (url)
- strbuf_addstr(&dump_ctx.url, url);
- dump_ctx.version = 1;
- strbuf_reset(&dump_ctx.uuid);
-}
-
-static void handle_property(const struct strbuf *key_buf,
- struct strbuf *val,
- uint32_t *type_set)
-{
- const char *key = key_buf->buf;
- size_t keylen = key_buf->len;
-
- switch (keylen + 1) {
- case sizeof("svn:log"):
- if (constcmp(key, "svn:log"))
- break;
- if (!val)
- die("invalid dump: unsets svn:log");
- strbuf_swap(&rev_ctx.log, val);
- break;
- case sizeof("svn:author"):
- if (constcmp(key, "svn:author"))
- break;
- if (!val)
- strbuf_reset(&rev_ctx.author);
- else
- strbuf_swap(&rev_ctx.author, val);
- break;
- case sizeof("svn:date"):
- if (constcmp(key, "svn:date"))
- break;
- if (!val)
- die("invalid dump: unsets svn:date");
- if (parse_date_basic(val->buf, &rev_ctx.timestamp, NULL))
- warning("invalid timestamp: %s", val->buf);
- break;
- case sizeof("svn:executable"):
- case sizeof("svn:special"):
- if (keylen == strlen("svn:executable") &&
- constcmp(key, "svn:executable"))
- break;
- if (keylen == strlen("svn:special") &&
- constcmp(key, "svn:special"))
- break;
- if (*type_set) {
- if (!val)
- return;
- die("invalid dump: sets type twice");
- }
- if (!val) {
- node_ctx.type = S_IFREG | 0644;
- return;
- }
- *type_set = 1;
- node_ctx.type = keylen == strlen("svn:executable") ?
- (S_IFREG | 0755) :
- S_IFLNK;
- }
-}
-
-static void die_short_read(void)
-{
- if (buffer_ferror(&input))
- die_errno("error reading dump file");
- die("invalid dump: unexpected end of file");
-}
-
-static void read_props(void)
-{
- static struct strbuf key = STRBUF_INIT;
- static struct strbuf val = STRBUF_INIT;
- const char *t;
- /*
- * NEEDSWORK: to support simple mode changes like
- * K 11
- * svn:special
- * V 1
- * *
- * D 14
- * svn:executable
- * we keep track of whether a mode has been set and reset to
- * plain file only if not. We should be keeping track of the
- * symlink and executable bits separately instead.
- */
- uint32_t type_set = 0;
- while ((t = buffer_read_line(&input)) && strcmp(t, "PROPS-END")) {
- uint32_t len;
- const char type = t[0];
- int ch;
-
- if (!type || t[1] != ' ')
- die("invalid property line: %s", t);
- len = atoi(&t[2]);
- strbuf_reset(&val);
- buffer_read_binary(&input, &val, len);
- if (val.len < len)
- die_short_read();
-
- /* Discard trailing newline. */
- ch = buffer_read_char(&input);
- if (ch == EOF)
- die_short_read();
- if (ch != '\n')
- die("invalid dump: expected newline after %s", val.buf);
-
- switch (type) {
- case 'K':
- strbuf_swap(&key, &val);
- continue;
- case 'D':
- handle_property(&val, NULL, &type_set);
- continue;
- case 'V':
- handle_property(&key, &val, &type_set);
- strbuf_reset(&key);
- continue;
- default:
- die("invalid property line: %s", t);
- }
- }
-}
-
-static void handle_node(void)
-{
- const uint32_t type = node_ctx.type;
- const int have_props = node_ctx.prop_length != -1;
- const int have_text = node_ctx.text_length != -1;
- /*
- * Old text for this node:
- * NULL - directory or bug
- * empty_blob - empty
- * "<dataref>" - data retrievable from fast-import
- */
- static const char *const empty_blob = "::empty::";
- const char *old_data = NULL;
- uint32_t old_mode = S_IFREG | 0644;
-
- if (node_ctx.action == NODEACT_DELETE) {
- if (have_text || have_props || node_ctx.srcRev)
- die("invalid dump: deletion node has "
- "copyfrom info, text, or properties");
- fast_export_delete(node_ctx.dst.buf);
- return;
- }
- if (node_ctx.action == NODEACT_REPLACE) {
- fast_export_delete(node_ctx.dst.buf);
- node_ctx.action = NODEACT_ADD;
- }
- if (node_ctx.srcRev) {
- fast_export_copy(node_ctx.srcRev, node_ctx.src.buf, node_ctx.dst.buf);
- if (node_ctx.action == NODEACT_ADD)
- node_ctx.action = NODEACT_CHANGE;
- }
- if (have_text && type == S_IFDIR)
- die("invalid dump: directories cannot have text attached");
-
- /*
- * Find old content (old_data) and decide on the new mode.
- */
- if (node_ctx.action == NODEACT_CHANGE && !*node_ctx.dst.buf) {
- if (type != S_IFDIR)
- die("invalid dump: root of tree is not a regular file");
- old_data = NULL;
- } else if (node_ctx.action == NODEACT_CHANGE) {
- uint32_t mode;
- old_data = fast_export_read_path(node_ctx.dst.buf, &mode);
- if (mode == S_IFDIR && type != S_IFDIR)
- die("invalid dump: cannot modify a directory into a file");
- if (mode != S_IFDIR && type == S_IFDIR)
- die("invalid dump: cannot modify a file into a directory");
- node_ctx.type = mode;
- old_mode = mode;
- } else if (node_ctx.action == NODEACT_ADD) {
- if (type == S_IFDIR)
- old_data = NULL;
- else if (have_text)
- old_data = empty_blob;
- else
- die("invalid dump: adds node without text");
- } else {
- die("invalid dump: Node-path block lacks Node-action");
- }
-
- /*
- * Adjust mode to reflect properties.
- */
- if (have_props) {
- if (!node_ctx.prop_delta)
- node_ctx.type = type;
- if (node_ctx.prop_length)
- read_props();
- }
-
- /*
- * Save the result.
- */
- if (type == S_IFDIR) /* directories are not tracked. */
- return;
- assert(old_data);
- if (old_data == empty_blob)
- /* For the fast_export_* functions, NULL means empty. */
- old_data = NULL;
- if (!have_text) {
- fast_export_modify(node_ctx.dst.buf, node_ctx.type, old_data);
- return;
- }
- if (!node_ctx.text_delta) {
- fast_export_modify(node_ctx.dst.buf, node_ctx.type, "inline");
- fast_export_data(node_ctx.type, node_ctx.text_length, &input);
- return;
- }
- fast_export_modify(node_ctx.dst.buf, node_ctx.type, "inline");
- fast_export_blob_delta(node_ctx.type, old_mode, old_data,
- node_ctx.text_length, &input);
-}
-
-static void begin_revision(const char *remote_ref)
-{
- if (!rev_ctx.revision) /* revision 0 gets no git commit. */
- return;
- fast_export_begin_commit(rev_ctx.revision, rev_ctx.author.buf,
- &rev_ctx.log, dump_ctx.uuid.buf, dump_ctx.url.buf,
- rev_ctx.timestamp, remote_ref);
-}
-
-static void end_revision(const char *note_ref)
-{
- struct strbuf mark = STRBUF_INIT;
- if (rev_ctx.revision) {
- fast_export_end_commit(rev_ctx.revision);
- fast_export_begin_note(rev_ctx.revision, "remote-svn",
- "Note created by remote-svn.", rev_ctx.timestamp, note_ref);
- strbuf_addf(&mark, ":%"PRIu32, rev_ctx.revision);
- fast_export_note(mark.buf, "inline");
- fast_export_buf_to_data(&rev_ctx.note);
- strbuf_release(&mark);
- }
-}
-
-void svndump_read(const char *url, const char *local_ref, const char *notes_ref)
-{
- char *val;
- char *t;
- uint32_t active_ctx = DUMP_CTX;
- uint32_t len;
-
- reset_dump_ctx(url);
- while ((t = buffer_read_line(&input))) {
- val = strchr(t, ':');
- if (!val)
- continue;
- val++;
- if (*val != ' ')
- continue;
- val++;
-
- /* strlen(key) + 1 */
- switch (val - t - 1) {
- case sizeof("SVN-fs-dump-format-version"):
- if (constcmp(t, "SVN-fs-dump-format-version"))
- continue;
- dump_ctx.version = atoi(val);
- if (dump_ctx.version > 3)
- die("expected svn dump format version <= 3, found %"PRIu32,
- dump_ctx.version);
- break;
- case sizeof("UUID"):
- if (constcmp(t, "UUID"))
- continue;
- strbuf_reset(&dump_ctx.uuid);
- strbuf_addstr(&dump_ctx.uuid, val);
- break;
- case sizeof("Revision-number"):
- if (constcmp(t, "Revision-number"))
- continue;
- if (active_ctx == NODE_CTX)
- handle_node();
- if (active_ctx == REV_CTX)
- begin_revision(local_ref);
- if (active_ctx != DUMP_CTX)
- end_revision(notes_ref);
- active_ctx = REV_CTX;
- reset_rev_ctx(atoi(val));
- strbuf_addf(&rev_ctx.note, "%s\n", t);
- break;
- case sizeof("Node-path"):
- if (constcmp(t, "Node-"))
- continue;
- if (!constcmp(t + strlen("Node-"), "path")) {
- if (active_ctx == NODE_CTX)
- handle_node();
- if (active_ctx == REV_CTX)
- begin_revision(local_ref);
- active_ctx = NODE_CTX;
- reset_node_ctx(val);
- strbuf_addf(&rev_ctx.note, "%s\n", t);
- break;
- }
- if (constcmp(t + strlen("Node-"), "kind"))
- continue;
- strbuf_addf(&rev_ctx.note, "%s\n", t);
- if (!strcmp(val, "dir"))
- node_ctx.type = S_IFDIR;
- else if (!strcmp(val, "file"))
- node_ctx.type = S_IFREG | 0644;
- else
- fprintf(stderr, "Unknown node-kind: %s\n", val);
- break;
- case sizeof("Node-action"):
- if (constcmp(t, "Node-action"))
- continue;
- strbuf_addf(&rev_ctx.note, "%s\n", t);
- if (!strcmp(val, "delete")) {
- node_ctx.action = NODEACT_DELETE;
- } else if (!strcmp(val, "add")) {
- node_ctx.action = NODEACT_ADD;
- } else if (!strcmp(val, "change")) {
- node_ctx.action = NODEACT_CHANGE;
- } else if (!strcmp(val, "replace")) {
- node_ctx.action = NODEACT_REPLACE;
- } else {
- fprintf(stderr, "Unknown node-action: %s\n", val);
- node_ctx.action = NODEACT_UNKNOWN;
- }
- break;
- case sizeof("Node-copyfrom-path"):
- if (constcmp(t, "Node-copyfrom-path"))
- continue;
- strbuf_reset(&node_ctx.src);
- strbuf_addstr(&node_ctx.src, val);
- strbuf_addf(&rev_ctx.note, "%s\n", t);
- break;
- case sizeof("Node-copyfrom-rev"):
- if (constcmp(t, "Node-copyfrom-rev"))
- continue;
- node_ctx.srcRev = atoi(val);
- strbuf_addf(&rev_ctx.note, "%s\n", t);
- break;
- case sizeof("Text-content-length"):
- if (constcmp(t, "Text") && constcmp(t, "Prop"))
- continue;
- if (constcmp(t + 4, "-content-length"))
- continue;
- {
- char *end;
- uintmax_t len;
-
- len = strtoumax(val, &end, 10);
- if (!isdigit(*val) || *end)
- die("invalid dump: non-numeric length %s", val);
- if (len > maximum_signed_value_of_type(off_t))
- die("unrepresentable length in dump: %s", val);
-
- if (*t == 'T')
- node_ctx.text_length = (off_t) len;
- else
- node_ctx.prop_length = (off_t) len;
- break;
- }
- case sizeof("Text-delta"):
- if (!constcmp(t, "Text-delta")) {
- node_ctx.text_delta = !strcmp(val, "true");
- break;
- }
- if (constcmp(t, "Prop-delta"))
- continue;
- node_ctx.prop_delta = !strcmp(val, "true");
- break;
- case sizeof("Content-length"):
- if (constcmp(t, "Content-length"))
- continue;
- len = atoi(val);
- t = buffer_read_line(&input);
- if (!t)
- die_short_read();
- if (*t)
- die("invalid dump: expected blank line after content length header");
- if (active_ctx == REV_CTX) {
- read_props();
- } else if (active_ctx == NODE_CTX) {
- handle_node();
- active_ctx = INTERNODE_CTX;
- } else {
- fprintf(stderr, "Unexpected content length header: %"PRIu32"\n", len);
- if (buffer_skip_bytes(&input, len) != len)
- die_short_read();
- }
- }
- }
- if (buffer_ferror(&input))
- die_short_read();
- if (active_ctx == NODE_CTX)
- handle_node();
- if (active_ctx == REV_CTX)
- begin_revision(local_ref);
- if (active_ctx != DUMP_CTX)
- end_revision(notes_ref);
-}
-
-static void init(int report_fd)
-{
- fast_export_init(report_fd);
- strbuf_init(&dump_ctx.uuid, 4096);
- strbuf_init(&dump_ctx.url, 4096);
- strbuf_init(&rev_ctx.log, 4096);
- strbuf_init(&rev_ctx.author, 4096);
- strbuf_init(&rev_ctx.note, 4096);
- strbuf_init(&node_ctx.src, 4096);
- strbuf_init(&node_ctx.dst, 4096);
- reset_dump_ctx(NULL);
- reset_rev_ctx(0);
- reset_node_ctx(NULL);
- return;
-}
-
-int svndump_init(const char *filename)
-{
- if (buffer_init(&input, filename))
- return error_errno("cannot open %s", filename ? filename : "NULL");
- init(REPORT_FILENO);
- return 0;
-}
-
-int svndump_init_fd(int in_fd, int back_fd)
-{
- if(buffer_fdinit(&input, xdup(in_fd)))
- return error_errno("cannot open fd %d", in_fd);
- init(xdup(back_fd));
- return 0;
-}
-
-void svndump_deinit(void)
-{
- fast_export_deinit();
- reset_dump_ctx(NULL);
- reset_rev_ctx(0);
- reset_node_ctx(NULL);
- strbuf_release(&rev_ctx.log);
- strbuf_release(&rev_ctx.author);
- strbuf_release(&rev_ctx.note);
- strbuf_release(&node_ctx.src);
- strbuf_release(&node_ctx.dst);
- if (buffer_deinit(&input))
- fprintf(stderr, "Input error\n");
- if (ferror(stdout))
- fprintf(stderr, "Output error\n");
-}
-
-void svndump_reset(void)
-{
- strbuf_release(&dump_ctx.uuid);
- strbuf_release(&dump_ctx.url);
- strbuf_release(&rev_ctx.log);
- strbuf_release(&rev_ctx.author);
-}