12 static const struct got_error *
13 parse_symref(struct got_reference **ref, const char *name, const char *line)
15 struct got_symref *symref;
20 return got_error(GOT_ERR_NOT_REF);
22 symref_name = strdup(name);
23 if (symref_name == NULL)
24 return got_error(GOT_ERR_NO_MEM);
25 symref_ref = strdup(line);
26 if (symref_ref == NULL) {
28 return got_error(GOT_ERR_NO_MEM);
31 *ref = calloc(1, sizeof(**ref));
32 (*ref)->flags |= GOT_REF_IS_SYMBOLIC;
33 symref = &((*ref)->ref.symref);
34 symref->name = symref_name;
35 symref->ref = symref_ref;
40 parse_sha1_digest(uint8_t *digest, const char *line)
45 for (i = 0; i < SHA1_DIGEST_LENGTH; i++) {
46 n = sscanf(line, "%hhx", &b);
56 static const struct got_error *
57 parse_ref_line(struct got_reference **ref, const char *name, const char *line)
59 uint8_t digest[SHA1_DIGEST_LENGTH];
62 if (strncmp(line, "ref: ", 5) == 0) {
64 return parse_symref(ref, name, line);
67 ref_name = strdup(name);
69 return got_error(GOT_ERR_NO_MEM);
71 if (!parse_sha1_digest(digest, line))
72 return got_error(GOT_ERR_NOT_REF);
74 *ref = calloc(1, sizeof(**ref));
75 (*ref)->ref.ref.name = ref_name;
76 memcpy(&(*ref)->ref.ref.sha1, digest, SHA1_DIGEST_LENGTH);
80 static const struct got_error *
81 parse_ref_file(struct got_reference **ref, const char *name,
84 const struct got_error *err = NULL;
85 FILE *f = fopen(abspath, "rb");
88 const char delim[3] = {'\0', '\0', '\0'};
91 return got_error(GOT_ERR_NOT_REF);
93 line = fparseln(f, &len, NULL, delim, 0);
95 err = got_error(GOT_ERR_NOT_REF);
99 err = parse_ref_line(ref, name, line);
106 const struct got_error *
107 got_ref_open(struct got_reference **ref, const char *path_refs,
110 const struct got_error *err = NULL;
111 char *path_ref = NULL;
112 char *normpath = NULL;
113 const char *parent_dir;
115 /* XXX For now, this assumes that refs exist in the filesystem. */
117 if (asprintf(&path_ref, "%s/%s", path_refs, refname) == -1) {
118 err = got_error(GOT_ERR_NO_MEM);
122 normpath = got_path_normalize(path_ref);
123 if (normpath == NULL) {
124 err = got_error(GOT_ERR_NOT_REF);
128 err = parse_ref_file(ref, refname, normpath ? normpath : path_refs);
136 got_ref_close(struct got_reference *ref)
138 if (ref->flags & GOT_REF_IS_SYMBOLIC)
139 free(ref->ref.symref.name);
141 free(ref->ref.ref.name);