| 350 | } |
| 351 | |
| 352 | static int validate_headref(const char *path) |
| 353 | { |
| 354 | struct stat st; |
| 355 | char buffer[256]; |
| 356 | const char *refname; |
| 357 | struct object_id oid; |
| 358 | int fd; |
| 359 | ssize_t len; |
| 360 | |
| 361 | if (lstat(path, &st) < 0) |
| 362 | return -1; |
| 363 | |
| 364 | /* Make sure it is a "refs/.." symlink */ |
| 365 | if (S_ISLNK(st.st_mode)) { |
| 366 | len = readlink(path, buffer, sizeof(buffer)-1); |
| 367 | if (len >= 5 && !memcmp("refs/", buffer, 5)) |
| 368 | return 0; |
| 369 | return -1; |
| 370 | } |
| 371 | |
| 372 | /* |
| 373 | * Anything else, just open it and try to see if it is a symbolic ref. |
| 374 | */ |
| 375 | fd = open(path, O_RDONLY); |
| 376 | if (fd < 0) |
| 377 | return -1; |
| 378 | len = read_in_full(fd, buffer, sizeof(buffer)-1); |
| 379 | close(fd); |
| 380 | |
| 381 | if (len < 0) |
| 382 | return -1; |
| 383 | buffer[len] = '\0'; |
| 384 | |
| 385 | /* |
| 386 | * Is it a symbolic ref? |
| 387 | */ |
| 388 | if (skip_prefix(buffer, "ref:", &refname)) { |
| 389 | while (isspace(*refname)) |
| 390 | refname++; |
| 391 | if (starts_with(refname, "refs/")) |
| 392 | return 0; |
| 393 | } |
| 394 | |
| 395 | /* |
| 396 | * Is this a detached HEAD? |
| 397 | */ |
| 398 | if (get_oid_hex_any(buffer, &oid) != GIT_HASH_UNKNOWN) |
| 399 | return 0; |
| 400 | |
| 401 | return -1; |
| 402 | } |
| 403 | |
| 404 | /* |
| 405 | * Test if it looks like we're at a git directory. |
no test coverage detected