From: Junio C Hamano Date: Mon, 21 Dec 2015 18:59:07 +0000 (-0800) Subject: Merge branch 'jk/ident-loosen-getpwuid' X-Git-Tag: v2.7.0-rc2~5 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/5498c57cdd637eb4f42ce8e296ce9ca4ab66e289?ds=inline;hp=-c Merge branch 'jk/ident-loosen-getpwuid' When getpwuid() on the system returned NULL (e.g. the user is not in the /etc/passwd file or other uid-to-name mappings), the codepath to find who the user is to record it in the reflog barfed and died. Loosen the check in this codepath, which already accepts questionable ident string (e.g. host part of the e-mail address is obviously bogus), and in general when we operate fmt_ident() function in non-strict mode. * jk/ident-loosen-getpwuid: ident: loosen getpwuid error in non-strict mode ident: keep a flag for bogus default_email ident: make xgetpwuid_self() a static local helper --- 5498c57cdd637eb4f42ce8e296ce9ca4ab66e289 diff --combined git-compat-util.h index 8e3986791d,0feeae2983..2da0a75a38 --- a/git-compat-util.h +++ b/git-compat-util.h @@@ -229,7 -229,7 +229,7 @@@ typedef unsigned long uintptr_t #else #define precompose_str(in,i_nfd2nfc) #define precompose_argv(c,v) -#define probe_utf8_pathname_composition(a,b) +#define probe_utf8_pathname_composition() #endif #ifdef MKDIR_WO_TRAILING_SLASH @@@ -748,9 -748,6 +748,9 @@@ static inline size_t xsize_t(off_t len return (size_t)len; } +__attribute__((format (printf, 3, 4))) +extern int xsnprintf(char *dst, size_t max, const char *fmt, ...); + /* in ctype.c, for kwset users */ extern const unsigned char tolower_trans_tbl[256]; @@@ -821,9 -818,6 +821,9 @@@ static inline int strtoul_ui(char cons char *p; errno = 0; + /* negative values would be accepted by strtoul */ + if (strchr(s, '-')) + return -1; ul = strtoul(s, &p, base); if (errno || *p || p == s || (unsigned int) ul != ul) return -1; @@@ -929,9 -923,6 +929,6 @@@ int access_or_die(const char *path, in /* Warn on an inaccessible file that ought to be accessible */ void warn_on_inaccessible(const char *path); - /* Get the passwd entry for the UID of the current process. */ - struct passwd *xgetpwuid_self(void); - #ifdef GMTIME_UNRELIABLE_ERRORS struct tm *git_gmtime(const time_t *); struct tm *git_gmtime_r(const time_t *, struct tm *); diff --combined ident.c index 00a62e0c42,bb1b174352..daf7e1ea83 --- a/ident.c +++ b/ident.c @@@ -10,6 -10,8 +10,8 @@@ 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; #define IDENT_NAME_GIVEN 01 #define IDENT_MAIL_GIVEN 02 @@@ -23,6 -25,25 +25,25 @@@ static int author_ident_explicitly_give #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; @@@ -70,48 -91,29 +91,52 @@@ static int add_mailname_host(struct str return 0; } +static int canonical_name(const char *host, struct strbuf *out) +{ + int status = -1; + +#ifndef NO_IPV6 + struct addrinfo hints, *ai; + memset (&hints, '\0', sizeof (hints)); + hints.ai_flags = AI_CANONNAME; + if (!getaddrinfo(host, NULL, &hints, &ai)) { + if (ai && strchr(ai->ai_canonname, '.')) { + strbuf_addstr(out, ai->ai_canonname); + status = 0; + } + freeaddrinfo(ai); + } +#else + struct hostent *he = gethostbyname(host); + if (he && strchr(he->h_name, '.')) { + strbuf_addstr(out, he->h_name); + status = 0; + } +#endif /* NO_IPV6 */ + + return status; +} + - static void add_domainname(struct strbuf *out) + static void add_domainname(struct strbuf *out, int *is_bogus) { char buf[1024]; - struct hostent *he; 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 ((he = gethostbyname(buf)) && strchr(he->h_name, '.')) - strbuf_addstr(out, he->h_name); - else { ++ 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 -124,13 +147,13 @@@ 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 -146,8 +169,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; @@@ -332,12 -335,17 +358,17 @@@ const char *fmt_ident(const char *name fputs(env_hint, stderr); die("empty ident name (for <%s>) not allowed", email); } - pw = xgetpwuid_self(); + pw = xgetpwuid_self(NULL); name = pw->pw_name; } - if (strict && email == git_default_email.buf && - strstr(email, "(none)")) { + if (want_name && strict && + name == git_default_name.buf && default_name_is_bogus) { + fputs(env_hint, stderr); + die("unable to auto-detect name (got '%s')", name); + } + + if (strict && email == git_default_email.buf && default_email_is_bogus) { fputs(env_hint, stderr); die("unable to auto-detect email address (got '%s')", email); } diff --combined wrapper.c index 6fcaa4dc62,dae5675a96..c95e2906b8 --- a/wrapper.c +++ b/wrapper.c @@@ -601,18 -601,6 +601,6 @@@ int access_or_die(const char *path, in return ret; } - struct passwd *xgetpwuid_self(void) - { - struct passwd *pw; - - errno = 0; - pw = getpwuid(getuid()); - if (!pw) - die(_("unable to look up current user in the passwd file: %s"), - errno ? strerror(errno) : _("no such user")); - return pw; - } - char *xgetcwd(void) { struct strbuf sb = STRBUF_INIT; @@@ -621,22 -609,6 +609,22 @@@ return strbuf_detach(&sb, NULL); } +int xsnprintf(char *dst, size_t max, const char *fmt, ...) +{ + va_list ap; + int len; + + va_start(ap, fmt); + len = vsnprintf(dst, max, fmt, ap); + va_end(ap); + + if (len < 0) + die("BUG: your snprintf is broken"); + if (len >= max) + die("BUG: attempt to snprintf into too-small buffer"); + return len; +} + static int write_file_v(const char *path, int fatal, const char *fmt, va_list params) {