관리 메뉴

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

[옛 강좌] 28. Perlprog - BBS 7 본문

Common Gateway Interface/Perl

[옛 강좌] 28. Perlprog - BBS 7

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

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

Perlprog - BBS 7

Description

게시판 만들기 7 - 편집하기


BBS 만들기 7

 게시판 만들기 일곱번째 입니다. 이번엔 편집기능에 대해서 알아보져.... 검색과 관리자를 뺀다면, 이제 쓸만한 게시판이 나오겠네여... ^^;

board_modify.cgi - 데이터 편집

 그럼 board_modify.cgi라는 이름으로 시작합니다.

#! /usr/local/bin/perl

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

&parse_input(*fields);

if (!$fields{'modify'})
{
	if (!(&form_method eq 'POST'))
	{
		&error_print;
		exit 0;
	}
	else
	{
		$now = &get_list($fields{'number'});
		$modify_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
		{
			&show_form($modify_file_name);
		}
	}
}
else
{
	&modify_data;
}
					

 전제척인 프로그램은 지난번에 했던것과 그리 큰 차이가 없져....

 board_view.cgi 에서 board_pwd.cgi로 프로그램을 넘겨주고, -- 기억나죠? 삭제인지 편집인지 확인해서, 메세지를 다르게 뿌려주고, 삭제일때는 board_delete.cgi로, 편집일땐 지금 우리가 하고자하는 board_modify.cgi로 넘겨주게 되죠.

 삭제 프로그램과 마찬가지로, 실제 파일번호(게시물에서 보여지는 번호가 아닌, 실제 링크된 인덱스번호)가 넘어오게 됩니다.

 이 프로그램의 처음 일은 삭제 시와 마찬가지로.. 변수 전송방식을 체크하고 맞으면, 패스워드를 확인합니다. 맞으면, 기존의 데이터를 불러서 편집 폼에 보여주게 되죠.

 이 때 삭제와 다른건, 수정된 데이터를 저장해야 되기 때문에(답변기능할때를 생각하면서) 수정폼에서 데이터의 저장을 눌렀을때 저장되는 루틴을 동작시켜야 하기 때문에, 이 폼에서 modify변수를 hidden으로 숨겨 놨다가, 보내게 됩니다.

 이 modify 변수가 정의되어 있으면, 데이터를 저장하고, 그렇지 않으면, 폼을 보여주게 되죠. 물론 처음 호출시 이 변수가 없으니 위의 if문이 실행되고, 다음 호출시는 이 변수가 있으니깐, 아래의 else문을 실행하게 됩니다.

 그럼 여기서 숙제~~~~~~ ^^;

 위의 show_form() 함수는 여러분이 직접 해보세요. 넘어가는 변수는 실제 파일이름... 이거 하나면 됩니다. 그럼 위 함수에선 board_write.cgi의 코드를 그대로 쓰면서, 해당 파일을 열어서, 비밀번호를 제외한 나머지 데이터를 해당위치에 보여주면 되져....... 이때 <form> 태그의 action값은 당연 board_modify.cgi가 되겠고....

 주의 하실점!!!

<input type=hidden name=modify value=1>
<input type=hidden name=count value=$mo_data{'COUNT'}>
<input type=hidden name=file_number value=$fields{'number'}>
					

 위와 같이 hidden으로 넘겨주는 변수를 빼먹으면 안됩니다. modify가 정의되어야 else() 문을 실행할 거고, 조회 수 같은경우... 초기화가 되면 안되죠. 기존의 값을 그대로 보존해야 되고, $fields{'number'}가 뭔지 모르신다면.... -.- 이건 안됩니다...

이론.... 다 갈켜줘버렸네여.... 충분하시겠져??? ^^;;

modify_data()

 그럼 이제.... 데이터의 저장을 보죠... 위의 폼에서 저장을 눌렀죠.. modify=1이라는 값을 가지니깐... modify_data() 함수를 호출합니다.

sub modify_data
{
	my ($ModiFileName, $date, $ip, @MoIdxData, @MoTemp, @MoPwdDate, $MoPass);
	
	#### 날짜와 IP를 얻어옵니다.
	$date = &get_date;
	$ip = $ENV{'REMOTE_ADDR'};
	
	#### 실제 파일이름을 얻고.... 변화된 데이터를 덮어 씁니다.
	$ModiFileName = $data_dir."/board".$fields{'file_number'}.".dat";
	
	open (FILE, ">$ModiFileName") || die &error_message("$ModiFileName을 열수 없습니다.");
	print FILE "IDX=$fields{'file_number'}\n";
	print FILE "COUNT=$fields{'count'}\n";
	print FILE "DATE=$date\n";
	print FILE "HOMEPAGE=$fields{'homepage'}\n";
	print FILE "NAME=$fields{'name'}\n";
	print FILE "IP=$ip\n";
	print FILE "EMAIL=$fields{'email'}\n";
	print FILE "TITLE=$fields{'title'}\n";
	print FILE "BODY=$fields{'body'}\n";
	close (FILE);
	
	#### 인덱스 파일과 패스워드 파일도 변경을 해야죠.
	open (FILE, "$idx_file") || die &error_message("$idx_file을 열수 없습니다.");
	@MoIdxData = <FILE>;
	close (FILE);

	#### 실제 파일번호와 인덱스 번호를 비교해서, 해당 인덱스의 정보를 변경합니다.
	open (FILE, ">$idx_file") || die &error_message("$idx_file을 열수 없습니다.");
	foreach (@MoIdxData)
	{
		@MoTemp = split(/::/, $_);
		if ($MoTemp[0] eq $fields{'file_number'})
		{
			print FILE $fields{'file_number'},"::", $fields{'name'},"::", $fields{'title'},"::", $fields{'count'},"::", $date,"\n";
		}
		else
		{
			print FILE $_;
		}
	}
	close (FILE);
	
	#### 패스워드도 위와 같은 방식으로 변경합니다.  
	$MoPass = &get_password($fields{'pawd'});
	open (FILE, "$pwd_file") || die &error_message("$pwd_file을 열수 없습니다.");
	@MoPwdData = <FILE>;
	close (FILE);
	
	open (FILE, ">$pwd_file") || die &error_message("$pwd_file을 열수 없습니다.");
	foreach (@MoPwdData)
	{
		@MoTemp = split(/::/, $_);
		if ($MoTemp[0] eq $fields{'file_number'})
		{
			print FILE $fields{'file_number'}, "::", $MoPass, "\n";
		}
		else
		{
			print FILE $_;
		}
	}
	close (FILE);
	
	#### 작업이 다끝이 났으니깐.... 목록을 보여주는 곳으로 갑니다.
	print "Location: $url/cgi-bin/view_list.cgi\n\n";
}
						

NOTES

 흠.... 편집하는 것도 끝이 났네여.... 이런 방법 말고도 다른 방법들이 많이 존재하죠.. 더 나은 방법들을 생각해보시구, 프로그램 해보세요. 이제 남은거라곤 검색과 관리자 뿐입니다.

 하지만 이 두 가지를 하기전에, 다음에는 파일 잠금에 대해서 잠시 알아보는 시간을 가질까 합니다. 지금까지는 데이터의 보호를 전혀 신경쓰지 않았습니다. 동시에 파일을 쓰기 위해 여는 경우를 생각해 볼수 있죠.... 가끔 카운터같은 경우 0으로 초기화 되는 경우가 생깁니다. 방명록, 또는 게시판의 인덱스 파일이 없어지는 경우도 있죠. 한 사람이 쓸려구 파일을 열구, 또 한사람이 쓸려구 파일을 열구..... 읽기위해 여는 거라면 큰 상관은 없겠죠... 하지만 쓰기위해 여는 건 문제가 됩니다.

 유닉스 계열이라면 flock() 함수가 지원이 되니깐 이 함수를 이용하면 되겠고... 윈도에선 이 flock()함수를 제공하지 않습니다.... 그러니 직접 구현해야 되겠져.... 물론 이렇게 한다구 아주 안전하게 보호할수 있는건 아닙니다. 정기적인 백업.... 아주 중요합니다.

 검색과 관리자의 기능을 빼더라도 이미 게시판의 기능들을 갖추고 있으니깐여.... 이 문제에 대해서 얘기하겠습니다.


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

0 Comments
댓글쓰기 폼