/*-
 * Copyright (c) 1998-2005 Joao Cabral
 *
 * 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *      DHIS(c)  Dynamic Host Information System Release 5
 */
#include<netinet/in.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<arpa/nameser.h>
#include<unistd.h>
#include<resolv.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<fcntl.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>

#define	NSUPDATE_CMD "/usr/bin/nsupdate"

int dns_update(unsigned char *r_dname,int r_opcode,short int r_type,
                unsigned int r_ttl,int r_size,unsigned char *r_data) {

        unsigned char str[1024];


        if(r_opcode==ADD) 
        sprintf(str,"update add %s %d IN ",r_dname,r_ttl);
        else if(r_opcode==DELETE)
        sprintf(str,"update delete %s IN ",r_dname);
        else return(0);

        if(r_type==T_A) strcat(str,"A ");
        else if(r_type==T_MX) strcat(str,"MX ");
        else if(r_type==T_CNAME) strcat(str,"CNAME ");
        else return(0);

        strcat(str,r_data);
        strcat(str,"\n");
        strcat(str,"\n");
	
	{ // Now for the forking and running nsupdate
	int fildes[2];
	int childpid;
	int r=0;
	
	if(pipe(fildes)) return(0);

	write(fildes[1],str,strlen(str)+1);

	childpid=fork();
	if(!childpid) { // I am the child 

	// Place the pipe read in stdin and close pipe write
	if(fildes[0]!=0) close(0);
        if(fildes[0]!=0) dup2(fildes[0],0);
        close(fildes[1]);

	// Redirect stdout and stderr to NULL
        close(1);
        close(2);
	open("/dev/null",O_WRONLY,0666);
	open("/dev/null",O_WRONLY,0666);

	r=execlp(NSUPDATE_CMD,NSUPDATE_CMD,"-d",NULL);
	if(r) exit(1); else exit(0);
	} else {
	int ret;
	close(fildes[0]);
	close(fildes[1]);
	if(waitpid(childpid,&ret,0)==-1) return(0);
	return(1);
	}
	}
}

