diff options
author | June McEnroe | 2019-12-19 21:55:05 +0000 |
---|---|---|
committer | Yigit Sever | 2023-07-21 03:03:49 +0300 |
commit | 284020825c91ec2c6704ab25f187b20656cf1300 (patch) | |
tree | 576cffd5bea9a8e525ae12b630c591545b3c9862 /ui-tree.c | |
parent | 1c9e818ddb4ad4601f3180cd9163625bd087f03a (diff) | |
download | cgit-284020825c91ec2c6704ab25f187b20656cf1300.tar.gz cgit-284020825c91ec2c6704ab25f187b20656cf1300.tar.bz2 cgit-284020825c91ec2c6704ab25f187b20656cf1300.zip |
ui-tree: show symlink targets in tree listing
Add links to symbolic link targets in tree listings, formatted like
"ls -l". Path normalization collapses any ".." components of the link.
Also fix up memory link on error path.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'ui-tree.c')
-rw-r--r-- | ui-tree.c | 22 |
1 files changed, 20 insertions, 2 deletions
@@ -204,9 +204,11 @@ static int ls_item(const struct object_id *oid, struct strbuf *base, | |||
204 | struct walk_tree_context *walk_tree_ctx = cbdata; | 204 | struct walk_tree_context *walk_tree_ctx = cbdata; |
205 | char *name; | 205 | char *name; |
206 | struct strbuf fullpath = STRBUF_INIT; | 206 | struct strbuf fullpath = STRBUF_INIT; |
207 | struct strbuf linkpath = STRBUF_INIT; | ||
207 | struct strbuf class = STRBUF_INIT; | 208 | struct strbuf class = STRBUF_INIT; |
208 | enum object_type type; | 209 | enum object_type type; |
209 | unsigned long size = 0; | 210 | unsigned long size = 0; |
211 | char *buf; | ||
210 | 212 | ||
211 | name = xstrdup(pathname); | 213 | name = xstrdup(pathname); |
212 | strbuf_addf(&fullpath, "%s%s%s", ctx.qry.path ? ctx.qry.path : "", | 214 | strbuf_addf(&fullpath, "%s%s%s", ctx.qry.path ? ctx.qry.path : "", |
@@ -218,8 +220,7 @@ static int ls_item(const struct object_id *oid, struct strbuf *base, | |||
218 | htmlf("<tr><td colspan='3'>bad object: %s %s</td></tr>", | 220 | htmlf("<tr><td colspan='3'>bad object: %s %s</td></tr>", |
219 | name, | 221 | name, |
220 | oid_to_hex(oid)); | 222 | oid_to_hex(oid)); |
221 | free(name); | 223 | goto cleanup; |
222 | return 0; | ||
223 | } | 224 | } |
224 | } | 225 | } |
225 | 226 | ||
@@ -239,6 +240,21 @@ static int ls_item(const struct object_id *oid, struct strbuf *base, | |||
239 | cgit_tree_link(name, NULL, class.buf, ctx.qry.head, | 240 | cgit_tree_link(name, NULL, class.buf, ctx.qry.head, |
240 | walk_tree_ctx->curr_rev, fullpath.buf); | 241 | walk_tree_ctx->curr_rev, fullpath.buf); |
241 | } | 242 | } |
243 | if (S_ISLNK(mode)) { | ||
244 | html(" -> "); | ||
245 | buf = read_object_file(oid, &type, &size); | ||
246 | if (!buf) { | ||
247 | htmlf("Error reading object: %s", oid_to_hex(oid)); | ||
248 | goto cleanup; | ||
249 | } | ||
250 | strbuf_addbuf(&linkpath, &fullpath); | ||
251 | strbuf_addf(&linkpath, "/../%s", buf); | ||
252 | strbuf_normalize_path(&linkpath); | ||
253 | cgit_tree_link(buf, NULL, class.buf, ctx.qry.head, | ||
254 | walk_tree_ctx->curr_rev, linkpath.buf); | ||
255 | free(buf); | ||
256 | strbuf_release(&linkpath); | ||
257 | } | ||
242 | htmlf("</td><td class='ls-size'>%li</td>", size); | 258 | htmlf("</td><td class='ls-size'>%li</td>", size); |
243 | 259 | ||
244 | html("<td>"); | 260 | html("<td>"); |
@@ -255,6 +271,8 @@ static int ls_item(const struct object_id *oid, struct strbuf *base, | |||
255 | cgit_blame_link("blame", NULL, "button", ctx.qry.head, | 271 | cgit_blame_link("blame", NULL, "button", ctx.qry.head, |
256 | walk_tree_ctx->curr_rev, fullpath.buf); | 272 | walk_tree_ctx->curr_rev, fullpath.buf); |
257 | html("</td></tr>\n"); | 273 | html("</td></tr>\n"); |
274 | |||
275 | cleanup: | ||
258 | free(name); | 276 | free(name); |
259 | strbuf_release(&fullpath); | 277 | strbuf_release(&fullpath); |
260 | strbuf_release(&class); | 278 | strbuf_release(&class); |