Skip to content

Commit b23e25a

Browse files
authored
Merge pull request #186 from jserv/check-recent-commit
Ensure repository currency
2 parents a8f4970 + f424d1d commit b23e25a

File tree

1 file changed

+109
-0
lines changed

1 file changed

+109
-0
lines changed

qtest.c

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,6 +1173,108 @@ static void usage(char *cmd)
11731173
exit(0);
11741174
}
11751175

1176+
extern char **environ;
1177+
1178+
/* Returns true if the hash is exactly 40 hexadecimal characters. */
1179+
static inline bool is_valid_sha1(const char *hash)
1180+
{
1181+
size_t len = strlen(hash);
1182+
if (len != 40)
1183+
return false;
1184+
for (size_t i = 0; i < len; i++) {
1185+
char c = hash[i];
1186+
if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
1187+
(c >= 'A' && c <= 'F'))) {
1188+
return false;
1189+
}
1190+
}
1191+
return true;
1192+
}
1193+
1194+
/* Checks if a specific SHA-1 commit exists in the git log. */
1195+
bool commit_exists(const char *commit_hash)
1196+
{
1197+
/* Verify the commit_hash is a valid SHA-1 hash */
1198+
if (!is_valid_sha1(commit_hash))
1199+
return false;
1200+
1201+
int pipefd[2];
1202+
if (pipe(pipefd) == -1) {
1203+
/* Error creating pipe */
1204+
perror("pipe");
1205+
return false;
1206+
}
1207+
1208+
posix_spawn_file_actions_t actions;
1209+
if (posix_spawn_file_actions_init(&actions) != 0) {
1210+
/* Error initializing spawn file actions */
1211+
perror("posix_spawn_file_actions_init");
1212+
close(pipefd[0]);
1213+
close(pipefd[1]);
1214+
return false;
1215+
}
1216+
1217+
/* Redirect child's stdout to the pipe's write end */
1218+
if (posix_spawn_file_actions_adddup2(&actions, pipefd[1], STDOUT_FILENO) !=
1219+
0) {
1220+
perror("posix_spawn_file_actions_adddup2");
1221+
posix_spawn_file_actions_destroy(&actions);
1222+
close(pipefd[0]);
1223+
close(pipefd[1]);
1224+
return false;
1225+
}
1226+
1227+
/* Close unused pipe ends in the child */
1228+
if (posix_spawn_file_actions_addclose(&actions, pipefd[0]) != 0 ||
1229+
posix_spawn_file_actions_addclose(&actions, pipefd[1]) != 0) {
1230+
perror("posix_spawn_file_actions_addclose");
1231+
posix_spawn_file_actions_destroy(&actions);
1232+
close(pipefd[0]);
1233+
close(pipefd[1]);
1234+
return false;
1235+
}
1236+
1237+
pid_t pid;
1238+
/* Use "--no-abbrev-commit" to ensure full SHA-1 hash is printed */
1239+
char *argv[] = {"git", "log", "--pretty=oneline", "--no-abbrev-commit",
1240+
NULL};
1241+
int spawn_ret = posix_spawnp(&pid, "git", &actions, NULL, argv, environ);
1242+
posix_spawn_file_actions_destroy(&actions);
1243+
if (spawn_ret != 0) {
1244+
/* Error spawning git process */
1245+
fprintf(stderr, "posix_spawnp failed: %s\n", strerror(spawn_ret));
1246+
close(pipefd[0]);
1247+
return false;
1248+
}
1249+
1250+
/* Parent process: close the write end of the pipe */
1251+
close(pipefd[1]);
1252+
1253+
FILE *stream = fdopen(pipefd[0], "r");
1254+
if (stream == NULL) {
1255+
/* Error converting file descriptor to stream */
1256+
perror("fdopen");
1257+
return false;
1258+
}
1259+
1260+
bool found = false;
1261+
char buffer[1024];
1262+
while (fgets(buffer, sizeof(buffer), stream)) {
1263+
/* Compare the first 40 characters of each line with commit_hash */
1264+
if (strncmp(buffer, commit_hash, 40) == 0) {
1265+
found = true;
1266+
break;
1267+
}
1268+
}
1269+
fclose(stream);
1270+
1271+
/* Wait for the child process to finish */
1272+
int status;
1273+
waitpid(pid, &status, 0);
1274+
1275+
return found;
1276+
}
1277+
11761278
#define GIT_HOOK ".git/hooks/"
11771279
static bool sanity_check()
11781280
{
@@ -1202,6 +1304,13 @@ static bool sanity_check()
12021304
}
12031305
return false;
12041306
}
1307+
#define COPYRIGHT_COMMIT_SHA1 "50c5ac53d31adf6baac4f8d3db6b3ce2215fee40"
1308+
if (!commit_exists(COPYRIGHT_COMMIT_SHA1)) {
1309+
fprintf(stderr,
1310+
"FATAL: The repository is outdated. Please update properly.\n");
1311+
return false;
1312+
}
1313+
12051314
return true;
12061315
}
12071316

0 commit comments

Comments
 (0)