avoid unnecessary string copies and allocations in get_packfile_size()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
diff --git a/lib/pack.c b/lib/pack.c
index 10e8be9..392de87 100644
--- a/lib/pack.c
+++ b/lib/pack.c
@@ -74,29 +74,41 @@ verify_fanout_table(uint32_t *fanout_table)
}
static const struct got_error *
-get_packfile_size(size_t *size, const char *path_idx)
+get_packfile_size(size_t *size, const char *path)
{
struct stat sb;
- char *path_pack;
- char base_path[PATH_MAX];
char *dot;
- if (strlcpy(base_path, path_idx, PATH_MAX) > PATH_MAX)
- return got_error(GOT_ERR_NO_SPACE);
-
- dot = strrchr(base_path, '.');
+ dot = strrchr(path, '.');
if (dot == NULL)
return got_error(GOT_ERR_BAD_PATH);
- *dot = '\0';
- if (asprintf(&path_pack, "%s.pack", base_path) == -1)
- return got_error_from_errno();
- if (stat(path_pack, &sb) != 0) {
+ /* Path must point to a pack index or to a pack file. */
+ if (strcmp(dot, ".idx") == 0) {
+ char *path_pack;
+ char base_path[PATH_MAX];
+
+ /* Convert pack index path to pack file path. */
+ if (strlcpy(base_path, path, PATH_MAX) > PATH_MAX)
+ return got_error(GOT_ERR_NO_SPACE);
+ dot = strrchr(base_path, '.');
+ if (dot == NULL)
+ return got_error(GOT_ERR_BAD_PATH);
+ *dot = '\0';
+ if (asprintf(&path_pack, "%s.pack", base_path) == -1)
+ return got_error_from_errno();
+
+ if (stat(path_pack, &sb) != 0) {
+ free(path_pack);
+ return got_error_from_errno();
+ }
free(path_pack);
- return got_error_from_errno();
- }
+ } else if (strcmp(dot, ".pack") == 0) {
+ if (stat(path, &sb) != 0)
+ return got_error_from_errno();
+ } else
+ return got_error(GOT_ERR_BAD_PATH);
- free(path_pack);
*size = sb.st_size;
return 0;
}