| 1455 | } |
| 1456 | |
| 1457 | int for_each_file_in_obj_subdir(unsigned int subdir_nr, |
| 1458 | struct strbuf *path, |
| 1459 | const struct git_hash_algo *algop, |
| 1460 | each_loose_object_fn obj_cb, |
| 1461 | each_loose_cruft_fn cruft_cb, |
| 1462 | each_loose_subdir_fn subdir_cb, |
| 1463 | void *data) |
| 1464 | { |
| 1465 | size_t origlen, baselen; |
| 1466 | DIR *dir; |
| 1467 | struct dirent *de; |
| 1468 | int r = 0; |
| 1469 | struct object_id oid; |
| 1470 | |
| 1471 | if (subdir_nr > 0xff) |
| 1472 | BUG("invalid loose object subdirectory: %x", subdir_nr); |
| 1473 | |
| 1474 | origlen = path->len; |
| 1475 | strbuf_complete(path, '/'); |
| 1476 | strbuf_addf(path, "%02x", subdir_nr); |
| 1477 | |
| 1478 | dir = opendir(path->buf); |
| 1479 | if (!dir) { |
| 1480 | if (errno != ENOENT) |
| 1481 | r = error_errno(_("unable to open %s"), path->buf); |
| 1482 | strbuf_setlen(path, origlen); |
| 1483 | return r; |
| 1484 | } |
| 1485 | |
| 1486 | oid.hash[0] = subdir_nr; |
| 1487 | strbuf_addch(path, '/'); |
| 1488 | baselen = path->len; |
| 1489 | |
| 1490 | while ((de = readdir_skip_dot_and_dotdot(dir))) { |
| 1491 | size_t namelen; |
| 1492 | |
| 1493 | namelen = strlen(de->d_name); |
| 1494 | strbuf_setlen(path, baselen); |
| 1495 | strbuf_add(path, de->d_name, namelen); |
| 1496 | if (namelen == algop->hexsz - 2 && |
| 1497 | !hex_to_bytes(oid.hash + 1, de->d_name, |
| 1498 | algop->rawsz - 1)) { |
| 1499 | oid_set_algo(&oid, algop); |
| 1500 | memset(oid.hash + algop->rawsz, 0, |
| 1501 | GIT_MAX_RAWSZ - algop->rawsz); |
| 1502 | if (obj_cb) { |
| 1503 | r = obj_cb(&oid, path->buf, data); |
| 1504 | if (r) |
| 1505 | break; |
| 1506 | } |
| 1507 | continue; |
| 1508 | } |
| 1509 | |
| 1510 | if (cruft_cb) { |
| 1511 | r = cruft_cb(de->d_name, path->buf, data); |
| 1512 | if (r) |
| 1513 | break; |
| 1514 | } |
no test coverage detected