MCPcopy Index your code
hub / github.com/RsyncProject/rsync / parse_merge_name

Function parse_merge_name

exclude.c:599–654  ·  view source on GitHub ↗

This returns an expanded (absolute) filename for the merge-file name if * the name has any slashes in it OR if the parent_dirscan var is True; * otherwise it returns the original merge_file name. If the len_ptr value * is non-NULL the merge_file name is limited by the referenced length * value and will be updated with the length of the resulting name. We * always return a name that is null

Source from the content-addressed store, hash-verified

597 * always return a name that is null terminated, even if the merge_file
598 * name was not. */
599static char *parse_merge_name(const char *merge_file, unsigned int *len_ptr,
600 unsigned int prefix_skip)
601{
602 static char buf[MAXPATHLEN];
603 char *fn, tmpbuf[MAXPATHLEN];
604 unsigned int fn_len;
605
606 if (!parent_dirscan && *merge_file != '/') {
607 /* Return the name unchanged it doesn't have any slashes. */
608 if (len_ptr) {
609 const char *p = merge_file + *len_ptr;
610 while (--p > merge_file && *p != '/') {}
611 if (p == merge_file) {
612 strlcpy(buf, merge_file, *len_ptr + 1);
613 return buf;
614 }
615 } else if (strchr(merge_file, '/') == NULL)
616 return (char *)merge_file;
617 }
618
619 fn = *merge_file == '/' ? buf : tmpbuf;
620 if (sanitize_paths) {
621 const char *r = prefix_skip ? "/" : NULL;
622 /* null-terminate the name if it isn't already */
623 if (len_ptr && merge_file[*len_ptr]) {
624 char *to = fn == buf ? tmpbuf : buf;
625 strlcpy(to, merge_file, *len_ptr + 1);
626 merge_file = to;
627 }
628 if (!sanitize_path(fn, merge_file, r, dirbuf_depth, SP_DEFAULT)) {
629 rprintf(FERROR, "merge-file name overflows: %s\n",
630 merge_file);
631 return NULL;
632 }
633 fn_len = strlen(fn);
634 } else {
635 strlcpy(fn, merge_file, len_ptr ? *len_ptr + 1 : MAXPATHLEN);
636 fn_len = clean_fname(fn, CFN_COLLAPSE_DOT_DOT_DIRS);
637 }
638
639 /* If the name isn't in buf yet, it wasn't absolute. */
640 if (fn != buf) {
641 int d_len = dirbuf_len - prefix_skip;
642 if (d_len + fn_len >= MAXPATHLEN) {
643 rprintf(FERROR, "merge-file name overflows: %s\n", fn);
644 return NULL;
645 }
646 memcpy(buf, dirbuf + prefix_skip, d_len);
647 memcpy(buf + d_len, fn, fn_len + 1);
648 fn_len = clean_fname(buf, CFN_COLLAPSE_DOT_DOT_DIRS);
649 }
650
651 if (len_ptr)
652 *len_ptr = fn_len;
653 return buf;
654}
655
656/* Sets the dirbuf and dirbuf_len values. */

Callers 2

setup_merge_fileFunction · 0.85
parse_filter_strFunction · 0.85

Calls 4

strlcpyFunction · 0.85
sanitize_pathFunction · 0.85
clean_fnameFunction · 0.85
rprintfFunction · 0.70

Tested by

no test coverage detected