存档

作者存档

在 OpenVZ 上安装 PPTP 完全版教程

2012年1月5日 没有评论

首先,我们必须要知道自己的VPS是否支持PPTP,如果你根据现在网上的那些教程做的话,那么你的第一步就是错的了。

cat /dev/ppp
cat: /dev/ppp: No such device or address
cat /dev/net/tun
cat: /dev/net/tun: File descriptor in bad state

我记得有一篇教程说了,这两个只要一个OK就可以了。我现在可以很负责的告诉大家额,如果你的结果和我上面的两个结果不一样的话,那么你是肯定无法正常使用PPTP的哦。
如果你的结果和我一样的话,那么就继续往下看吧。

yum install -y ppp
yum install -y iptables
rpm -ivh http://acelnmp.googlecode.com/files/pptpd-1.3.4-1.rhel5.1.i386.rpm(X86)
rpm -ivh http://acelnmp.googlecode.com/files/pptpd-1.3.4-1.rhel5.1.x86_64.rpm(X64)
vi /etc/pptpd.conf
# localip 192.168.0.1 -> localip 192.168.0.1
# remoteip 192.168.0.234-238,192.168.0.245 ->remoteip 192.168.0.234-238,192.168.0.245
vi /etc/ppp/options.pptpd
# ms-dns 192.168.0.1 -> ms-dns 8.8.8.8
# ms-dns 192.168.0.2 -> ms-dns 8.8.4.4
require-mppe-128 -> # require-mppe-128
vi /etc/ppp/chap-secrets
用户名 pptpd 密码 *
vi /etc/sysctl.conf
net.ipv4.ip_forward = 0 -> net.ipv4.ip_forward = 1
net.ipv4.tcp_syncookies = 1 -> # net.ipv4.tcp_syncookies = 1
sysctl -p
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j SNAT –to-source  你的VPS的IP
/etc/init.d/iptables save
chkconfig pptpd on
chkconfig iptables on
/etc/init.d/pptpd restart
/etc/init.d/iptables restart

现在你已经可以使用PPTP了,如果你连接的时候出现619错误的话。

rm -r /dev/ppp
mknod /dev/ppp c 108 0

分类: Linux相关 标签:

“Content rectangle not entirely on screen with the menu bar”的解决方案

2011年12月20日 没有评论

打开xib,选择window,拖动一下上面的白色矩形,放到较中间的问题。警告消失。

分类: MAC 标签:

cocoa恢复显示关闭的窗口

2011年11月25日 没有评论

在Mac OS中,点击窗口左上方的x,窗口将会关闭。如果你希望通过点击dock上的图标将窗口重新打开,你可以用如下方法做。

实现方法如下:

在delegate里设置一个outlet,比如myWindow:

IBOutlet NSWindow *myWindow;

在Interface Builder中,将主窗口的”Release When Closed”选项取消掉。再将delegate里的myWindow和你的主窗口连接起来,然后在delegate里实现如下方法:

- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag

{

if (flag) {

return NO;

}

else

{

[myWindow makeKeyAndOrderFront:self];

return YES;

}

}

这样窗口即使被关闭,也可以点击dock上的图标重新恢复显示。

分类: 编程开发 标签:

安全模式下, 某用户的php文件访问另一用户文件的问题

2011年11月8日 没有评论

如果一个php文件的属主是 user1, 想包含一个user2的php文件, 而且safe_mode为On, 这时就会报错:
Warning: require_once() [function.require-once]: SAFE MODE Restriction in effect. The script whose uid is 11111 is not allowed to access ./include/common.inc.php owned by uid 10011 in /var/www/vhosts/neten.de/httpdocs/show.php on line 88

解决的方法有三种, 第三种最好:
1. 关闭safe mode
2. 手工更改生成目录的属主。
3. 把user1和user2设为同组, php.ini设置safe_mode_gid=On, 重启apache

什么, 你不会设定两个用户为同组啊? 那接着看吧:
groupadd somegroup
usermod -G somegroup user1
usermod -G somegroup user2

-G表示还让user1,2呆在原来的组, 如果你比较狠心, 可以用-g, 这样他们就只在somegroup内了.

分类: 建站相关 标签:

关于解决”cannot modify header information – headers already sent by”的错误

2011年11月3日 没有评论

一个上传文件的功能,上传成功 返回信息的时候经常提示:cannot modify header information – headers already sent by (……)。其实已经实现需要的效果了,就是这个错误信息看着不爽,网上找了很多办法,综合使用得到的解决方法是

1在页面顶部的php标签中加入ob_start();

2在返回的信息下面加入ob_end_flush();

这样就可以屏蔽错误信息的现实了

另外转一下其他人的方法,也许在其他情况下也会有效

If you got this message: “Warning: Cannot modify header information – headers already sent by ….”
如果在执行php程序时看到这条警告:”Warning: Cannot modify header information – headers already sent by ….”

Few notes based on the following user posts:
有以下几种解决方法:

1. Blank lines (空白行):
Make sure no blank line after <?php … ?> of the calling php script.
检查有<?php … ?> 后面没有空白行,特别是include或者require的文件。不少问题是这些空白行导致的。

 

 

2. Use exit statement (用exit来解决):
Use exit after header statement seems to help some people
在header后加上exit();
header (“Location: xxx”);
exit();

 

3. PHP has this annoying problem, if your HTML goes before any PHP code or any header modification before redirecting to certain page, it’ll said “Warning: Cannot modify header information – headers already sent by ….” Basically anytime you output to browser, the header is set and cannot be modified.   So two ways to get around the problem:

3a. Use Javascript (用Javascript来解决):
<? echo “<script> self.location(\”file.php\”);</script>”; ?>
Since it’s a script, it won’t modify the header until execution of Javascript.
可以用Javascript来代替header。但是上面的这段代码我没有执行成功… 另外需要注意,采用这种方法需要浏览器支持Javascript.

3b. Use output buffering (用输出缓存来解决):
<?php ob_start(); ?>
… HTML codes …
<?php
… PHP codes …
header (“Location: ….”);
ob_end_flush();
?>
This will save the output buffer on server and not output to browser yet, which means you can modify the header all you want until the ob_end_flush() statement.   This method is cleaner than the Javascript since Javascript method assumes the browser has Javascript turn on.   However, there are overhead to store output buffer on server before output, but with modern hardware I would imagine it won’t be that big of deal.   Javascript solution would be better if you know for sure your user has Javascript turn on on their browser.

就像上面的代码那样,这种方法在生成页面的时候缓存,这样就允许在输出head之后再输出header了。本站的许愿板就是采用这种方法解决的header问题。

在后台管理或者有时候在论坛,点击一个页面,页顶会出现
Warning: Cannot modify header information – headers already sent by….
这类语句,造成这个原因是因为setcookie语句的问题。

cookie本身在使用上有一些限制,例如:
1.呼叫setcookie的敘述必須放在<html>標籤之前
2.呼叫setcookie之前,不可使用echo
3.直到網頁被重新載入後,cookie才會在程式中出現
4.setcookie函數必須在任何資料輸出至瀏覽器前,就先送出
5.……
基於上面這些限制,所以執行setcookie()函數時,常會碰到”Undefined index”、”Cannot modify header information – headers already sent by”…等問題,解決”Cannot modify header information – headers already sent by”這個錯誤的方法是在產生cookie前,先延緩資料輸出至瀏覽器,因此,您可以在程式的最前方加上ob_start();這個函數。这样就可以解决了。

 

4.set output_buffering = On in php.ini (开启php.ini中的output_buffering )
set output_buffering = On will enable output buffering for all files. But this method may slow down your php output. The performance of this method depends on which Web server you’re working with, and what kind of scripts you’re using.
这种方法和3b的方法理论上是一样的。但是这种方法开启了所有php程序的输出缓存,这样做可能影响php执行效率,这取决于服务器的性能和代码的复杂度。

分类: 琐碎收藏 标签:

PHP 5.3.1 安全模式session_start权限问题的解决办法

2011年11月3日 没有评论

出现session_start写入权限问题。

提示信息如下:

Warning: session_start() [function.session-start]: SAFE MODE Restriction in effect. The script whose uid is 2023 is not allowed to access /var/tmp/ owned by uid 0 in /configs/config.inc.php on line 9

Fatal error: session_start() [<a href='function.session-start'>function.session-start</a>]: Failed to initialize storage module: files (path: ) in /configs/config.inc.php on line 9

 

后来在php5的changelog里找到一个bug报告。里面提到一个安全模式的bug。默认session的save_path

; where MODE is the octal representation of the mode. Note that this
; does not overwrite the process’s umask.
; http://php.net/session.save-path
; session.save_path = “/tmp”

这样会要校验权限。在php.ini文件里,

显式指定session的save_path为/tmp即
session.save_path = “/tmp”
重启web服务就解决了。

分类: 琐碎收藏 标签:

URL映射 php 实现

2011年10月20日 没有评论

1、大家来说说URL映射吧
一般url映射有两种方式,一种是通过mod_rewrite实现,这种网上教材很多我也不多说了。另外一种是在程序中模拟,比如类似zend Framework中的那种方式/index.php/controller/action/var1/value1/var2/value2/。这里方 式其实最主要是通过一个统一的输入接口,然后对url进行解析,最后转发到相应的controller中的module。

我这里写了两个简单函数来模拟。
第一个函数主要是进行地址解析,把类似/index.php/controller/action/var1/value1/var2/value2/的地址解析出来,一般来说要解析成三部分:controller,module,params。


<?
/**
*对url路由进行简单的解析,支持对/path/to/site/index.php/module/action/parm/value
* /path/to/site/index.php?/module/action/parm/value和
* /path/to/site/?/module/action/parm/value三种形式的处理
*@param:null
*@return:router array
*/
function url_router(){
$path=strip_tags($_SERVER['REQUEST_URI']);
$strpos=strpos($path,'.php');
if($strpos){
$path=substr($path,$strpos+4);
}else{
if(empty($_SERVER['QUERY_STRING'])){
$strpos=strpos($path,'?');
if($strpos){
$path=substr($path,$strpos+1);
}else{
$path='';
}
}else{
$path=$_SERVER['QUERY_STRING'];
}
}
//统一化$path的格式,如果$path的第一个字符为/则去掉
if($path[0]=='/'){
$path=substr($path,1);
}
//解析,并且路由
if(!empty($path)){
$path=explode('/',$path);
$router['controller']=$path[0];
$router['action']=(!empty($path[1]))?$path[1]:'index';
//print_r($path);
for($i=2;$i<sizeof($path);$i=$i+2){
$params[$path[$i]]=(isset($path[$i+1]))?$path[$i+1]:'';
}
$router['params']=$params;
}else{
//默认路由信息
$router['controller']='index';
$router['action']='index';
$router['params']=array();
}
return $router;
}
?>

这里就完成主要的url解析功能,然后是转发映射,下面这个函数实现(注意这个函数的实现是结合了我自己的架构,所以你采用的话需要相应的修改,当然你的MVC如果类似zend Framework,那应该要该的不多。)

<?
function url_dispatch($router,$app_path='/app/controllers/')
{
require_once(SERVER_PATH.'/libs/controller.class.php');
$controller=$router['controller'].'Controller';
//echo SERVER_PATH.$app_path.$controller.'.class.php';
if(!file_exists(SERVER_PATH.$app_path.$controller.'.class.php'))die('缺少必要的类!');
require_once(SERVER_PATH.$app_path.$controller.'.class.php');
$controller=new $controller();
$controller->_setParam($router['params']);
$controller->{$router['action'].'Action'}();
return true;
}
?>

分类: PHP 标签:

草图设计软件

2011年9月15日 没有评论

Balsamiq Mockups

分类: 软件收藏 标签:

通过.htaccess提高网站安全性

2011年9月14日 1 条评论

网站安全性不容小视,尤其是是对于后台管理目录的访问需要格外的严格控制,否则一旦被人得到网站管理员的密码,再通过后台管理可能的上传操作就可以 拿下整个网站了。但是,目前一般来说我们对后台管理的权限都是通过程序本身的密码限制的,而程序本身的密码又受到了自身的安全性限制。因此需要更为底层的 访问限制来保障网站的安全性。当然,备份工作也不能忽视。

.htaccess文件便是Apache下的一个分布式配置文件,其对于网站的各种功能配置有非常重要的作用,我们也可以通过这个文件来限制对网站的访问。下面我将具体说明配置方法:

1、为网站的重要目录(比如后台管理)设置Apache访问控制密码。

首先建立一个名称为.htpasswd的文本文件,里面输入设置好的访问控制用户名和密码。文件内容因涉及到加密算法,需要打开 http://tool.liehuo.net/htaccess/在线生成页面,然后选择“文件夹密码保护”栏目,让你后输入你想要的用户名和密码,最后点击“创建.htpasswd内容”按钮,下面将会显示该文件的内容。

注意,该文件的内容应该类似于:

username:gQQ/SeV/5y2bM

冒号前面的是用户名,后面的是加密后的密码,请不要手动更改。创建完成后,请将此文件上传至无法通过HTTP访问到的目录下,然后记录下这个文件的绝对路径。

上传后,手动建立一个内容如下的名为.htaccess的文件:

AuthUserFile /home/foo/bar/.htpasswd
AuthGroupFile /dev/null
AuthName “Please enter your ID and password”
AuthType Basic
require valid-user

其中第一行“/home/foo/bar/.htpasswd”为.htpasswd文件的绝对地址,请根据实际情况进行修改。然后将此文件上传到需要保护的目录下即可。

此时,访问受保护的目录,将会弹出一个需要登录获取访问权限的窗口,输入你设置的用户名和密码,才能看见程序的登陆页面。并且,这个密码是非常安全 的。它并没有记录在网站的数据库中,也没有记录在网站的目录下。并且,任何对受保护目录的访问都需要进行授权。因此安全性非常高。

2、阻止某些IP对网站的访问。

比如希望阻止某一IP对网站的访问以提高安全性,可以直接将IP地址拒绝。也是通过.htaccess文件实现。在.htaccess文件中加入以下内容:

order deny,allow
deny from 127.0.0.1

上面的127.0.0.1即是网站拒绝需要访问的IP地址。然后将.htaccess文件上传到网站的根目录下即可。

 

原文:http://www.veryhuo.com/a/view/20430.html

分类: 建站相关 标签:

自定义 UITableViewCell 的 accessory 样式

2011年9月14日 没有评论

对于 UITableViewCell 而言,其 accessoryType
属性有4种取值:

UITableViewCellAccessoryNone
,

UITableViewCellAccessoryDisclosureIndicator
,

UITableViewCellAccessoryDetailDisclosureButton
,

UITableViewCellAccessoryCheckmark

分别显示 UITableViewCell 附加按钮的4种样式:

无、


除此之外,如果你想使用自定义附件按钮的其他样式,必需使用
UITableView 的 accessoryType 属性。比如,我们想自定义一个


的附件按钮,你可以这样做:



UIButton
*button ;



if

(
isEditableOrNot
){

UIImage
*image= [

UIImage
  

imageNamed
:
@"delete.png"
];


button = [
UIButton

buttonWithType
:
UIButtonTypeCustom
];

CGRect
frame =
CGRectMake
(
0.0
,
0.0

, image.
size
.
width
, image.
size
.
height
);

button.
frame
= frame;


[button
setBackgroundImage
:image

forState
:
UIControlStateNormal
];

 

button.
backgroundColor

= [

UIColor

clearColor
];

cell.
accessoryView

= button;


}

else
{

button = [

UIButton

buttonWithType
:
UIButtonTypeCustom
];


button.
backgroundColor

= [

UIColor

clearColor
];

cell.
accessoryView

= button;


}

这样,当 isEditableOrNot 变量为 YES 时,显示如下视图:

 



但仍然还存在一个问题,附件按钮的事件不可用。即事件无法传递到
UITableViewDelegate

accessoryButtonTappedForRowWithIndexPath
方法。

也许你会说,我们可以给 UIButton 加上一个 target。

好,让我们来看看行不行。在上面的代码中加入:

[button
addTarget
:
self

action
:
@selector
(
btnClicked
:
event
:)  
forControlEvents
:
UIControlEventTouchUpInside
];

然后实现btnClicked方法,随便在其中添加点什么。

点击每个 UIButton,btnClicked 方法中的代码被调用了!一切都是那么完美。

 

但问题在于,每个 UITableViewCell 都有一个附件按钮,在点击某个按钮时,我们无法知道到底是哪一个按钮发生了点击动作!因为
addTarget 方法无法让我们传递一个区别按钮们的参数,比如 indexPath.row 或者别的什么对象。addTarget 方法最多允许传递两个参数:target
和 event,而我们确实也这么做了。但这两个参数都有各自的用途,target 指向事件委托对象——这里我们把 self 即 UIViewController
实例传递给它,event 指向所发生的事件比如一个单独的触摸或多个触摸。我们需要额外的参数来传递按钮所属的 UITableViewCell 或者行索引,但很遗憾,只依靠
Cocoa 框架,我们无法做到。

但我们可以利用 event 参数,在 btnClicked 方法中判断出事件发生在UITableView
的哪一个 cell 上。因为 UITableView 有一个很关键的方法


indexPathForRowAtPoint
,可以根据触摸发生的位置,返回触摸发生在哪一个 cell 的indexPath。 而且通过 event 对象,我们也可以获得每个触摸在视图中的位置:

 

//
检查用户点击按钮时的位置,并转发事件到对应的
accessory
tapped

事件

- (
void
)btnClicked:(

id
)sender
event:(

id
)event

{



NSSet

*touches =
[event

allTouches
];



UITouch
*touch =
[touches

anyObject

];



CGPoint

currentTouchPosition = [touch

locationInView
:
self

.
tableView
];



NSIndexPath
*indexPath
= [

self

.
tableView

indexPathForRowAtPoint
:
currentTouchPosition];



if
(indexPath
!=

nil
)


{

[
self

tableView
:
self
.
tableView

accessoryButtonTappedForRowWithIndexPath
:
indexPath];


}

}

这样,UITableView的accessoryButtonTappedForRowWithIndexPath方法会被触发,并且获得一个
indexPath 参数。通过这个indexPath 参数,我们可以区分到底是众多按钮中的哪一个附件按钮发生了触摸事件:

-(
void

)tableView:(
UITableView
*)
tableView
accessoryButtonTappedForRowWithIndexPath:(
NSIndexPath
*)indexPath{

int
* idx= indexPath.
row
;



//
在这里加入自己的逻辑




⋯⋯

}

原文:http://blog.csdn.net/kmyhy/article/details/6442351

分类: iPhone 标签: