/* birthdays.c -- Send happy birthday message to those people whose birthday
   it is.  Optionally send notifications to other people. */

/* Copyright (C) 1988,1990 Free Software Foundation, Inc.

   This file is part of GNU Finger.

   GNU Finger is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published
   by the Free Software Foundation; either version 1, or (at your
   option) any later version.

   GNU Finger is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with GNU Finger; see the file COPYING.  If not, write to the
   Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */

#include <stdio.h>
#include <config.h>
#include <sys/types.h>
#include <sys/file.h>
#include <time.h>

#ifdef TM_IN_SYS_TIME
#include <sys/time.h>
#endif

#include <ndbm.h>
#include <fingerpaths.h>
#include <general.h>
#include "recedit.h"

extern DATE *decode_birthdate ();
extern FIELD_DESC *birthdate_field ();

/* Name of this program. */
char *progname;

/* Names of additional users to notify when a birthday is found. */
char **others = (char **)NULL;

/* Non-zero means print the names of the people who are having birthdays
   instead of mailing to them. */
int no_mailing = 0;

/* Global variable holds on to record format. */
FIELD_DESC **Fields;

main (argc, argv)
     int argc;
     char **argv;
{
  DBM *database;
  FIELD_DESC *field;

  progname = argv[0];
  argc--;
  argv++;

  if (argc)
    {
      register int i;

      if (strcmp (argv[0], "-n") == 0)
	{
	  no_mailing = 1;
	  argv++;
	  argc--;
	}

      if (argc)
	{
	  others = (char **)xmalloc ((1 + argc) * sizeof (char *));

	  for (i = 0; i < argc; i++)
	    others[i] = argv[i];

	  others[i] = (char *)NULL;
	}
    }

  database = dbm_open (DBMINFO, O_RDONLY, 0666);

  if (!database)
    {
      fprintf (stderr, "Cannot access database `%s'.\n", DBMINFO);
      exit (1);
    }

  Fields = re_read_description_file (FORMATFILE);

  if (!Fields)
    {
      fprintf (stderr, "%s: Cannot read description file %s.\n",
	       progname, FORMATFILE);
      exit (1);
    }

  field = birthdate_field (Fields);

  if (field)
    check_birthdates (database);

  dbm_close (database);
}

check_birthdates (database)
     DBM *database;
{
  FIELD_DESC **fields, *bfield;
  DATE *birthdate;
  datum info, key;
  struct tm *sys_time;
  long clock;
  int this_month, this_day;

  clock = time (0);
  sys_time = localtime (&clock);
  this_month = sys_time->tm_mon + 1;
  this_day = sys_time->tm_mday;

  for (key = dbm_firstkey (database); key.dptr != NULL;
       key = dbm_nextkey (database))
    {
      info = dbm_fetch (database, key);

      if (!info.dptr)
	continue;

      fields = re_copy_fields (Fields);

      re_extract_fields (info.dptr, fields);

      bfield = birthdate_field (fields);
      birthdate = decode_birthdate (bfield);

      if (birthdate)
	{
	  if (birthdate->month == this_month && birthdate->day == this_day)
	    notify_users (fields);

	  free (birthdate);
	}
      
      re_free_fields (fields);
    }
}

/* Notify the user in FIELDS that it is his/her birthday.  In addition,
   if we are notifying a mailing list, then send mail to them as well. */
notify_users (fields)
     FIELD_DESC **fields;
{
  register int i;
  FILE *stream, *popen ();
  char **value, *user_address, *real_name;
  char mail_command[1024];

  value = (char **)re_get_field_value (fields, "E-Mail Address");
  user_address = *value;

  value = (char **)re_get_field_value (fields, "Real Name");
  real_name = *value;

  if (!real_name)
    {
      value = (char **)re_get_field_value (fields, "User Name");
      real_name = *value;
    }

  if (no_mailing)
    {
      fprintf (stdout, "Today is %s's birthday.  Don't forget to wish\n",
	       real_name);
      fprintf (stdout, "him or her a happy birthday.\n");
      fflush (stdout);
      return;
    }

  if (user_address)
    {
      sprintf (mail_command, "/bin/rmail %s", user_address);
      stream = popen (mail_command, "w");

      if (stream)
	{
	  char *first_name, *temp;

	  first_name = (char *)xmalloc (1 + strlen (real_name));
	  strcpy (first_name, real_name);
	  temp = (char *)index (first_name, ' ');
	  if (temp)
	    *temp = '\0';
	  
	  fprintf (stream, "From: The Birthday Daemon\n");
	  fprintf (stream, "To: %s\n", user_address);
	  fprintf (stream, "Subject: Happy Birthday!\n\n");

	  fprintf (stream, "Happy birthday to you,\n");
	  fprintf (stream, "happy birthday to you,\n");
	  fprintf (stream, "happy birthday dear %s,\n", first_name);
	  fprintf (stream, "Happy birthday to you!\n\n");
	  fprintf (stream, "Many happy returns,\n\n");
	  fprintf (stream, "\tThe Birthday Daemon");
	  free (first_name);
	  pclose (stream);
	}
    }

  /* If there are other people to notify, then do so now. */
  if (others)
    {
      char *name;

      for (i = 0; name = others[i]; i++)
	{
	  sprintf (mail_command, "/bin/rmail %s", name);
	  stream = popen (mail_command, "w");

	  if (stream)
	    {
	      fprintf (stream, "From: The Birthday Daemon\n");
	      fprintf (stream, "To: %s\n", name);
	      fprintf (stream, "Subject: Birthday Notification (%s).\n\n",
		       real_name);

	      fprintf (stream,
		       "Today is %s's birthday.  Don't forget to wish\n",
		       real_name);
	      fprintf (stream, "him or her a happy birthday.\n\n");
	      fprintf (stream, "\tThe Birthday Daemon");
	      pclose (stream);
	    }
	}
    }
}

