91
91
different purpose instead: at apply-textdelta time, we set it to a
92
92
subpool of the file pool, which is destroyed in textdelta-end. */
93
93
typedef struct ra_svn_token_entry_t {
96
96
svn_boolean_t is_file;
97
97
svn_stream_t *dstream; /* svndiff stream for apply_textdelta */
135
136
eb->conn->may_check_for_error = eb->conn->error_check_interval == 0;
137
138
/* any incoming data? */
138
if (svn_ra_svn__input_waiting(eb->conn, pool))
139
SVN_ERR(svn_ra_svn__data_available(eb->conn, &available));
140
142
eb->got_status = TRUE;
141
143
SVN_ERR(svn_ra_svn__write_cmd_abort_edit(eb->conn, pool));
393
395
SVN_ERR_ASSERT(!eb->got_status);
394
396
eb->got_status = TRUE;
395
397
SVN_ERR(svn_ra_svn__write_cmd_close_edit(eb->conn, pool));
396
err = svn_ra_svn__read_cmd_response(eb->conn, pool, "");
398
err = svn_error_trace(svn_ra_svn__read_cmd_response(eb->conn, pool, ""));
399
svn_error_clear(svn_ra_svn__write_cmd_abort_edit(eb->conn, pool));
401
return svn_error_compose_create(
404
svn_ra_svn__write_cmd_abort_edit(eb->conn, pool)));
402
406
if (eb->callback)
403
407
SVN_ERR(eb->callback(eb->callback_baton));
462
466
/* Store a token entry. The token string will be copied into pool. */
463
467
static ra_svn_token_entry_t *store_token(ra_svn_driver_state_t *ds,
464
void *baton, const char *token,
465
470
svn_boolean_t is_file,
466
471
apr_pool_t *pool)
468
473
ra_svn_token_entry_t *entry;
470
475
entry = apr_palloc(pool, sizeof(*entry));
471
entry->token = apr_pstrdup(pool, token);
476
entry->token = svn_string_dup(token, pool);
472
477
entry->baton = baton;
473
478
entry->is_file = is_file;
474
479
entry->dstream = NULL;
475
480
entry->pool = pool;
476
svn_hash_sets(ds->tokens, entry->token, entry);
482
apr_hash_set(ds->tokens, entry->token->data, entry->token->len, entry);
480
static svn_error_t *lookup_token(ra_svn_driver_state_t *ds, const char *token,
487
static svn_error_t *lookup_token(ra_svn_driver_state_t *ds,
481
489
svn_boolean_t is_file,
482
490
ra_svn_token_entry_t **entry)
484
*entry = svn_hash_gets(ds->tokens, token);
492
*entry = apr_hash_get(ds->tokens, token->data, token->len);
485
493
if (!*entry || (*entry)->is_file != is_file)
486
494
return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
487
495
_("Invalid file or dir token during edit"));
508
516
svn_revnum_t rev;
509
517
apr_pool_t *subpool;
511
519
void *root_baton;
513
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "(?r)c", &rev, &token));
521
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "(?r)s", &rev, &token));
514
522
subpool = svn_pool_create(ds->pool);
515
523
SVN_CMD_ERR(ds->editor->open_root(ds->edit_baton, rev, subpool,
523
531
const apr_array_header_t *params,
524
532
ra_svn_driver_state_t *ds)
526
const char *path, *token;
527
536
svn_revnum_t rev;
528
537
ra_svn_token_entry_t *entry;
530
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c(?r)c",
539
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c(?r)s",
531
540
&path, &rev, &token));
532
541
SVN_ERR(lookup_token(ds, token, FALSE, &entry));
533
542
path = svn_relpath_canonicalize(path, pool);
540
549
const apr_array_header_t *params,
541
550
ra_svn_driver_state_t *ds)
543
const char *path, *token, *child_token, *copy_path;
552
const char *path, *copy_path;
553
svn_string_t *token, *child_token;
544
554
svn_revnum_t copy_rev;
545
555
ra_svn_token_entry_t *entry;
546
556
apr_pool_t *subpool;
547
557
void *child_baton;
549
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "ccc(?cr)", &path, &token,
559
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "css(?cr)", &path, &token,
550
560
&child_token, ©_path, ©_rev));
551
561
SVN_ERR(lookup_token(ds, token, FALSE, &entry));
552
562
subpool = svn_pool_create(entry->pool);
573
583
const apr_array_header_t *params,
574
584
ra_svn_driver_state_t *ds)
576
const char *path, *token, *child_token;
587
svn_string_t *token, *child_token;
577
588
svn_revnum_t rev;
578
589
ra_svn_token_entry_t *entry;
579
590
apr_pool_t *subpool;
580
591
void *child_baton;
582
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "ccc(?r)", &path, &token,
593
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "css(?r)", &path, &token,
583
594
&child_token, &rev));
584
595
SVN_ERR(lookup_token(ds, token, FALSE, &entry));
585
596
subpool = svn_pool_create(entry->pool);
595
606
const apr_array_header_t *params,
596
607
ra_svn_driver_state_t *ds)
598
const char *token, *name;
599
611
svn_string_t *value;
600
612
ra_svn_token_entry_t *entry;
602
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "cc(?s)", &token, &name,
614
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "sc(?s)", &token, &name,
604
616
SVN_ERR(lookup_token(ds, token, FALSE, &entry));
605
617
SVN_CMD_ERR(ds->editor->change_dir_prop(entry->baton, name, value,
612
624
const apr_array_header_t *params,
613
625
ra_svn_driver_state_t *ds)
616
628
ra_svn_token_entry_t *entry;
618
630
/* Parse and look up the directory token. */
619
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c", &token));
631
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "s", &token));
620
632
SVN_ERR(lookup_token(ds, token, FALSE, &entry));
622
634
/* Close the directory and destroy the baton. */
623
635
SVN_CMD_ERR(ds->editor->close_directory(entry->baton, pool));
624
svn_hash_sets(ds->tokens, token, NULL);
636
apr_hash_set(ds->tokens, token->data, token->len, NULL);
625
637
svn_pool_destroy(entry->pool);
626
638
return SVN_NO_ERROR;
632
644
ra_svn_driver_state_t *ds)
634
646
const char *path;
636
648
ra_svn_token_entry_t *entry;
638
650
/* Parse parameters and look up the directory token. */
639
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "cc", &path, &token));
651
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "cs", &path, &token));
640
652
SVN_ERR(lookup_token(ds, token, FALSE, &entry));
642
654
/* Call the editor. */
649
661
const apr_array_header_t *params,
650
662
ra_svn_driver_state_t *ds)
652
const char *path, *token, *file_token, *copy_path;
664
const char *path, *copy_path;
665
svn_string_t *token, *file_token;
653
666
svn_revnum_t copy_rev;
654
667
ra_svn_token_entry_t *entry, *file_entry;
656
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "ccc(?cr)", &path, &token,
669
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "css(?cr)", &path, &token,
657
670
&file_token, ©_path, ©_rev));
658
671
SVN_ERR(lookup_token(ds, token, FALSE, &entry));
660
path = svn_relpath_canonicalize(path, pool);
674
/* The PATH should be canonical .. but never trust incoming data. */
675
if (!svn_relpath_is_canonical(path))
676
path = svn_relpath_canonicalize(path, pool);
662
678
/* Some operations pass COPY_PATH as a full URL (commits, etc.).
663
679
Others (replay, e.g.) deliver an fspath. That's ... annoying. */
680
696
const apr_array_header_t *params,
681
697
ra_svn_driver_state_t *ds)
683
const char *path, *token, *file_token;
700
svn_string_t *token, *file_token;
684
701
svn_revnum_t rev;
685
702
ra_svn_token_entry_t *entry, *file_entry;
687
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "ccc(?r)", &path, &token,
704
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "css(?r)", &path, &token,
688
705
&file_token, &rev));
689
706
SVN_ERR(lookup_token(ds, token, FALSE, &entry));
691
path = svn_relpath_canonicalize(path, pool);
709
/* The PATH should be canonical .. but never trust incoming data. */
710
if (!svn_relpath_is_canonical(path))
711
path = svn_relpath_canonicalize(path, pool);
692
713
file_entry = store_token(ds, NULL, file_token, TRUE, ds->file_pool);
693
714
SVN_CMD_ERR(ds->editor->open_file(path, entry->baton, rev, ds->file_pool,
694
715
&file_entry->baton));
700
721
const apr_array_header_t *params,
701
722
ra_svn_driver_state_t *ds)
704
725
ra_svn_token_entry_t *entry;
705
726
svn_txdelta_window_handler_t wh;
707
728
char *base_checksum;
709
730
/* Parse arguments and look up the token. */
710
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c(?c)",
731
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "s(?c)",
711
732
&token, &base_checksum));
712
733
SVN_ERR(lookup_token(ds, token, TRUE, &entry));
713
734
if (entry->dstream)
725
746
const apr_array_header_t *params,
726
747
ra_svn_driver_state_t *ds)
729
750
ra_svn_token_entry_t *entry;
730
751
svn_string_t *str;
732
753
/* Parse arguments and look up the token. */
733
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "cs", &token, &str));
754
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "ss", &token, &str));
734
755
SVN_ERR(lookup_token(ds, token, TRUE, &entry));
735
756
if (!entry->dstream)
736
757
return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
744
765
const apr_array_header_t *params,
745
766
ra_svn_driver_state_t *ds)
748
769
ra_svn_token_entry_t *entry;
750
771
/* Parse arguments and look up the token. */
751
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c", &token));
772
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "s", &token));
752
773
SVN_ERR(lookup_token(ds, token, TRUE, &entry));
753
774
if (!entry->dstream)
754
775
return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
764
785
const apr_array_header_t *params,
765
786
ra_svn_driver_state_t *ds)
767
const char *token, *name;
789
svn_string_t *token, *value;
769
790
ra_svn_token_entry_t *entry;
771
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "cc(?s)", &token, &name,
792
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "sc(?s)", &token, &name,
773
794
SVN_ERR(lookup_token(ds, token, TRUE, &entry));
774
795
SVN_CMD_ERR(ds->editor->change_file_prop(entry->baton, name, value, pool));
780
801
const apr_array_header_t *params,
781
802
ra_svn_driver_state_t *ds)
784
805
ra_svn_token_entry_t *entry;
785
806
const char *text_checksum;
787
808
/* Parse arguments and look up the file token. */
788
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c(?c)",
809
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "s(?c)",
789
810
&token, &text_checksum));
790
811
SVN_ERR(lookup_token(ds, token, TRUE, &entry));
792
813
/* Close the file and destroy the baton. */
793
814
SVN_CMD_ERR(ds->editor->close_file(entry->baton, text_checksum, pool));
794
svn_hash_sets(ds->tokens, token, NULL);
815
apr_hash_set(ds->tokens, token->data, token->len, NULL);
795
816
if (--ds->file_refs == 0)
796
817
svn_pool_clear(ds->file_pool);
797
818
return SVN_NO_ERROR;
803
824
ra_svn_driver_state_t *ds)
805
826
const char *path;
807
828
ra_svn_token_entry_t *entry;
809
830
/* Parse parameters and look up the parent directory token. */
810
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "cc", &path, &token));
831
SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "cs", &path, &token));
811
832
SVN_ERR(lookup_token(ds, token, FALSE, &entry));
813
834
/* Call the editor. */
979
1000
/* Abort the edit and use non-blocking I/O to write the error. */
981
svn_error_clear(editor->abort_edit(edit_baton, subpool));
1003
err = svn_error_compose_create(
1005
svn_error_trace(editor->abort_edit(edit_baton,
982
1008
svn_ra_svn__set_block_handler(conn, blocked_write, &state);
984
1010
write_err = svn_ra_svn__write_cmd_failure(
988
1014
write_err = svn_ra_svn__flush(conn, subpool);
989
1015
svn_ra_svn__set_block_handler(conn, NULL, NULL);
990
svn_error_clear(err);
1016
svn_error_clear(err); /* We just sent this error */
991
1017
SVN_ERR(write_err);