/* See LICENSE file for copyright and license details. */
#include "common.h"
/* Date components are in different options to avoid date format confusion */
USAGE("([-Y | -y year] [-M | -m month] [-D | -d day] [-B | -b] | -u) contact-id ...");
#if defined(__GNUC__)
__attribute__((__pure__))
#endif
static int
getintarg(const char *arg)
{
int ret = 0;
for (; isdigit(*arg); arg++) {
if (ret > (INT_MAX - (*arg & 15)) / 10)
return -1;
ret = ret * 10 + (*arg & 15);
}
if (*arg)
return -1;
return ret;
}
int
main(int argc, char *argv[])
{
static int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int year = 0, month = 0, day = 0, before_on_common = -1, remove = 0;
struct passwd *user;
struct libcontacts_contact contact;
int ret = 0;
size_t i;
ARGBEGIN {
case 'y':
if (year)
usage();
year = getintarg(ARG());
if (year < 0)
usage();
break;
case 'Y':
if (year)
usage();
year = -1;
break;
case 'm':
if (month)
usage();
month = getintarg(ARG());
if (month < 0)
usage();
break;
case 'M':
if (month)
usage();
month = -1;
break;
case 'd':
if (day)
usage();
day = getintarg(ARG());
if (day < 0)
usage();
break;
case 'D':
if (day)
usage();
day = -1;
break;
case 'b':
if (before_on_common == 0)
usage();
before_on_common = 1;
break;
case 'B':
if (before_on_common == 1)
usage();
before_on_common = 0;
break;
case 'u':
remove = 1;
break;
default:
usage();
} ARGEND;
if ((year | month | day | (before_on_common + 1)) && remove)
usage();
if (year % 4 == 0 && (year % 100 || year % 400 == 0)) /* 0 is a leap year */
days_in_month[1] += 1;
if ((month && month > 12) || day > days_in_month[month - 1])
usage();
if (!argc)
usage();
for (i = 0; argv[i]; i++)
if (!*argv[i] || strchr(argv[i], '/'))
usage();
errno = 0;
user = getpwuid(getuid());
if (!user)
eprintf("getpwuid: %s\n", errno ? strerror(errno) : "user does not exist");
for (; *argv; argv++) {
if (libcontacts_load_contact(*argv, &contact, user)) {
weprintf("libcontacts_load_contact %s: %s\n", *argv,
errno ? strerror(errno) : "contact file is malformatted");
ret = 1;
} else {
if (remove) {
if (!contact.birthday)
goto next;
libcontacts_birthday_destroy(contact.birthday);
free(contact.birthday);
contact.birthday = NULL;
} else {
if (!contact.birthday)
contact.birthday = ecalloc(1, sizeof(*contact.birthday));
if (year)
contact.birthday->year = year < 0 ? 0 : (unsigned int)year;
if (month)
contact.birthday->month = month < 0 ? 0 : (unsigned char)month;
if (day)
contact.birthday->day = day < 0 ? 0 : (unsigned char)day;
if (before_on_common >= 0)
contact.birthday->before_on_common = (unsigned char)before_on_common;
}
if (libcontacts_save_contact(&contact, user)) {
weprintf("libcontacts_save_contact %s:", *argv);
ret = 1;
}
next:
libcontacts_contact_destroy(&contact);
}
}
if (fflush(stdout) || ferror(stdout) || fclose(stdout))
eprintf("printf:");
return ret;
}