4 * create git identifier lines of the form "name <email> date"
6 * Copyright (C) 2005 Linus Torvalds
10 static char git_default_date
[50];
14 static void copy_gecos(const struct passwd
*w
, char *name
, size_t sz
)
19 nlen
= strlen(w
->pw_name
);
21 /* Traditionally GECOS field had office phone numbers etc, separated
22 * with commas. Also & stands for capitalized form of the login name.
25 for (len
= 0, dst
= name
, src
= w
->pw_gecos
; len
< sz
; src
++) {
29 if (ch
== 0 || ch
== ',')
34 if (len
+ nlen
< sz
) {
35 /* Sorry, Mr. McDonald... */
36 *dst
++ = toupper(*w
->pw_name
);
37 memcpy(dst
, w
->pw_name
+ 1, nlen
- 1);
44 die("Your parents must have hated you!");
48 static void copy_email(const struct passwd
*pw
)
51 * Make up a fake email address
52 * (name + '@' + hostname [+ '.' + domainname])
54 size_t len
= strlen(pw
->pw_name
);
55 if (len
> sizeof(git_default_email
)/2)
56 die("Your sysadmin must hate you!");
57 memcpy(git_default_email
, pw
->pw_name
, len
);
58 git_default_email
[len
++] = '@';
59 gethostname(git_default_email
+ len
, sizeof(git_default_email
) - len
);
60 if (!strchr(git_default_email
+len
, '.')) {
61 struct hostent
*he
= gethostbyname(git_default_email
+ len
);
64 len
= strlen(git_default_email
);
65 git_default_email
[len
++] = '.';
66 if (he
&& (domainname
= strchr(he
->h_name
, '.')))
67 strlcpy(git_default_email
+ len
, domainname
+ 1,
68 sizeof(git_default_email
) - len
);
70 strlcpy(git_default_email
+ len
, "(none)",
71 sizeof(git_default_email
) - len
);
77 static void setup_ident(void)
80 struct passwd
*pw
= NULL
;
82 /* Get the name ("gecos") */
83 if (!git_default_name
[0]) {
84 pw
= getpwuid(getuid());
86 die("You don't exist. Go away!");
87 copy_gecos(pw
, git_default_name
, sizeof(git_default_name
));
90 if (!git_default_email
[0]) {
91 const char *email
= getenv("EMAIL");
93 if (email
&& email
[0])
94 strlcpy(git_default_email
, email
,
95 sizeof(git_default_email
));
98 pw
= getpwuid(getuid());
100 die("You don't exist. Go away!");
106 /* And set the default date */
107 if (!git_default_date
[0])
108 datestamp(git_default_date
, sizeof(git_default_date
));
111 static int add_raw(char *buf
, size_t size
, int offset
, const char *str
)
113 size_t len
= strlen(str
);
114 if (offset
+ len
> size
)
116 memcpy(buf
+ offset
, str
, len
);
120 static int crud(unsigned char c
)
122 static char crud_array
[256];
123 static int crud_array_initialized
= 0;
125 if (!crud_array_initialized
) {
128 for (k
= 0; k
<= 31; ++k
) crud_array
[k
] = 1;
137 crud_array
['\''] = 1;
138 crud_array_initialized
= 1;
140 return crud_array
[c
];
144 * Copy over a string to the destination, but avoid special
145 * characters ('\n', '<' and '>') and remove crud at the end
147 static int copy(char *buf
, size_t size
, int offset
, const char *src
)
152 /* Remove crud from the beginning.. */
153 while ((c
= *src
) != 0) {
159 /* Remove crud from the end.. */
169 * Copy the rest to the buffer, but avoid the special
170 * characters '\n' '<' and '>' that act as delimiters on
171 * a identification line
173 for (i
= 0; i
< len
; i
++) {
176 case '\n': case '<': case '>':
186 static const char au_env
[] = "GIT_AUTHOR_NAME";
187 static const char co_env
[] = "GIT_COMMITTER_NAME";
188 static const char *env_hint
=
190 "*** Your name cannot be determined from your system services (gecos).\n"
194 " git config --global user.email \"you@email.com\"\n"
195 " git config --global user.name \"Your Name\"\n"
197 "to set your account\'s default identity.\n"
198 "Omit --global to set the identity only in this repository.\n"
201 const char *fmt_ident(const char *name
, const char *email
,
202 const char *date_str
, int error_on_no_name
)
204 static char buffer
[1000];
210 name
= git_default_name
;
212 email
= git_default_email
;
215 #ifndef NO_ETC_PASSWD
219 if (0 <= error_on_no_name
&&
220 name
== git_default_name
&& env_hint
) {
221 fprintf(stderr
, env_hint
, au_env
, co_env
);
222 env_hint
= NULL
; /* warn only once, for "git-var -l" */
224 if (0 < error_on_no_name
)
225 die("empty ident %s <%s> not allowed", name
, email
);
226 #ifndef NO_ETC_PASSWD
227 pw
= getpwuid(getuid());
229 die("You don't exist. Go away!");
230 strlcpy(git_default_name
, pw
->pw_name
,
231 sizeof(git_default_name
));
233 strlcpy(git_default_name
, "unknown",
234 sizeof(git_default_name
));
236 name
= git_default_name
;
239 strcpy(date
, git_default_date
);
241 parse_date(date_str
, date
, sizeof(date
));
243 i
= copy(buffer
, sizeof(buffer
), 0, name
);
244 i
= add_raw(buffer
, sizeof(buffer
), i
, " <");
245 i
= copy(buffer
, sizeof(buffer
), i
, email
);
246 i
= add_raw(buffer
, sizeof(buffer
), i
, "> ");
247 i
= copy(buffer
, sizeof(buffer
), i
, date
);
248 if (i
>= sizeof(buffer
))
249 die("Impossibly long personal identifier");
254 const char *git_author_info(int error_on_no_name
)
256 return fmt_ident(getenv("GIT_AUTHOR_NAME"),
257 getenv("GIT_AUTHOR_EMAIL"),
258 getenv("GIT_AUTHOR_DATE"),
262 const char *git_committer_info(int error_on_no_name
)
264 return fmt_ident(getenv("GIT_COMMITTER_NAME"),
265 getenv("GIT_COMMITTER_EMAIL"),
266 getenv("GIT_COMMITTER_DATE"),