#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

/*

	bash-3.0-geinpeek-0.2 ÀÚµ¿ ÀÎ½ºÅç·¯

	( install-0.2.c )

	ÄÄÆÄÀÏ # gcc install-0.2.c -o install-0.2
	½ÇÇà   # ./install-0.2
*/


/* ¼³Ä¡¿¡ ÀÌ¿ëÇÒ ÀÓ½Ãµð·ºÅä¸® */
#define	DOWNLOAD_DIR	"/root/tmp"

/* ANSI »ö»ó ¸ÅÅ©·Î */
#define SET_ANSI(){     printf("\033[0;44;36m"); }
#define UNSET_ANSI(){   printf("\033[0m");      }


/* ÇÁ·ÎÅäÅ¸ÀÔ */
int download_file(char *src_url);
int checking_file(char *bin_file);
int xtract_package(char *src_url);
void select_and_patch();
void compile_geinpeek_bash();
void make_install();
void make_clean();


/* ¼³Ä¡¿¡ ÇÊ¿äÇÑ ÇÊ¼ö À¯Æ¿¸®Æ¼ ¸ñ·Ï */
char needed[5][16]=
{
    "/bin/bash",
    "/usr/bin/patch",
	"/usr/bin/wget",
	"/bin/tar",
	"\x00",
};

/* À¥»ó¿¡¼­ ´Ù¿î·ÎµåÇÒ ¼Ò½ºÆÐÅ°Áö ¸ñ·Ï */
char download_list[3][128]=
{
    "http://ftp.gnu.org/pub/gnu/bash/bash-3.0.tar.gz",
    "http://kldp.net/frs/download.php/3191/bash-3.0-geinpeek-0.2.tar.gz",
	"\x00",
};

/* ÇÊ¼öÆÐÄ¡ ÆÄÀÏ¸ñ·Ï */
char needed_patch_list[3][64]=
{
	"Makefile.in-geinpeek.diff",
	"ghelper.c",				/* »ç¿ëÀÚ¸í·É ÀÔ·ÂÁ¤º¸ ¸ð´ÏÅÍ¸µ µ¥¸ó */
	"\x00",
};

/* »ç¿ëÀÚ ¼±ÅÃ ÆÐÄ¡Å°Æ® ÆÄÀÏ¸ñ·Ï */
char patchkit_list[3][64]=
{
	"execute_cmd.c-geinpeek.diff",		/* ¸ÞÀÎ ½º´ÏÇÎ ÆÐÄ¡ */
	"shell.c-geinpeek.diff",		/* ·Î±×ÀÎ ¾Ë¸®¹Ì ÆÐÄ¡ ( ¹ÌÃßÃµ ) */
	"\x00",	
};


/* ¼³Ä¡¿Ï·á ¾Ë¸²¸» */
char cong[]=
{
	"BASH-GEINPEEK ÀÇ ¼¼°è¿¡ ¿À½Å°ÍÀ» È¯¿µÇÕ´Ï´Ù ^-^/\n\n"
	"ºü¸¥ ½ÇÇà¹ý : # ghelper 90.txt\n"
};
	

int main()
{

	unsigned int i = 0, ret = 0;

	system("rm -rf /root/tmp");

	if(strcmp(getenv("SHELL"), "/bin/bash") == 0){
		fprintf(stderr, "\n\nÀÌ ¼³Ä¡°úÁ¤À» ÁøÇàÇÏ½Ã·Á¸é root »ç¿ëÀÚÀÇ ±âº»½©À» csh ·Î º¯°æÈÄ\n"
				"Àç·Î±×ÀÎ ÈÄ ½ÃµµÇÏ¼Å¾ßÇÕ´Ï´Ù.\n\n");
		return(1);
	}

	/* 1 ´Ü°è : GNU bash & geinpeek ¼Ò½ºÄÚµå¸¦ ¾ÈÀüÇÑ ¿ÀÇÂ¼Ò½º À¥µð·ºÅä¸®¿¡¼­ ´Ù¿î·Îµå. */

	for(i = 0; download_list[i][0] != '\x00'; i++){
		if(download_file(download_list[i]) != 0){
			ret ++;
			fprintf(stderr, "¼Ò½º ÄÚµå(tar.gz) ´Ù¿î·Îµå¿¡ ½ÇÆÐÇß½À´Ï´Ù:\n\t=> %s\n", download_list[i]);
		}
	}

	printf("\n");

	if(ret != 0)
		return(2);

	ret = 0;

	/* 2 ´Ü°è : ¼³Ä¡¿¡ ÇÊ¿äÇÑ À¯Æ¿¸®Æ¼µéÀÌ ¼³Ä¡µÇ¾ú´ÂÁö È®ÀÎ */
	
	for(i = 0; needed[i][0] != '\x00'; i++){
		if(checking_file(needed[i]) != 0){
			ret ++;
			fprintf(stderr, "¿ä±¸µÇ´Â À¯Æ¿¸®Æ¼ : %s\n", needed[i]);
		} else{
			printf("Á¡°Ë: %s : ¹ß°ß!\n", needed[i]);
		}
	}
	
	if(ret != 0)
		return(3);

	printf("\n");

	/* 3 ´Ü°è : ¼Ò½ºÄÚµå ÆÐÅ°Áö ¾ÐÃà ÇØÁ¦ */

	for(i = 0; download_list[i][0] != '\x00'; i++){
		if(xtract_package(download_list[i]) != 0){
			ret ++;
			fprintf(stderr, "´Ù¿î·ÎµåÇÑ ÆÄÀÏ(tar.gz) ¾ÐÃàÇØÁ¦ ½ÇÆÐ :\n\t=> %s\n", download_list[i]);
		} else{
			printf("¾ÐÃàÇØÁ¦: %s : ¼º°ø!\n", download_list[i]);
		}
	}

	if(ret != 0)
		return(4);

	ret = 0;

	printf("\n");

	/* 4 ´Ü°è : bash-geinpeek ÀÇ ÆÐÄ¡Å°Æ® ÆÄÀÏµéÀ» patch Åø·Î ¹è½Ã¼Ò½ºÆ®¸®¿¡ ÆÐÄ¡ */
	
	select_and_patch();	

	printf("\n");
		
	/* 5 ´Ü°è : Àû¿ëµÈ ¹è½Ã¼Ò½º ÄÄÆÄÀÏ */
	
	compile_geinpeek_bash();

	printf("\n");

	/* 6 ´Ü°è : ¿øº» bash ÆÄÀÏ ¹é¾÷ÈÄ Á¦ÀÎÇÈ ¹è½Ã½©À» /bin/bash ·Î ±³Ã¼ */
	
	make_install();

	/* 7 ´Ü°è : ¼³Ä¡ÃàÇÏ¸Þ½ÃÁö¿Í µµ¿ò¸» Ãâ·Â */
	
	SET_ANSI();
	fprintf(stdout, "%s\n", cong);
	UNSET_ANSI();

	/* 8 ´Ü°è : ¼³Ä¡ ÀÓ½Ãµð·ºÅä¸® Á¦°Å */

	make_clean();



}

#define	OK_MARK		"200 OK"

int download_file(char *src_url)
{
	char sho[128];
	FILE *pfp;
	char msg_buf[2048];
	unsigned int indx = 0;

	sprintf(sho, "%s %s -P %s", needed[2], src_url, DOWNLOAD_DIR);

	if((pfp = popen(sho, "r")) == NULL){
		fprintf(stderr, "\n\n%s : ¿À·ù\n\n", sho);
		goto failed;
	}

	while(!feof(pfp))
		msg_buf[indx++] = fgetc(pfp);

	if(strstr(msg_buf, OK_MARK) != NULL){
		fprintf(stderr, "\n\n%s : ¼Ò½º ÆÄÀÏÀ» ¹ß°ßÇÏÁö ¸øÇß½À´Ï´Ù.\n\n", src_url);
		goto failed;
	}


success:
	pclose(pfp);
	return(0);

failed:
	pclose(pfp);
	make_clean();

}


void make_clean()
{
	char sho[128];

	sprintf(sho, "rm -rf %s\n", DOWNLOAD_DIR);
	system(sho);

	printf("ÆÄÀÏÁ¤¸®: rm -rf %s\n", DOWNLOAD_DIR);

	printf("bye!\n");

	exit(1);

}


int checking_file(char *bin_file)
{
	return access(bin_file, X_OK);
}

#define	ERROR_MARK	"Error exit"

int xtract_package(char *src_url)
{
        char sho[128];
        FILE *pfp;
        char msg_buf[65535];
        unsigned int indx = 0, indxx = 0;
	char *src_file;


	/* URL ¿¡¼­ ½ÇÁ¦ ÆÄÀÏ¸í ÃßÃâ */

	
	if((src_file = strrchr(src_url, '/')) == NULL){
		fprintf(stderr, "\n\n%s : Àß¸øµÈ URL ÀÔ´Ï´Ù.\n\n", src_url);
		goto failed;
	}
	
        sprintf(sho, "%s xzvf %s%s -C %s", needed[3], DOWNLOAD_DIR, src_file, DOWNLOAD_DIR);

        if((pfp = popen(sho, "r")) == NULL){
                fprintf(stderr, "\n\n%s : ¿À·ù\n\n", sho);
                goto failed;
        }

        while(!feof(pfp))
                msg_buf[indx++] = fgetc(pfp);

        if(strstr(msg_buf, ERROR_MARK) != NULL){
                fprintf(stderr, "\n\n%s : ¼Ò½º ÆÄÀÏ ¾ÐÃàÇØÁ¦ ¿À·ù\n\n", src_file);
                goto failed;
        }


success:
        pclose(pfp);
        return(0);

failed:
        pclose(pfp);
        make_clean();
		
}

void select_and_patch()
{
	unsigned int indsx = 0;
	char sho[128];
	char c;

	for(indsx = 0; needed_patch_list[indsx][0] != '\x00'; indsx++){
		sprintf(sho, "mv %s/bash-3.0-geinpeek-0.2/%s %s/bash-3.0", 
			DOWNLOAD_DIR, needed_patch_list[indsx], DOWNLOAD_DIR);
		system(sho);

        if(strstr(needed_patch_list[indsx], ".diff") != NULL){
			printf("ÇÊ¼ö ÆÐÄ¡ : %s [ Àû¿ëµÇ¾úÀ½ ]\n", needed_patch_list[indsx]);
			sprintf(sho, "cd %s/bash-3.0/; patch -f < %s", DOWNLOAD_DIR, needed_patch_list[indsx]);
			system(sho);
		}
	}

        for(indsx = 0; patchkit_list[indsx][0] != '\x00'; indsx++){
                sprintf(sho, "mv %s/bash-3.0-geinpeek-0.2/%s %s/bash-3.0",
                        DOWNLOAD_DIR, patchkit_list[indsx], DOWNLOAD_DIR);
                system(sho);

		SET_ANSI();
		printf("BASH-GEINPEEK : %s Àû¿ëÇÏ½Ã°Ú½À´Ï±î ? (Y/N) ", patchkit_list[indsx]);
		UNSET_ANSI();

		c = ' ';

		fflush(stdin);
		c = fgetc(stdin);	
		
		if(c == 'y' || c == 'Y'){
	        sprintf(sho, "cd %s/bash-3.0/; patch -f < %s", DOWNLOAD_DIR, patchkit_list[indsx]);
			system(sho);
        }
		getchar();
        }
}

void compile_geinpeek_bash()
{
	char sho[128];

	printf("BASH-GEINPEEK : Á¦ÀÎÇÈ ¹è½Ã ÄÄÆÄÀÏ ½ÃÀÛ..\n\n");

	sprintf(sho, "cd %s/bash-3.0/; ./configure; make", DOWNLOAD_DIR);
	system(sho);

	SET_ANSI();
	printf("\n\nBASH-GEINPEEK : Á¦ÀÎÇÈ ¹è½Ã ÄÄÆÄÀÏ ¿Ï·á!!\n\n");
	UNSET_ANSI();

}

void make_install()
{
	char sho[128];

	printf("BASH-GEINPEEK : ÄÄÆÄÀÏµÈ ¹ÙÀÌ³Ê¸®¸¦ ÀûÀýÇÑ µð·ºÅä¸®·Î º¹»çÇÕ´Ï´Ù.\n\n");
	
	printf("backup: /bin/bash to /root/bash\n");
	system("cp /bin/bash /root/bash");

	sprintf(sho, "cd %s/bash-3.0/; mv bash /bin/bash; mv ghelper /sbin/ghelper; chmod 700 /sbin/ghelper");
	system(sho);

	printf("install: bash(Á¦ÀÎÇÈ ¹èÇÇµÈ ¹è½Ã½©) -> /bin/bash\n");
	printf("install: ghelper(¸ð´ÏÅÍ¸µ µ¥¸ó) -> /sbin/ghelper\n");
	
}



