관리 메뉴

(코딩캣) = "코딩"하는 고양이;

[옛 강좌] 27. Perlprog - BBS 6 본문

Common Gateway Interface/Perl

[옛 강좌] 27. Perlprog - BBS 6

컴파일러님, 이 코드는 고양이발로 작성되었습니다. 코딩집사 2015. 4. 29. 13:20

 이 게시물은 지금은 폐쇄되어 접속되지 않는 Kim Young Soo(http://hours.interpia98.net/~unisoo/)님의 웹 사이트에 2001년경 게시된 내용을 바탕으로 오늘날 웹 환경에 맞게 내용을 덧붙였습니다.

Perlprog - BBS 6

Description

게시판 만들기 6 - 데이터 삭제


BBS 만들기 6

 이번에 할 내용은 게시된 내용물을 삭제하는 것입니다.

 원하는 데이터를 읽은다음, 삭제표시 아이콘을 누르면, 암호 확인 창이 뜨고, 암호를 입력 하고, 틀리면 틀린다는 메세지를, 맞으면 삭제하는 방법으로 하겠습니다.

사용자 확인(Register)

 그럼 우선, 아이콘을 눌렀을 때 확인하는 파일을 먼저 만들겠습니다. 이 파일은 삭제뿐 아니라, 편집할 때도 마찬가지로 뜨게 되어있는 파일입니다.

이 때 삭제인지, 편집인지를 가려서 프로그램을 따로 실행시킵니다. 그럼 이 확인하는 프로그램을 board_pwd.cgi라고 이름짓고 시작합니다.

board_pwd.cgi - 사용자 확인

 이 프로그램은 간단합니다. 그 전에.... board_view.cgi에서 삭제를 눌렀을 때 어떤 변수가 넘어 와야 하는지 생각해보죠. 그리고 이 프로그램에선 그 변수들을 hidden으로 숨겨서 실제로 작업을 하게되는 board_delete.cgi로 넘겨주게 됩니다.

<a href=./board_pwd.cgi?mode=delete&number=$file_number>

위에서 보시다시피, 넘겨주는 변수는

mode
삭제 모드죠, 이것이 편집이면, mode=modify가 됩니다.
number
실제로 지워지거나 편집되어 지는 파일번호를 넘깁니다.

 이제 필요한 것이 준비 됐으니깐....

#! /usr/local/bin/perl

require "./basic.pl";

$temp = $ENV{'QUERY_STRING'};

&parse_data($temp, *data);

if ($data{'mode'} eq "delete")
{
	&go_delete;
}
else
{
	&go_modify;
}
					

 위의 프로그램이 메인 루틴입니다. 보시면 아시겠지만서리.... mode가 delete이면 go_delete() 함수를 호출하구, 아니면 go_modify() 함수를 호출합니다.

이 두 개의 함수는 입력 폼을 보여주는 것이, 이 함수의 모든 기능입니다. 이 때, board_view.cgi에서 넘어온 두 개의 변수를 hidden으로 넘겨줌과 동시에, 입력 받을 패스워드를 다음 프로그램(board_delete.cgi 나 board_modify.cgi)에 넘겨주게 됩니다.

go_delete()

sub go_delete
{
	&print_header;
	
	print "
		<html>
		<body bgcolor=white>
		
			<form action=./board_delete.cgi method=post>
			
				<table width=200 border=0>
					<tr>
						<td align=center bgcolor=aliceblue>
							<font size=2 color=red><b>정말로 삭제하실려구여?</b></font><br>
							<font size=2 color=blue>비밀번호를 입력하세요</font>
						</td>
					</tr>
					<tr>
						<td align=center bgcolor=blue>
							<input type=password name=pwd size=10 maxlength=8>
							<input type=hidden name=number value=$data{'number'}>
							<input type=submit value=확인>
						</td>
					</tr>
				</table>
			</form>
		</body>
		</html>\n";
}
						

go_modify()

sub go_modify
{
	&print_header;
	
	print "
		<html>
			<body bgcolor=white>
				<form action=./board_modify.cgi method=post>
				<table width=200 border=0>
				<tr>
					<td align=center bgcolor=aliceblue>
						<font size=2 color=red><b>고치시려구여?</b></font><br>
						<font size=2 color=blue>비밀번호를 입력하세요</font>
					</td>
				</tr>
				<tr>
					<td align=center bgcolor=blue>
						<input type=password name=pwd size=15 maxlength=8>
						<input type=hidden name=number value=$data{'number'}>
						<input type=submit value=확인>
					</td>
				</tr>
				</table>
				</form>
			</body>
		</html>\n";
}
						

위의 함수에서는 별루 드릴 말씀이 없네여.... ^^; 모두들 잘 아시리라 믿구...

board_delete.cgi - 데이터 삭제

 board_delete.cgi 에 대해서 알아 보겠습니다. 이 삭제는 생각보다는 쉽습니다. 해당하는 파일을 지우기만 하면 되져.

 이 때, 한 가지 더 생각할것은, 인덱스 파일이져.... 파일을 하나씩 따로 저장이 되어있기 때문에 삭제하기 좋지만, 인덱스 파일은 줄 단위로 하나의 파일에 저장이 되어있기 때문에, 해당하는 행을 찾아서 지워야 합니다. 패스워드를 저장한 파일도 마찬가지구여...

 그럼 소스를 보겠습니다.

#! /usr/local/bin/perl

require "./basic.pl";
require "./board.conf";

### 아래의 조건문은 전송방식을 먼저 점검합니다. 이런 이유는 누군가가 브라우져의 주소줄에 
### board_delete.cgi?pwd=xxxx...... 이런 식으로 접근하는 것을 막기 위해서 입니다. 주소 줄이 아닌, 폼에서 오는 데이터만
### 검사하겠다는 겁니다. 그런 다음... 암호를 점검하게 되죠. 이런다구 보안이 아주 좋아지는 건 아니지만, 어느정도..... ^^; 
if (!(&form_method eq 'POST'))
{
	&error_print;
	exit 0;
}

### 전송방식이 맞다면, 지정한 암호를 검사합니다.
### 맞으면 아래의 함수 delete_data()를 실행시킨 다음(이건 두번 합니다. 인덱스 파일과, 패스워드파일 에 대해서...),
### 본래의 파일을 삭제합니다. 삭제 후... 리스트를 보여줍니다. 
else
{
	&parse_input (*fields);
	
	$now = &get_list($fields{'number'});
	$delete_file_name = $data_dir."/board".$fields{'number'}.".dat";
	
	open (FILE, "$pwd_file") || die &error_message("$pwd_file을 열수 없습니다.");;
	@pwd = <FILE>;
	$now_pwd = $pwd[$now];
	close (FILE);
	
	($idx, $password) = split(/::/, $now_pwd);
	
	chomp($password);
	
	if (crypt($fields{'pwd'}, $password) ne $password)
	{
		&error_print;
		exit 0;
	}
	else
	{
		&delete_data($idx_file, $now);
		&delete_data($pwd_file, $now);
		unlink($delete_file_name);
		
		print "Location: $url/cgi-bin/view_list.cgi\n\n";
	}
}
					

 메인 루틴이 끝났습니다. 이젠 우리가 사용할 함수들에 대해서 보겠습니다.

error_print()

 이 함수는 전송방식이 post가 아니라던가, 암호가 틀렸을경우에 뿌리는 메세지 입니다.

sub error_print
{
	&print_header;
	
	print "
		<html>
			<body bgcolor=white>
				<font size=2 color=red><b>이거 뭡니까? 엉?</b></font>
			</body>
		</html>\n";
}
						

 이 함수는 인덱스 파일과 패스워드 파일에서 우리가 삭제하고 했던 데이터를 지우는 부분입니다. 이 함수는 인자로 인덱스 파일이나 패스워드 파일과, 지우고자 하는 배열의 번호를 넘겨 받습니다.

 이 get_list() 함수에 대해서는 지난주에 했기 땜시..... 넘어 갑니당.....

 이 함수는, 해당하는 파일을 열어서, 안의 데이터를 해쉬에 저장을 합니다. 그리고 delete() 함수를 이용해서 원하는 데이터를 없앤 후, 다시 저장을 하는 과정을 거치게 됩니다.

delete_data()

sub delete_data
{
	my ($d_file, $d_now) = @_;
	my ($hash_count, %delete_hash, $list, $total_hash);
	
	open (FILE, "$d_file") || die &error_message("$d_file을 열수 없습니다.");
	$hash_count = 0;
	while (<FILE>)
	{
		$delete_hash{$hash_count} = $_;
		$hash_count++;
	}
	close (FILE);
	
	delete $delete_hash{$d_now};
	
	$total_hash = &get_max_number;
	
	open (FILE, ">$d_file") || die &error_message("$d_file을 열수 없습니다.");
	for ($list = 0; $list < $total_hash; $list++)
	{
		print FILE $delete_hash{$list};
	}
	close (FILE);
}
						

get_list()

 이 함수는 지난주에도 나왔었죠. 실제 파일번호를 가지고, 인덱스파일을 가지고, 배열번호를 알아내는 함수입니다.

sub get_list
{
	my ($get_idx) = @_;
	open (FILE, "$idx_file") || die &error_message("$idx_file을 열수 없습니다.");
	
	$get_count = 0;
	
	while (<FILE>)
	{
		@temp = split(/::/, $_);
		if ($temp[0] eq $get_idx)
		{
			last;
		}
		$get_count++;
	}
	close (FILE);
	
	return $get_count++;
}
						

NOTES

 이로서 우리는 데이터를 지울수도 있게 되었습니다.

 다음 주엔 편집에 대해서 보겠습니다. 그리 어렵지 않겠죠? 지금까지 온거라면, 편집 기능은 우스워 보일수도 있겠네여....

이 문서는 Perl 패키지내의 pod2html를 이용하여 만들었습니다. - Kim Young Soo

0 Comments
댓글쓰기 폼