/*
#ident	"@(#)smail/util:RELEASE-3_2_0_121:mksort.c,v 1.23 2005/09/09 18:08:44 woods Exp"
 */

/*
 *    Copyright (C) 1987, 1988 Ronald S. Karr and Landon Curt Noll
 *    Copyright (C) 1992  Ronald S. Karr
 * 
 * See the file COPYING, distributed with smail, for restriction
 * and warranty information.
 */

/*
 * mksort.c:
 *	Take a list of lines and sort them.  If the flag -f is given,
 *	then ignore case in comparisons.
 */

#include "defs.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>

#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
#  include <stdlib.h>
# endif
#endif

#ifdef HAVE_STRING_H
# if !defined(STDC_HEADERS) && defined(HAVE_MEMORY_H)
#  include <memory.h>
# endif
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif

#ifdef __STDC__
# include <stdarg.h>
#else
# include <varargs.h>
#endif

#include "smail.h"
#include "alloc.h"
#include "list.h"
#include "main.h"
#include "parse.h"
#include "addr.h"
#include "exitcodes.h"
#include "log.h"
#include "field.h"
#include "smailstring.h"
#include "dys.h"
#include "smailsock.h"
#include "route.h"
#include "bindlib.h"
#include "exitcodes.h"
#include "spool.h"
#include "extern.h"
#include "smailport.h"

/* variables provided by this file */
char *program;				/* argv[0] from main */
int debug = 0;
FILE *errfile;

/* functions local to this file */
static int cmp __P((const void *, const void *));
static int cmpic __P((const void *, const void *));
static char **mkvectors __P((size_t, char *));
static int read_lines __P((struct str *, FILE *));

/*ARGSUSED*/
int
main(argc, argv)
    int argc GCC_UNUSED_HACK;
    char **argv;
{
    struct str strings;
    int (*compare_fun) __P((const void *, const void *));
    size_t ct = 0;
    char **v;
    size_t i;

    program = *argv++;
    errfile = stderr;

    /* if -f, then perform case-folded comparisons */
    if (*argv && EQ(*argv, "-f")) {
	compare_fun = cmpic;
	argv++;
    } else {
	compare_fun = cmp;
    }
    STR_INIT(&strings);
    if (*argv == NULL) {
	ct += read_lines(&strings, stdin);
    }
    while (*argv) {
	FILE *f;

	if (EQ(*argv, "-")) {
	    f = stdin;
	} else {
	    f = fopen(*argv, "r");
	    if (f == NULL) {
		(void) fprintf(stderr, "%s: cannot open %s: ", program, *argv);
		perror("");
		exit(errno);
	    }
	}
	ct += read_lines(&strings, f);
	argv++;
    }

    v = mkvectors(ct, strings.p);
    qsort((char *)v, ct, sizeof(char *), compare_fun);

    for (i = 0; i < ct; i++) {
	printf("%s\n", v[i]);
    }

    exit(0);

    /* NOTREACHED */
}

static int
read_lines(ssp, f)
    register struct str *ssp;
    register FILE *f;
{
    register int c;
    int ct = 0;

    while ((c = getc(f)) != EOF) {
	if (c == '\n') {
	    STR_NEXT(ssp, '\0');
	    ct++;
	} else {
	    STR_NEXT(ssp, c);
	}
    }

    return ct;
}

static char **
mkvectors(ct, strings)
    size_t ct;				/* count of strings */
    char *strings;			/* null-terminated strings */
{
    char **v;
    register char **vp;
    register char *sp = strings;

    v = vp = (char **)xmalloc(ct * sizeof(char *));
    for (sp = strings; ct; ct--, sp += strlen(sp) + 1) {
	*vp++ = sp;
    }
    return v;
}

static int
cmp(a, b)
    const void *a;
    const void *b;
{
    const char *s1 = *(const char * const *) a;
    const char *s2 = *(const char * const *) b;
    register int c1, c2;

    for (;;) {
	c1 = *s1++;
	c2 = *s2++;
	if (isspace((int) c1) || c1 == ':')
	    c1 = '\0';
	if (isspace((int) c2) || c2 == ':')
	    c2 = '\0';
	if (c1 != c2)
	    return c1 - c2;
	if (c1 == '\0')
	    break;
    }
    return c1 - c2;
}

static int
cmpic(a, b)
    const void *a;
    const void *b;
{
    const char *s1 = *(const char * const *) a;
    const char *s2 = *(const char * const *) b;
    register int c1, c2;

    for (;;) {
	c1 = tolower((int) *s1++);
	c2 = tolower((int) *s2++);
	if (isspace((int) c1) || c1 == ':')
	    c1 = '\0';
	if (isspace((int) c2) || c2 == ':')
	    c2 = '\0';
	if (c1 != c2)
	    return c1 - c2;
	if (c1 == '\0')
	    break;
    }
    return c1 - c2;
}

/*
 * standalone versions of some referenced routines
 */

void
freeze_message()
{
    return;
}

char *
bind_compute_domain()
{
    return NULL;
}

char *
bind_lookup_txt_rr(s, ep)
    char *s GCC_UNUSED_HACK;
    struct error **ep GCC_UNUSED_HACK;
{
    return NULL;
}

/*
 * standalone versions of some referenced variables
 */

enum er_proc error_processing = MAIL_BACK;
int force_zero_exitvalue = FALSE;
pid_t daemon_pid = 0xDEAD;
char *message_id = NULL;		/* unique ID for this message */
enum op_mode operation_mode = MODE_DEFAULT;	/* mode of operation */
int only_testing = TRUE;
char *spool_dir;			/* directory used to spool message */
char *spool_fn = NULL;			/* basename of open spool file */
int islocal = TRUE;
char *sender = "nsc!tron";
char *sender_name = "MasterControlProgram";
char *smtp_local_net = NULL;
char *local_sender;
uid_t real_uid = 0;
gid_t prog_egid = 0;

/* 
 * Local Variables:
 * c-file-style: "smail"
 * End:
 */
