/*
 *      $Filename: rfcstuff.c $
 *      $Revision: 1.3 $
 *      $Date: 1994/03/13 18:24:34 $
 *
 *      Copyright (C) 1993 by Peter Simons <simons@peti.GUN.de>
 *
 *      This program 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 2 of
 *      the License, or (at your option) any later version.
 *
 *      This program 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 this program; if not, write to the Free Software
 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *      $Id: rfcstuff.c 1.3 1994/03/13 18:24:34 simons Exp simons $
 *
 */


/**************************************************************************
 *                                                                        *
 * Section: Macros, Definitions, Includes, Structures                     *
 *                                                                        *
 **************************************************************************/

/************************************* Includes ***********/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "protos.h"
#include "pgpsendmail.h"

/************************************* Prototypes *********/

/************************************* Defines ************/

/************************************* global Variables ***/
static const char __RCSId[] = "$Id: rfcstuff.c 1.3 1994/03/13 18:24:34 simons Exp simons $";


/**************************************************************************
 *                                                                        *
 * SECTION: Subroutines                                                   *
 *                                                                        *
 **************************************************************************/

 /*
  * This routine expects a buffer holding a RFC mail and does all the parsing
  * for the receipients, namely the "To:" and the "Cc:" line. It will
  * return an array of pointers, each entry containing one address without
  * comments and stuff like that.
  */

char **FindReceipients(char *header)
{
        char **receipients, *line;

        if (!(receipients = malloc(sizeof(char *[MAX_RECEIPIENTS])))) {
                MakeLogEntry(PRGNAME, MLE_ERROR, "Failed allocating my buffers!");
                return NULL;
        }
        *receipients = NULL;

        if (line = FindHeaderEntry(header, "To: ")) {
                SplitAddressLine(line, receipients);
                free(line);
        }
        if (line = FindHeaderEntry(header, "Cc: ")) {
                SplitAddressLine(line, receipients);
                free(line);
        }

        ParseAddressLines(receipients);

        return receipients;
}



 /*
  * This routine finds a certain header entry in the provided textbuffer,
  * even if the entry is split over several lines.
  */

char *FindHeaderEntry(char *header, char *entry)
{
        char *linebuf, *tmp;
        int i = 0;

        if (!(linebuf = malloc(MY_BUFLEN*5)))
                return NULL;
        tmp = linebuf;

        while (*header) {
                if (!strncmp(header, entry, strlen(entry))) {
                        header += strlen(entry);
                        while (isspace(*header))       /* skip the entry-introducer */
                                header++;
                        do {
                                while (i < MY_BUFLEN && *header != '\n')
                                        tmp[i++] = *(header++);
                                if (i < MY_BUFLEN && isspace(header[1])) {
                                        header++;
                                        tmp[i++] = ' ';
                                }
                                else
                                        break;
                        } while (1);
                        break;
                }
                else
                while (*header != '\n' && *header)      /* goto next line */
                        header++;
                if (*header == '\n')
                        header++;
        }
        if (i)
                tmp[i] = '\0';
        else {
                free(linebuf);          /* The entry is not available. */
                return NULL;
        }

        return linebuf;
}



 /*
  * This routine splits a line of addresses up and inserts each address
  * in an array of pointers.
  */

void SplitAddressLine(char *line, char *receipients[])
{
        int brackets, i;


        if (!line || !receipients)      /* security check */
                return;


        /* Find end of array and append new entries there. */

        while (*receipients)
                receipients++;


        /* Split the provided line. */

        *(receipients++) = line;
        for (i = 0, brackets = 0; line[i]; i++) {
                if (line[i] == '(')
                        brackets++;
                if (line[i] == ')')
                        brackets--;
                if (line[i] == ',' && !brackets) {

                        /*
                         * Found end of address. Insert \0 mark and copy the
                         * buffer for our array.
                         */

                        line[i++] = '\0';
                        receipients[-1] = strdup(receipients[-1]);


                        /* Skip spaces until the next address. */

                        while (isspace(line[i]))
                                i++;
                        *receipients++ = &line[i];
                }
        }
        if (*(receipients[-1])) {
                receipients[-1] = strdup(receipients[-1]);
                *receipients = NULL;
        }
        else
                receipients[-1] = NULL;
}



 /*
  * This routines browses through an array of addresses and removes
  * all this RFC comment stuff, just leaving the plain address.
  */

void ParseAddressLines(char **receipients)
{
        char line[MY_BUFLEN];
        int brackets, i, z;

        while (*receipients) {
                strcpy(line, *receipients);
                for (i = 0, z = 0, brackets = 0; line[i] != '\0'; i++) {
                        if (line[i] == '(' && (i == 0 || isspace(line[i-1])))
                                brackets++;
                        if (line[i] == ')' && (line[i+1] == '\0' || isspace(line[i+1])))
                                brackets--;
                        if (line[i] == '<' && brackets == 0) {
                                i++;
                                while (1) {             /* Forever! */
                                        if (line[i] == '>' && (line[i+1] == '\0' || isspace(line[i+1])))
                                                break;
                                        (*receipients)[z++] = line[i++];
                                }
                                (*receipients)[z] = '\0';
                                break;
                        }
                }
                if (z == 0) {   /* No <address> occured. */
                        i = 0;
                        while (!isspace((*receipients)[i]))
                                i++;
                        (*receipients)[i] = '\0';
                }
                receipients++;
        }
}


 /*
  * MakeDomainAddress browses through an array of addresses and
  * looks for addresses which do not contain either a "!" or a
  * "@". These addresses will be converted in full domain addresses
  * of the local site.
  *
  * PORT NOTE: This routine has to determine the name and domain
  * of the local site. This is done using the netsupport.library.
  */

void MakeDomainAddress(char **receipients)
{
        char line[128], *p;

        while (*receipients) {
                if (!stristr(*receipients, "@") && !stristr(*receipients, "!")) {
                        sprintf(line, "%s@%s", *receipients, FindConfig(NODENAME));
                        strcat(line, FindConfig(DOMAINNAME));
                        if (p = strdup(line)) {
                                free(*receipients);
                                *receipients = p;
                        }
                }
                receipients++;
        }
}

