📄 1041.html
字号:
<br>
#include <br>
#include <br>
#include <br>
<br>
void main(void) <br>
{ <br>
char buf[1024]; <br>
int ok; <br>
<br>
printf("Welcome to goodie service!"); <br>
fflush(stdout); <br>
<br>
ok=0; <br>
do { <br>
while (fgets(buf,1023,stdin)==NULL); <br>
if (strncasecmp(buf,"exit",4)==0) ok=1; <br>
printf(buf); <br>
fflush(stdout); <br>
} while (!ok); <br>
} <br>
<br>
执行结果 <br>
telnet localhost 20001 <br>
或 <br>
telnet your_host_name 20001 <br>
<br>
Trying 127.0.0.1... <br>
Connected to localhost. <br>
Escape character is '^]'. <br>
Welcome to goodie service! <br>
<br>
输入"help" <br>
<br>
help <br>
help <br>
<br>
输入"exit" <br>
<br>
exit <br>
exit <br>
Connection closed by foreign host. <br>
<br>
接下来,我们将设计一个稍微复杂一点点的通讯协定,比较通用於一般用途。 <br>
#include <br>
#include <br>
#include <br>
<br>
char *cmds[]={ <br>
"help", <br>
"say", <br>
"hello", <br>
"bye", <br>
"exit", <br>
NULL <br>
}; <br>
<br>
int getcmd(char *cmd) <br>
{ <br>
int n=0; <br>
while (cmds[n]!=NULL) { <br>
if (strncasecmp(cmd,cmds[n],strlen(cmds[n]))==0) return n; <br>
n++; <br>
} <br>
return -1; <br>
} <br>
<br>
void main(void) <br>
{ <br>
char buf[1024]; <br>
int ok; <br>
<br>
printf("Welcome to goodie service!"); <br>
fflush(stdout); <br>
<br>
ok=0; <br>
do { <br>
while (fgets(buf,1023,stdin)==NULL); <br>
switch (getcmd(buf)) { <br>
case -1: printf("Unknown command!"); break; <br>
case 0: printf("How may I help you, sir?"); break; <br>
case 1: printf("I will say %s",&buf[3]); break; <br>
case 2: printf("How're you doing today?"); break; <br>
case 3: printf("Si ya, mate!"); ok=1; break; <br>
case 4: printf("Go ahead!"); ok=1; break; <br>
} <br>
fflush(stdout); <br>
} while (!ok); <br>
<br>
} <br>
<br>
telnet localhost 20001 <br>
或 <br>
telnet your_host_name 20001 <br>
<br>
试试看输入"help"、"say"、"hello"、"bye"、"exit"等等指令,及其它一些不在命令列中的指令。 <br>
<br>
在设计inetd服务程式时,要特别注意buffer overflow的问题,也就是以下这种状况: <br>
<br>
char buffer_overflow[64]; <br>
fscanf(stdin,"%s",buffer_overflow); <br>
<br>
历来几乎所有的安全漏洞都是由此而来的。 <br>
你一定不可这样用,不论任何理由,类同的用法也不可以。Cracker可以透过将您的buffer塞爆,然後塞进他自己的程式进来执行。 <br>
<br>
<br>
Linux程式设计- 6.syslog <br>
http://www.openchess.org/noitatsko/programming/ (2001-05-24 19:00:00) <br>
在Linux下有个syslogd的Daemon程式,syslog是个系统管理员必看的档案。因此,如果您的程式有除错或安全讯息要显示,写到syslog是个很好的选择。 <br>
syslog有三个函数,使用上,一般您只需要用syslog(...)这个函数即可,一般使用状况下,openlog/closelog是可有可无的。 <br>
<br>
syslog()中的priority是facility及level的组合,其後参数的用法与printf无异。 <br>
<br>
例: <br>
#include <br>
#include <br>
#include <br>
#include <br>
void main(void) <br>
{ <br>
if (fork()==0) { <br>
for (;;) { <br>
syslog(LOG_USER|LOG_INFO,"syslog programming test"); <br>
sleep(10); <br>
} <br>
} <br>
} <br>
<br>
检验: <br>
tail -f /var/log/messages <br>
Mar 22 01:42:51 foxman log: syslog programming test <br>
Mar 22 01:43:31 foxman last message repeated 4 times <br>
Mar 22 01:44:31 foxman last message repeated 6 times <br>
Mar 22 01:45:31 foxman last message repeated 6 times <br>
Mar 22 01:46:21 foxman last message repeated 5 times <br>
<br>
<br>
<br>
-------------------------------------------------------------------------------- <br>
<br>
void openlog( char *ident, int option, int facility) <br>
void syslog( int priority, char *format, ...) <br>
void closelog( void ) <br>
option <br>
用於openlog()的option参数可以是以下几个的组合: <br>
<br>
LOG_CONS : 如果送到system logger时发生问题,直接写入系统console。 <br>
LOG_NDELAY : 立即开启连接(通常,连接是在第一次写入讯息时才打开的)。 <br>
LOG_PERROR : 将讯息也同时送到stderr <br>
LOG_PID : 将PID含入所有讯息中 <br>
<br>
facility <br>
facility参数用来指定何种程式在记录讯息,这可让设定档来设定何种讯息如何处理。 <br>
<br>
LOG_AUTH : 安全/授权讯息(别用这个,请改用LOG_AUTHPRIV) <br>
LOG_AUTHPRIV : 安全/授权讯息 <br>
LOG_CRON : 时间守护神专用(cron及at) <br>
LOG_DAEMON : 其它系统守护神 <br>
LOG_KERN : 核心讯息 <br>
LOG_LOCAL0到LOG_LOCAL7 : 保留 <br>
LOG_LPR : line printer次系统 <br>
LOG_MAIL : mail次系统 <br>
LOG_NEWS : USENET news次系统 <br>
LOG_SYSLOG : syslogd内部所产生的讯息 <br>
LOG_USER(default) : 一般使用者等级讯息 <br>
LOG_UUCP : UUCP次系统 <br>
<br>
level <br>
决定讯息的重要性. 以下的等级重要性逐次递减: <br>
<br>
LOG_EMERG : 系统无法使用 <br>
LOG_ALERT : 必须要立即采取反应行动 <br>
LOG_CRIT : 重要状况发生 <br>
LOG_ERR : 错误状况发生 <br>
LOG_WARNING : 警告状况发生 <br>
LOG_NOTICE : 一般状况,但也是重要状况 <br>
LOG_INFO : 资讯讯息 <br>
LOG_DEBUG : 除错讯息 <br>
<br>
Linux程式设计- 7.zlib的运用 <br>
http://www.openchess.org/noitatsko/programming/ (2001-05-24 20:10:00) <br>
<br>
<br>
gzip(*.gz)档案格式几乎是Linux下的标准格式了,有人认为bzip2的压缩率比gzip来得高。一般来说,这个说法大致正确,不过根据我个人的经验,有一半以上的档案,bzip2没有比gzip的压缩率来得高,有少数状况下,gzip压缩率反而比bzip2来的高。 <br>
zlib是个支援gzip档案格式的函数库,它使得gz档的存取就犹如开档关档一样地容易,您可以很容易地为您的程式加入gz档的支援。 <br>
<br>
<br>
<br>
-------------------------------------------------------------------------------- <br>
<br>
使用例 : showgz.c <br>
#include <br>
#include <br>
#include <br>
void main(int argc,char **argv) <br>
{ <br>
gzFile zip; <br>
int c; <br>
<br>
if (argc<2) return; <br>
<br>
zip = gzopen(argv[1],"rb"); <br>
while ((c=gzgetc(zip))!=EOF) putchar(c); <br>
gzclose(zip); <br>
} <br>
<br>
编译 <br>
gcc -o showgz showgz.c -lz <br>
检验 <br>
gzip -9 < showgz.c > showgz.c.gz <br>
./showgz showgz.c.gz <br>
将会把这个程式内容显示出来,showgz的作用可说等於gzip -dc。 <br>
<br>
<br>
<br>
-------------------------------------------------------------------------------- <br>
<br>
函数宣告 <br>
gzFile gzopen (const char *path, const char *mode); <br>
开启一个gzip(*.gz)档。 <br>
mode参数可为"rb"或"wb"。 <br>
另外也可包含压缩程度如"wb9"。 <br>
用'f'作为过滤资料,如"wb6f"。 <br>
用'h'可指定Huffman only压缩,如"wb1h" <br>
gzopen亦可用於读取非压缩的gzip档案格式,在这种状况下,gzread会直接读取,而不进行解压缩。 <br>
<br>
int gzread (gzFile file, voidp buf, unsigned len); <br>
与read的用法相同。 <br>
<br>
int gzwrite (gzFile file, const voidp buf, unsigned len); <br>
与write用法相同。 <br>
<br>
int gzprintf (gzFile file, const char *format, ...); <br>
与fprintf用法相同。 <br>
<br>
char * gzgets (gzFile file, char *buf, int len); <br>
与fgets用法相同。 <br>
<br>
int gzputc (gzFile file, int c); <br>
与fputc用法相同。 <br>
<br>
int gzgetc (gzFile file); <br>
与fgetc用法相同。 <br>
<br>
int gzflush (gzFile file, int flush); <br>
与fflush作用相同。 <br>
<br>
z_off_t gzseek (gzFile file, z_off_t offset, int whence); <br>
whence不支援SEEK_END <br>
如果档案是开启为"读取",则SEEK_SET及SEEK_CUR,向前及向後均支援,不过很慢就是了。 <br>
如果档案是开启为"写入",仅支援向前SEEK。 <br>
<br>
int gzrewind (gzFile file); <br>
与gzseek(file, 0L, SEEK_SET)相同作用,仅在读取时有效。 <br>
<br>
z_off_t gztell (gzFile file); <br>
返回值 : 目前档案位置(解压缩後的位置) <br>
<br>
int gzeof (gzFile file); <br>
返回值 : 1 - EOF, 0 - not EOF <br>
<br>
int gzclose (gzFile file); <br>
关闭档案 <br>
返回值 : zlib error number <br>
<br>
<br>
Linux程式设计- 8.crypt <br>
http://www.openchess.org/noitatsko/programming/ (2001-05-24 21:04:00) <br>
<br>
<br>
crypt是个密码加密函数,它是基於Data Encryption Standard(DES)演算法。crypt基本上是One way encryption,因此它只适用於密码的使用,不适合於资料加密。 <br>
char *crypt(const char *key, const char *salt); <br>
<br>
key是使用者的密码。salt是两个字,每个字可从[a-zA-Z0-9./]中选出来,因此同一密码增加了4096种可能性。透过使用key中每个字的低七位元,取得56-bit关键字,这56-bit关键字被用来加密成一组字,这组字有13个可显示的ASCII字,包含开头两个salt。 <br>
<br>
crypt在您有自行管理使用者的场合时使用,例如会员网站、BBS等等。 <br>
<br>
<br>
<br>
-------------------------------------------------------------------------------- <br>
<br>
例一 : crypt_word.c <br>
#include <br>
#include <br>
#include <br>
void main(int argc,char **argv) <br>
{ <br>
if (argc!=3) exit(0); <br>
printf("%s",crypt(argv[1],argv[2])); <br>
} <br>
<br>
编译 <br>
gcc -o crypt_word crypt.c -lcrypt <br>
检验 <br>
请先看您的/etc/passwd,找一个您自己的帐号,看前面两个字,那是您自己的salt。接下来输入: <br>
./crypt_word your_password salt <br>
<br>
看看它们是否相同(应该要相同,除非您加了crypt plugin或使用不同的crypt function,例如shadow、pam,这种状况下,加密字是不同的),另外检验看看他们是否为13个字。 <br>
<br>
您也可以利用Apache上所附的htpasswd来产生加密字做为验。 <br>
<br>
例二: verify_passwd.c <br>
注意,这个例读取/etc/passwd的资料,不适用於使用shadow或已经使用pam的系统(例如slackware,RedHat及Debian在不外加crypt plugin的状况下,应当相同)。此例仅供参考,做为解crypt函数运作的情形,真正撰写程式时,应该避免类似的写法。 <br>
#include <br>
#include <br>
#include <br>
<br>
typedef struct { <br>
char username[64]; <br>
char passwd[16]; <br>
int uid; <br>
int gid; <br>
char name[256]; <br>
char root[256]; <br>
char shell[256]; <br>
} account; <br>
<br>
/* 注意! 以下的写法,真实世界的软体开发状况下,千万不要用! */ <br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -