*/
#include "cache.h"
-#include <pwd.h>
-#include <time.h>
-#include <ctype.h>
+static char git_default_date[50];
-static char real_email[1000];
-static char real_name[1000];
-static char real_date[50];
-
-int setup_ident(void)
+static void copy_gecos(struct passwd *w, char *name, int sz)
{
- int len;
- struct passwd *pw = getpwuid(getuid());
+ char *src, *dst;
+ int len, nlen;
- if (!pw)
- die("You don't exist. Go away!");
+ nlen = strlen(w->pw_name);
- /* Get the name ("gecos") */
- len = strlen(pw->pw_gecos);
- if (len >= sizeof(real_name))
+ /* Traditionally GECOS field had office phone numbers etc, separated
+ * with commas. Also & stands for capitalized form of the login name.
+ */
+
+ for (len = 0, dst = name, src = w->pw_gecos; len < sz; src++) {
+ int ch = *src;
+ if (ch != '&') {
+ *dst++ = ch;
+ if (ch == 0 || ch == ',')
+ break;
+ len++;
+ continue;
+ }
+ if (len + nlen < sz) {
+ /* Sorry, Mr. McDonald... */
+ *dst++ = toupper(*w->pw_name);
+ memcpy(dst, w->pw_name + 1, nlen - 1);
+ dst += nlen - 1;
+ }
+ }
+ if (len < sz)
+ name[len] = 0;
+ else
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)
+}
+
+static void copy_email(struct passwd *pw)
+{
+ /*
+ * Make up a fake email address
+ * (name + '@' + hostname [+ '.' + domainname])
+ */
+ int len = strlen(pw->pw_name);
+ if (len > sizeof(git_default_email)/2)
die("Your sysadmin must hate you!");
- memcpy(real_email, pw->pw_name, len);
- real_email[len++] = '@';
- gethostname(real_email + len, sizeof(real_email) - len);
-#ifndef NO_GETDOMAINNAME
- if (!strchr(real_email+len, '.')) {
- len = strlen(real_email);
- real_email[len++] = '.';
- getdomainname(real_email+len, sizeof(real_email)-len);
+ memcpy(git_default_email, pw->pw_name, len);
+ git_default_email[len++] = '@';
+ gethostname(git_default_email + len, sizeof(git_default_email) - len);
+ if (!strchr(git_default_email+len, '.')) {
+ struct hostent *he = gethostbyname(git_default_email + len);
+ char *domainname;
+
+ len = strlen(git_default_email);
+ git_default_email[len++] = '.';
+ if (he && (domainname = strchr(he->h_name, '.')))
+ strlcpy(git_default_email + len, domainname + 1,
+ sizeof(git_default_email) - len);
+ else
+ strlcpy(git_default_email + len, "(none)",
+ sizeof(git_default_email) - len);
}
-#endif
+}
+
+static void setup_ident(void)
+{
+ struct passwd *pw = NULL;
+
+ /* Get the name ("gecos") */
+ if (!git_default_name[0]) {
+ pw = getpwuid(getuid());
+ if (!pw)
+ die("You don't exist. Go away!");
+ copy_gecos(pw, git_default_name, sizeof(git_default_name));
+ }
+
+ if (!git_default_email[0]) {
+ if (!pw)
+ pw = getpwuid(getuid());
+ if (!pw)
+ die("You don't exist. Go away!");
+ copy_email(pw);
+ }
+
/* And set the default date */
- datestamp(real_date, sizeof(real_date));
- return 0;
+ if (!git_default_date[0])
+ datestamp(git_default_date, sizeof(git_default_date));
}
static int add_raw(char *buf, int size, int offset, const char *str)
/*
* Copy the rest to the buffer, but avoid the special
- * characters '\n' '<' and '>' that act as delimeters on
+ * characters '\n' '<' and '>' that act as delimiters on
* a identification line
*/
for (i = 0; i < len; i++) {
return offset;
}
-char *get_ident(const char *name, const char *email, const char *date_str)
+static const char au_env[] = "GIT_AUTHOR_NAME";
+static const char co_env[] = "GIT_COMMITTER_NAME";
+static const char *env_hint =
+"\n"
+"*** Your name cannot be determined from your system services (gecos).\n"
+"\n"
+"Run\n"
+"\n"
+" git config user.email \"you@email.com\"\n"
+" git config user.name \"Your Name\"\n"
+"\n"
+"To set the identity in this repository.\n"
+"Add --global to set your account\'s default\n"
+"\n";
+
+const char *fmt_ident(const char *name, const char *email,
+ const char *date_str, int error_on_no_name)
{
static char buffer[1000];
char date[50];
int i;
+ setup_ident();
if (!name)
- name = real_name;
+ name = git_default_name;
if (!email)
- email = real_email;
- strcpy(date, real_date);
+ email = git_default_email;
+
+ if (!*name) {
+ struct passwd *pw;
+
+ if (0 <= error_on_no_name &&
+ name == git_default_name && env_hint) {
+ fprintf(stderr, env_hint, au_env, co_env);
+ env_hint = NULL; /* warn only once, for "git-var -l" */
+ }
+ if (0 < error_on_no_name)
+ die("empty ident %s <%s> not allowed", name, email);
+ pw = getpwuid(getuid());
+ if (!pw)
+ die("You don't exist. Go away!");
+ strlcpy(git_default_name, pw->pw_name,
+ sizeof(git_default_name));
+ name = git_default_name;
+ }
+
+ strcpy(date, git_default_date);
if (date_str)
parse_date(date_str, date, sizeof(date));
return buffer;
}
-char *git_author_info(void)
+const char *git_author_info(int error_on_no_name)
{
- return get_ident(gitenv("GIT_AUTHOR_NAME"), gitenv("GIT_AUTHOR_EMAIL"), gitenv("GIT_AUTHOR_DATE"));
+ return fmt_ident(getenv("GIT_AUTHOR_NAME"),
+ getenv("GIT_AUTHOR_EMAIL"),
+ getenv("GIT_AUTHOR_DATE"),
+ error_on_no_name);
}
-char *git_committer_info(void)
+const char *git_committer_info(int error_on_no_name)
{
- return get_ident(gitenv("GIT_COMMITTER_NAME"), gitenv("GIT_COMMITTER_EMAIL"), gitenv("GIT_COMMITTER_DATE"));
+ return fmt_ident(getenv("GIT_COMMITTER_NAME"),
+ getenv("GIT_COMMITTER_EMAIL"),
+ getenv("GIT_COMMITTER_DATE"),
+ error_on_no_name);
}