Merge branch 'ew/connect-verbose'
[gitweb.git] / ident.c
diff --git a/ident.c b/ident.c
index 4e7f99d5dd79745e53c55e8ae39ab12dc39789df..6e125821f0563c46eaf8253f31e19d9d97a94e7e 100644 (file)
--- a/ident.c
+++ b/ident.c
 static struct strbuf git_default_name = STRBUF_INIT;
 static struct strbuf git_default_email = STRBUF_INIT;
 static struct strbuf git_default_date = STRBUF_INIT;
+static int default_email_is_bogus;
+static int default_name_is_bogus;
+
+static int ident_use_config_only;
 
 #define IDENT_NAME_GIVEN 01
 #define IDENT_MAIL_GIVEN 02
 #define IDENT_ALL_GIVEN (IDENT_NAME_GIVEN|IDENT_MAIL_GIVEN)
 static int committer_ident_explicitly_given;
 static int author_ident_explicitly_given;
+static int ident_config_given;
 
 #ifdef NO_GECOS_IN_PWENT
 #define get_gecos(ignored) "&"
@@ -23,6 +28,25 @@ static int author_ident_explicitly_given;
 #define get_gecos(struct_passwd) ((struct_passwd)->pw_gecos)
 #endif
 
+static struct passwd *xgetpwuid_self(int *is_bogus)
+{
+       struct passwd *pw;
+
+       errno = 0;
+       pw = getpwuid(getuid());
+       if (!pw) {
+               static struct passwd fallback;
+               fallback.pw_name = "unknown";
+#ifndef NO_GECOS_IN_PWENT
+               fallback.pw_gecos = "Unknown";
+#endif
+               pw = &fallback;
+               if (is_bogus)
+                       *is_bogus = 1;
+       }
+       return pw;
+}
+
 static void copy_gecos(const struct passwd *w, struct strbuf *name)
 {
        char *src;
@@ -55,7 +79,7 @@ static int add_mailname_host(struct strbuf *buf)
                                strerror(errno));
                return -1;
        }
-       if (strbuf_getline(&mailnamebuf, mailname, '\n') == EOF) {
+       if (strbuf_getline(&mailnamebuf, mailname) == EOF) {
                if (ferror(mailname))
                        warning("cannot read /etc/mailname: %s",
                                strerror(errno));
@@ -86,7 +110,7 @@ static int canonical_name(const char *host, struct strbuf *out)
                freeaddrinfo(ai);
        }
 #else
-       struct hostent *he = gethostbyname(buf);
+       struct hostent *he = gethostbyname(host);
        if (he && strchr(he->h_name, '.')) {
                strbuf_addstr(out, he->h_name);
                status = 0;
@@ -96,22 +120,26 @@ static int canonical_name(const char *host, struct strbuf *out)
        return status;
 }
 
-static void add_domainname(struct strbuf *out)
+static void add_domainname(struct strbuf *out, int *is_bogus)
 {
        char buf[1024];
 
        if (gethostname(buf, sizeof(buf))) {
                warning("cannot get host name: %s", strerror(errno));
                strbuf_addstr(out, "(none)");
+               *is_bogus = 1;
                return;
        }
        if (strchr(buf, '.'))
                strbuf_addstr(out, buf);
-       else if (canonical_name(buf, out) < 0)
+       else if (canonical_name(buf, out) < 0) {
                strbuf_addf(out, "%s.(none)", buf);
+               *is_bogus = 1;
+       }
 }
 
-static void copy_email(const struct passwd *pw, struct strbuf *email)
+static void copy_email(const struct passwd *pw, struct strbuf *email,
+                      int *is_bogus)
 {
        /*
         * Make up a fake email address
@@ -122,13 +150,13 @@ static void copy_email(const struct passwd *pw, struct strbuf *email)
 
        if (!add_mailname_host(email))
                return; /* read from "/etc/mailname" (Debian) */
-       add_domainname(email);
+       add_domainname(email, is_bogus);
 }
 
 const char *ident_default_name(void)
 {
        if (!git_default_name.len) {
-               copy_gecos(xgetpwuid_self(), &git_default_name);
+               copy_gecos(xgetpwuid_self(&default_name_is_bogus), &git_default_name);
                strbuf_trim(&git_default_name);
        }
        return git_default_name.buf;
@@ -144,7 +172,8 @@ const char *ident_default_email(void)
                        committer_ident_explicitly_given |= IDENT_MAIL_GIVEN;
                        author_ident_explicitly_given |= IDENT_MAIL_GIVEN;
                } else
-                       copy_email(xgetpwuid_self(), &git_default_email);
+                       copy_email(xgetpwuid_self(&default_email_is_bogus),
+                                  &git_default_email, &default_email_is_bogus);
                strbuf_trim(&git_default_email);
        }
        return git_default_email.buf;
@@ -319,27 +348,40 @@ const char *fmt_ident(const char *name, const char *email,
        int want_date = !(flag & IDENT_NO_DATE);
        int want_name = !(flag & IDENT_NO_NAME);
 
-       if (want_name && !name)
-               name = ident_default_name();
-       if (!email)
-               email = ident_default_email();
-
-       if (want_name && !*name) {
-               struct passwd *pw;
-
-               if (strict) {
-                       if (name == git_default_name.buf)
+       if (want_name) {
+               int using_default = 0;
+               if (!name) {
+                       name = ident_default_name();
+                       using_default = 1;
+                       if (strict && default_name_is_bogus) {
                                fputs(env_hint, stderr);
-                       die("empty ident name (for <%s>) not allowed", email);
+                               die("unable to auto-detect name (got '%s')", name);
+                       }
+                       if (strict && ident_use_config_only
+                           && !(ident_config_given & IDENT_NAME_GIVEN))
+                               die("user.useConfigOnly set but no name given");
+               }
+               if (!*name) {
+                       struct passwd *pw;
+                       if (strict) {
+                               if (using_default)
+                                       fputs(env_hint, stderr);
+                               die("empty ident name (for <%s>) not allowed", email);
+                       }
+                       pw = xgetpwuid_self(NULL);
+                       name = pw->pw_name;
                }
-               pw = xgetpwuid_self();
-               name = pw->pw_name;
        }
 
-       if (strict && email == git_default_email.buf &&
-           strstr(email, "(none)")) {
-               fputs(env_hint, stderr);
-               die("unable to auto-detect email address (got '%s')", email);
+       if (!email) {
+               email = ident_default_email();
+               if (strict && default_email_is_bogus) {
+                       fputs(env_hint, stderr);
+                       die("unable to auto-detect email address (got '%s')", email);
+               }
+               if (strict && ident_use_config_only
+                   && !(ident_config_given & IDENT_MAIL_GIVEN))
+                       die("user.useConfigOnly set but no mail given");
        }
 
        strbuf_reset(&ident);
@@ -413,6 +455,11 @@ int author_ident_sufficiently_given(void)
 
 int git_ident_config(const char *var, const char *value, void *data)
 {
+       if (!strcmp(var, "user.useconfigonly")) {
+               ident_use_config_only = git_config_bool(var, value);
+               return 0;
+       }
+
        if (!strcmp(var, "user.name")) {
                if (!value)
                        return config_error_nonbool(var);
@@ -420,6 +467,7 @@ int git_ident_config(const char *var, const char *value, void *data)
                strbuf_addstr(&git_default_name, value);
                committer_ident_explicitly_given |= IDENT_NAME_GIVEN;
                author_ident_explicitly_given |= IDENT_NAME_GIVEN;
+               ident_config_given |= IDENT_NAME_GIVEN;
                return 0;
        }
 
@@ -430,6 +478,7 @@ int git_ident_config(const char *var, const char *value, void *data)
                strbuf_addstr(&git_default_email, value);
                committer_ident_explicitly_given |= IDENT_MAIL_GIVEN;
                author_ident_explicitly_given |= IDENT_MAIL_GIVEN;
+               ident_config_given |= IDENT_MAIL_GIVEN;
                return 0;
        }