static void handle_new_lock_ctx(struct xml_ctx *ctx, int tag_closed) { struct remote_lock *lock = (struct remote_lock *)ctx->userData; git_SHA_CTX sha_ctx; unsigned char lock_token_sha1[20]; if (tag_closed && ctx->cdata) { if (!strcmp(ctx->name, DAV_ACTIVELOCK_OWNER)) { lock->owner = xstrdup(ctx->cdata); } else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TIMEOUT)) { const char *arg; if (skip_prefix(ctx->cdata, "Second-", &arg)) lock->timeout = strtol(arg, NULL, 10); } else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TOKEN)) { lock->token = xstrdup(ctx->cdata); git_SHA1_Init(&sha_ctx); git_SHA1_Update(&sha_ctx, lock->token, strlen(lock->token)); git_SHA1_Final(lock_token_sha1, &sha_ctx); lock->tmpfile_suffix[0] = '_'; memcpy(lock->tmpfile_suffix + 1, sha1_to_hex(lock_token_sha1), 40); } } }
static const char *remote_submodule_branch(const char *path) { const struct submodule *sub; gitmodules_config(); git_config(submodule_config, NULL); sub = submodule_from_path(null_sha1, path); if (!sub) return NULL; if (!sub->branch) return "master"; if (!strcmp(sub->branch, ".")) { unsigned char sha1[20]; const char *refname = resolve_ref_unsafe("HEAD", 0, sha1, NULL); if (!refname) die(_("No such ref: %s"), "HEAD"); /* detached HEAD */ if (!strcmp(refname, "HEAD")) die(_("Submodule (%s) branch configured to inherit " "branch from superproject, but the superproject " "is not on any branch"), sub->name); if (!skip_prefix(refname, "refs/heads/", &refname)) die(_("Expecting a full ref name, got %s"), refname); return refname; } return sub->branch; }
static enum ack_type get_ack(struct packet_reader *reader, struct object_id *result_oid) { int len; const char *arg; if (packet_reader_read(reader) != PACKET_READ_NORMAL) die(_("git fetch-pack: expected ACK/NAK, got a flush packet")); len = reader->pktlen; if (!strcmp(reader->line, "NAK")) return NAK; if (skip_prefix(reader->line, "ACK ", &arg)) { if (!get_oid_hex(arg, result_oid)) { arg += 40; len -= arg - reader->line; if (len < 1) return ACK; if (strstr(arg, "continue")) return ACK_continue; if (strstr(arg, "common")) return ACK_common; if (strstr(arg, "ready")) return ACK_ready; return ACK; } } die(_("git fetch-pack: expected ACK/NAK, got '%s'"), reader->line); }
static void show_one_commit(struct commit *commit, int no_name) { struct strbuf pretty = STRBUF_INIT; const char *pretty_str = "(unavailable)"; struct commit_name *name = commit->util; if (commit->object.parsed) { pp_commit_easy(CMIT_FMT_ONELINE, commit, &pretty); pretty_str = pretty.buf; } skip_prefix(pretty_str, "[PATCH] ", &pretty_str); if (!no_name) { if (name && name->head_name) { printf("[%s", name->head_name); if (name->generation) { if (name->generation == 1) printf("^"); else printf("~%d", name->generation); } printf("] "); } else printf("[%s] ", find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV)); } puts(pretty_str); strbuf_release(&pretty); }
static char *get_default_remote(void) { char *dest = NULL, *ret; unsigned char sha1[20]; struct strbuf sb = STRBUF_INIT; const char *refname = resolve_ref_unsafe("HEAD", 0, sha1, NULL); if (!refname) die(_("No such ref: %s"), "HEAD"); /* detached HEAD */ if (!strcmp(refname, "HEAD")) return xstrdup("origin"); if (!skip_prefix(refname, "refs/heads/", &refname)) die(_("Expecting a full ref name, got %s"), refname); strbuf_addf(&sb, "branch.%s.remote", refname); if (git_config_get_string(sb.buf, &dest)) ret = xstrdup("origin"); else ret = dest; strbuf_release(&sb); return ret; }
static void update_head(const struct ref *our, const struct ref *remote, const char *msg) { if (our && !prefixcmp(our->name, "refs/heads/")) { /* Local default branch link */ create_symref("HEAD", our->name, NULL); if (!option_bare) { const char *head = skip_prefix(our->name, "refs/heads/"); update_ref(msg, "HEAD", our->old_sha1, NULL, 0, DIE_ON_ERR); install_branch_config(0, head, option_origin, our->name); } } else if (our) { struct commit *c = lookup_commit_reference(our->old_sha1); /* --branch specifies a non-branch (i.e. tags), detach HEAD */ update_ref(msg, "HEAD", c->object.sha1, NULL, REF_NODEREF, DIE_ON_ERR); } else if (remote) { /* * We know remote HEAD points to a non-branch, or * HEAD points to a branch but we don't know which one. * Detach HEAD in all these cases. */ update_ref(msg, "HEAD", remote->old_sha1, NULL, REF_NODEREF, DIE_ON_ERR); } }
void parse_gpg_output(struct signature_check *sigc) { const char *buf = sigc->gpg_status; int i; /* Iterate over all search strings */ for (i = 0; i < ARRAY_SIZE(sigcheck_gpg_status); i++) { const char *found, *next; if (!skip_prefix(buf, sigcheck_gpg_status[i].check + 1, &found)) { found = strstr(buf, sigcheck_gpg_status[i].check); if (!found) continue; found += strlen(sigcheck_gpg_status[i].check); } sigc->result = sigcheck_gpg_status[i].result; /* The trust messages are not followed by key/signer information */ if (sigc->result != 'U') { sigc->key = xmemdupz(found, 16); /* The ERRSIG message is not followed by signer information */ if (sigc-> result != 'E') { found += 17; next = strchrnul(found, '\n'); sigc->signer = xmemdupz(found, next - found); } } } }
static const char *anonymize_refname(const char *refname) { /* * If any of these prefixes is found, we will leave it intact * so that tags remain tags and so forth. */ static const char *prefixes[] = { "refs/heads/", "refs/tags/", "refs/remotes/", "refs/" }; static struct hashmap refs; static struct strbuf anon = STRBUF_INIT; int i; /* * We also leave "master" as a special case, since it does not reveal * anything interesting. */ if (!strcmp(refname, "refs/heads/master")) return refname; strbuf_reset(&anon); for (i = 0; i < ARRAY_SIZE(prefixes); i++) { if (skip_prefix(refname, prefixes[i], &refname)) { strbuf_addstr(&anon, prefixes[i]); break; } } anonymize_path(&anon, refname, &refs, anonymize_ref_component); return anon.buf; }
struct taginfo *cgit_parse_tag(struct tag *tag) { void *data; enum object_type type; unsigned long size; const char *p; struct taginfo *ret = NULL; data = read_sha1_file(tag->object.oid.hash, &type, &size); if (!data || type != OBJ_TAG) goto cleanup; ret = xcalloc(1, sizeof(struct taginfo)); for (p = data; !end_of_header(p); p = next_header_line(p)) { if (skip_prefix(p, "tagger ", &p)) { parse_user(p, &ret->tagger, &ret->tagger_email, &ret->tagger_date, &ret->tagger_tz); } } while (p && *p == '\n') p++; if (p && *p) ret->msg = xstrdup(p); cleanup: free(data); return ret; }
static void fetch_symref(const char *path, char **symref, struct object_id *oid) { char *url = xstrfmt("%s%s", repo->url, path); struct strbuf buffer = STRBUF_INIT; const char *name; if (http_get_strbuf(url, &buffer, NULL) != HTTP_OK) die("Couldn't get %s for remote symref\n%s", url, curl_errorstr); free(url); FREE_AND_NULL(*symref); oidclr(oid); if (buffer.len == 0) return; /* Cut off trailing newline. */ strbuf_rtrim(&buffer); /* If it's a symref, set the refname; otherwise try for a sha1 */ if (skip_prefix(buffer.buf, "ref: ", &name)) { *symref = xmemdupz(name, buffer.len - (name - buffer.buf)); } else { get_oid_hex(buffer.buf, oid); } strbuf_release(&buffer); }
static char *find_branch_name(struct rev_info *rev) { int i, positive = -1; struct object_id branch_oid; const struct object_id *tip_oid; const char *ref, *v; char *full_ref, *branch = NULL; for (i = 0; i < rev->cmdline.nr; i++) { if (rev->cmdline.rev[i].flags & UNINTERESTING) continue; if (positive < 0) positive = i; else return NULL; } if (positive < 0) return NULL; ref = rev->cmdline.rev[positive].name; tip_oid = &rev->cmdline.rev[positive].item->oid; if (dwim_ref(ref, strlen(ref), branch_oid.hash, &full_ref) && skip_prefix(full_ref, "refs/heads/", &v) && !oidcmp(tip_oid, &branch_oid)) branch = xstrdup(v); free(full_ref); return branch; }
static struct rpc_service *select_service(struct strbuf *hdr, const char *name) { const char *svc_name; struct rpc_service *svc = NULL; int i; if (!skip_prefix(name, "git-", &svc_name)) forbidden(hdr, "Unsupported service: '%s'", name); for (i = 0; i < ARRAY_SIZE(rpc_service); i++) { struct rpc_service *s = &rpc_service[i]; if (!strcmp(s->name, svc_name)) { svc = s; break; } } if (!svc) forbidden(hdr, "Unsupported service: '%s'", name); if (svc->enabled < 0) { const char *user = getenv("REMOTE_USER"); svc->enabled = (user && *user) ? 1 : 0; } if (!svc->enabled) forbidden(hdr, "Service not enabled: '%s'", svc->name); return svc; }
static NORETURN int die_push_simple(struct branch *branch, struct remote *remote) { /* * There's no point in using shorten_unambiguous_ref here, * as the ambiguity would be on the remote side, not what * we have locally. Plus, this is supposed to be the simple * mode. If the user is doing something crazy like setting * upstream to a non-branch, we should probably be showing * them the big ugly fully qualified ref. */ const char *advice_maybe = ""; const char *short_upstream = branch->merge[0]->src; skip_prefix(short_upstream, "refs/heads/", &short_upstream); /* * Don't show advice for people who explicitly set * push.default. */ if (push_default == PUSH_DEFAULT_UNSPECIFIED) advice_maybe = _("\n" "To choose either option permanently, " "see push.default in 'git help config'."); die(_("The upstream branch of your current branch does not match\n" "the name of your current branch. To push to the upstream branch\n" "on the remote, use\n" "\n" " git push %s HEAD:%s\n" "\n" "To push to the branch of the same name on the remote, use\n" "\n" " git push %s %s\n" "%s"), remote->name, short_upstream, remote->name, branch->name, advice_maybe); }
int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix) { char buffer[HEADERSIZE]; struct ustar_header *header = (struct ustar_header *)buffer; char *content = buffer + RECORDSIZE; const char *comment; ssize_t n; if (argc != 1) usage(builtin_get_tar_commit_id_usage); git_config(git_default_config, NULL); n = read_in_full(0, buffer, HEADERSIZE); if (n < 0) die_errno("git get-tar-commit-id: read error"); if (n != HEADERSIZE) die_errno("git get-tar-commit-id: EOF before reading tar header"); if (header->typeflag[0] != 'g') return 1; if (!skip_prefix(content, "52 comment=", &comment)) return 1; if (write_in_full(1, comment, 41) < 0) die_errno("git get-tar-commit-id: write error"); return 0; }
static enum ack_type get_ack(int fd, unsigned char *result_sha1) { int len; char *line = packet_read_line(fd, &len); const char *arg; if (!len) die(_("git fetch-pack: expected ACK/NAK, got EOF")); if (!strcmp(line, "NAK")) return NAK; if (skip_prefix(line, "ACK ", &arg)) { if (!get_sha1_hex(arg, result_sha1)) { arg += 40; len -= arg - line; if (len < 1) return ACK; if (strstr(arg, "continue")) return ACK_continue; if (strstr(arg, "common")) return ACK_common; if (strstr(arg, "ready")) return ACK_ready; return ACK; } } die(_("git fetch_pack: expected ACK/NAK, got '%s'"), line); }
static int parse_want(const char *line) { const char *arg; if (skip_prefix(line, "want ", &arg)) { struct object_id oid; struct object *o; if (get_oid_hex(arg, &oid)) die("git upload-pack: protocol error, " "expected to get oid, not '%s'", line); o = parse_object(&oid); if (!o) { packet_write_fmt(1, "ERR upload-pack: not our ref %s", oid_to_hex(&oid)); die("git upload-pack: not our ref %s", oid_to_hex(&oid)); } if (!(o->flags & WANTED)) { o->flags |= WANTED; add_object_array(o, NULL, &want_obj); } return 1; } return 0; }
/* * Server calls this */ void obfuscate_receive_seed(int sock_in) { struct seed_msg seed; u_char padding_drain[OBFUSCATE_MAX_PADDING]; u_int len; u_int32_t padding_length; u_int32_t test_magic; u_int offset, remaining; len = atomicio(read, sock_in, &seed, sizeof(struct seed_msg)); debug2("obfuscate_receive_seed: read %d byte seed message from client", len); if(len != sizeof(struct seed_msg)) fatal("obfuscate_receive_seed: read failed"); // PSIPHON: HTTP-PREFIX offset = skip_prefix(sock_in, (u_char*)&seed, sizeof(struct seed_msg)); if (offset > 0) { remaining = len - offset; memmove(&seed, ((unsigned char*)&seed) + offset, remaining); len = remaining + atomicio(read, sock_in, ((unsigned char*)&seed) + remaining, sizeof(struct seed_msg) - remaining); debug2("obfuscate_receive_seed: read %d byte seed message from client", len); if(len != sizeof(struct seed_msg)) fatal("obfuscate_receive_seed: reread failed"); } initialize(seed.seed_buffer, 1, 1); // try fixed key pair first // create a copy of seed.magic because obfuscate_input(..) destroys it test_magic = seed.magic; obfuscate_input((u_char *)&test_magic, 4); if(OBFUSCATE_MAGIC_VALUE != ntohl(test_magic)) { debug2("trying ossh backwards compatibility mode"); initialize(seed.seed_buffer, 1, 0); // try backwards compatible key pair obfuscate_input((u_char *)&seed.magic, 4); if(OBFUSCATE_MAGIC_VALUE != ntohl(seed.magic)) { logit("Magic value check failed (%u) on obfuscated handshake.", ntohl(seed.magic)); read_forever(sock_in); } } else { seed.magic = test_magic; } obfuscate_input((u_char *)&seed.padding_length, 4); padding_length = ntohl(seed.padding_length); if(padding_length > OBFUSCATE_MAX_PADDING) { logit("Illegal padding length %d for obfuscated handshake", ntohl(seed.padding_length)); read_forever(sock_in); } len = atomicio(read, sock_in, padding_drain, padding_length); if(len != padding_length) fatal("obfuscate_receive_seed: read failed"); debug2("obfuscate_receive_seed: read %d bytes of padding from client.", len); obfuscate_input(padding_drain, padding_length); }
static int handshake_version(struct child_process *process, const char *welcome_prefix, int *versions, int *chosen_version) { int version_scratch; int i; char *line; const char *p; if (!chosen_version) chosen_version = &version_scratch; if (packet_write_fmt_gently(process->in, "%s-client\n", welcome_prefix)) return error("Could not write client identification"); for (i = 0; versions[i]; i++) { if (packet_write_fmt_gently(process->in, "version=%d\n", versions[i])) return error("Could not write requested version"); } if (packet_flush_gently(process->in)) return error("Could not write flush packet"); if (!(line = packet_read_line(process->out, NULL)) || !skip_prefix(line, welcome_prefix, &p) || strcmp(p, "-server")) return error("Unexpected line '%s', expected %s-server", line ? line : "<flush packet>", welcome_prefix); if (!(line = packet_read_line(process->out, NULL)) || !skip_prefix(line, "version=", &p) || strtol_i(p, 10, chosen_version)) return error("Unexpected line '%s', expected version", line ? line : "<flush packet>"); if ((line = packet_read_line(process->out, NULL))) return error("Unexpected line '%s', expected flush", line); /* Check to make sure that the version received is supported */ for (i = 0; versions[i]; i++) { if (versions[i] == *chosen_version) break; } if (!versions[i]) return error("Version %d not supported", *chosen_version); return 0; }
char * skip_csi(char *input) { if ((unsigned char) *input == CSI) { return input + 1; } return skip_prefix(csi_input(), input); }
char * skip_ss3(char *input) { if ((unsigned char) *input == SS3) { return input + 1; } return skip_prefix(ss3_input(), input); }
char * skip_dcs(char *input) { if ((unsigned char) *input == DCS) { return input + 1; } return skip_prefix(dcs_input(), input); }
static void cmd_log_init(int argc, const char **argv, const char *prefix, struct rev_info *rev) { int i; int decoration_style = 0; rev->abbrev = DEFAULT_ABBREV; rev->commit_format = CMIT_FMT_DEFAULT; if (fmt_pretty) get_commit_format(fmt_pretty, rev); rev->verbose_header = 1; DIFF_OPT_SET(&rev->diffopt, RECURSIVE); rev->show_root_diff = default_show_root; rev->subject_prefix = fmt_patch_subject_prefix; DIFF_OPT_SET(&rev->diffopt, ALLOW_TEXTCONV); if (default_date_mode) rev->date_mode = parse_date_format(default_date_mode); /* * Check for -h before setup_revisions(), or "git log -h" will * fail when run without a git directory. */ if (argc == 2 && !strcmp(argv[1], "-h")) usage(builtin_log_usage); argc = setup_revisions(argc, argv, rev, "HEAD"); if (rev->diffopt.pickaxe || rev->diffopt.filter) rev->always_show_header = 0; if (DIFF_OPT_TST(&rev->diffopt, FOLLOW_RENAMES)) { rev->always_show_header = 0; if (rev->diffopt.nr_paths != 1) usage("git logs can only follow renames on one pathname at a time"); } for (i = 1; i < argc; i++) { const char *arg = argv[i]; if (!strcmp(arg, "--decorate")) { decoration_style = DECORATE_SHORT_REFS; } else if (!prefixcmp(arg, "--decorate=")) { const char *v = skip_prefix(arg, "--decorate="); if (!strcmp(v, "full")) decoration_style = DECORATE_FULL_REFS; else if (!strcmp(v, "short")) decoration_style = DECORATE_SHORT_REFS; else die("invalid --decorate option: %s", arg); } else if (!strcmp(arg, "--source")) { rev->show_source = 1; } else if (!strcmp(arg, "-h")) { usage(builtin_log_usage); } else die("unrecognized argument: %s", arg); } if (decoration_style) { rev->show_decorations = 1; load_ref_decorations(decoration_style); } }
static int git_pretty_formats_config(const char *var, const char *value, void *cb) { struct cmt_fmt_map *commit_format = NULL; const char *name; const char *fmt; int i; if (!skip_prefix(var, "pretty.", &name)) return 0; for (i = 0; i < builtin_formats_len; i++) { if (!strcmp(commit_formats[i].name, name)) return 0; } for (i = builtin_formats_len; i < commit_formats_len; i++) { if (!strcmp(commit_formats[i].name, name)) { commit_format = &commit_formats[i]; break; } } if (!commit_format) { ALLOC_GROW(commit_formats, commit_formats_len+1, commit_formats_alloc); commit_format = &commit_formats[commit_formats_len]; memset(commit_format, 0, sizeof(*commit_format)); commit_formats_len++; } commit_format->name = xstrdup(name); commit_format->format = CMIT_FMT_USERFORMAT; if (git_config_string(&fmt, var, value)) return -1; if (skip_prefix(fmt, "format:", &fmt)) commit_format->is_tformat = 0; else if (skip_prefix(fmt, "tformat:", &fmt) || strchr(fmt, '%')) commit_format->is_tformat = 1; else commit_format->is_alias = 1; commit_format->user_format = fmt; return 0; }
static int fsck_commit_buffer(struct commit *commit, const char *buffer, fsck_error error_func) { unsigned char tree_sha1[20], sha1[20]; struct commit_graft *graft; unsigned parent_count, parent_line_count = 0; int err; if (!skip_prefix(buffer, "tree ", &buffer)) return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'tree' line"); if (get_sha1_hex(buffer, tree_sha1) || buffer[40] != '\n') return error_func(&commit->object, FSCK_ERROR, "invalid 'tree' line format - bad sha1"); buffer += 41; while (skip_prefix(buffer, "parent ", &buffer)) { if (get_sha1_hex(buffer, sha1) || buffer[40] != '\n') return error_func(&commit->object, FSCK_ERROR, "invalid 'parent' line format - bad sha1"); buffer += 41; parent_line_count++; } graft = lookup_commit_graft(commit->object.sha1); parent_count = commit_list_count(commit->parents); if (graft) { if (graft->nr_parent == -1 && !parent_count) ; /* shallow commit */ else if (graft->nr_parent != parent_count) return error_func(&commit->object, FSCK_ERROR, "graft objects missing"); } else { if (parent_count != parent_line_count) return error_func(&commit->object, FSCK_ERROR, "parent objects missing"); } if (!skip_prefix(buffer, "author ", &buffer)) return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'author' line"); err = fsck_ident(&buffer, &commit->object, error_func); if (err) return err; if (!skip_prefix(buffer, "committer ", &buffer)) return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'committer' line"); err = fsck_ident(&buffer, &commit->object, error_func); if (err) return err; if (!commit->tree) return error_func(&commit->object, FSCK_ERROR, "could not load commit's tree %s", sha1_to_hex(tree_sha1)); return 0; }
static int get_alias(const char *var, const char *value, void *data) { struct string_list *list = data; if (skip_prefix(var, "alias.", &var)) string_list_append(list, var)->util = xstrdup(value); return 0; }
static const char *cleanup_path(const char *path) { /* Clean it up */ if (skip_prefix(path, "./", &path)) { while (*path == '/') path++; } return path; }
static int receive_unpack_status(int in) { const char *line = packet_read_line(in, NULL); if (!skip_prefix(line, "unpack ", &line)) return error(_("unable to parse remote unpack status: %s"), line); if (strcmp(line, "ok")) return error(_("remote unpack failed: %s"), line); return 0; }
int urlmatch_config_entry(const char *var, const char *value, void *cb) { struct string_list_item *item; struct urlmatch_config *collect = cb; struct urlmatch_item matched = {0}; struct url_info *url = &collect->url; const char *key, *dot; struct strbuf synthkey = STRBUF_INIT; int retval; if (!skip_prefix(var, collect->section, &key) || *(key++) != '.') { if (collect->cascade_fn) return collect->cascade_fn(var, value, cb); return 0; /* not interested */ } dot = strrchr(key, '.'); if (dot) { char *config_url, *norm_url; struct url_info norm_info; config_url = xmemdupz(key, dot - key); norm_url = url_normalize_1(config_url, &norm_info, 1); free(config_url); if (!norm_url) return 0; retval = match_urls(url, &norm_info, &matched); free(norm_url); if (!retval) return 0; key = dot + 1; } if (collect->key && strcmp(key, collect->key)) return 0; item = string_list_insert(&collect->vars, key); if (!item->util) { item->util = xcalloc(1, sizeof(matched)); } else { if (cmp_matches(&matched, item->util) < 0) /* * Our match is worse than the old one, * we cannot use it. */ return 0; /* Otherwise, replace it with this one. */ } memcpy(item->util, &matched, sizeof(matched)); strbuf_addstr(&synthkey, collect->section); strbuf_addch(&synthkey, '.'); strbuf_addstr(&synthkey, key); retval = collect->collect_fn(synthkey.buf, value, collect->cb); strbuf_release(&synthkey); return retval; }
/* * If the git_dir is not directly inside the working tree, then git will not * find it by default, and we need to set the worktree explicitly. */ static int needs_work_tree_config(const char *git_dir, const char *work_tree) { if (!strcmp(work_tree, "/") && !strcmp(git_dir, "/.git")) return 0; if (skip_prefix(git_dir, work_tree, &git_dir) && !strcmp(git_dir, "/.git")) return 0; return 1; }
static int read_request(FILE *fh, struct credential *c, struct strbuf *action, int *timeout) { static struct strbuf item = STRBUF_INIT; const char *p; strbuf_getline(&item, fh, '\n'); if (!skip_prefix(item.buf, "action=", &p)) return error("client sent bogus action line: %s", item.buf); strbuf_addstr(action, p); strbuf_getline(&item, fh, '\n'); if (!skip_prefix(item.buf, "timeout=", &p)) return error("client sent bogus timeout line: %s", item.buf); *timeout = atoi(p); if (credential_read(c, fh) < 0) return -1; return 0; }