You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
2.9 KiB
138 lines
2.9 KiB
/* |
|
* ident.c |
|
* |
|
* create git identifier lines of the form "name <email> date" |
|
* |
|
* Copyright (C) 2005 Linus Torvalds |
|
*/ |
|
#include "cache.h" |
|
|
|
#include <pwd.h> |
|
#include <time.h> |
|
#include <ctype.h> |
|
|
|
static char real_email[1000]; |
|
static char real_name[1000]; |
|
static char real_date[50]; |
|
|
|
int setup_ident(void) |
|
{ |
|
int len; |
|
struct passwd *pw = getpwuid(getuid()); |
|
|
|
if (!pw) |
|
die("You don't exist. Go away!"); |
|
|
|
/* Get the name ("gecos") */ |
|
len = strlen(pw->pw_gecos); |
|
if (len >= sizeof(real_name)) |
|
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) |
|
die("Your parents must have hated you"); |
|
memcpy(real_email, pw->pw_name, len); |
|
real_email[len++] = '@'; |
|
gethostname(real_email + len, sizeof(real_email) - len); |
|
if (!strchr(real_email+len, '.')) { |
|
len = strlen(real_email); |
|
real_email[len++] = '.'; |
|
getdomainname(real_email+len, sizeof(real_email)-len); |
|
} |
|
|
|
/* And set the default date */ |
|
datestamp(real_date, sizeof(real_date)); |
|
return 0; |
|
} |
|
|
|
static int add_raw(char *buf, int size, int offset, const char *str) |
|
{ |
|
int len = strlen(str); |
|
if (offset + len > size) |
|
return size; |
|
memcpy(buf + offset, str, len); |
|
return offset + len; |
|
} |
|
|
|
static int crud(unsigned char c) |
|
{ |
|
static const char crud_array[256] = { |
|
[0 ... 31] = 1, |
|
[' '] = 1, |
|
['.'] = 1, [','] = 1, |
|
[':'] = 1, [';'] = 1, |
|
['<'] = 1, ['>'] = 1, |
|
['"'] = 1, ['\''] = 1, |
|
}; |
|
return crud_array[c]; |
|
} |
|
|
|
/* |
|
* Copy over a string to the destination, but avoid special |
|
* characters ('\n', '<' and '>') and remove crud at the end |
|
*/ |
|
static int copy(char *buf, int size, int offset, const char *src) |
|
{ |
|
int i, len; |
|
unsigned char c; |
|
|
|
/* Remove crud from the beginning.. */ |
|
while ((c = *src) != 0) { |
|
if (!crud(c)) |
|
break; |
|
src++; |
|
} |
|
|
|
/* Remove crud from the end.. */ |
|
len = strlen(src); |
|
while (len > 0) { |
|
c = src[len-1]; |
|
if (!crud(c)) |
|
break; |
|
--len; |
|
} |
|
|
|
/* |
|
* Copy the rest to the buffer, but avoid the special |
|
* characters '\n' '<' and '>' that act as delimeters on |
|
* a identification line |
|
*/ |
|
for (i = 0; i < len; i++) { |
|
c = *src++; |
|
switch (c) { |
|
case '\n': case '<': case '>': |
|
continue; |
|
} |
|
if (offset >= size) |
|
return size; |
|
buf[offset++] = c; |
|
} |
|
return offset; |
|
} |
|
|
|
char *get_ident(const char *name, const char *email, const char *date_str) |
|
{ |
|
static char buffer[1000]; |
|
char date[50]; |
|
int i; |
|
|
|
if (!name) |
|
name = real_name; |
|
if (!email) |
|
email = real_email; |
|
strcpy(date, real_date); |
|
if (date_str) |
|
parse_date(date_str, date, sizeof(date)); |
|
|
|
i = copy(buffer, sizeof(buffer), 0, name); |
|
i = add_raw(buffer, sizeof(buffer), i, " <"); |
|
i = copy(buffer, sizeof(buffer), i, email); |
|
i = add_raw(buffer, sizeof(buffer), i, "> "); |
|
i = copy(buffer, sizeof(buffer), i, date); |
|
if (i >= sizeof(buffer)) |
|
die("Impossibly long personal identifier"); |
|
buffer[i] = 0; |
|
return buffer; |
|
}
|
|
|