Go away, boring passwords

This article was originally posted on TrendSpace

Are you boring with inputting passwords so many times or remember so many different passwords? Here is the way we can save much time in typing passwords in Linux.

1) For FTP passwords

Create a file with the name ~/.netrc with lines in the following format:

machine <Site Name> login <User Name> password <Password>

This information will be used by ftp/lftp/wget to login the corresponding site. After providing the login information in this file, you no longer need to type in the user name or password when accessing the corresponding sites.

Be careful, in order to enhance security, the ~/.netrc file should have the 600 access right.

For more information, see “man 5 netrc”.

2) For SSH connection

If you need to login or copy files with another machine via SSH connections frequently, you can set up public and private key pair using the DSA encryption scheme to save the work of typing passwords.

On local machine:

$ mkdir ~/.ssh
$ chmod 700 ~/.ssh
$ cd ~/.ssh
$ ssh-keygen -t dsa
$ chmod 600 id_dsa{,.pub}

Here, you got your private key in id_dsa file and your public key in id_dsa.pub file. Do keep your id_dsa file secret and send the id_dsa.pub file to the remote machines you want to access.

Copy id_dsa.pub file to remote machines and add it’s content to ~/.ssh/authorized_keys file on the remote machine, after doing this, you can access the remote machine via SSH (ssh,scp,sftp) without input passwords.

For more information, see “man ssh”.

小函数,大问题

对于strcpy,sprintf,strcat这些不安全的函数的讨论应该算是不少了,大家都知道可以用strncpy,snprintf和strncat来替换它们。但实际工作中似乎这些“安全版”的函数带来的疑惑还是不小,总结了一下,列在这里。

1.sprintf(char * str, const char * format, …) -> snprintf(char * str, size_t size, const char * format, …)

vsprintf(char * str, const char * format, va_list ap) -> vsnprintf(char * str, size_t size, const char * format, va_list ap)

按照C/C++标准,snprintf和vsnprintf永远不会往str中输出多于size所指定的字节数的字符(包括结尾的’/0’),它们也保证了一定会在str中写入’/0’,所以在使用这个函数后不用担心结尾的问题。

举例:

char buf[5];
snprintf(buf, 5, "This is a test string."); // buf becomes "This", buf[4] is '/0'
snprintf(buf, 6, "This is a test string."); // ERROR: buffer overflow
snprintf(buf, 5, "abc"); // buf becomes "abc", the value of buf[3] is '/0', buf[4] is undefined.

然而,VC中的_snprintf函数并没有按照这样的规定来做,它在输出缓冲区不够大时就不会输出结尾的’/0′(跟strncpy的行为类似)。所以要让上面的程序工作正常,必须做相应的修改。

char buf[5];
_snprintf(buf, 5, "This is a test string.");// buf becomes "This ", buf[4] is ' '
buf[4] = 0; // buf[4] is '/0' now.
_snprintf(buf, 6, "This is a test string."); // ERROR: buffer overflow
_snprintf(buf, 5, "abc"); // buf becomes "abc", the value of buf[3] is '/0', buf[4] is undefined.

如果要保证可移植性,就得按VC的写法,做一次对于标准来说很多余的“填0”的操作,再通过定义宏来区别平台分别选用snprintf或_snprintf。

2. strcat(char * dest, const char * src) -> strncat(char * dest, const char * src, size_t n);

这个函数比较简单,它保证不会写入多于n+1个字符,并且保证最后一定以’/0’结束。

举例:

char dest[5] = "abc";
strncat(dest, "defghijklmn", 5 - 3 - 1); // dest becomes "abcd", dest[4] is '/0',
// always minus the buffer length by 1 as the value of n.
strncat(dest, "defghijklmn", 5 - 3); // ERROR: buffer overflow

3. strcpy(char * dest, const char * src) -> strncpy(char * dest, const char * src, size_t n);

strncpy是一个比较容易出错的函数,它保证复制src中不多于n字节的内容,但是如果src的前n个字节中没有包含’/0’,就会导致 dest没有正常的以’/0’终止。另外,它还保证如果src的长度小于n,则dest剩余的部分都会以’/0’填充。在用这个函数时,有一个最佳实践就 是先把dest以0填充,并传入dest的长度减1的值作为n,这样可以确保安全。

举例:

  char buf[5] = {0}; // Always zero-fill the buffer,
// always use this form to initialize the stack arrays to get
//better performance over memset.
char * buf2 = new char[5];
memset(buf2, 0, 5); // Always zero-fill the buffer
strncpy(buf, "abcde", 5); // ERROR: buf is not null-terminated.
strncpy(buf2, "abcde", 5 - 1); // Right, always minus the buffer length by 1
//as the value of n. buf becomes "abcd", buf[4]
//is '/0' by initilization;
// This is a common error in the existing code.
char buf3[5];
const char * str = "Test";
strncpy(buf3, str, strlen(str)); // Wrong, buf may not null-terminated,
// potential buffer-overflow
strncpy(buf3, str, strlen(str)+1); // Wrong, potential buffer-overflow.
//No difference with using strcpy.

走进Linux编程的大门

以我本人初学Linux编程的一点心得体会与大家分享。

发表于《电脑爱好者》2001年第5期。以我现在的眼光看,这篇文章可真是不值得一提!

====

随着Linux的不断普及,使用Linux的人也越来越多,其中不乏编程爱好者。但他们中间不少人刚学会了Linux的基本操作,对编程这一技术活还心存疑惑:在Linux中如何进行程序设计,用什么样的开发工具?本文就以我初学Linux编程的一点心得体会和大家共同探讨有关Linux编程的问题。

Linux作为一个免费的操作系统,其源码开放性已成为其最大的特点,我们可以方便的得到Linux系统及其应用软件的源代码,Linux编程也就是在这样的环境下进行的对程序的编写或修改的工作,学会了Linux编程,不但可以自己编写一些共享的小程序供大家使用,也可以对现有的软件进行一点修改,让它们更适合自己的口味。

Linux下编程的工具很多,不同版本的Linux也提供了不同的开发工具,常用的语言一般主要是C/C++,通常情况下Linux都提供了在控制台终端下的C语言编译程序GCC。我们只要建立一个C语言源程序文件,比如hello.c,然后在终端下运行:gcc hello.c,系统便会自动对程序进行编译,如果没有出错的话,在当前目录生成a.out文件,否则显示出错提示。生成a.out后,我们只需在其所在目录键入 ./a.out就可以运行这个程序。但是这样的文本命令方式的开发工作实在很不方便,所以现在不少版本的Linux都在X-Windows图形界面下为我们提供了集成开发环境,比如蓝点Linux环境下的KDevelop等等,这些集成环境不但为我们提供了一个良好的编程界面,也为编程工作提供了极大的使利。

首次运行KDevelop时,系统会自动运行KDevelop设置安装程序,这个程序将验证正常运行KDevelop所必的文件是否齐全,通过设置后,我们就可以开始使用它了。KDevelop为我们在Linux下展现了一个类似于Visual C++的集成开发环境(见图一)。在这个环境的左半边有CV、LFV、RFV等几个标签,分别表示了类列表、逻辑文件列表和实际文件列表,里面保含了整个工程的所有的类和文件的概貌。开发环境的右半边则是文档显示区,用于显示源程序或是帮助信息。

下面我们就一起来使用这个开发工具来开发两个小程序,试试走进Linux编程的感觉。

我们先来尝试用它来制作一个最简单最经典的“Hello World!”程序,它是在Linux的文本界面即终端中运行的,如同在初学C语言时开发的第一个程序–在DOS下运行的“Hello World!”一样。

先打开“项目”菜单,选择“新建…”,在弹出的Application Wizard中选择“终端程序-C程序”(如果您熟悉使用C++程序的话可在此选C++程序,不过后面的程序清单就得修改修了),并单击“下一步”(见图二)。在向导的第二页中输入项目的名称等信息,然后把“生成源文件和头文件”前的勾去掉(见图三)。如果不是这样做的话,Application Wizard会自动生成一些源代码,碰巧还正是我们要做的“Hello World”程序,但我们为了说明问题,就不图这个方便了,我们自己做。单击“生成”按钮,稍等一会儿,等屏幕出现READY后,单击“退出” 按钮,我们的项目便生成了。

接着,我们就得录入源程序了。选择文件菜单中的“新建”命令,新建一个“C/C++程序”(我们的例子是C程序),系统自动按照Application Wizard中选定的文件头模板生成了一个空文件,我们就将把下面的程序输入这个文件,输入时要注意大小写,C语言对字母大小写敏感的:

#include <stdio.h>
main()
{
printf("Hello World!/n");
}

学过C语言的朋友一定对这段代码感到很熟悉,这的确是一个经典的程序,几乎所有C语言的入门书上都有它。

然后,我们选择菜单或工具条中的“运行”命令,执行这个程序,经过一段时间的编译,程序运行结果就出现在终端中,输出了“Hello world!” 这句话。

别看这个程序很简单,但它确实是我们在Linux环境下做的第一个程序。Linux下的C和ANSI C是完全兼容的,对于学过C程序设计的朋友不能不说是个好消息。您是不是已经对Linux编程产生了很大的兴趣呢?

不过,这个程序实在太简单了,能不能做一个在X-Window下运行的图形程序呢?做这样的程序很困难吗?别急,跟我一起来试一试。

要编写图形程序,一个优秀的开发包是必不可少的。如同在VC++中的MFC类库,KDevelop为Linux下编程提供了功能强大的Qt库和KDE库,用它们都可以方便的编写X-Window下的 KDE图形界面程序。除此之外,KDevelop还提供了“对话框编辑器”等一系列实用的工具使开发图形程序变得更方便。

同上面一样,我们一起来开发一个X-Window下的图形版“Hello World”程序。我们选择使用比较简单的Qt库来写我们的程序,一起来体验一下这个强大而又易用的开发包。

第一步还是建立工程文件,方法和前面建立终端程序的工程文件类似,不同的是在Application Wizard的第一步中不再是选择“终端程序-C程序”,而是选择“Qt程序-普通”,同样的,为了说明问题,在Wizard的第二步中,我们也把“生成源文件和头文件”选择前的勾去掉, 我们自己来写程序。工程建好后,我们就可以写程序了,同上面一样,我们新建一个C/C++程序,并输入下面的源程序:

#include <qapplication.h>
#include <qpushbutton.h>
int main( int argc, char **argv )
{
QApplication a( argc, argv );
QPushButton hello( "Hello World!" );
hello.resize( 100, 30 );
a.setMainWidget( &hello );
hello.show();
return a.exec();
}

与前面的C程序相比,这个程序要复杂的多,不过不要紧,我们一行行进行分析。

程序前两行调用了两个头文件,其中qapplication.h是建立一个Qt程序所需的最基本的库,任何Qt程序都要用到它。由于我们打算用一个按钮来显示“Hello world!”的文字,所以还要包含qpushbutton.h这个头文件。

主程序第一句建立了一个名为a的Qt程序,并把命令行参数传递给它。第二行建立了一个名为hello的按钮,它的标题为“Hello World!”,这就实现了我们要在屏幕上显示“Hello world!”文字的愿望。第三行使用PushButton的resize方法改变了这个hello按钮的大小。第四行设置了a程序的主控件为这个hello按钮(Widget这个词可以翻译为控件)。由于在Qt库做程序时,新建控件默认是不显示的,所以在第五行要用show方法把hello按钮显示出来。程序最后一行返回了a程序的运行返回值。

这么一解释,这个程序也就显得不是很困难了。怎么样,与VC++中的MFC类库相比,Qt库有过之而无不及吧。

下面我们就可以运行程序了,单击工具栏上的“运行”按钮,通过编译就可以了。程序运行后,屏幕上将出现一个小窗口,里面一个“Hello World!”按钮,它占满了整个窗口(这是由于它是此程序的主控件的原因),并且这个窗口还可以移动、改变大小等等。不过这时“Hello World!”这个按钮还没有作用,点击它不会有任何效果。如何给Hello World编写一个事件响应的函数呢? 比如我们想让“Hello   World”按钮被点击后程序结束运行该如何做呢?

在Qt库中,消息的响应是通过connect函数实现的。所以,很简单的,我们只要在源程序中“a.setMainWidget(&hello)”前加上一行:

QObject::connect( &hello, SIGNAL(clicked()), &a, SLOT(quit()) );

就可以了。这一行的意思就是把hello按钮的clicked事件与a程序的quit()函数连接起来。

至此,相信您对Linux的编程已经有了一个感性的认识吧!是不是很有意思呢,经过一通时间的学习,您一定会喜欢上Linux编程的。

另外,KDevelop不但为我们提供了强大开发环境,还给我们提供了详实的文档资料,包括了“编程手册”、“KDE库”、“Qt库”等一系列的文档,“Qt库”文档中还包含了一个14步教程,从头讲述Qt程序设计方法,最后一讲与我们一起完成了一个完整的游戏程序,是Linux编程入门难得的好教材。以上这些资料,都是学习Linux程序设计必不可少的优秀的参考资料,大家应当尽量用好它们。

以上都是我初学Linux编程的一点心得和体会,拿出来和大家分享,有不当之处还请多指正。

Win 95 使用技巧

介绍了一堆使用Windows 95 的技巧,现在来看又不新鲜又不实用。

发表于《学生计算机世界》1998年8月3日第四版

====

  • 加速“开始”菜单中子菜单的弹出:用 “运行”对话框执行REGEDIT.EXE注册表编辑器,展开“我的电脑/HKEY_CURRENT_USER/Control Panel/desktop”,在该位置增加一项“MenuShowDelay”,并设定其键值为“0”,即可实现子菜单的快速弹出。
  • 在Windows 95的“MS-DOS方式”中,不但可以用 “CD..”退到上层目录,还可以使用“CD…”、“CD….”退回到上两层、上三层目录。
  • 在Windows 95 OSR 2 版(下称Win95B)中,“DIR,”已不能列出隐含文件和目录,只能用“DIR/A”列出它们。
  • 不使用“CD播放器”播放CD,你应在CD播放开始后,关闭“CD播放器”,否则系统速度将大打折扣。
  • Win95B中的EMM386.EXE文件有错误,会引起一部分基于MS-DOS的程序的运行失败。可以用Windows 95中的EMM386.EXE来替代它。
  • Windows中的计算器附件经常会算错,若能找到Windows 98 测试版(即Memphis)中的计算器来替换,就可以减少许多错误。
  • 加快Windows对硬盘的访问速度:打开“控制面板/系统/性能/文件系统…/硬盘”,设定本机硬盘类型为用于“网络服务器”,即可加速系统对硬盘的访问。
  • Win95B安装时,会自动安装IE3.0,且未提供卸载选项,若不想用它,或想用 Netscape取代它,可先安装一个IE3.01之类的升级版本,然后再从控制面板中卸载它。
  • 不要把Windows 95的任务条竖起来,这可能会引起Word6.0等一些应用程序的运行错误,这是Windows 95中一个已知的BUG。
  • 安装Win95B后,即使未使用FAT32分区,也不要用F4键进入旧版DOS,否则您将无法回到Win95B中,想避免这一现象,可从网上下载W95Boot和Fix95B等一些Patch程序。
  • 修改Windows目录中的SYSTEM.INI文件中的“shell=Explorer.exe”一行为“shell=Program.exe”可修改Windows 95使用界面为Windows 3.2风格的程序管理器界面。
  • 在Win95B中,在“C:/Program Files/plus!/system”目录下有一“NOCOMP.EXE”程序用它可以快速创建一张应急启动软盘,可用这张盘取代Windows安装时 创建的标准启动盘。用这张启动盘启动,可以比用标准启动盘启动为DOS程序提供更多的常规内存。
  • 可在Windows 95中安装一个IE4.0,它可以使Windows界面发生不少有益的变化,如:单击取代双击,“开始”菜单中各项排列可按用户爱好的顺序排列等。
  • 若您的Windows系统崩溃了,在重新安装前,可试着将原安装盘中的USER.DAT和SYSTEM.DAT文件拷入Windows目录,来替换现存的,或许可以免去重装Windows的麻烦。
  • Office 97中的JPEG过滤器与PLUS!中的JPEG过滤器有冲突,若安装PLUS!后又装Office 97。则在使用PLUS!的“桌面主题”时,会出现一般保护错。解决方法是使用Office 97光盘上“/ValuPack/Patch”中的Patch程序。
  • 用 “画笔”程序修改C:/LOGO.SYS、C:/WINDOWS/LOGOW.SYS、 C:/WINDOWS/LOGOS.SYS文件,即可改变Windows 95 启动封面、关机等待画面和安全关机画面。
  • 用Shift键可以临时改变文件关联情况。如:双击一个扩展名为DOC的文件,系统将用Word打开它,若想用写字板打开它,可在按住Shift键的同时在该文件上右击鼠击。在菜单中选 “打开方式”,再选Word Pad,即可。
  • 按住Shift的同时按Del键,或将某文件拖曳到“回收站”,可实现对文件的立即删除,即不把文件放入回收站而直接删除。
  • 可利用资源管理器在“开始”菜单的任意位置建一个文件夹,名字为“控制面板.{21EC2020-3AEA-1069-A2DD-08002B30309D}”,以实现对控制面板中各项功能的快速访问。
  • 把Windows 95升级到Win95B:若直接在Windows 95中执行SETUP.EXE,则会在安装过程中提示无法升级。但只要在“软件许可证条例”对话框弹出时,利用多任务,用记事簿打开安装程序建立的 WININST0.400文件夹中的SETUPPP.INF文件,在[data]段中加入“OEMUP=1”,存盘,切回安装程序,继续安装,即可实现升 级工作。
  • 可以把一程序或文件从“我的电脑”或“资源管理器”中拖至“运行”对话框,以便快速访问该程序或文档。
  • 快速重启Windows的技巧:按Ctrl+Alt+Del键,在弹出的“关闭程序”对话框中选“Explorer”,按“结束任务”,在弹出的“关闭Windows”对话框中按“否”,稍候,系统弹出一对话框,按“结束任务”,就完成了对Windows的快速重启。
  • 删除不必要的字体,并经常清理注册表,可使Window 95的启动和运行速度大大加快。
  • 只要把DOS的IO.SYS、MSDOS.SYS和COMMAND.COM文件的扩展名改成“DOS”拷入C盘根目录,并在Windows 95的MSDOS.SYS文件的第二段中加入BootMulti=1即可实现Windows和DOS的双启动。(Win95B不适用)。
  • 快速 识别Windows 95 的版本:打开“控制面板/系统”若为“Windows 95 4.00950”,则为Windows 95的原始版本;若为“Windows 95 4.00950A”则为Windows 95A版;若为“Windows 95 4.00950B”则为Windows 95 OSR 2版;若为“Windows 95 4.00950B”且“添加/删除程序”对话框中有对USB的支持,则为Windows 95 OSR2.1版。

Win95双启动的恢复

介绍了恢复Windows 95双启动的方法。不过,对于先现在玩电脑的实在不算新玩意,不看也罢。

发表于《学生计算机世界》1998年4月27日第四版,发表时有删节,这是删节后的版本,这是我这辈子发表的第一篇文章,稿费25元。

====

Windows 95中提供了双启动,即旧版DOS和Windows 95的双重选择启动。

开机待屏幕出现“Starting Windows 95…”时按F4键,可启动旧版DOS;按F8可出现启动菜单,选择Windows 95或DOS的启动。

然而,Windows 95的双启动有时会失效。主要现象是:开机后按F4无效;按F8出现的菜单中无旧版本DOS一项;按F4后系统提示引导DOS失败;选了开机菜单中旧版本DOS一项后系统提示DOS引导失败。

出现这些情况的原因主要有以下几种:

  1. 安装Windows 95时使用升级安装。
  2. 虽使用了“在其它目录中安装”的方法,但在使用过程中出现了意外的DOS文件被破坏。
  3. MSDOS.SYS文件中禁止了双启动。
  4. 安装Windows 95时,是新机器上用“Windows 95标准版”第一张盘启动机器后进行的安装,原机上无DOS系统。

那么,失去双启动功能后,如何将其恢复呢?

首先,对于情况3:“MSDOS.SYS中禁止了双启动。”的情况,只需修改MSDOS.SYS文件,确保该文件中有“BootMulti=1”一行。而对于其它情况,可用下面的方法修复:

首先找一台正确安装了DOS系统的计算机或准备一张DOS的安装盘中的第一号盘,将上面的IO.SYS、MSDOS.SYS和COMMAND.COM文件分别改名为IO.DOS、MSDOS.DOS、COMMAND.DOS并拷入装有Windows 95系统的计算机的C盘根目录下。接着,建立合适的CONFIG.SYS和AUTOEXEC.BAT文件,分别改名为CONFIG.DOS和 AUTOEXEC.DOS,也拷入C盘根目录。最后也应在MSDOS.SYS文件中加入BootMulti=1一行。重新启动计算机,双启动功能被恢复。