/*
 * This file was generated automatically by xsubpp version 1.9508 from the 
 * contents of managesieve.xs. Do not edit this file, edit managesieve.xs instead.
 *
 *	ANY CHANGES MADE HERE WILL BE LOST! 
 *
 */

#line 1 "managesieve.xs"
/*
 * Copyright (c) 1998-2000 Carnegie Mellon University.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The name "Carnegie Mellon University" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For permission or any other legal
 *    details, please contact  
 *      Office of Technology Transfer
 *      Carnegie Mellon University
 *      5000 Forbes Avenue
 *      Pittsburgh, PA  15213-3890
 *      (412) 268-4387, fax: (412) 268-7395
 *      tech-transfer@andrew.cmu.edu
 *
 * 4. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by Computing Services
 *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
 *
 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

/* $Id: managesieve.xs,v 1.18 2002/05/25 19:57:51 leg Exp $ */

#ifdef __cplusplus
extern "C" {
#endif
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#ifdef __cplusplus
}
#endif

#include "managesieve.h"

#include <netinet/in.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <netdb.h>

typedef struct xscyrus *Sieveobj;
static char *globalerr = NULL;

#include "isieve.h"

static int
not_here(s)
char *s;
{
    croak("%s not implemented on this architecture", s);
    return -1;
}

static double
constant(name, arg)
char *name;
int arg;
{
    errno = 0;
    switch (*name) {
    }
    errno = EINVAL;
    return 0;

not_there:
    errno = ENOENT;
    return 0;
}

int
fatal(s,t)
char *s;
int t;
{
    croak("failure: %s", s);
    return -1;
}

static int
perlsieve_getpass(conn, context, id, psecret)
	sasl_conn_t *conn;
	void *context;
	int id;
        sasl_secret_t **psecret;
{
        int count;
        dSP ;
        char *tmp;
        SV * func = (SV *) context;

        ENTER ;
        SAVETMPS;
        PUSHMARK(sp) ;

        XPUSHs(sv_2mortal(newSVpv("password", 0)));
	XPUSHs(sv_2mortal(newSVpv("Please enter your password", 0)));

        PUTBACK ;
        count = perl_call_sv(func, G_SCALAR);
        SPAGAIN ;
        if (count != 1)
            croak("Big trouble\n") ;
        tmp = POPp;

        /* copy result */
        *psecret = malloc(sizeof(sasl_secret_t) + strlen(tmp) + 2);
        if (!*psecret) return SASL_NOMEM;
        strcpy( (*psecret)->data ,tmp);
        (*psecret)->len = strlen(tmp);

        PUTBACK ;
        FREETMPS ;
        LEAVE ;

        PUTBACK ;

        return SASL_OK;
}

static int
perlsieve_simple(context, id, result, len)
	void *context;
        int id;
	unsigned char **result;
        unsigned *len;
{
        int count;
        dSP ;
        char *tmp;
        SV * func = (SV *) context;

        ENTER ;
        SAVETMPS;
        PUSHMARK(sp) ;
	if (id == SASL_CB_USER) {
	        XPUSHs(sv_2mortal(newSVpv("username", 0)));
		XPUSHs(sv_2mortal(newSVpv("Please enter your username", 0)));
	} else if (id == SASL_CB_AUTHNAME) {
	        XPUSHs(sv_2mortal(newSVpv("authname", 0)));
		XPUSHs(sv_2mortal(newSVpv("Please enter your authentication name", 0)));
	} else if (id == SASL_CB_GETREALM) {
	        XPUSHs(sv_2mortal(newSVpv("realm", 0)));
		XPUSHs(sv_2mortal(newSVpv("Please enter your realm", 0)));
	} else {
	        croak("Bad callback\n");
		return SASL_FAIL;
	}

        PUTBACK ;
        count = perl_call_sv(func, G_SCALAR);
        SPAGAIN ;
        if (count != 1)
            croak("Big trouble\n") ;
        tmp = POPp;

        /* copy result */
        *result = malloc(strlen(tmp) + 2);
        if (!*result) return SASL_NOMEM;
        strcpy(*result,tmp);
        if (len) *len = strlen(*result);

        PUTBACK ;
        FREETMPS ;
        LEAVE ;

        PUTBACK ;

        return SASL_OK;
}


static void *
call_listcb(unsigned char *name, int isactive, void *rock)
{
        dSP ;
        PUSHMARK(sp) ;
        XPUSHs(sv_2mortal(newSVpv(name, 0)));
        XPUSHs(sv_2mortal(newSViv(isactive)));
        PUTBACK ;

        /* call perl func */
        perl_call_sv((SV *)rock, G_DISCARD) ;
	return NULL;
}


#line 219 "managesieve.c"
XS(XS_Cyrus__SIEVE__managesieve_sieve_get_handle)
{
    dXSARGS;
    if (items != 5)
	Perl_croak(aTHX_ "Usage: Cyrus::SIEVE::managesieve::sieve_get_handle(servername, username_cb, authname_cb, password_cb, realm_cb)");
    {
	char *	servername = (char *)SvPV(ST(0),PL_na);
	SV *	username_cb = ST(1);
	SV *	authname_cb = ST(2);
	SV *	password_cb = ST(3);
	SV *	realm_cb = ST(4);
#line 223 "managesieve.xs"
  Sieveobj ret = NULL;
  sasl_callback_t *callbacks;
  int sock,port;
  sasl_conn_t *saslconn;
  int r;
  struct servent *serv;
  char *mechlist=NULL,*mlist=NULL;
  const char *mtried;
  isieve_t *obj;

#line 242 "managesieve.c"
	Sieveobj	RETVAL;
#line 235 "managesieve.xs"
  /* xxx this gets leaked! */
  callbacks = safemalloc(5 * sizeof(sasl_callback_t));

  callbacks[0].id = SASL_CB_USER;
  callbacks[0].proc = &perlsieve_simple;
  callbacks[0].context = username_cb;
  callbacks[1].id = SASL_CB_AUTHNAME;
  callbacks[1].proc = &perlsieve_simple;
  callbacks[1].context = authname_cb;
  callbacks[2].id = SASL_CB_GETREALM;
  callbacks[2].proc = &perlsieve_simple;
  callbacks[2].context = realm_cb;
  callbacks[3].id = SASL_CB_PASS;
  callbacks[3].proc = &perlsieve_getpass;
  callbacks[3].context = password_cb;
  callbacks[4].id = SASL_CB_LIST_END;

  /* map port -> num */
  serv = getservbyname("sieve", "tcp");
  if (serv == NULL) {
      port = 2000;
  } else {
      port = ntohs(serv->s_port);
  }

  if (init_net(servername, port, &obj)) {
      globalerr = "network initialization failed";
      XSRETURN_UNDEF;
  }

  if (init_sasl(obj, 128, callbacks)) {
      globalerr = "sasl initialization failed";
      XSRETURN_UNDEF;
  }

  ret = malloc(sizeof(struct xscyrus));
  ret->class = safemalloc(20);
  strcpy(ret->class,"managesieve");
  ret->isieve = obj;
  ret->errstr = NULL;

  mechlist=read_capability(obj);
  if(!mechlist) {
	globalerr = "sasl mech list empty";
	XSRETURN_UNDEF;
  }

  mlist = (char*) xstrdup(mechlist);
  if(!mlist) {
	globalerr = "could not allocate memory for mech list";
	XSRETURN_UNDEF;
  }

  /* loop through all the mechanisms */
  do {
    mtried = NULL;
    r = auth_sasl(mlist, obj, &mtried, &globalerr);

    if(r) init_sasl(obj, 128, callbacks);

    if(mtried) {
	char *newlist = (char*) xmalloc(strlen(mlist)+1);
	char *mtr = (char*) xstrdup(mtried);
	char *tmp;

	ucase(mtr);
	tmp = strstr(mlist,mtr);
	*tmp ='\0';
	strcpy(newlist, mlist);
	tmp++;

	tmp = strchr(tmp,' ');
        if (tmp) {
	    strcat(newlist,tmp);
	}

	free(mtr);
	free(mlist);
	mlist = newlist;
    }
  } while (r && mtried);

  if(r) {
	/* we failed */
	free(ret->class);
	free(ret);
	XSRETURN_UNDEF;
  }
  ST(0) = sv_newmortal();
  sv_setref_pv(ST(0), ret->class, (void *) ret);
#line 335 "managesieve.c"
    }
    XSRETURN(1);
}

XS(XS_Cyrus__SIEVE__managesieve_sieve_get_error)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Cyrus::SIEVE::managesieve::sieve_get_error(obj)");
    {
	Sieveobj	obj;
	char *	RETVAL;
	dXSTARG;

		IV tmp = SvIV((SV*)SvRV(ST(0)));
		obj = (Sieveobj) tmp;;
#line 330 "managesieve.xs"
    RETVAL = obj->errstr;
#line 354 "managesieve.c"
	sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
    }
    XSRETURN(1);
}

XS(XS_Cyrus__SIEVE__managesieve_sieve_get_global_error)
{
    dXSARGS;
    if (items != 0)
	Perl_croak(aTHX_ "Usage: Cyrus::SIEVE::managesieve::sieve_get_global_error()");
    {
	char *	RETVAL;
	dXSTARG;
#line 337 "managesieve.xs"
    RETVAL = globalerr;
#line 370 "managesieve.c"
	sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
    }
    XSRETURN(1);
}

XS(XS_Cyrus__SIEVE__managesieve_sieve_logout)
{
    dXSARGS;
    if (items != 1)
	Perl_croak(aTHX_ "Usage: Cyrus::SIEVE::managesieve::sieve_logout(obj)");
    {
	Sieveobj	obj;
	int	RETVAL;
	dXSTARG;

		IV tmp = SvIV((SV*)SvRV(ST(0)));
		obj = (Sieveobj) tmp;;
#line 345 "managesieve.xs"
	/* xxx this leaves the object unusable */
	isieve_logout(&(obj->isieve));
	XSRETURN_UNDEF;
#line 392 "managesieve.c"
    }
    XSRETURN(1);
}

XS(XS_Cyrus__SIEVE__managesieve_sieve_put_file)
{
    dXSARGS;
    if (items != 2)
	Perl_croak(aTHX_ "Usage: Cyrus::SIEVE::managesieve::sieve_put_file(obj, filename)");
    {
	Sieveobj	obj;
	char *	filename = (char *)SvPV(ST(1),PL_na);
	int	RETVAL;
	dXSTARG;

		IV tmp = SvIV((SV*)SvRV(ST(0)));
		obj = (Sieveobj) tmp;;
#line 354 "managesieve.xs"
    RETVAL = isieve_put_file(obj->isieve, filename, NULL, &obj->errstr);
#line 412 "managesieve.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}

XS(XS_Cyrus__SIEVE__managesieve_sieve_put_file_withdest)
{
    dXSARGS;
    if (items != 3)
	Perl_croak(aTHX_ "Usage: Cyrus::SIEVE::managesieve::sieve_put_file_withdest(obj, filename, destname)");
    {
	Sieveobj	obj;
	char *	filename = (char *)SvPV(ST(1),PL_na);
	char *	destname = (char *)SvPV(ST(2),PL_na);
	int	RETVAL;
	dXSTARG;

		IV tmp = SvIV((SV*)SvRV(ST(0)));
		obj = (Sieveobj) tmp;;
#line 364 "managesieve.xs"
    RETVAL = isieve_put_file(obj->isieve, filename, destname, &obj->errstr);
#line 434 "managesieve.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}

XS(XS_Cyrus__SIEVE__managesieve_sieve_put)
{
    dXSARGS;
    if (items != 3)
	Perl_croak(aTHX_ "Usage: Cyrus::SIEVE::managesieve::sieve_put(obj, name, data)");
    {
	Sieveobj	obj;
	char *	name = (char *)SvPV(ST(1),PL_na);
	char *	data = (char *)SvPV(ST(2),PL_na);
	int	RETVAL;
	dXSTARG;

		IV tmp = SvIV((SV*)SvRV(ST(0)));
		obj = (Sieveobj) tmp;;
#line 375 "managesieve.xs"
    RETVAL = isieve_put(obj->isieve, name, data, strlen(data), &obj->errstr);
#line 456 "managesieve.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}

XS(XS_Cyrus__SIEVE__managesieve_sieve_delete)
{
    dXSARGS;
    if (items != 2)
	Perl_croak(aTHX_ "Usage: Cyrus::SIEVE::managesieve::sieve_delete(obj, name)");
    {
	Sieveobj	obj;
	char *	name = (char *)SvPV(ST(1),PL_na);
	int	RETVAL;
	dXSTARG;

		IV tmp = SvIV((SV*)SvRV(ST(0)));
		obj = (Sieveobj) tmp;;
#line 385 "managesieve.xs"
    RETVAL = isieve_delete(obj->isieve, name, &obj->errstr);
#line 477 "managesieve.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}

XS(XS_Cyrus__SIEVE__managesieve_sieve_list)
{
    dXSARGS;
    if (items != 2)
	Perl_croak(aTHX_ "Usage: Cyrus::SIEVE::managesieve::sieve_list(obj, cb)");
    {
	Sieveobj	obj;
	SV *	cb = ST(1);
	int	RETVAL;
	dXSTARG;

		IV tmp = SvIV((SV*)SvRV(ST(0)));
		obj = (Sieveobj) tmp;;
#line 395 "managesieve.xs"
    RETVAL = isieve_list(obj->isieve, (isieve_listcb_t *) &call_listcb,
			 cb, &obj->errstr);
#line 499 "managesieve.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}

XS(XS_Cyrus__SIEVE__managesieve_sieve_activate)
{
    dXSARGS;
    if (items != 2)
	Perl_croak(aTHX_ "Usage: Cyrus::SIEVE::managesieve::sieve_activate(obj, name)");
    {
	Sieveobj	obj;
	char *	name = (char *)SvPV(ST(1),PL_na);
	int	RETVAL;
	dXSTARG;

		IV tmp = SvIV((SV*)SvRV(ST(0)));
		obj = (Sieveobj) tmp;;
#line 406 "managesieve.xs"
    RETVAL = isieve_activate(obj->isieve, name, &obj->errstr);
#line 520 "managesieve.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}

XS(XS_Cyrus__SIEVE__managesieve_sieve_get)
{
    dXSARGS;
    if (items != 3)
	Perl_croak(aTHX_ "Usage: Cyrus::SIEVE::managesieve::sieve_get(obj, name, output)");
    {
	Sieveobj	obj;
	char *	name = (char *)SvPV(ST(1),PL_na);
	char *	output = (char *)SvPV(ST(2),PL_na);
	int	RETVAL;
	dXSTARG;

		IV tmp = SvIV((SV*)SvRV(ST(0)));
		obj = (Sieveobj) tmp;;
#line 417 "managesieve.xs"
    RETVAL = isieve_get(obj->isieve, name, &output, &obj->errstr);  

#line 543 "managesieve.c"
	sv_setpv((SV*)ST(2), output);
	SvSETMAGIC(ST(2));
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}

#ifdef __cplusplus
extern "C"
#endif
XS(boot_Cyrus__SIEVE__managesieve)
{
    dXSARGS;
    char* file = __FILE__;

    XS_VERSION_BOOTCHECK ;

        newXSproto("Cyrus::SIEVE::managesieve::sieve_get_handle", XS_Cyrus__SIEVE__managesieve_sieve_get_handle, file, "$$$$$");
        newXSproto("Cyrus::SIEVE::managesieve::sieve_get_error", XS_Cyrus__SIEVE__managesieve_sieve_get_error, file, "$");
        newXSproto("Cyrus::SIEVE::managesieve::sieve_get_global_error", XS_Cyrus__SIEVE__managesieve_sieve_get_global_error, file, "");
        newXSproto("Cyrus::SIEVE::managesieve::sieve_logout", XS_Cyrus__SIEVE__managesieve_sieve_logout, file, "$");
        newXSproto("Cyrus::SIEVE::managesieve::sieve_put_file", XS_Cyrus__SIEVE__managesieve_sieve_put_file, file, "$$");
        newXSproto("Cyrus::SIEVE::managesieve::sieve_put_file_withdest", XS_Cyrus__SIEVE__managesieve_sieve_put_file_withdest, file, "$$$");
        newXSproto("Cyrus::SIEVE::managesieve::sieve_put", XS_Cyrus__SIEVE__managesieve_sieve_put, file, "$$$");
        newXSproto("Cyrus::SIEVE::managesieve::sieve_delete", XS_Cyrus__SIEVE__managesieve_sieve_delete, file, "$$");
        newXSproto("Cyrus::SIEVE::managesieve::sieve_list", XS_Cyrus__SIEVE__managesieve_sieve_list, file, "$$");
        newXSproto("Cyrus::SIEVE::managesieve::sieve_activate", XS_Cyrus__SIEVE__managesieve_sieve_activate, file, "$$");
        newXSproto("Cyrus::SIEVE::managesieve::sieve_get", XS_Cyrus__SIEVE__managesieve_sieve_get, file, "$$$");
    XSRETURN_YES;
}

