Create TOC

2006년 3월 16일

파일 이름이 깨지지 않도록 HTTP Header 처리하기

opera등의 웹브라우저에서 파일 다운로드시 파일명이 깨지는 경우가 있다.

파일명에 한글이 들어가 있고 파일 직접 링크가 아니고 별도 서버 프로그램(php 등)을 통해서 다운 받는 경우 발생하는데, 서버쪽 프로그램을 수정해줘야 한다.

php 경우 아래처럼 수정해주면 된다.

<?php
$fname = "파일명";
function id_browser() {
    $browser=$_SERVER['HTTP_USER_AGENT'];

    if(ereg('Opera(/| )([0-9].[0-9]{1,2})', $browser))
    {
        return 'OPERA';
    }
    else if(ereg('MSIE ([0-9].[0-9]{1,2})', $browser))
    {
        return 'IE';
    }
    else if(ereg('OmniWeb/([0-9].[0-9]{1,2})', $browser))
    {
        return 'OMNIWEB';
    }
    else if(ereg('(Konqueror/)(.*)', $browser))
    {
        return 'KONQUEROR';
    }
    else if(ereg('Mozilla/([0-9].[0-9]{1,2})', $browser))
    {
        return 'MOZILLA';
    }
    else
    {
        return 'OTHER';
    }
}

$browser = id_browser();

$download_size = filesize($fname);
header("Content-Type: application/x-download");
if ($browser == 'IE')
{
    header("Content-Disposition: attachment; filename=" . urlencode(iconv("cp949", "utf-8", $fname)) );
}
else
{
    header("Content-Disposition: attachment; filename=" . iconv("cp949", "utf-8", $fname) );
}
header("Accept-Ranges: bytes");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . $download_size );

@readfile($fname);
?>

HTTP 헤더중 Content-Disposition: 에 파일 이름을 기술하는데 브라우저마다 인식하는 방법이 다르기 때문에 별도 처리들 해줘야 한다.

IE 경우는 utf-8 문자열을 urlencode 해줘야 하고, Opera나 Firefox 는 그냥 utf-8 로 써주면 된다.

2006년 3월 8일

Apache에서 Robot 접근 막기

평소에는 robot에 대해 무관심 했었는데 어느 날 서버 로그를 보니 MSN robot이 내 사이트 전체를 긁고 있었다. 물론 robot.txt 파일을 만들어서 robot 이 내 사이트에 접근하지 않도록 했었지만 MSN은 그 규칙을 무시하고 있었다.

그래서 처음에는 MSN의 robot만 막으려고 했지만 서버 로그를 관찰한 결과 robot.txt 는 무용지물이라고 결론내리고 apache의 rewrite 모듈을 이용해 robot을 막기로 했다.

테스트 환경

  • Debian Sarge
  • Apache 2.0

Apache 설정

Apache 2.0으로 오면서 기존에 httpd.conf 에 통합되었던 설정 파일이 여러 디렉토리로 분산 되었다.

  • 설정 파일인 /etc/apache2/apache2.conf
  • 모듈 설정 파일이 있는 /etc/apache2/mods-avaliable
  • 사용할 모듈 설정 파일이 있는 /etc/apache2/mods-enabled 실제로는 /etc/apache2/mods-avaliable 에 있는 파일을 심볼릭 링크를 걸어서 사용한다.
  • 웹사이트 설정 파일이 있는 /etc/apache2/sites-avaliable
  • 사용할 웹사이트 설정 파일이 있는 /etc/apache2/sites-avaliable 실제로는 /etc/apache2/sites-avaliable 에 있는 파일을 심볼릭 링크를 걸어서 사용한다.

rewrite 모듈 활성화

rewrite모듈을 apache가 읽도록 하기 위해서 /etc/apache2/mods-enabled 디렉토리에서 아래 명령을 실행한다.

$ ln -s ../mods-avaliable/rewrite.load

웹사이트 설정 변경

웹사이트 설정 파일을 하나 만든다(여기서는 testserver 로 한다. 기존에 사용 하던 파일이 있으면 그 파일을 수정한다).

$ cd /etc/apache2/sites-avaliable
$ vi testserver

아래와 같은 내용을 입력한다.


    ...

    # robot 막기
    RewriteEngine On
    RewriteCond %{HTTP_USER_AGENT} ^.*Slurp.* [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} ^.*MMCrawler.* [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} ^.*grub-client.* [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} ^.*WISEbot.* [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} ^.*robot.* [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} ^.*Gaisbot.* [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} ^.*WebRobot.* [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} ^.*WebZIP.*  [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} ^.*Teleport.* [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} ^.*MSNBot.* [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} ^.*Yahoo.* [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} ^.*Naver.* [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} ^.*Empas.* [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} ^.*Crawler.* [NC]
    RewriteRule .* - [F,L]

    ...

설정이 끝났으면 아래 명령으로 방금 설정한 testserver 를 apache 시작 시 읽도록 한다.

$ cd /etc/apache2/sites-enabled
$ ln -s ../sites-avaliable/testserver

아파치 재 시작

$ /etc/init.d/apache2 restart

이제 웹서버 로그를 살펴보면 위에 기술된 webrobot들은 모두 403 에러(접근 금지) 를 만나게 된다.

인터넷 연결상태 알아오기


DWORD dwConnectionTypes;
if(InternetGetConnectedState(&dwConnectionTypes, 0)) // 정상적으로 검사됨
{
	if((dwConnectionTypes & INTERNET_CONNECTION_MODEM) != 0)
		printf("Internet connection using modem");

	if((dwConnectionTypes & INTERNET_CONNECTION_LAN) != 0)
		printf("Internet connection using LAN");

	if((dwConnectionTypes & INTERNET_CONNECTION_PROXY) != 0)
		printf("Internet connection using Proxy");

	if((dwConnectionTypes & INTERNET_CONNECTION_MODEM_BUSY) != 0)
		printf("Modem is busy");

	if((dwConnectionTypes & INTERNET_RAS_INSTALLED) != 0)
		printf("RAS is installed");

	if((dwConnectionTypes & INTERNET_CONNECTION_OFFLINE) != 0)
		printf("Offline");
}
else
	printf("InternetGetConnectedState() API is failed!");

파일 write시에 다른 프로세스가 접근하지 못하도록 파일을 lock

Original link

int f_lockwrite(char* szMsg, int iFileDesc)
{
	struct flock    *stFlock;
	int             n;

	stFlock = (struct flock*)malloc(sizeof(struct flock));
	stFlock->l_type = F_WRLCK;
	fcntl(iFileDesc, F_SETLKW, stFlock);
	if ((n = write(iFileDesc, szMsg, 1)) <= 0)
 	{
		return -1;
	}
	stFlock.l_type = F_UNLCK;
	fcntl(iFileDesc, F_SETLK, stFlock);
	free(stFlock);
	return 1;
}

Windows Icon Cache를 다시 생성하기

가끔 Windows Icon Cache 가 깨져서 다시 생성해야 할 필요가 있다. 보통은 icon cache 파일을 삭제후 재부팅 하거나 바탕화면 등록 정보에서 icon 크기를 바꾸면 된다.

아래 코드는 바탕화면 icon 크기를 변경시켜서 icon cache를 다시 생성하게 만드는 코드이다.

#include <atlbase.h>

/**	@brief	윈도우의 아이콘 캐쉬를 다시 빌드한다.
 *
 *	@author	Yun-yong Choi
 */
void __cdecl RebuildIconCache(void)
{
	CRegKey RegKey;		/**< registry interface */
	int OldSize = 0;	/**< 원래 shell icon 크기를 저장 */

	LRESULT lRet = RegKey.Open(HKEY_CURRENT_USER,
		"Control Panel\\Desktop\\WindowMetrics",
		KEY_ALL_ACCESS);

	if (lRet == ERROR_SUCCESS)
	{
		DWORD dwCnt;
		CHAR buf[BUFSIZ] = {0, };

		dwCnt = BUFSIZ - 1;

		lRet = RegKey.QueryValue(buf, "Shell Icon Size", &dwCnt);
		if (lRet != ERROR_SUCCESS)
		{
			RegKey.Close();
			return;
		}

		OldSize = atoi(buf);
		wsprintf(buf, "%ld", OldSize + 1);
		RegKey.SetValue(buf, "Shell Icon Size");
		SendMessage( HWND_BROADCAST, WM_SETTINGCHANGE,
			SPI_SETICONMETRICS, (LPARAM)( "WindowMetrics" ));

		if (OldSize > 0)
		{
			wsprintf(buf, "%ld", OldSize);
			RegKey.SetValue(buf, "Shell Icon Size");

			SendMessage( HWND_BROADCAST, WM_SETTINGCHANGE,
				SPI_SETICONMETRICS, (LPARAM)( "WindowMetrics" ));
		}
		else
		{
			RegKey.DeleteValue("Shell Icon Size");

			SendMessage( HWND_BROADCAST, WM_SETTINGCHANGE,
				SPI_SETICONMETRICS, (LPARAM)( "WindowMetrics" ));
		}
		RegKey.Close();
	}
}

Kernel 2.6.x에서 한/영 전환키 사용하기

커널을 수정하지 않는 방법

/etc/init.d/bootmisc.shDebian sid기준 아래와 같은 내용을 추가합니다.아래와 같은 내용을 추가합니다.

setkeycodes 71 122
setkeycodes 72 123

~/.Xmodmap 파일에 아래 내용을 추가합니다.

keycode 210 = Hangul
keycode 209 = Hangul_Hanja

X 시작시 Xmodmap파일을 읽도록 적당히 설정합니다. 내 경우에는 ~/.xsession 파일에 아래 내용을 추가했습니다.

xmodmap ~/.Xmodmap

커널을 수정하는 방법

input.c 파일을 수정해야 한다.

--- linux/drivers/input/input.c~   2004-02-11 02:50:37.000000000 +0900
+++ linux/drivers/input/input.c   2004-02-13 14:32:02.726977768 +0900
@@ -92,8 +92,11 @@

       case EV_KEY:

-         if (code > KEY_MAX || !test_bit(code, dev->keybit) || !!test_bit(code, dev->key) == value)
-            return;
+         if (code != KEY_HANGUEL && code != KEY_HANJA)
+         {
+            if (code > KEY_MAX || !test_bit(code, dev->keybit) || !!test_bit(code, dev->key) == value)
+               return;
+         }

          if (value == 2)
             break;

Debian/Tip모음

각종 그룹 설정

사운드 카드 출력 권한

# adduser user_id audio

각종 디스크 접근 권한

# adduser user_id floppy
# adduser user_id cdrom
# adduser user_id disk

Video4Linux

# adduser user_id video

log파일 읽기 권한 부여

# adduser user_id adm

/usr/src 아래 소스파일에 접근 권한 부여

# adduser user_id src

/usr/local 아래작업 권한과 /home 아래 디렉토리 만드는 권한 부여

# adduser user_id staff

serial port 접근 권한

# adduser user_id dialout

공유 설정 권한

# adduser user_id sambashare

로케일

로케일 설정

# dpkg-reconfigure locales

한글 로케일로 설정

/etc/skel/ 에 만들기

# set-language-env -E

현재 사용자의 홈 디렉에 만들기

# set-language-env -R

fat32 한국어 codepage로 mount

/etc/fstab에 아래와 같이 설정.

/dev/hda1 /mnt/win vfat noauto,iocharset=cp949,defaults 0 0

X.org

X.org에서 hal을 지원하면서 크게 수정해야 할 부분이 없어졌다.

Windows Manager 바꾸기

# update-alternative --config x-session-manager
# update-alternative --config x-window-manager

service daemon 추가 제거

제거

# update-rc.d -f xdm remove

추가

# update-rc.d xdm defaults 99 01

kernel

Debian/Kernel 패키지 만들기

mount

autofs 사용시 root 이외의 사용자가 mount 되는 파티션에 접근하기

/etc/auto.misc 파일을 아래와 같이 수정한다.

win_c  -fstype=vfat,gid=disk,umask=022 :/dev/hda1

위 설정대로 하면 /dev/hda1 파티션을 /var/autofs/misc/win_c 에 mount하고 disk 그룹 사용자가 읽기,실행 권한을 가지도록 한다.

Package 관리

패키지 목록 갱신하기

$ apt-get update

패키지 설치하기

$ apt-get install hello
$ dpkg -i hello*.deb

설치된 패키지 업그레이드하기

$ apt-get upgrade
$ apt-get dselect-upgrade

시스템 업그레이드

stable 에서 testing 이나 unstable로 시스템을 변경하고 싶을때 사용한다.

$ apt-get dist-upgrade

패키지 삭제하기

$ apt-get remove hello

패키지 설정 삭제하기

$ apt-get remove --purge hello

특정 패키지의 자세한 정보 출력하기

$ dpkg --print-avail hello
$ dpkg -p hello
$ apt-cache show hello

설치된 패키지 전체 목록 보기

$ dpkg -l

설치된 패키지 해당 파일 목록 보기

$ apt-file list hello
$ dpkg -L hello

특정 파일이 어느 패키지에 속해 있는지 보여주기

$ apt-file search foofile
$ dpkg --search foofile
$ dpkg -S foofile

패키지 소스 받기

$ apt-get source hello

패키지 소스 받아 컴파일 설치하기

$ apt-get -b source hello
$ apt-get source hello
$ apt-get build-dep less
$ cd hello-###/
$ fakeroot ./debian/rules binary

패키지 의존성 보기

$ apt-cache depends hello

패키지 역 의존성 보기

$ apt-cache rdepends hello

패키지 빌드 의존성 충족시키기

$ apt-get build-dep hello

고아 패키지 찾기

다른 패키지와 연관성이 없는 고아 패키지 검색하기.

$ deborphan

이름으로 패키지 찾기

$ apt-cache pkgnames hello

설명으로 패키지 찾기

$ apt-cache search hello

GNOME

gnome-volume-manager 사용

  • usbmount 등이 있으면 삭제
  • plugdev 그룹에 자신의 id 추가
  • fstab에서 외부 장치에 대한 부분 주석 처리. 내장 하드 에 대해서 주석 처리 했더니 권한 문제가 생겼다. 해결 방법은 아직 모른다.
  • gconf-editor를 사용해서 /system/storage/default_options 에 codepage와 iocharset 값을 추가. debian 에서 기본 커널을 사용할 경우 iocharset가 iso8859-1 이기 때문에 한글 문제가 발생한다. 아래는 로케일이 ko_KR.UTF-8 일 경우 설정 창이다.

Debian/Clie 싱크하기

환경

  • Debian Linux Sid
  • Linux Kernel 2.4.20 (devfs 사용)
  • Clie T650
  • Gnome-Pilot2 2.0.10

커널 설정

아래와 같이 커널 옵션을 변경한 후 커널을 빌드한다.

CONFIG_USB_SERIAL=m
CONFIG_USB_SERIAL_VISOR=m

시스템 재부팅 후 모듈이 제대로 빌드되었는지 확인한다.

# /sbin/modprobe visor

kernel: usb.c: registered new driver serial
kernel: usbserial.c: USB Serial support registered for Generic
kernel: usbserial.c: USB Serial Driver core v1.4
kernel: usbserial.c: USB Serial support registered for Handspring Visor / Palm 4.0 / Clie 4.x

모듈을 올리고 Clie를 Cradle에 올리고 Hotsync 버튼을 누르면 /var/log/messages 파일에 아래와 같은 로그가 남는다.

/var/log/messages

kernel: hub.c: new USB device 00:07.2-2.3, assigned address 8
kernel: usbserial.c: Handspring Visor / Palm 4.0 / Clie 4.x converter detected
kernel: visor.c: Handspring Visor / Palm 4.0 / Clie 4.x: Number of ports: 2
kernel: visor.c: Handspring Visor / Palm 4.0 / Clie 4.x: port 1, is for Generic use and is bound to ttyUSB0
kernel: visor.c: Handspring Visor / Palm 4.0 / Clie 4.x: port 2, is for HotSync use and is bound to ttyUSB1
kernel: usbserial.c: Handspring Visor / Palm 4.0 / Clie 4.x converter now attached to ttyUSB0 (or usb/tts/0 for devfs)
kernel: usbserial.c: Handspring Visor / Palm 4.0 / Clie 4.x converter now attached to ttyUSB1 (or usb/tts/1 for devfs)

gnome-pilot 설정

gnome-pilot 설정 화면에서 아래와 같이 port를 설정한다.

참고

현재 evolution 1.4.4 에서는 evolution의 gnome-pilot용 conduit의 문제로 hotsync를 수행하면 한글이 깨진다.

Apache에서 외부 무단 링크 차단

외부 사이트에서 내 사이트에 있는 내용을 무단 링크하는것을 막는 방법이다. HTTP 헤더중 Referer 을 사용해서 접근을 금지시킨다.

편의상 현재 내 서버는 testserver.com 이라고 한다.

아파치 설정에 아래 내용을 추가한다.

SetEnvIfNoCase Referer "http://testserver.com" permit
SetEnvIfNoCase Referer "^$" permit            # 주소창에 직접 친 경우는 허용
<FilesMatch ".(gif|jpg|png|asf|zip|rar)$"> # 무단 링크를 막을 파일 확장자
    deny from all
    allow from env=permit
    ErrorDocument 403 "Forbidden"
</FilesMatch>

64-Bit Programming Models

한번쯤 읽어볼만한 글(링크)

DatatypeLP64ILP64LLP64ILP32LP32
char88888
short1616161616
_int32 32
int3264323216
long6464323232
long long 64
pointer6464643232