static int run(int argc, char *argv[]) { int r, k; if (argc != 2) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program requires one argument."); log_setup_service(); umask(0022); mac_selinux_init(); if (streq(argv[1], "start")) { r = unlink_or_warn("/run/nologin"); k = unlink_or_warn("/etc/nologin"); if (r < 0) return r; return k; } else if (streq(argv[1], "stop")) return create_shutdown_run_nologin_or_warn(); return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown verb '%s'.", argv[1]); }
static void check_expected_revs(const char **revs, int rev_nr) { int i; for (i = 0; i < rev_nr; i++) { if (!is_expected_rev(revs[i])) { unlink_or_warn(git_path_bisect_ancestors_ok()); unlink_or_warn(git_path_bisect_expected_rev()); } } }
static int prune_object(const struct object_id *oid, const char *fullpath, void *data) { struct stat st; /* * Do we know about this object? * It must have been reachable */ if (lookup_object(oid->hash)) return 0; if (lstat(fullpath, &st)) { /* report errors, but do not stop pruning */ error("Could not stat '%s'", fullpath); return 0; } if (st.st_mtime > expire) return 0; if (show_only || verbose) { enum object_type type = sha1_object_info(oid->hash, NULL); printf("%s %s\n", oid_to_hex(oid), (type > 0) ? typename(type) : "unknown"); } if (!show_only) unlink_or_warn(fullpath); return 0; }
static void prune_dir(int i, DIR *dir, char *pathname, int len, int opts) { struct dirent *de; char hex[40]; sprintf(hex, "%02x", i); while ((de = readdir(dir)) != NULL) { unsigned char sha1[20]; if (strlen(de->d_name) != 38) continue; memcpy(hex+2, de->d_name, 38); if (get_sha1_hex(hex, sha1)) continue; if (!has_sha1_pack(sha1)) continue; memcpy(pathname + len, de->d_name, 38); if (opts & DRY_RUN) printf("rm -f %s\n", pathname); else unlink_or_warn(pathname); display_progress(progress, i + 1); } pathname[len] = 0; rmdir(pathname); }
struct ref *fetch_pack(struct fetch_pack_args *my_args, int fd[], struct child_process *conn, const struct ref *ref, const char *dest, int nr_heads, char **heads, char **pack_lockfile) { struct stat st; struct ref *ref_cpy; fetch_pack_setup(); if (&args != my_args) memcpy(&args, my_args, sizeof(args)); if (args.depth > 0) { if (stat(git_path("shallow"), &st)) st.st_mtime = 0; } if (heads && nr_heads) nr_heads = remove_duplicates(nr_heads, heads); if (!ref) { packet_flush(fd[1]); die("no matching remote head"); } ref_cpy = do_fetch_pack(fd, ref, nr_heads, heads, pack_lockfile); if (args.depth > 0) { struct cache_time mtime; struct strbuf sb = STRBUF_INIT; char *shallow = git_path("shallow"); int fd; mtime.sec = st.st_mtime; mtime.nsec = ST_MTIME_NSEC(st); if (stat(shallow, &st)) { if (mtime.sec) die("shallow file was removed during fetch"); } else if (st.st_mtime != mtime.sec #ifdef USE_NSEC || ST_MTIME_NSEC(st) != mtime.nsec #endif ) die("shallow file was changed during fetch"); fd = hold_lock_file_for_update(&lock, shallow, LOCK_DIE_ON_ERROR); if (!write_shallow_commits(&sb, 0) || write_in_full(fd, sb.buf, sb.len) != sb.len) { unlink_or_warn(shallow); rollback_lock_file(&lock); } else { commit_lock_file(&lock); } strbuf_release(&sb); } reprepare_packed_git(); return ref_cpy; }
void transport_unlock_pack(struct transport *transport) { if (transport->pack_lockfile) { unlink_or_warn(transport->pack_lockfile); FREE_AND_NULL(transport->pack_lockfile); } }
struct ref *fetch_pack(struct fetch_pack_args *args, int fd[], struct child_process *conn, const struct ref *ref, const char *dest, struct ref **sought, int nr_sought, char **pack_lockfile) { struct ref *ref_cpy; fetch_pack_setup(); if (nr_sought) nr_sought = remove_duplicates_in_refs(sought, nr_sought); if (!ref) { packet_flush(fd[1]); die("no matching remote head"); } ref_cpy = do_fetch_pack(args, fd, ref, sought, nr_sought, pack_lockfile); if (args->depth > 0 && alternate_shallow_file) { if (*alternate_shallow_file == '\0') { /* --unshallow */ unlink_or_warn(git_path("shallow")); rollback_lock_file(&shallow_lock); } else commit_lock_file(&shallow_lock); } reprepare_packed_git(); return ref_cpy; }
static int convert_graft_file(int force) { const char *graft_file = get_graft_file(); FILE *fp = fopen_or_warn(graft_file, "r"); struct strbuf buf = STRBUF_INIT, err = STRBUF_INIT; struct argv_array args = ARGV_ARRAY_INIT; if (!fp) return -1; while (strbuf_getline(&buf, fp) != EOF) { if (*buf.buf == '#') continue; argv_array_split(&args, buf.buf); if (args.argc && create_graft(args.argc, args.argv, force, 1)) strbuf_addf(&err, "\n\t%s", buf.buf); argv_array_clear(&args); } fclose(fp); strbuf_release(&buf); if (!err.len) return unlink_or_warn(graft_file); warning(_("could not convert the following graft(s):\n%s"), err.buf); strbuf_release(&err); return -1; }
static void clean_pack_garbage(void) { int i; for (i = 0; i < pack_garbage.nr; i++) unlink_or_warn(pack_garbage.items[i].string); string_list_clear(&pack_garbage, 0); }
/* * User defined low-level merge driver support. */ static int ll_ext_merge(const struct ll_merge_driver *fn, mmbuffer_t *result, const char *path, mmfile_t *orig, const char *orig_name, mmfile_t *src1, const char *name1, mmfile_t *src2, const char *name2, const struct ll_merge_options *opts, int marker_size) { char temp[4][50]; struct strbuf cmd = STRBUF_INIT; struct strbuf_expand_dict_entry dict[6]; struct strbuf path_sq = STRBUF_INIT; const char *args[] = { NULL, NULL }; int status, fd, i; struct stat st; assert(opts); sq_quote_buf(&path_sq, path); dict[0].placeholder = "O"; dict[0].value = temp[0]; dict[1].placeholder = "A"; dict[1].value = temp[1]; dict[2].placeholder = "B"; dict[2].value = temp[2]; dict[3].placeholder = "L"; dict[3].value = temp[3]; dict[4].placeholder = "P"; dict[4].value = path_sq.buf; dict[5].placeholder = NULL; dict[5].value = NULL; if (fn->cmdline == NULL) die("custom merge driver %s lacks command line.", fn->name); result->ptr = NULL; result->size = 0; create_temp(orig, temp[0], sizeof(temp[0])); create_temp(src1, temp[1], sizeof(temp[1])); create_temp(src2, temp[2], sizeof(temp[2])); xsnprintf(temp[3], sizeof(temp[3]), "%d", marker_size); strbuf_expand(&cmd, fn->cmdline, strbuf_expand_dict_cb, &dict); args[0] = cmd.buf; status = run_command_v_opt(args, RUN_USING_SHELL); fd = open(temp[1], O_RDONLY); if (fd < 0) goto bad; if (fstat(fd, &st)) goto close_bad; result->size = st.st_size; result->ptr = xmallocz(result->size); if (read_in_full(fd, result->ptr, result->size) != result->size) { FREE_AND_NULL(result->ptr); result->size = 0; } close_bad: close(fd); bad: for (i = 0; i < 3; i++) unlink_or_warn(temp[i]); strbuf_release(&cmd); strbuf_release(&path_sq); return status; }
void transport_unlock_pack(struct transport *transport) { if (transport->pack_lockfile) { unlink_or_warn(transport->pack_lockfile); free(transport->pack_lockfile); transport->pack_lockfile = NULL; } }
static void free_note_data(struct note_data *d) { if (d->edit_path) { unlink_or_warn(d->edit_path); free(d->edit_path); } strbuf_release(&d->buf); }
/* make sure nobody touched the ref, and unlink */ static void prune_ref(struct ref_to_prune *r) { struct ref_lock *lock = lock_ref_sha1(r->name + 5, r->sha1); if (lock) { unlink_or_warn(git_path("%s", r->name)); unlock_ref(lock); } }
/* * User defined low-level merge driver support. */ static int ll_ext_merge(const struct ll_merge_driver *fn, mmbuffer_t *result, const char *path, mmfile_t *orig, mmfile_t *src1, const char *name1, mmfile_t *src2, const char *name2, int virtual_ancestor) { char temp[3][50]; struct strbuf cmd = STRBUF_INIT; struct strbuf_expand_dict_entry dict[] = { { "O", temp[0] }, { "A", temp[1] }, { "B", temp[2] }, { NULL } }; const char *args[] = { "sh", "-c", NULL, NULL }; int status, fd, i; struct stat st; if (fn->cmdline == NULL) die("custom merge driver %s lacks command line.", fn->name); result->ptr = NULL; result->size = 0; create_temp(orig, temp[0]); create_temp(src1, temp[1]); create_temp(src2, temp[2]); strbuf_expand(&cmd, fn->cmdline, strbuf_expand_dict_cb, &dict); args[2] = cmd.buf; status = run_command_v_opt(args, 0); if (status < -ERR_RUN_COMMAND_FORK) ; /* failure in run-command */ else status = -status; fd = open(temp[1], O_RDONLY); if (fd < 0) goto bad; if (fstat(fd, &st)) goto close_bad; result->size = st.st_size; result->ptr = xmalloc(result->size + 1); if (read_in_full(fd, result->ptr, result->size) != result->size) { free(result->ptr); result->ptr = NULL; result->size = 0; } close_bad: close(fd); bad: for (i = 0; i < 3; i++) unlink_or_warn(temp[i]); strbuf_release(&cmd); return status; }
void rollback_lock_file(struct lock_file *lk) { if (lk->filename[0]) { if (lk->fd >= 0) close(lk->fd); unlink_or_warn(lk->filename); } lk->filename[0] = 0; }
/* * Run "gpg" to see if the payload matches the detached signature. * gpg_output, when set, receives the diagnostic output from GPG. * gpg_status, when set, receives the status output from GPG. */ int verify_signed_buffer(const char *payload, size_t payload_size, const char *signature, size_t signature_size, struct strbuf *gpg_output, struct strbuf *gpg_status) { struct child_process gpg = CHILD_PROCESS_INIT; const char *args_gpg[] = {NULL, "--status-fd=1", "--verify", "FILE", "-", NULL}; char path[PATH_MAX]; int fd, ret; struct strbuf buf = STRBUF_INIT; struct strbuf *pbuf = &buf; args_gpg[0] = gpg_program; fd = git_mkstemp(path, PATH_MAX, ".git_vtag_tmpXXXXXX"); if (fd < 0) return error(_("could not create temporary file '%s': %s"), path, strerror(errno)); if (write_in_full(fd, signature, signature_size) < 0) return error(_("failed writing detached signature to '%s': %s"), path, strerror(errno)); close(fd); gpg.argv = args_gpg; gpg.in = -1; gpg.out = -1; if (gpg_output) gpg.err = -1; args_gpg[3] = path; if (start_command(&gpg)) { unlink(path); return error(_("could not run gpg.")); } sigchain_push(SIGPIPE, SIG_IGN); write_in_full(gpg.in, payload, payload_size); close(gpg.in); if (gpg_output) { strbuf_read(gpg_output, gpg.err, 0); close(gpg.err); } if (gpg_status) pbuf = gpg_status; strbuf_read(pbuf, gpg.out, 0); close(gpg.out); ret = finish_command(&gpg); sigchain_pop(SIGPIPE); unlink_or_warn(path); ret |= !strstr(pbuf->buf, "\n[GNUPG:] GOODSIG "); strbuf_release(&buf); /* no matter it was used or not */ return ret; }
/* * User defined low-level merge driver support. */ static int ll_ext_merge(const struct ll_merge_driver *fn, mmbuffer_t *result, const char *path, mmfile_t *orig, mmfile_t *src1, const char *name1, mmfile_t *src2, const char *name2, int flag, int marker_size) { char temp[4][50]; struct strbuf cmd = STRBUF_INIT; struct strbuf_expand_dict_entry dict[] = { { "O", temp[0] }, { "A", temp[1] }, { "B", temp[2] }, { "L", temp[3] }, { NULL } }; const char *args[] = { NULL, NULL }; int status, fd, i; struct stat st; if (fn->cmdline == NULL) die("custom merge driver %s lacks command line.", fn->name); result->ptr = NULL; result->size = 0; create_temp(orig, temp[0]); create_temp(src1, temp[1]); create_temp(src2, temp[2]); sprintf(temp[3], "%d", marker_size); strbuf_expand(&cmd, fn->cmdline, strbuf_expand_dict_cb, &dict); args[0] = cmd.buf; status = run_command_v_opt(args, RUN_USING_SHELL); fd = open(temp[1], O_RDONLY); if (fd < 0) goto bad; if (fstat(fd, &st)) goto close_bad; result->size = st.st_size; result->ptr = xmalloc(result->size + 1); if (read_in_full(fd, result->ptr, result->size) != result->size) { free(result->ptr); result->ptr = NULL; result->size = 0; } close_bad: close(fd); bad: for (i = 0; i < 3; i++) unlink_or_warn(temp[i]); strbuf_release(&cmd); return status; }
void rerere_clear(struct string_list *merge_rr) { int i; for (i = 0; i < merge_rr->nr; i++) { const char *name = (const char *)merge_rr->items[i].util; if (!has_rerere_resolution(name)) unlink_rr_item(name); } unlink_or_warn(git_path("MERGE_RR")); }
void rollback_lock_file(struct lock_file *lk) { if (!lk->active) return; if (!close_lock_file(lk)) { unlink_or_warn(lk->filename.buf); lk->active = 0; strbuf_reset(&lk->filename); } }
static int prune_tmp_file(const char *fullpath) { struct stat st; if (lstat(fullpath, &st)) return error("Could not stat '%s'", fullpath); if (st.st_mtime > expire) return 0; if (show_only || verbose) printf("Removing stale temporary file %s\n", fullpath); if (!show_only) unlink_or_warn(fullpath); return 0; }
static int prune_tmp_object(const char *path, const char *filename) { const char *fullpath = mkpath("%s/%s", path, filename); struct stat st; if (lstat(fullpath, &st)) return error("Could not stat '%s'", fullpath); if (st.st_mtime > expire) return 0; printf("Removing stale temporary file %s\n", fullpath); if (!show_only) unlink_or_warn(fullpath); return 0; }
static void remove_lock_file(void) { pid_t me = getpid(); while (lock_file_list) { if (lock_file_list->owner == me && lock_file_list->filename[0]) { if (lock_file_list->fd >= 0) close(lock_file_list->fd); unlink_or_warn(lock_file_list->filename); } lock_file_list = lock_file_list->next; } }
static int prune_object(const struct object_id *oid, const char *path, void *data) { int *opts = data; if (!has_sha1_pack(oid->hash)) return 0; if (*opts & PRUNE_PACKED_DRY_RUN) printf("rm -f %s\n", path); else unlink_or_warn(path); return 0; }
int delete_ref(const char *refname, const unsigned char *sha1, int delopt) { struct ref_lock *lock; int err, i = 0, ret = 0, flag = 0; lock = lock_ref_sha1_basic(refname, sha1, 0, &flag); if (!lock) return 1; if (!(flag & REF_ISPACKED) || flag & REF_ISSYMREF) { /* loose */ const char *path; if (!(delopt & REF_NODEREF)) { i = strlen(lock->lk->filename) - 5; /* .lock */ lock->lk->filename[i] = 0; path = lock->lk->filename; } else { path = git_path("%s", refname); } err = unlink_or_warn(path); if (err && errno != ENOENT) ret = 1; if (!(delopt & REF_NODEREF)) lock->lk->filename[i] = '.'; } /* removing the loose one could have resurrected an earlier * packed one. Also, if it was not loose we need to repack * without it. */ ret |= repack_without_ref(refname); unlink_or_warn(git_path("logs/%s", lock->ref_name)); invalidate_cached_refs(); unlock_ref(lock); return ret; }
/* * During a conflict resolution, after "rerere" recorded the * preimages, abandon them if the user did not resolve them or * record their resolutions. And drop $GIT_DIR/MERGE_RR. * * NEEDSWORK: shouldn't we be calling this from "reset --hard"? */ void rerere_clear(struct string_list *merge_rr) { int i; if (setup_rerere(merge_rr, 0) < 0) return; for (i = 0; i < merge_rr->nr; i++) { struct rerere_id *id = merge_rr->items[i].util; if (!has_rerere_resolution(id)) unlink_rr_item(id); } unlink_or_warn(git_path_merge_rr()); rollback_lock_file(&write_lock); }
/* public */ int update_server_info(int force) { /* We would add more dumb-server support files later, * including index of available pack files and their * intended audiences. */ int errs = 0; errs = errs | update_info_refs(force); errs = errs | update_info_packs(force); /* remove leftover rev-cache file if there is any */ unlink_or_warn(git_path("info/rev-cache")); return errs; }
static int prune_object(const char *fullpath, const unsigned char *sha1) { struct stat st; if (lstat(fullpath, &st)) return error("Could not stat '%s'", fullpath); if (st.st_mtime > expire) return 0; if (show_only || verbose) { enum object_type type = sha1_object_info(sha1, NULL); printf("%s %s\n", sha1_to_hex(sha1), (type > 0) ? typename(type) : "unknown"); } if (!show_only) unlink_or_warn(fullpath); return 0; }
/* * Scan the path for conflicts, do the "handle_path()" thing above, and * return the number of conflict hunks found. */ static int handle_file(struct index_state *istate, const char *path, unsigned char *hash, const char *output) { int has_conflicts = 0; struct rerere_io_file io; int marker_size = ll_merge_marker_size(istate, path); memset(&io, 0, sizeof(io)); io.io.getline = rerere_file_getline; io.input = fopen(path, "r"); io.io.wrerror = 0; if (!io.input) return error_errno(_("could not open '%s'"), path); if (output) { io.io.output = fopen(output, "w"); if (!io.io.output) { error_errno(_("could not write '%s'"), output); fclose(io.input); return -1; } } has_conflicts = handle_path(hash, (struct rerere_io *)&io, marker_size); fclose(io.input); if (io.io.wrerror) error(_("there were errors while writing '%s' (%s)"), path, strerror(io.io.wrerror)); if (io.io.output && fclose(io.io.output)) io.io.wrerror = error_errno(_("failed to flush '%s'"), path); if (has_conflicts < 0) { if (output) unlink_or_warn(output); return error(_("could not parse conflict hunks in '%s'"), path); } if (io.io.wrerror) return -1; return has_conflicts; }
static int handle_file(const char *path, unsigned char *sha1, const char *output) { int hunk_no = 0; struct rerere_io_file io; int marker_size = ll_merge_marker_size(path); memset(&io, 0, sizeof(io)); io.io.getline = rerere_file_getline; io.input = fopen(path, "r"); io.io.wrerror = 0; if (!io.input) return error("Could not open %s", path); if (output) { io.io.output = fopen(output, "w"); if (!io.io.output) { fclose(io.input); return error("Could not write %s", output); } } hunk_no = handle_path(sha1, (struct rerere_io *)&io, marker_size); fclose(io.input); if (io.io.wrerror) error("There were errors while writing %s (%s)", path, strerror(io.io.wrerror)); if (io.io.output && fclose(io.io.output)) io.io.wrerror = error("Failed to flush %s: %s", path, strerror(errno)); if (hunk_no < 0) { if (output) unlink_or_warn(output); return error("Could not parse conflict hunks in %s", path); } if (io.io.wrerror) return -1; return hunk_no; }
static int run_gpg_verify(const char *buf, unsigned long size, int verbose) { struct child_process gpg; const char *args_gpg[] = {"gpg", "--verify", "FILE", "-", NULL}; char path[PATH_MAX]; size_t len; int fd, ret; fd = git_mkstemp(path, PATH_MAX, ".git_vtag_tmpXXXXXX"); if (fd < 0) return error("could not create temporary file '%s': %s", path, strerror(errno)); if (write_in_full(fd, buf, size) < 0) return error("failed writing temporary file '%s': %s", path, strerror(errno)); close(fd); /* find the length without signature */ len = parse_signature(buf, size); if (verbose) write_in_full(1, buf, len); memset(&gpg, 0, sizeof(gpg)); gpg.argv = args_gpg; gpg.in = -1; args_gpg[2] = path; if (start_command(&gpg)) { unlink(path); return error("could not run gpg."); } write_in_full(gpg.in, buf, len); close(gpg.in); ret = finish_command(&gpg); unlink_or_warn(path); return ret; }