summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Anshul Gupta <ansg191@anshulg.com> 2025-04-11 11:18:45 -0700
committerGravatar Anshul Gupta <ansg191@anshulg.com> 2025-04-11 11:18:45 -0700
commit31fe9b891bfe816841580a8da9a6fea9d7569413 (patch)
tree80f546f29fa7a2def4fb5ac78f42bcf06df9732a /src
parentbd38d13887edbe7fc775c2b4fe8719c8436f0962 (diff)
downloadgithub-mirror-31fe9b891bfe816841580a8da9a6fea9d7569413.tar.gz
github-mirror-31fe9b891bfe816841580a8da9a6fea9d7569413.tar.zst
github-mirror-31fe9b891bfe816841580a8da9a6fea9d7569413.zip
Support loading tokens from external files
Diffstat (limited to 'src')
-rw-r--r--src/config.c74
-rw-r--r--src/config.h5
2 files changed, 75 insertions, 4 deletions
diff --git a/src/config.c b/src/config.c
index 7f610a6..f143f55 100644
--- a/src/config.c
+++ b/src/config.c
@@ -10,6 +10,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/errno.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -80,6 +81,70 @@ static char *trim(char *start, char *end)
return start;
}
+/**
+ * Parse a token value from the config file.
+ * If the token is a file path, read the file and set the token to its contents.
+ * If not a file path, the raw token value is checked for validity.
+ * It then checks that the token starts with:
+ * - "ghp_"
+ * - "gho_"
+ * - "ghu_"
+ * - "ghs_"
+ * - "ghf_"
+ * @param value token value
+ * @param cfg config struct
+ * @return 0 on success, -1 on error
+ */
+static int parse_token(char *value, struct config *cfg)
+{
+ char *token = value;
+
+ // Open the file to check if it is a file
+ const int fd = open(value, O_RDONLY);
+ if (fd == -1) {
+ if (errno != ENOENT) {
+ perror("Error opening token file");
+ return -1;
+ }
+ // Not a file, token check
+ cfg->token_owned = 0;
+ goto token_check;
+ }
+
+ // Read the file
+ token = malloc(64);
+ if (!token) {
+ perror("Error allocating token buffer");
+ close(fd);
+ return -1;
+ }
+
+ // Read the file contents
+ const ssize_t bytes_read = read(fd, token, 64);
+ if (bytes_read < 0) {
+ perror("Error reading token file");
+ free(token);
+ close(fd);
+ return -1;
+ }
+ token[bytes_read] = '\0';
+
+ cfg->token_owned = 1;
+ close(fd);
+
+token_check:
+ if (!strncmp(token, "ghp_", 4) || !strncmp(token, "gho_", 4) ||
+ !strncmp(token, "ghu_", 4) || !strncmp(token, "ghs_", 4) ||
+ !strncmp(token, "ghf_", 4)) {
+ cfg->token = token;
+ } else {
+ fprintf(stderr, "Error: invalid token format: %s\n", token);
+ free(token);
+ return -1;
+ }
+ return 0;
+}
+
static int parse_line_inner(struct config *cfg, enum config_section section,
char *key, char *value)
{
@@ -92,9 +157,10 @@ static int parse_line_inner(struct config *cfg, enum config_section section,
case section_github:
if (!strcmp(key, "endpoint"))
cfg->endpoint = value;
- else if (!strcmp(key, "token"))
- cfg->token = value;
- else if (!strcmp(key, "user_agent"))
+ else if (!strcmp(key, "token")) {
+ if (parse_token(value, cfg) < 0)
+ return -1;
+ } else if (!strcmp(key, "user_agent"))
cfg->user_agent = value;
else if (!strcmp(key, "owner"))
cfg->owner = value;
@@ -264,5 +330,7 @@ void config_free(struct config *config)
if (!config || !config->contents)
return;
munmap(config->contents, config->contents_len);
+ if (config->token_owned)
+ free((char *) config->token);
free(config);
}
diff --git a/src/config.h b/src/config.h
index 2fa32d2..ece19d9 100644
--- a/src/config.h
+++ b/src/config.h
@@ -17,8 +17,11 @@ struct config {
char *contents;
size_t contents_len;
- const char *endpoint;
const char *token;
+ /// Whether the token's memory is owned or borrowed from contents
+ int token_owned;
+
+ const char *endpoint;
const char *user_agent;
/// The owner of the repositories