static int buffer_want_with_caps(const git_remote_head *head, transport_smart_caps *caps, git_buf *buf) { git_buf str = GIT_BUF_INIT; char oid[GIT_OID_HEXSZ +1] = {0}; unsigned int len; /* Prefer side-band-64k if the server supports both */ if (caps->side_band) { if (caps->side_band_64k) git_buf_printf(&str, "%s ", GIT_CAP_SIDE_BAND_64K); else git_buf_printf(&str, "%s ", GIT_CAP_SIDE_BAND); } if (caps->ofs_delta) git_buf_puts(&str, GIT_CAP_OFS_DELTA " "); if (caps->multi_ack) git_buf_puts(&str, GIT_CAP_MULTI_ACK " "); if (caps->include_tag) git_buf_puts(&str, GIT_CAP_INCLUDE_TAG " "); if (git_buf_oom(&str)) return -1; len = (unsigned int) (strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ + git_buf_len(&str) + 1 /* LF */); git_buf_grow(buf, git_buf_len(buf) + len); git_oid_fmt(oid, &head->oid); git_buf_printf(buf, "%04xwant %s %s\n", len, oid, git_buf_cstr(&str)); git_buf_free(&str); return git_buf_oom(buf); }
static int buffer_want_with_caps(git_remote_head *head, git_transport_caps *caps, git_buf *buf) { git_buf str = GIT_BUF_INIT; char oid[GIT_OID_HEXSZ +1] = {0}; unsigned int len; if (caps->ofs_delta) git_buf_puts(&str, GIT_CAP_OFS_DELTA " "); if (caps->multi_ack) git_buf_puts(&str, GIT_CAP_MULTI_ACK " "); if (git_buf_oom(&str)) return -1; len = (unsigned int) (strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ + git_buf_len(&str) + 1 /* LF */); git_buf_grow(buf, git_buf_len(buf) + len); git_oid_fmt(oid, &head->oid); git_buf_printf(buf, "%04xwant %s %s\n", len, oid, git_buf_cstr(&str)); git_buf_free(&str); return git_buf_oom(buf); }
static int on_body_parse_response(http_parser *parser, const char *str, size_t len) { transport_http *t = (transport_http *) parser->data; git_buf *buf = &t->buf; git_vector *common = &t->common; int error; const char *line_end, *ptr; if (len == 0) { /* EOF */ if (git_buf_len(buf) != 0) { giterr_set(GITERR_NET, "Unexpected EOF"); return t->error = -1; } else { return 0; } } git_buf_put(buf, str, len); ptr = buf->ptr; while (1) { git_pkt *pkt; if (git_buf_len(buf) == 0) return 0; error = git_pkt_parse_line(&pkt, ptr, &line_end, git_buf_len(buf)); if (error == GIT_EBUFS) { return 0; /* Ask for more */ } if (error < 0) return t->error = -1; git_buf_consume(buf, line_end); if (pkt->type == GIT_PKT_PACK) { git__free(pkt); t->pack_ready = 1; return 0; } if (pkt->type == GIT_PKT_NAK) { git__free(pkt); return 0; } if (pkt->type != GIT_PKT_ACK) { git__free(pkt); continue; } if (git_vector_insert(common, pkt) < 0) return -1; } return error; }
int git_path_to_dir(git_buf *path) { if (path->asize > 0 && git_buf_len(path) > 0 && path->ptr[git_buf_len(path) - 1] != '/') git_buf_putc(path, '/'); return git_buf_oom(path) ? -1 : 0; }
int dircount(void *payload, git_buf *pathbuf) { int *entries = payload; size_t len = git_buf_len(pathbuf); if (len < 5 || strcmp(pathbuf->ptr + (git_buf_len(pathbuf) - 5), "/.git") != 0) (*entries)++; return 0; }
/** * Create credential object from S4 class 'cred_env'. * * @param cred The newly created credential object. * @param allowed_types A bitmask stating which cred types are OK to return. * @param credentials The S4 class object with credentials. * @return 0 on success, else -1. */ static int git2r_cred_env( git_cred **cred, unsigned int allowed_types, SEXP credentials) { if (GIT_CREDTYPE_USERPASS_PLAINTEXT & allowed_types) { int err; git_buf username = GIT_BUF_INIT; git_buf password = GIT_BUF_INIT; /* Read value of the username environment variable */ err = git__getenv(&username, CHAR(STRING_ELT( GET_SLOT(credentials, Rf_install("username")), 0))); if (err) goto cleanup; if (!git_buf_len(&username)) { err = -1; goto cleanup; } /* Read value of the password environment variable */ err = git__getenv(&password, CHAR(STRING_ELT( GET_SLOT(credentials, Rf_install("password")), 0))); if (err) goto cleanup; if (!git_buf_len(&password)) { err = -1; goto cleanup; } err = git_cred_userpass_plaintext_new( cred, git_buf_cstr(&username), git_buf_cstr(&password)); cleanup: git_buf_free(&username); git_buf_free(&password); if (err) return -1; return 0; } return -1; }
int git_path_walk_up( git_buf *path, const char *ceiling, int (*cb)(void *data, git_buf *), void *data) { int error = 0; git_buf iter; ssize_t stop = 0, scan; char oldc = '\0'; assert(path && cb); if (ceiling != NULL) { if (git__prefixcmp(path->ptr, ceiling) == 0) stop = (ssize_t)strlen(ceiling); else stop = git_buf_len(path); } scan = git_buf_len(path); iter.ptr = path->ptr; iter.size = git_buf_len(path); iter.asize = path->asize; while (scan >= stop) { error = cb(data, &iter); iter.ptr[scan] = oldc; if (error) { giterr_set_after_callback(error); break; } scan = git_buf_rfind_next(&iter, '/'); if (scan >= 0) { scan++; oldc = iter.ptr[scan]; iter.size = scan; iter.ptr[scan] = '\0'; } } if (scan >= 0) iter.ptr[scan] = oldc; return error; }
static int buffer_to_file( git_buf *buffer, const char *path, mode_t dir_mode, int file_open_flags, mode_t file_mode) { int fd, error, error_close; if ((error = git_futils_mkpath2file(path, dir_mode)) < 0) return error; if ((fd = p_open(path, file_open_flags, file_mode)) < 0) return fd; error = p_write(fd, git_buf_cstr(buffer), git_buf_len(buffer)); error_close = p_close(fd); if (!error) error = error_close; if (!error && (file_mode & 0100) != 0 && (error = p_chmod(path, file_mode)) < 0) giterr_set(GITERR_OS, "Failed to set permissions on '%s'", path); return error; }
static int prepare_worktree_commit_message( git_buf* msg, const char *user_message) { git_buf buf = GIT_BUF_INIT; int error; if ((error = git_buf_set(&buf, git_buf_cstr(msg), git_buf_len(msg))) < 0) return error; git_buf_clear(msg); if (!user_message) git_buf_printf(msg, "WIP on %s", git_buf_cstr(&buf)); else { const char *colon; if ((colon = strchr(git_buf_cstr(&buf), ':')) == NULL) goto cleanup; git_buf_puts(msg, "On "); git_buf_put(msg, git_buf_cstr(&buf), colon - buf.ptr); git_buf_printf(msg, ": %s\n", user_message); } error = (git_buf_oom(msg) || git_buf_oom(&buf)) ? -1 : 0; cleanup: git_buf_free(&buf); return error; }
static int diff_print_patch_line( const git_diff_delta *delta, const git_diff_range *range, char line_origin, /* GIT_DIFF_LINE value from above */ const char *content, size_t content_len, void *data) { diff_print_info *pi = data; if (S_ISDIR(delta->new_file.mode)) return 0; git_buf_clear(pi->buf); if (line_origin == GIT_DIFF_LINE_ADDITION || line_origin == GIT_DIFF_LINE_DELETION || line_origin == GIT_DIFF_LINE_CONTEXT) git_buf_printf(pi->buf, "%c%.*s", line_origin, (int)content_len, content); else if (content_len > 0) git_buf_printf(pi->buf, "%.*s", (int)content_len, content); if (git_buf_oom(pi->buf)) return -1; if (pi->print_cb(delta, range, line_origin, git_buf_cstr(pi->buf), git_buf_len(pi->buf), pi->payload)) return callback_error(); return 0; }
static int futils__rmdir_empty_parent(void *opaque, git_buf *path) { futils__rmdir_data *data = opaque; int error; if (git_buf_len(path) <= data->baselen) return GIT_ITEROVER; error = p_rmdir(git_buf_cstr(path)); if (error) { int en = errno; if (en == ENOENT || en == ENOTDIR) { giterr_clear(); error = 0; } else if (en == ENOTEMPTY || en == EEXIST || en == EBUSY) { giterr_clear(); error = GIT_ITEROVER; } else { futils__error_cannot_rmdir(git_buf_cstr(path), NULL); } } return error; }
const char *cl_git_sandbox_path(int is_dir, ...) { const char *path = NULL; static char _temp[GIT_PATH_MAX]; git_buf buf = GIT_BUF_INIT; va_list arg; cl_git_pass(git_buf_sets(&buf, clar_sandbox_path())); va_start(arg, is_dir); while ((path = va_arg(arg, const char *)) != NULL) { cl_git_pass(git_buf_joinpath(&buf, buf.ptr, path)); } va_end(arg); cl_git_pass(git_path_prettify(&buf, buf.ptr, NULL)); if (is_dir) git_path_to_dir(&buf); /* make sure we won't truncate */ cl_assert(git_buf_len(&buf) < sizeof(_temp)); git_buf_copy_cstr(_temp, sizeof(_temp), &buf); git_buf_dispose(&buf); return _temp; }
/* * Read the contents of `file_path` and set `path_out` to the repo dir that * it points to. Before calling, set `path_out` to the base directory that * should be used if the contents of `file_path` are a relative path. */ static int read_gitfile(git_buf *path_out, const char *file_path) { int error = 0; git_buf file = GIT_BUF_INIT; size_t prefix_len = strlen(GIT_FILE_CONTENT_PREFIX); assert(path_out && file_path); if (git_futils_readbuffer(&file, file_path) < 0) return -1; git_buf_rtrim(&file); /* apparently on Windows, some people use backslashes in paths */ git_path_mkposix(file.ptr); if (git_buf_len(&file) <= prefix_len || memcmp(git_buf_cstr(&file), GIT_FILE_CONTENT_PREFIX, prefix_len) != 0) { giterr_set(GITERR_REPOSITORY, "The `.git` file at '%s' is malformed", file_path); error = -1; } else if ((error = git_path_dirname_r(path_out, file_path)) >= 0) { const char *gitlink = git_buf_cstr(&file) + prefix_len; while (*gitlink && git__isspace(*gitlink)) gitlink++; error = git_path_prettify_dir( path_out, gitlink, git_buf_cstr(path_out)); } git_buf_free(&file); return error; }
static int packfile_load__cb(void *data, git_buf *path) { struct pack_backend *backend = (pack_backend*) data; struct git_pack_file *pack; const char *path_str = git_buf_cstr(path); size_t i, cmp_len = git_buf_len(path); int error; if (cmp_len <= strlen(".idx") || git__suffixcmp(path_str, ".idx") != 0) return 0; /* not an index */ cmp_len -= strlen(".idx"); for (i = 0; i < backend->packs.length; ++i) { struct git_pack_file *p = (git_pack_file*) git_vector_get(&backend->packs, i); if (memcmp(p->pack_name, path_str, cmp_len) == 0) return 0; } error = git_mwindow_get_pack(&pack, path->ptr); /* ignore missing .pack file as git does */ if (error == GIT_ENOTFOUND) { giterr_clear(); return 0; } if (!error) error = git_vector_insert(&backend->packs, pack); return error; }
static bool _check_dir_contents( git_buf *dir, const char *sub, bool (*predicate)(const char *)) { bool result; size_t dir_size = git_buf_len(dir); size_t sub_size = strlen(sub); size_t alloc_size; /* leave base valid even if we could not make space for subdir */ if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, dir_size, sub_size) || GIT_ADD_SIZET_OVERFLOW(&alloc_size, alloc_size, 2) || git_buf_try_grow(dir, alloc_size, false, false) < 0) return false; /* save excursion */ git_buf_joinpath(dir, dir->ptr, sub); result = predicate(dir->ptr); /* restore path */ git_buf_truncate(dir, dir_size); return result; }
static void setProcessError(DWORD exitCode, git_buf *errBuf) { if (!git_buf_oom(errBuf) && git_buf_len(errBuf)) giterr_set(GITERR_FILTER, "External filter application exited non-zero (%ld) and reported:\n%s", exitCode, errBuf->ptr); else giterr_set(GITERR_FILTER, "External filter application exited non-zero: %ld", exitCode); }
int git_futils_writebuffer( const git_buf *buf, const char *path, int flags, mode_t mode) { int fd, error = 0; if (flags <= 0) flags = O_CREAT | O_TRUNC | O_WRONLY; if (!mode) mode = GIT_FILEMODE_BLOB; if ((fd = p_open(path, flags, mode)) < 0) { giterr_set(GITERR_OS, "Could not open '%s' for writing", path); return fd; } if ((error = p_write(fd, git_buf_cstr(buf), git_buf_len(buf))) < 0) { giterr_set(GITERR_OS, "Could not write to '%s'", path); (void)p_close(fd); return error; } if ((error = p_close(fd)) < 0) giterr_set(GITERR_OS, "Error while closing '%s'", path); return error; }
size_t git_patch_size( git_patch *patch, int include_context, int include_hunk_headers, int include_file_headers) { size_t out; assert(patch); out = patch->content_size; if (!include_context) out -= patch->context_size; if (include_hunk_headers) out += patch->header_size; if (include_file_headers) { git_buf file_header = GIT_BUF_INIT; if (git_diff_delta__format_file_header( &file_header, patch->delta, NULL, NULL, 0) < 0) giterr_clear(); else out += git_buf_len(&file_header); git_buf_free(&file_header); } return out; }
int git_reference_normalize_name( char *buffer_out, size_t buffer_size, const char *name, unsigned int flags) { git_buf buf = GIT_BUF_INIT; int error; if ((error = git_reference__normalize_name(&buf, name, flags)) < 0) goto cleanup; if (git_buf_len(&buf) > buffer_size - 1) { giterr_set( GITERR_REFERENCE, "The provided buffer is too short to hold the normalization of '%s'", name); error = GIT_EBUFS; goto cleanup; } git_buf_copy_cstr(buffer_out, buffer_size, &buf); error = 0; cleanup: git_buf_free(&buf); return error; }
static int loose_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb cb, void *data) { char *objects_dir; int error; git_buf buf = GIT_BUF_INIT; struct foreach_state state; loose_backend *backend = (loose_backend *) _backend; assert(backend && cb); objects_dir = backend->objects_dir; git_buf_sets(&buf, objects_dir); git_path_to_dir(&buf); if (git_buf_oom(&buf)) return -1; memset(&state, 0, sizeof(state)); state.cb = cb; state.data = data; state.dir_len = git_buf_len(&buf); error = git_path_direach(&buf, 0, foreach_cb, &state); git_buf_dispose(&buf); return error; }
/* Explore an entry of a directory and see if it matches a short oid */ static int fn_locate_object_short_oid(void *state, git_buf *pathbuf) { loose_locate_object_state *sstate = (loose_locate_object_state *)state; if (git_buf_len(pathbuf) - sstate->dir_len != GIT_OID_HEXSZ - 2) { /* Entry cannot be an object. Continue to next entry */ return 0; } if (git_path_isdir(pathbuf->ptr) == false) { /* We are already in the directory matching the 2 first hex characters, * compare the first ncmp characters of the oids */ if (!memcmp(sstate->short_oid + 2, (unsigned char *)pathbuf->ptr + sstate->dir_len, sstate->short_oid_len - 2)) { if (!sstate->found) { sstate->res_oid[0] = sstate->short_oid[0]; sstate->res_oid[1] = sstate->short_oid[1]; memcpy(sstate->res_oid+2, pathbuf->ptr+sstate->dir_len, GIT_OID_HEXSZ-2); } sstate->found++; } } if (sstate->found > 1) return GIT_EAMBIGUOUS; return 0; }
static int diff_file_content_load_workdir_file( git_diff_file_content *fc, git_buf *path) { int error = 0; git_vector filters = GIT_VECTOR_INIT; git_buf raw = GIT_BUF_INIT, filtered = GIT_BUF_INIT; git_file fd = git_futils_open_ro(git_buf_cstr(path)); if (fd < 0) return fd; if (!fc->file->size && !(fc->file->size = git_futils_filesize(fd))) goto cleanup; if (diff_file_content_binary_by_size(fc)) goto cleanup; if ((error = git_filters_load( &filters, fc->repo, fc->file->path, GIT_FILTER_TO_ODB)) < 0) goto cleanup; /* error >= is a filter count */ if (error == 0) { if (!(error = git_futils_mmap_ro( &fc->map, fd, 0, (size_t)fc->file->size))) fc->flags |= GIT_DIFF_FLAG__UNMAP_DATA; else /* fall through to try readbuffer below */ giterr_clear(); } if (error != 0) { error = git_futils_readbuffer_fd(&raw, fd, (size_t)fc->file->size); if (error < 0) goto cleanup; if (!filters.length) git_buf_swap(&filtered, &raw); else error = git_filters_apply(&filtered, &raw, &filters); if (!error) { fc->map.len = git_buf_len(&filtered); fc->map.data = git_buf_detach(&filtered); fc->flags |= GIT_DIFF_FLAG__FREE_DATA; } git_buf_free(&raw); git_buf_free(&filtered); } cleanup: git_filters_free(&filters); p_close(fd); return error; }
int git_repository_fetchhead_foreach(git_repository *repo, git_repository_fetchhead_foreach_cb cb, void *payload) { git_buf path = GIT_BUF_INIT, file = GIT_BUF_INIT, name = GIT_BUF_INIT; const char *ref_name; git_oid oid; const char *remote_url; unsigned int is_merge = 0; char *buffer, *line; size_t line_num = 0; int error = 0; assert(repo && cb); if (git_buf_joinpath(&path, repo->path_repository, GIT_FETCH_HEAD_FILE) < 0) return -1; if ((error = git_futils_readbuffer(&file, git_buf_cstr(&path))) < 0) goto done; buffer = file.ptr; while ((line = git__strsep(&buffer, "\n")) != NULL) { ++line_num; if ((error = fetchhead_ref_parse( &oid, &is_merge, &name, &remote_url, line, line_num)) < 0) goto done; if (git_buf_len(&name) > 0) ref_name = git_buf_cstr(&name); else ref_name = NULL; error = cb(ref_name, remote_url, &oid, is_merge, payload); if (error) { giterr_set_after_callback(error); goto done; } } if (*buffer) { giterr_set(GITERR_FETCHHEAD, "No EOL at line %"PRIuZ, line_num+1); error = -1; goto done; } done: git_buf_free(&file); git_buf_free(&path); git_buf_free(&name); return error; }
static int process_entry_path( const char* entry_path, const git_oid *note_oid, int (*note_cb)(git_note_data *note_data, void *payload), void *payload) { int error = -1; size_t i = 0, j = 0, len; git_buf buf = GIT_BUF_INIT; git_note_data note_data; if ((error = git_buf_puts(&buf, entry_path)) < 0) goto cleanup; len = git_buf_len(&buf); while (i < len) { if (buf.ptr[i] == '/') { i++; continue; } if (git__fromhex(buf.ptr[i]) < 0) { /* This is not a note entry */ goto cleanup; } if (i != j) buf.ptr[j] = buf.ptr[i]; i++; j++; } buf.ptr[j] = '\0'; buf.size = j; if (j != GIT_OID_HEXSZ) { /* This is not a note entry */ goto cleanup; } if ((error = git_oid_fromstr( ¬e_data.annotated_object_oid, buf.ptr)) < 0) goto cleanup; git_oid_cpy(¬e_data.blob_oid, note_oid); if (note_cb(¬e_data, payload)) error = GIT_EUSER; cleanup: git_buf_free(&buf); return error; }
int git_branch_upstream__name( git_buf *tracking_name, git_repository *repo, const char *canonical_branch_name) { const char *remote_name, *merge_name; git_buf buf = GIT_BUF_INIT; int error = -1; git_remote *remote = NULL; const git_refspec *refspec; assert(tracking_name && canonical_branch_name); if (!git_reference__is_branch(canonical_branch_name)) return not_a_local_branch(canonical_branch_name); if ((error = retrieve_upstream_configuration( &remote_name, repo, canonical_branch_name, "branch.%s.remote")) < 0) goto cleanup; if ((error = retrieve_upstream_configuration( &merge_name, repo, canonical_branch_name, "branch.%s.merge")) < 0) goto cleanup; if (!*remote_name || !*merge_name) { giterr_set(GITERR_REFERENCE, "branch '%s' does not have an upstream", canonical_branch_name); error = GIT_ENOTFOUND; goto cleanup; } if (strcmp(".", remote_name) != 0) { if ((error = git_remote_load(&remote, repo, remote_name)) < 0) goto cleanup; refspec = git_remote__matching_refspec(remote, merge_name); if (!refspec) { error = GIT_ENOTFOUND; goto cleanup; } if (git_refspec_transform_r(&buf, refspec, merge_name) < 0) goto cleanup; } else if (git_buf_sets(&buf, merge_name) < 0) goto cleanup; error = git_buf_set(tracking_name, git_buf_cstr(&buf), git_buf_len(&buf)); cleanup: git_remote_free(remote); git_buf_free(&buf); return error; }
static void expect_unquote_pass(const char *expected, const char *quoted) { git_buf buf = GIT_BUF_INIT; cl_git_pass(git_buf_puts(&buf, quoted)); cl_git_pass(git_buf_unquote(&buf)); cl_assert_equal_s(expected, git_buf_cstr(&buf)); cl_assert_equal_i(strlen(expected), git_buf_len(&buf)); git_buf_dispose(&buf); }
void test_pack_indexer__no_tmp_files(void) { git_indexer *idx = NULL; git_buf path = GIT_BUF_INIT; git_buf first_tmp_file = GIT_BUF_INIT; /* Precondition: there are no temporary files. */ cl_git_pass(git_buf_sets(&path, clar_sandbox_path())); cl_git_pass(find_tmp_file_recurs(&first_tmp_file, &path)); git_buf_free(&path); cl_assert(git_buf_len(&first_tmp_file) == 0); cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL, NULL)); git_indexer_free(idx); cl_git_pass(git_buf_sets(&path, clar_sandbox_path())); cl_git_pass(find_tmp_file_recurs(&first_tmp_file, &path)); git_buf_free(&path); cl_assert(git_buf_len(&first_tmp_file) == 0); git_buf_free(&first_tmp_file); }
static int diff_file_content_commit_to_str( git_diff_file_content *fc, bool check_status) { char oid[GIT_OID_HEXSZ+1]; git_buf content = GIT_BUF_INIT; const char *status = ""; if (check_status) { int error = 0; git_submodule *sm = NULL; unsigned int sm_status = 0; const git_oid *sm_head; if ((error = git_submodule_lookup(&sm, fc->repo, fc->file->path)) < 0) { /* GIT_EEXISTS means a "submodule" that has not been git added */ if (error == GIT_EEXISTS) { giterr_clear(); error = 0; } return error; } if ((error = git_submodule_status(&sm_status, fc->repo, fc->file->path, GIT_SUBMODULE_IGNORE_UNSPECIFIED)) < 0) { git_submodule_free(sm); return error; } /* update OID if we didn't have it previously */ if ((fc->file->flags & GIT_DIFF_FLAG_VALID_ID) == 0 && ((sm_head = git_submodule_wd_id(sm)) != NULL || (sm_head = git_submodule_head_id(sm)) != NULL)) { git_oid_cpy(&fc->file->id, sm_head); fc->file->flags |= GIT_DIFF_FLAG_VALID_ID; } if (GIT_SUBMODULE_STATUS_IS_WD_DIRTY(sm_status)) status = "-dirty"; git_submodule_free(sm); } git_oid_tostr(oid, sizeof(oid), &fc->file->id); if (git_buf_printf(&content, "Subproject commit %s%s\n", oid, status) < 0) return -1; fc->map.len = git_buf_len(&content); fc->map.data = git_buf_detach(&content); fc->flags |= GIT_DIFF_FLAG__FREE_DATA; return 0; }
int git_path_direach( git_buf *path, int (*fn)(void *, git_buf *), void *arg) { ssize_t wd_len; DIR *dir; struct dirent *de, *de_buf; if (git_path_to_dir(path) < 0) return -1; wd_len = git_buf_len(path); if ((dir = opendir(path->ptr)) == NULL) { giterr_set(GITERR_OS, "Failed to open directory '%s'", path->ptr); return -1; } #ifdef __sun de_buf = git__malloc(sizeof(struct dirent) + FILENAME_MAX + 1); #else de_buf = git__malloc(sizeof(struct dirent)); #endif while (p_readdir_r(dir, de_buf, &de) == 0 && de != NULL) { int result; if (is_dot_or_dotdot(de->d_name)) continue; if (git_buf_puts(path, de->d_name) < 0) { closedir(dir); git__free(de_buf); return -1; } result = fn(arg, path); git_buf_truncate(path, wd_len); /* restore path */ if (result < 0) { closedir(dir); git__free(de_buf); return -1; } } closedir(dir); git__free(de_buf); return 0; }
static int buffer_want_with_caps(const git_remote_head *head, transport_smart_caps *caps, git_buf *buf) { git_buf str = GIT_BUF_INIT; char oid[GIT_OID_HEXSZ +1] = {0}; size_t len; /* Prefer multi_ack_detailed */ if (caps->multi_ack_detailed) git_buf_puts(&str, GIT_CAP_MULTI_ACK_DETAILED " "); else if (caps->multi_ack) git_buf_puts(&str, GIT_CAP_MULTI_ACK " "); /* Prefer side-band-64k if the server supports both */ if (caps->side_band_64k) git_buf_printf(&str, "%s ", GIT_CAP_SIDE_BAND_64K); else if (caps->side_band) git_buf_printf(&str, "%s ", GIT_CAP_SIDE_BAND); if (caps->include_tag) git_buf_puts(&str, GIT_CAP_INCLUDE_TAG " "); if (caps->thin_pack) git_buf_puts(&str, GIT_CAP_THIN_PACK " "); if (caps->ofs_delta) git_buf_puts(&str, GIT_CAP_OFS_DELTA " "); if (git_buf_oom(&str)) return -1; len = strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ + git_buf_len(&str) + 1 /* LF */; if (len > 0xffff) { giterr_set(GITERR_NET, "tried to produce packet with invalid length %" PRIuZ, len); return -1; } git_buf_grow_by(buf, len); git_oid_fmt(oid, &head->oid); git_buf_printf(buf, "%04xwant %s %s\n", (unsigned int)len, oid, git_buf_cstr(&str)); git_buf_dispose(&str); GITERR_CHECK_ALLOC_BUF(buf); return 0; }