Use git config file for committer name and email info
[git.git] / ident.c
1 /*
2  * ident.c
3  *
4  * create git identifier lines of the form "name <email> date"
5  *
6  * Copyright (C) 2005 Linus Torvalds
7  */
8 #include "cache.h"
9
10 #include <pwd.h>
11 #include <time.h>
12 #include <ctype.h>
13
14 static char git_default_date[50];
15
16 static void copy_gecos(struct passwd *w, char *name, int sz)
17 {
18         char *src, *dst;
19         int len, nlen;
20
21         nlen = strlen(w->pw_name);
22
23         /* Traditionally GECOS field had office phone numbers etc, separated
24          * with commas.  Also & stands for capitalized form of the login name.
25          */
26
27         for (len = 0, dst = name, src = w->pw_gecos; len < sz; src++) {
28                 int ch = *src;
29                 if (ch != '&') {
30                         *dst++ = ch;
31                         if (ch == 0 || ch == ',')
32                                 break;
33                         len++;
34                         continue;
35                 }
36                 if (len + nlen < sz) {
37                         /* Sorry, Mr. McDonald... */
38                         *dst++ = toupper(*w->pw_name);
39                         memcpy(dst, w->pw_name + 1, nlen - 1);
40                         dst += nlen - 1;
41                 }
42         }
43         if (len < sz)
44                 name[len] = 0;
45         else
46                 die("Your parents must have hated you!");
47
48 }
49
50 int setup_ident(void)
51 {
52         int len;
53         struct passwd *pw = getpwuid(getuid());
54
55         if (!pw)
56                 die("You don't exist. Go away!");
57
58         /* Get the name ("gecos") */
59         copy_gecos(pw, git_default_name, sizeof(git_default_name));
60
61         /* Make up a fake email address (name + '@' + hostname [+ '.' + domainname]) */
62         len = strlen(pw->pw_name);
63         if (len > sizeof(git_default_email)/2)
64                 die("Your sysadmin must hate you!");
65         memcpy(git_default_email, pw->pw_name, len);
66         git_default_email[len++] = '@';
67         gethostname(git_default_email + len, sizeof(git_default_email) - len);
68         if (!strchr(git_default_email+len, '.')) {
69                 len = strlen(git_default_email);
70                 git_default_email[len++] = '.';
71                 getdomainname(git_default_email+len, sizeof(git_default_email)-len);
72         }
73         /* And set the default date */
74         datestamp(git_default_date, sizeof(git_default_date));
75         return 0;
76 }
77
78 static int add_raw(char *buf, int size, int offset, const char *str)
79 {
80         int len = strlen(str);
81         if (offset + len > size)
82                 return size;
83         memcpy(buf + offset, str, len);
84         return offset + len;
85 }
86
87 static int crud(unsigned char c)
88 {
89         static char crud_array[256];
90         static int crud_array_initialized = 0;
91
92         if (!crud_array_initialized) {
93                 int k;
94
95                 for (k = 0; k <= 31; ++k) crud_array[k] = 1;
96                 crud_array[' '] = 1;
97                 crud_array['.'] = 1;
98                 crud_array[','] = 1;
99                 crud_array[':'] = 1;
100                 crud_array[';'] = 1;
101                 crud_array['<'] = 1;
102                 crud_array['>'] = 1;
103                 crud_array['"'] = 1;
104                 crud_array['\''] = 1;
105                 crud_array_initialized = 1;
106         }
107         return crud_array[c];
108 }
109
110 /*
111  * Copy over a string to the destination, but avoid special
112  * characters ('\n', '<' and '>') and remove crud at the end
113  */
114 static int copy(char *buf, int size, int offset, const char *src)
115 {
116         int i, len;
117         unsigned char c;
118
119         /* Remove crud from the beginning.. */
120         while ((c = *src) != 0) {
121                 if (!crud(c))
122                         break;
123                 src++;
124         }
125
126         /* Remove crud from the end.. */
127         len = strlen(src);
128         while (len > 0) {
129                 c = src[len-1];
130                 if (!crud(c))
131                         break;
132                 --len;
133         }
134
135         /*
136          * Copy the rest to the buffer, but avoid the special
137          * characters '\n' '<' and '>' that act as delimeters on
138          * a identification line
139          */
140         for (i = 0; i < len; i++) {
141                 c = *src++;
142                 switch (c) {
143                 case '\n': case '<': case '>':
144                         continue;
145                 }
146                 if (offset >= size)
147                         return size;
148                 buf[offset++] = c;
149         }
150         return offset;
151 }
152
153 char *get_ident(const char *name, const char *email, const char *date_str)
154 {
155         static char buffer[1000];
156         char date[50];
157         int i;
158
159         if (!name)
160                 name = git_default_name;
161         if (!email)
162                 email = git_default_email;
163         strcpy(date, git_default_date);
164         if (date_str)
165                 parse_date(date_str, date, sizeof(date));
166
167         i = copy(buffer, sizeof(buffer), 0, name);
168         i = add_raw(buffer, sizeof(buffer), i, " <");
169         i = copy(buffer, sizeof(buffer), i, email);
170         i = add_raw(buffer, sizeof(buffer), i, "> ");
171         i = copy(buffer, sizeof(buffer), i, date);
172         if (i >= sizeof(buffer))
173                 die("Impossibly long personal identifier");
174         buffer[i] = 0;
175         return buffer;
176 }
177
178 char *git_author_info(void)
179 {
180         return get_ident(getenv("GIT_AUTHOR_NAME"), getenv("GIT_AUTHOR_EMAIL"), getenv("GIT_AUTHOR_DATE"));
181 }
182
183 char *git_committer_info(void)
184 {
185         return get_ident(getenv("GIT_COMMITTER_NAME"), getenv("GIT_COMMITTER_EMAIL"), getenv("GIT_COMMITTER_DATE"));
186 }