/*
**  This utility program converts pre-2.0 Dialup IP configuration files
**  into 2.0 style.  It writes a sample diald.conf and creates the access
**  files.
**  Copyright (c) 1991 Bolt Beranek and Newman, Inc.
**  All rights reserved.
**
**  Redistribution and use in source and binary forms are permitted
**  provided that: (1) source distributions retain this entire copyright
**  notice and comment, and (2) distributions including binaries display
**  the following acknowledgement:  ``This product includes software
**  developed by Bolt Beranek and Newman, Inc. and CREN/CSNET'' in the
**  documentation or other materials provided with the distribution and in
**  all advertising materials mentioning features or use of this software.
**  Neither the name of Bolt Beranek and Newman nor CREN/CSNET may be used
**  to endorse or promote products derived from this software without
**  specific prior written permission.
**
**  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
**  WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
**  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
 * Copyright (c) 1992 Purdue University
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * by Purdue University.  The name of the University may not be used
 * to endorse or promote products derived * from this software without
 * specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 * Note: this copyright applies to portions of this software developed
 * at Purdue beyond the software covered by the original copyright.
 */
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/dir.h>

#define MAXDEV		10
#define SMBUF		30
#define EQ(a, b)	(strcmp((a), (b)) == 0)
#define nexttok()	strtok((char *)NULL, SEPARATORS)

static char		SEPARATORS[] = " \t";
static char		ACCESS_TEMP[] = "temp.access";
static char		CONFIG_FILE[] = "diald.conf";

extern char		*strtok();
extern char		*strchr();
extern char		*strrchr();
extern char		*strcpy();
extern void		exit();


static void
printlist(access, label)
    FILE	*access;
    char	*label;
{
    int		i;
    char	*p;

    fprintf(access, "%s%s\t", label, strlen(label) < 8 ? "\t" : "");
    for (i = 0; p = nexttok(); i++)
	fprintf(access, "%s%s", i ? " " : "", p);
    fprintf(access, "\n");
}


main()
{
    DIR			*dp;
    struct direct	*ep;
    int			bad;
    FILE		*F;
    FILE		*access;
    FILE		*config;
    char		*word;
    char		*p;
    char		buff[256];
    char		sitename[SMBUF];
    int			speeds[MAXDEV];
    int			nspeeds;
    char		device[SMBUF];
    char		lines[MAXDEV][SMBUF];
    int			nlines;
    char		script[SMBUF];
    char		tranfile[SMBUF];
    int			i;

    /* Create config file, get ready to scan directory. */
    if ((config = fopen(CONFIG_FILE, "w")) == NULL) {
	perror("Can't create config file");
	exit(1);
    }
    if ((dp = opendir(".")) == NULL) {
	perror("Can't open \".\"");
	exit(1);
    }

    /* Loop over all files in the current directory. */
    for (bad = 0; ep = readdir(dp); ) {
	/* Is this a config file? */
	if ((p = strrchr(ep->d_name, '.')) == NULL || strcmp(p, ".conf") != 0)
	    continue;

	/* Open the access file and the config file. */
	if ((access = fopen(ACCESS_TEMP, "w")) == NULL) {
	    perror("Can't open temporary file");
	    bad++;
	    continue;
	}
	if ((F = fopen(ep->d_name, "r")) == NULL) {
	    perror(ep->d_name);
	    bad++;
	    (void)fclose(access);
	    continue;
	}

	/* Loop over all lines in the config file. */
	nspeeds = nlines = 0;
	device[0] = '\0';
	script[0] = '\0';
	sitename[0] = '\0';
	tranfile[0] = '\0';
	while (fgets(buff, sizeof buff, F)) {
	    if ((p = strchr(buff, '\n')) == NULL) {
		fprintf(stderr, "Line too long in %s:\n%s...\n",
		    ep->d_name, buff);
		bad++;
		break;
	    }
	    *p = '\0';

	    /* Ignore blank and comment lines. */
	    if (buff[0] == '#' || (word = strtok(buff, SEPARATORS)) == NULL)
		continue;

	    if (EQ(word, "devices"))
		(void)strcpy(device, (p = nexttok()) ? p : "");
	    else if (EQ(word, "script"))
		(void)strcpy(script, (p = nexttok()) ? p : "");
	    else if (EQ(word, "sitename"))
		(void)strcpy(sitename, (p = nexttok()) ? p : "");
	    else if (EQ(word, "tranfile"))
		(void)strcpy(tranfile, (p = nexttok()) ? p : "");
	    else if (EQ(word, "host"))
		;
	    else if (EQ(word, "badsrcaddresses"))
		printlist(access, "disallowfrom");
	    else if (EQ(word, "gooddstaddresses"))
		printlist(access, "allowto");
	    else if (EQ(word, "protocols")
		  || EQ(word, "monday")
		  || EQ(word, "tuesday")
		  || EQ(word, "wednesday")
		  || EQ(word, "thursday")
		  || EQ(word, "fridat")
		  || EQ(word, "saturday")
		  || EQ(word, "sunday")
		  || EQ(word, "weekdays")
		  || EQ(word, "weekends"))
		printlist(access, word);
	    else if (EQ(word, "speeds")) {
		for (nspeeds = 0; nspeeds < MAXDEV && (p = nexttok()); nspeeds++)
		    speeds[nspeeds] = atoi(p);
		if (nspeeds >= MAXDEV) {
		    fprintf(stderr, "Too many speeds\n");
		    bad++;
		}
	    }
	    else if (EQ(word, "lines")) {
		for (nlines = 0; nlines < MAXDEV && (p = nexttok()); nlines++)
		    (void)strcpy(lines[nlines], p);
		if (nlines >= MAXDEV) {
		    fprintf(stderr, "Too many lines\n");
		    bad++;
		}
	    }
	    else
		fprintf(stderr,
		    "Warning, don't know keyword \"%s\" in \"%s\"\n",
			word, ep->d_name);
	}

	(void)fclose(access);
	(void)fclose(F);

	/* Verify data. */
	if (device[0] == '\0') {
	    fprintf(stderr, "No device in \"%s\"\n", ep->d_name);
	    bad++;
	    continue;
	}
	if (script[0] == '\0') {
	    fprintf(stderr, "No script in \"%s\"\n", ep->d_name);
	    bad++;
	    continue;
	}
	if (sitename[0] == '\0') {
	    fprintf(stderr, "No sitename in \"%s\"\n", ep->d_name);
	    bad++;
	    continue;
	}
	if (nlines != nspeeds) {
	    fprintf(stderr, "Lines and speeds don't match in \"%s\"\n",
		ep->d_name);
	    bad++;
	    continue;
	}

	/* Write out the config entry. */
	fprintf(config, "##\n##\n");
	fprintf(config, "%s:%s:", device, sitename);
	for (i = 0; i < nlines; i++)
	    fprintf(config, "%s%s#%d", i ? " " : "", lines[i], speeds[i]);
	fprintf(config, ":%s:%s:%s.access\n", script, tranfile, device);

	/* Close the files, rename the temporary file to the working one. */
	(void)sprintf(buff, "%s.access", device);
	(void)rename(ACCESS_TEMP, buff);
    }


    (void)unlink(ACCESS_TEMP);
    (void)fclose(config);
    (void)closedir(dp);
    exit(bad ? 1 : 0);
    /* NOTREACHED */
}
