/* gsqld.C - Shell-Interface for Internet-SQL
 *           (c) Michael Koehne <kraehe@bakunin.norh.de>
 */

extern "C" { 
#ifdef KRB5
	#include <krb5/krb5.h>
	#include <krb5/ext-proto.h>
	#include <krb5/los-proto.h>
	#include <sys/types.h>
	#include <sys/socket.h>
	#include <netinet/in.h>
	#include <netdb.h>
	#include <com_err.h>
	#include <syslog.h>
	#include "krb5-gsql.h"
#endif
	#include "unistd.h"
	#include "stdlib.h"
	#include "stdio.h"
	#include "memory.h"
	#include "string.h"
#ifdef SUNOS
	extern int putenv();
	extern int fprintf();
	extern int fflush();
#endif
}

#include "tw_types.h"
#include "SqlManager.h"
#include "SqlShql.h"

SqlManager sql;
// SqlShql sql;
Text sql_stat(16);

char *database;
int sql_debug=0;
int sql_pc=0;
int demon=0;

int sql_backend(SqlParser *sql)
{	Text *res;
	int i;
	char *row;
	int flag;

	if (demon) fprintf(stdout,"- Seq BEGIN\n");

	res = sql->sql_getresult();
	if (res) {
		if (res->nlines) {
			for (i=0; i<res->nlines;i++) {
				if (demon)
					fprintf(stdout,"# %s\n",res->lines[i]);
				else
					fprintf(stderr,"%s\n",res->lines[i]);
				}
			}


		flag = 1;
		while ((row = sql->sql_getrow())) {
			if (flag) {
				if (demon) fprintf(stdout,"- Seq ROWS\n");
				flag=0;
				}
			if (demon)
				fprintf(stdout,"> %s\n",row);
			else	fprintf(stdout,"%s\n",row);
			free(row);
			}
		}

	if (demon) fprintf(stdout,"- Seq END\n");
	fflush(stdout);

	return(1);
	}

main(int argc,char **argv)
{	char statement[256];
	int stdinflag=1;
	LineStream *sql_stream;
	char *p,*q;
#ifdef KRB5
	struct sockaddr_in peername;
	krb5_address peeraddr;
	krb5_data recv_data;
	krb5_error_code retval;
	krb5_principal server,client;
	char *sql_user;	
	int sock = 0, namelen = sizeof(peername);
#endif

	database=0;

	p = argv[0]; while ((q=strchr(p,'/'))) p=q+1;
	if (!strcmp(p,"gsqld")) demon=1;

	while (--argc) {
		argv++;
		if (!memcmp(*argv,"-d",2)) parser_debug=1;
		else
		if (!memcmp(*argv,"-pc",3)) sql_pc=1;
		else
		if (!memcmp(*argv,"-s",2)) putenv(strdup((*argv)+2));
		else 
		if (!database)
			database=strdup(*argv);
		else {	strcpy(statement,*argv);
			strcat(statement,";");
			sql_stat.add_line(statement);
			stdinflag=0;
			}
		}

	sql.sql_backend = sql_backend;

	if (database) {
		sprintf(statement,"database %s;",database);
		sql_stat.add_line(0,statement);
		}

	if (sql_stat.nlines) {
		/*
		fprintf(stderr,"Init param\n");
		*/
		sql.sql_new(&sql_stat);
		}

	if (stdinflag) {
		/*
		fprintf(stderr,"Init stdin\n");
		*/
#ifdef KRB5
		if (demon) {
			krb5_init_ets();

			openlog("gsqld", 0, LOG_DAEMON);

			if (retval = krb5_sname_to_principal(NULL,
				GSQL_SERVICE, KRB5_NT_SRV_HST, &server)) {
				syslog(LOG_ERR, "while generating service name (%s) %s", GSQL_SERVICE, error_message(retval));
				exit(1);
				}
			if (getpeername(0, (struct sockaddr *)&peername,
					&namelen)) {
				syslog(LOG_ERR, "getpeername %m:");
				exit(1);
				}
			peeraddr.addrtype = peername.sin_family;
			peeraddr.length = sizeof(peername.sin_addr);
			peeraddr.contents = (krb5_octet *)&peername.sin_addr;

			if (retval = krb5_recvauth((krb5_pointer)&sock,
				GSQL_VERSION, server, &peeraddr,
				0, 0, 0, 0, 0, 0, &client, 0, 0)) {
				syslog(LOG_ERR,"recvauth failed--%s",
					error_message(retval));
				exit(1);
				}

			if (retval = krb5_unparse_name(client, &sql_user)) {
				syslog(LOG_ERR, "unparse failed: %s",
					error_message(retval));
				sql_user = "<unparse error>";
				}
			else
				syslog(LOG_INFO, "Identified: %s", sql_user);	
			}
#endif
		sql_stream = new FileStream(0,O_RDONLY);
		sql.sql_new(sql_stream);
		delete sql_stream;
		}
	}
