summaryrefslogtreecommitdiff
path: root/ident.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-07-12 11:49:27 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-12 11:49:27 -0700
commit6aa33f4035d547ac2bd629b1cfd9c46262809d73 (patch)
tree539198e1f042cdef705e654df8d995b6c2747227 /ident.c
parent26a2d8ae898f5442904dd2fbf89c5fe34480ea85 (diff)
downloadgit-6aa33f4035d547ac2bd629b1cfd9c46262809d73.tar.gz
Abstract out the "name <email> date" handling of commit-tree.c
We'll want to use it for the tagging too.
Diffstat (limited to 'ident.c')
-rw-r--r--ident.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/ident.c b/ident.c
new file mode 100644
index 0000000000..faff44175b
--- /dev/null
+++ b/ident.c
@@ -0,0 +1,138 @@
+/*
+ * ident.c
+ *
+ * create git identifier lines of the form "name <email> date"
+ *
+ * Copyright (C) 2005 Linus Torvalds
+ */
+#include "cache.h"
+
+#include <pwd.h>
+#include <time.h>
+#include <ctype.h>
+
+static char real_email[1000];
+static char real_name[1000];
+static char real_date[50];
+
+int setup_ident(void)
+{
+ int len;
+ struct passwd *pw = getpwuid(getuid());
+
+ if (!pw)
+ die("You don't exist. Go away!");
+
+ /* Get the name ("gecos") */
+ len = strlen(pw->pw_gecos);
+ if (len >= sizeof(real_name))
+ die("Your parents must have hated you");
+ memcpy(real_name, pw->pw_gecos, len+1);
+
+ /* Make up a fake email address (name + '@' + hostname [+ '.' + domainname]) */
+ len = strlen(pw->pw_name);
+ if (len > sizeof(real_email)/2)
+ die("Your parents must have hated you");
+ memcpy(real_email, pw->pw_name, len);
+ real_email[len++] = '@';
+ gethostname(real_email + len, sizeof(real_email) - len);
+ if (!strchr(real_email+len, '.')) {
+ len = strlen(real_email);
+ real_email[len++] = '.';
+ getdomainname(real_email+len, sizeof(real_email)-len);
+ }
+
+ /* And set the default date */
+ datestamp(real_date, sizeof(real_date));
+ return 0;
+}
+
+static int add_raw(char *buf, int size, int offset, const char *str)
+{
+ int len = strlen(str);
+ if (offset + len > size)
+ return size;
+ memcpy(buf + offset, str, len);
+ return offset + len;
+}
+
+static int crud(unsigned char c)
+{
+ static const char crud_array[256] = {
+ [0 ... 31] = 1,
+ [' '] = 1,
+ ['.'] = 1, [','] = 1,
+ [':'] = 1, [';'] = 1,
+ ['<'] = 1, ['>'] = 1,
+ ['"'] = 1, ['\''] = 1,
+ };
+ return crud_array[c];
+}
+
+/*
+ * Copy over a string to the destination, but avoid special
+ * characters ('\n', '<' and '>') and remove crud at the end
+ */
+static int copy(char *buf, int size, int offset, const char *src)
+{
+ int i, len;
+ unsigned char c;
+
+ /* Remove crud from the beginning.. */
+ while ((c = *src) != 0) {
+ if (!crud(c))
+ break;
+ src++;
+ }
+
+ /* Remove crud from the end.. */
+ len = strlen(src);
+ while (len > 0) {
+ c = src[len-1];
+ if (!crud(c))
+ break;
+ --len;
+ }
+
+ /*
+ * Copy the rest to the buffer, but avoid the special
+ * characters '\n' '<' and '>' that act as delimeters on
+ * a identification line
+ */
+ for (i = 0; i < len; i++) {
+ c = *src++;
+ switch (c) {
+ case '\n': case '<': case '>':
+ continue;
+ }
+ if (offset >= size)
+ return size;
+ buf[offset++] = c;
+ }
+ return offset;
+}
+
+char *get_ident(const char *name, const char *email, const char *date_str)
+{
+ static char buffer[1000];
+ char date[50];
+ int i;
+
+ if (!name)
+ name = real_name;
+ if (!email)
+ email = real_email;
+ strcpy(date, real_date);
+ if (date_str)
+ parse_date(date_str, date, sizeof(date));
+
+ i = copy(buffer, sizeof(buffer), 0, name);
+ i = add_raw(buffer, sizeof(buffer), i, " <");
+ i = copy(buffer, sizeof(buffer), i, email);
+ i = add_raw(buffer, sizeof(buffer), i, "> ");
+ i = copy(buffer, sizeof(buffer), i, date);
+ if (i >= sizeof(buffer))
+ die("Impossibly long personal identifier");
+ buffer[i] = 0;
+ return buffer;
+}