/* See LICENSE file for copyright and license details. */ #include "common.h" USAGE("[-n] (-L | contact-id ...)"); static struct tm *now; static int compare_by_birthdate(const void *apv, const void *bpv) { struct libcontacts_contact *const *ap = apv, *const *bp = bpv; const struct libcontacts_contact *a = *ap, *b = *bp; if (!a->birthday != !b->birthday) return !a->birthday ? -1 : +1; if (!a->birthday) return 0; if (a->birthday->year != b->birthday->year) return a->birthday->year < b->birthday->year ? -1 : +1; if (a->birthday->month != b->birthday->month) return a->birthday->month < b->birthday->month ? -1 : +1; if (a->birthday->day != b->birthday->day) return a->birthday->day < b->birthday->day ? -1 : +1; if (a->birthday->before_on_common != b->birthday->before_on_common) return a->birthday->before_on_common ? -1 : +1; return 0; } static int compare_by_birthday(const void *apv, const void *bpv) { struct libcontacts_contact *const *ap = apv, *const *bp = bpv; const struct libcontacts_contact *a = *ap, *b = *bp; int av, bv, nv; if (!a->birthday != !b->birthday) return !a->birthday ? -1 : +1; if (!a->birthday) return 0; if (!a->birthday->month != !b->birthday->month) return !a->birthday->month ? -1 : +1; if (!a->birthday->month) return 0; if (!a->birthday->day != !b->birthday->day) return !a->birthday->day ? -1 : +1; if (!a->birthday->day) return 0; av = (12 + (a->birthday->month - 1) % 12) % 12 * 31; av += (31 + (a->birthday->day - 1) % 31) % 31; bv = (12 + (b->birthday->month - 1) % 12) % 12 * 31; bv += (31 + (b->birthday->day - 1) % 31) % 31; nv = (12 + (now->tm_mon) % 12) % 12 * 31; nv += (31 + (now->tm_mday - 1) % 31) % 31; av = (12 * 31 + (av - nv) % (12 * 31)) % (12 * 31); bv = (12 * 31 + (bv - nv) % (12 * 31)) % (12 * 31); if (av != bv) return av - bv; if (a->birthday->before_on_common != b->birthday->before_on_common) return a->birthday->before_on_common ? -1 : +1; return 0; } int main(int argc, char *argv[]) { int next = 0, list = 0; struct passwd *user; struct libcontacts_contact **contacts; time_t tim; int ret = 0; size_t i; ARGBEGIN { case 'n': next = 1; break; case 'L': list = 1; break; default: usage(); } ARGEND; if (list ? argc : !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"); tim = time(NULL); now = localtime(&tim); if (!now) eprintf("localtime:"); if (list) { if (libcontacts_load_contacts(&contacts, user, 0)) eprintf("libcontacts_load_contacts:"); for (i = 0; contacts[i]; i++); } else { contacts = ecalloc((size_t)argc + 1, sizeof(*contacts)); for (i = 0; *argv; argv++) { contacts[i] = emalloc(sizeof(**contacts)); if (libcontacts_load_contact(*argv, contacts[i], user)) { weprintf("libcontacts_load_contact %s: %s\n", *argv, errno ? strerror(errno) : "contact file is malformatted"); ret = 1; free(contacts[i]); } else { i++; } } contacts[i] = NULL; } if (next) qsort(contacts, i, sizeof(*contacts), compare_by_birthday); else qsort(contacts, i, sizeof(*contacts), compare_by_birthdate); for (i = 0; contacts[i]; i++) { if (contacts[i]->birthday) { if (next) { if (argc != 1) printf("%s: ", contacts[i]->id); print_birthday(contacts[i]->birthday, now); } else if (contacts[i]->birthday->month && contacts[i]->birthday->year) { if (argc != 1) printf("%s: ", contacts[i]->id); print_birthdate(contacts[i]->birthday, now); } } libcontacts_contact_destroy(contacts[i]); free(contacts[i]); } if (fflush(stdout) || ferror(stdout) || fclose(stdout)) eprintf("printf:"); free(contacts); return ret; }