int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *path) { int error, fd; char full_path[GIT_PATH_MAX]; char buffer[2048]; git_off_t size; git_odb_stream *stream; if (repo->path_workdir == NULL) return GIT_ENOTFOUND; git__joinpath(full_path, repo->path_workdir, path); if ((fd = gitfo_open(full_path, O_RDONLY)) < 0) return GIT_ENOTFOUND; if ((size = gitfo_size(fd)) < 0 || !git__is_sizet(size)) { gitfo_close(fd); return GIT_EOSERR; } if ((error = git_odb_open_wstream(&stream, repo->db, (size_t)size, GIT_OBJ_BLOB)) < GIT_SUCCESS) { gitfo_close(fd); return error; } while (size > 0) { ssize_t read_len; read_len = read(fd, buffer, sizeof(buffer)); if (read_len < 0) { gitfo_close(fd); stream->free(stream); return GIT_EOSERR; } stream->write(stream, buffer, read_len); size -= read_len; } error = stream->finalize_write(oid, stream); stream->free(stream); return error; }
static int lock_file(git_filebuf *file, int flags) { if (gitfo_exists(file->path_lock) == 0) { if (flags & GIT_FILEBUF_FORCE) gitfo_unlink(file->path_lock); else return git__throw(GIT_EOSERR, "Failed to lock file"); } /* create path to the file buffer is required */ if (flags & GIT_FILEBUF_FORCE) { file->fd = gitfo_creat_locked_force(file->path_lock, 0644); } else { file->fd = gitfo_creat_locked(file->path_lock, 0644); } if (file->fd < 0) return git__throw(GIT_EOSERR, "Failed to create lock"); if ((flags & GIT_FILEBUF_APPEND) && gitfo_exists(file->path_original) == 0) { git_file source; char buffer[2048]; size_t read_bytes; source = gitfo_open(file->path_original, O_RDONLY); if (source < 0) return git__throw(GIT_EOSERR, "Failed to lock file. Could not open %s", file->path_original); while ((read_bytes = gitfo_read(source, buffer, 2048)) > 0) { gitfo_write(file->fd, buffer, read_bytes); if (file->digest) git_hash_update(file->digest, buffer, read_bytes); } gitfo_close(source); } return GIT_SUCCESS; }
static int pack_openidx_map(git_pack *p) { char pb[GIT_PATH_MAX]; off_t len; if (git__fmt(pb, sizeof(pb), "%s/pack/%s.idx", p->backend->objects_dir, p->pack_name) < 0) return GIT_ERROR; if ((p->idx_fd = gitfo_open(pb, O_RDONLY)) < 0) return GIT_ERROR; if ((len = gitfo_size(p->idx_fd)) < 0 || !git__is_sizet(len) || gitfo_map_ro(&p->idx_map, p->idx_fd, 0, (size_t)len)) { gitfo_close(p->idx_fd); return GIT_ERROR; } return GIT_SUCCESS; }
int gitfo_read_file(gitfo_buf *obj, const char *path) { git_file fd; size_t len; git_off_t size; unsigned char *buff; assert(obj && path && *path); if ((fd = gitfo_open(path, O_RDONLY)) < 0) return GIT_ERROR; if (((size = gitfo_size(fd)) < 0) || !git__is_sizet(size+1)) { gitfo_close(fd); return GIT_ERROR; } len = (size_t) size; if ((buff = git__malloc(len + 1)) == NULL) { gitfo_close(fd); return GIT_ERROR; } if (gitfo_read(fd, buff, len) < 0) { gitfo_close(fd); free(buff); return GIT_ERROR; } buff[len] = '\0'; gitfo_close(fd); obj->data = buff; obj->len = len; return GIT_SUCCESS; }
static int open_pack(git_pack *p) { char pb[GIT_PATH_MAX]; struct stat sb; if (p->pack_fd != -1) return GIT_SUCCESS; if (git__fmt(pb, sizeof(pb), "%s/pack/%s.pack", p->backend->objects_dir, p->pack_name) < 0) return GIT_ERROR; if (pack_openidx(p)) return GIT_ERROR; if ((p->pack_fd = gitfo_open(pb, O_RDONLY)) < 0) goto error_cleanup; if (gitfo_fstat(p->pack_fd, &sb) || !S_ISREG(sb.st_mode) || p->pack_size != sb.st_size || check_pack_hdr(p) || check_pack_sha1(p)) goto error_cleanup; if (!git__is_sizet(p->pack_size) || gitfo_map_ro(&p->pack_map, p->pack_fd, 0, (size_t)p->pack_size) < 0) goto error_cleanup; pack_decidx(p); return GIT_SUCCESS; error_cleanup: gitfo_close(p->pack_fd); p->pack_fd = -1; pack_decidx(p); return GIT_ERROR; }
static int lock_file(git_filebuf *file, int flags) { if (gitfo_exists(file->path_lock) == 0) { if (flags & GIT_FILEBUF_FORCE) gitfo_unlink(file->path_lock); else return GIT_EOSERR; } file->fd = gitfo_creat(file->path_lock, 0644); if (file->fd < 0) return GIT_EOSERR; /* TODO: do a flock() in the descriptor file_lock */ if ((flags & GIT_FILEBUF_APPEND) && gitfo_exists(file->path_original) == 0) { git_file source; char buffer[2048]; size_t read_bytes; source = gitfo_open(file->path_original, O_RDONLY); if (source < 0) return GIT_EOSERR; while ((read_bytes = gitfo_read(source, buffer, 2048)) > 0) { gitfo_write(file->fd, buffer, read_bytes); if (file->digest) git_hash_update(file->digest, buffer, read_bytes); } gitfo_close(source); } return GIT_SUCCESS; }