summaryrefslogtreecommitdiff
path: root/src/signature.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/signature.c')
-rw-r--r--src/signature.c333
1 files changed, 0 insertions, 333 deletions
diff --git a/src/signature.c b/src/signature.c
deleted file mode 100644
index 1efda212a..000000000
--- a/src/signature.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Copyright (C) the libgit2 contributors. All rights reserved.
- *
- * This file is part of libgit2, distributed under the GNU GPL v2 with
- * a Linking Exception. For full terms see the included COPYING file.
- */
-
-#include "signature.h"
-
-#include "repository.h"
-#include "git2/common.h"
-#include "posix.h"
-
-void git_signature_free(git_signature *sig)
-{
- if (sig == NULL)
- return;
-
- git__free(sig->name);
- sig->name = NULL;
- git__free(sig->email);
- sig->email = NULL;
- git__free(sig);
-}
-
-static int signature_error(const char *msg)
-{
- git_error_set(GIT_ERROR_INVALID, "failed to parse signature - %s", msg);
- return -1;
-}
-
-static bool contains_angle_brackets(const char *input)
-{
- return strchr(input, '<') != NULL || strchr(input, '>') != NULL;
-}
-
-static bool is_crud(unsigned char c)
-{
- return c <= 32 ||
- c == '.' ||
- c == ',' ||
- c == ':' ||
- c == ';' ||
- c == '<' ||
- c == '>' ||
- c == '"' ||
- c == '\\' ||
- c == '\'';
-}
-
-static char *extract_trimmed(const char *ptr, size_t len)
-{
- while (len && is_crud((unsigned char)ptr[0])) {
- ptr++; len--;
- }
-
- while (len && is_crud((unsigned char)ptr[len - 1])) {
- len--;
- }
-
- return git__substrdup(ptr, len);
-}
-
-int git_signature_new(git_signature **sig_out, const char *name, const char *email, git_time_t time, int offset)
-{
- git_signature *p = NULL;
-
- GIT_ASSERT_ARG(name);
- GIT_ASSERT_ARG(email);
-
- *sig_out = NULL;
-
- if (contains_angle_brackets(name) ||
- contains_angle_brackets(email)) {
- return signature_error(
- "Neither `name` nor `email` should contain angle brackets chars.");
- }
-
- p = git__calloc(1, sizeof(git_signature));
- GIT_ERROR_CHECK_ALLOC(p);
-
- p->name = extract_trimmed(name, strlen(name));
- GIT_ERROR_CHECK_ALLOC(p->name);
- p->email = extract_trimmed(email, strlen(email));
- GIT_ERROR_CHECK_ALLOC(p->email);
-
- if (p->name[0] == '\0' || p->email[0] == '\0') {
- git_signature_free(p);
- return signature_error("Signature cannot have an empty name or email");
- }
-
- p->when.time = time;
- p->when.offset = offset;
- p->when.sign = (offset < 0) ? '-' : '+';
-
- *sig_out = p;
- return 0;
-}
-
-int git_signature_dup(git_signature **dest, const git_signature *source)
-{
- git_signature *signature;
-
- if (source == NULL)
- return 0;
-
- signature = git__calloc(1, sizeof(git_signature));
- GIT_ERROR_CHECK_ALLOC(signature);
-
- signature->name = git__strdup(source->name);
- GIT_ERROR_CHECK_ALLOC(signature->name);
-
- signature->email = git__strdup(source->email);
- GIT_ERROR_CHECK_ALLOC(signature->email);
-
- signature->when.time = source->when.time;
- signature->when.offset = source->when.offset;
- signature->when.sign = source->when.sign;
-
- *dest = signature;
-
- return 0;
-}
-
-int git_signature__pdup(git_signature **dest, const git_signature *source, git_pool *pool)
-{
- git_signature *signature;
-
- if (source == NULL)
- return 0;
-
- signature = git_pool_mallocz(pool, sizeof(git_signature));
- GIT_ERROR_CHECK_ALLOC(signature);
-
- signature->name = git_pool_strdup(pool, source->name);
- GIT_ERROR_CHECK_ALLOC(signature->name);
-
- signature->email = git_pool_strdup(pool, source->email);
- GIT_ERROR_CHECK_ALLOC(signature->email);
-
- signature->when.time = source->when.time;
- signature->when.offset = source->when.offset;
- signature->when.sign = source->when.sign;
-
- *dest = signature;
-
- return 0;
-}
-
-int git_signature_now(git_signature **sig_out, const char *name, const char *email)
-{
- time_t now;
- time_t offset;
- struct tm *utc_tm;
- git_signature *sig;
- struct tm _utc;
-
- *sig_out = NULL;
-
- /*
- * Get the current time as seconds since the epoch and
- * transform that into a tm struct containing the time at
- * UTC. Give that to mktime which considers it a local time
- * (tm_isdst = -1 asks it to take DST into account) and gives
- * us that time as seconds since the epoch. The difference
- * between its return value and 'now' is our offset to UTC.
- */
- time(&now);
- utc_tm = p_gmtime_r(&now, &_utc);
- utc_tm->tm_isdst = -1;
- offset = (time_t)difftime(now, mktime(utc_tm));
- offset /= 60;
-
- if (git_signature_new(&sig, name, email, now, (int)offset) < 0)
- return -1;
-
- *sig_out = sig;
-
- return 0;
-}
-
-int git_signature_default(git_signature **out, git_repository *repo)
-{
- int error;
- git_config *cfg;
- const char *user_name, *user_email;
-
- if ((error = git_repository_config_snapshot(&cfg, repo)) < 0)
- return error;
-
- if (!(error = git_config_get_string(&user_name, cfg, "user.name")) &&
- !(error = git_config_get_string(&user_email, cfg, "user.email")))
- error = git_signature_now(out, user_name, user_email);
-
- git_config_free(cfg);
- return error;
-}
-
-int git_signature__parse(git_signature *sig, const char **buffer_out,
- const char *buffer_end, const char *header, char ender)
-{
- const char *buffer = *buffer_out;
- const char *email_start, *email_end;
-
- memset(sig, 0, sizeof(git_signature));
-
- if (ender &&
- (buffer_end = memchr(buffer, ender, buffer_end - buffer)) == NULL)
- return signature_error("no newline given");
-
- if (header) {
- const size_t header_len = strlen(header);
-
- if (buffer + header_len >= buffer_end || memcmp(buffer, header, header_len) != 0)
- return signature_error("expected prefix doesn't match actual");
-
- buffer += header_len;
- }
-
- email_start = git__memrchr(buffer, '<', buffer_end - buffer);
- email_end = git__memrchr(buffer, '>', buffer_end - buffer);
-
- if (!email_start || !email_end || email_end <= email_start)
- return signature_error("malformed e-mail");
-
- email_start += 1;
- sig->name = extract_trimmed(buffer, email_start - buffer - 1);
- sig->email = extract_trimmed(email_start, email_end - email_start);
-
- /* Do we even have a time at the end of the signature? */
- if (email_end + 2 < buffer_end) {
- const char *time_start = email_end + 2;
- const char *time_end;
-
- if (git__strntol64(&sig->when.time, time_start,
- buffer_end - time_start, &time_end, 10) < 0) {
- git__free(sig->name);
- git__free(sig->email);
- sig->name = sig->email = NULL;
- return signature_error("invalid Unix timestamp");
- }
-
- /* do we have a timezone? */
- if (time_end + 1 < buffer_end) {
- int offset, hours, mins;
- const char *tz_start, *tz_end;
-
- tz_start = time_end + 1;
-
- if ((tz_start[0] != '-' && tz_start[0] != '+') ||
- git__strntol32(&offset, tz_start + 1,
- buffer_end - tz_start - 1, &tz_end, 10) < 0) {
- /* malformed timezone, just assume it's zero */
- offset = 0;
- }
-
- hours = offset / 100;
- mins = offset % 100;
-
- /*
- * only store timezone if it's not overflowing;
- * see http://www.worldtimezone.com/faq.html
- */
- if (hours <= 14 && mins <= 59) {
- sig->when.offset = (hours * 60) + mins;
- sig->when.sign = tz_start[0];
- if (tz_start[0] == '-')
- sig->when.offset = -sig->when.offset;
- }
- }
- }
-
- *buffer_out = buffer_end + 1;
- return 0;
-}
-
-int git_signature_from_buffer(git_signature **out, const char *buf)
-{
- git_signature *sig;
- const char *buf_end;
- int error;
-
- GIT_ASSERT_ARG(out);
- GIT_ASSERT_ARG(buf);
-
- *out = NULL;
-
- sig = git__calloc(1, sizeof(git_signature));
- GIT_ERROR_CHECK_ALLOC(sig);
-
- buf_end = buf + strlen(buf);
- error = git_signature__parse(sig, &buf, buf_end, NULL, '\0');
-
- if (error)
- git__free(sig);
- else
- *out = sig;
-
- return error;
-}
-
-void git_signature__writebuf(git_buf *buf, const char *header, const git_signature *sig)
-{
- int offset, hours, mins;
- char sign;
-
- offset = sig->when.offset;
- sign = (sig->when.offset < 0 || sig->when.sign == '-') ? '-' : '+';
-
- if (offset < 0)
- offset = -offset;
-
- hours = offset / 60;
- mins = offset % 60;
-
- git_buf_printf(buf, "%s%s <%s> %u %c%02d%02d\n",
- header ? header : "", sig->name, sig->email,
- (unsigned)sig->when.time, sign, hours, mins);
-}
-
-bool git_signature__equal(const git_signature *one, const git_signature *two)
-{
- GIT_ASSERT_ARG(one);
- GIT_ASSERT_ARG(two);
-
- return
- git__strcmp(one->name, two->name) == 0 &&
- git__strcmp(one->email, two->email) == 0 &&
- one->when.time == two->when.time &&
- one->when.offset == two->when.offset &&
- one->when.sign == two->when.sign;
-}
-