Linux程式设计(转载)一

    技术2022-05-11  29

    Linux程式设计--前言、目录 --------------------------------------------------------------------------------来自:http://www.openchess.org/noitatsko/programming/

    在这里的内容大都是属於入门类的,有点包山包海的,颇为散乱,许多部份都是浅尝即止,主要让您不在Linux Programming的海洋世界中溺水,让您多少可以写一点像样的东西出来,进一步的技巧需要您自己下功夫去钻研。有些新手可能会对这些内容感到吃力, 认为这不是"入门级"的。不过,毕竟这里不是"C/C++语言程式设计入门",在这里的东西,大都是如果您对Linux Programming有兴趣,可以给您一点概念的内容。我能做到的,大概只是领您进门罢了,这些程式都附有原始码,有些甚至有很详细的文件,当您对某个 部份感兴趣时,您应该自行进门挖宝。重覆一点,这里都是"入门级"的,遇到比较深的,我大多会含糊带过,免得您头脑发胀,您可依照所指定的进一步资料做深 一层的钻研。 注意 : 此部份属於文字着作,目前本人保留文字着作权。大部份内容为我目前正在计划撰写的"Linux程式设计 - 一般篇"及"Linux程式设计 - X Window篇"两本书的内容。因此您不得映射或任意散播 (虽然如此,我并不禁止你带回家,但不要没看完又跑来拿就是了)。 如果您有映射需求,请来信通知我。多数状况下,通常我会授权给您进行、传播及教学用途上。例程式的部份,版权BSD Style,本人授权给大众用於任意用途。(BSD style,您无须公开延伸工作。GPL则您需要释放延伸工作,不合於实际。)

    OK STATION, Webmaster, Brian Lin, foxman@okstation.com

     

    --------------------------------------------------------------------------------

    这里是一些有关Linux Programming的英文链结,非常地有用,我主要地参考了六本原文书及这些链结: http://www.faq.org/programming.shtml http://linuxwww.db.erau.edu/LPG/ http://www.cm.cf.ac.uk/Dave/X_lectu...ller/index.html http://www.ee.mu.oz.au/linux/programming/ http://www.ibrado.com/sock-faq/ http://www.asset.com/WSRD/abstracts/ABSTRACT_1073.html http://www.unix.geek.org.uk/~arny/info/library_toc.html http://i44www.info.uni-karlsruhe.de...nf96/paper.html

    --------------------------------------------------------------------------------

    1.Linux程式设计 - fork 2.Linux程式设计 - pthread 3.Linux程式设计 - signals 4.Linux程式设计 - socket 5.Linux程式设计 - inetd 6.Linux程式设计 - syslog 7.Linux程式设计 - zlib 8.Linux程式设计 - crypt 9.Linux程式设计 - PAM 10.Linux程式设计 - termios/keymap/terminal programming 11.Linux程式设计 - Shell Script(bash) 12.Linux程式设计 - 目录操作 13.Linux程式设计 - 记忆体对映mmap 14.Linux程式设计 - 动态函数库载入 15.Linux程式设计 - select 16.Linux程式设计 - TarBall 17.Linux程式设计 - svgalib 18.Linux程式设计 - dialog 19.Linux程式设计 - gpm 20.Linux程式设计 - getopt 21.Linux程式设计 - IPC 22.Linux程式设计 - FIFO 23.Linux程式设计 - Shared Memory 24.Linux程式设计 - semaphore 25.Linux程式设计 - Message Queues 26.Linux程式设计 - PIPE 27.Linux程式设计 - GNU Debugger 28.Linux程式设计 - GNU Make 29.Linux程式设计 - 时间处理 30.Linux程式设计 - 使用者资讯管理(pwd) 31.Linux程式设计 - 工作群资讯管理(grp) 32.Linux程式设计入门 - GGI 33.Linux程式设计入门 - ncurses 34.Linux程式设计入门 - utmp 35.Linux程式设计入门 - slang 36.Linux程式设计入门 - newt 37.Linux程式设计入门 - i18n 38.Linux程式设计入门 - CGI 39.Linux程式设计入门 - gdbm 40.Linux程式设计入门 - regex 41.X Window程式设计 - GTK+ 42.X Window程式设计 - Qt 43.X Window程式设计 - xform 44.X Window程式设计 - Motif 45.X Window程式设计 - XIM Server/Client 46.X Window程式设计 - freetype, TrueType Fonts support 47.X Window程式设计 - Mesa, OpenGL 48.X Window程式设计 - libjpeg 49.X Window程式设计 - libtiff 50.X Window程式设计 - libpbm 51.X Window程式设计 - giflib 52.X Window程式设计 - tcl/tk, Perl/tk, Python/tk     不要忘记自己的目标,一切都得靠自己去争取~~~     langlang 查看公开信息 发送悄悄话给langlang 给langlang发送Email 访问langlang的个人网站 查找langlang发表的更多帖子 添加 langlang 到好友列表  05-05-10, 18:21    第 2 楼  langlang  管理员         帖子: 223精华: 12注册日期: 2005-03-01来自: 广州  

    --------------------------------------------------------------------------------

    Linux程式设计 - 1.fork

    在UNIX程式设计中,学会fork()的运用,算是相当基本的功夫。 fork()及signal经常运用在daemon守护神这一类常驻程式,另外像a4c.tty/yact/chdrv这些中文终端机程式也有用到,一般如Mozilla/Apache/Squid等大程式几乎都一定会用到。 -------------------------------------------------------------------------程序分歧fork() fork()会产生一个与父程序相同的子程序,唯一不同之处在於其process id(pid)。 如果我们要撰写守护神程式,或是例如网路伺服器,需要多个行程来同时提供多个连线,可以利用fork()来产生多个相同的行程。

    函数宣告 pid_t fork(void); pid_t vfork(void); 返回值: -1 : 失败。 0 : 子程序。 >0 : 将子程序的process id传回给父程序。 在Linux下fork()及vfork()是相同的东西。

     

    Linux程式设计- 2.fork, pthread, and signals

    虽然在UNIX下的程式写作,对thread的功能需求并非很大,但thread在现代的作业系统中,几乎都已经存在了。pthread是Linux上的thread函数库,如果您要在Linux下撰写多线程式,例如MP3播放程式,熟悉pthread的用法是必要的。 有关thread写作,有两本很好的书: Programming with POSIX Threads Multithreading Programming Techniques 另外有一份初学者的参考文件Getting Started With POSIX Threads

    pthread及signal都可以用一大章来讨论。在这里,我只谈及最简单及常用的技巧,当您熟悉这些基本技巧的运用後,再找一些专门深入探讨pthread及signal程式写作的书籍来研究。这些进阶的写法,用到的机会较少,将层次分明,学习速度应该会比较快。

     

    --------------------------------------------------------------------------------

    thread 我假设您对thread已经有一些基本的概念,因此,在此我将着重於如何实作。 函数宣告 int pthread_create(pthread_t * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg); int pthread_join(pthread_t th, void **thread_return); int pthread_detach(pthread_t th); void pthread_exit(void *retval); int pthread_attr_init(pthread_attr_t *attr); 资料结构 typedef struct { int detachstate; int schedpolicy; struct sched_param schedparam; int inheritsched; int scope; } pthread_attr_t; 例一: #include #include #include #include void * mythread(void *arg) {

    for (;;) { printf("thread/n"); sleep(1); } return NULL; }

    void main(void) { pthread_t th;

    if (pthread_create(&th,NULL,mythread,NULL)!=0) exit(0);

    for (;;) { printf("main process/n"); sleep(3); } }

    执行结果: ./ex1 main process thread thread thread main process thread thread thread main process thread thread thread main process

     

    Linux程式设计- 3.signals

    信号处理

    -------------------------------------------------------------------------信号处理概说 送出信号 接收信号 信号的处理 任务控制

    -------------------------------------------------------------------------POSIX IPC reliable/unreliable reentrant pending sending signals catching signals manipulating signal definitions

    -------------------------------------------------------------------------信号singals 信 号的处理可以用一大章来写,涉及的层面也会深入整个作业系统中,我并不打算这样做,因为您可能会越搞越迷糊。这里我只告诉您如何接上信号,在实用的层面 上,这样便很够用了。您可以先利用这些基本的技巧来撰写程式,等到有进一步高等应用的需要时,找一本较深入的UNIX Programming教材,专门研究signal的写法。 一般简单的signal写法如下:

    void mysignal(int signo) { /* my signal handler */ }

    void initsignal(void) { struct sigaction act;

    act.sa_handler = mysignal; act.sa_flags = 0; sigemptyset(&act.sa_mask); sigaction(SIGHUP,&act,NULL); sigaction(SIGINT,&act,NULL); sigaction(SIGQUIT,&act,NULL); sigaction(SIGILL,&act,NULL); sigaction(SIGTERM,&act,NULL); }

    例一: lock.c 在fork的例三中提到,在daemon被杀掉时,需要在离开前,将/var/run/lock.pid删除。这里我们可以利用signal来处理这件事。 #include #include #include #include

    #define LOCK_FILE "/var/run/lock.pid"

    void quit(int signo) { printf("Receive signal %d/n",signo); unlink(LOCK_FILE); exit(1); }

    void main(void) { FILE *fp; pid_t pid; struct sigaction act;

    if (access(LOCK_FILE,R_OK)==0) { printf("Existing a copy of this daemon!/n"); exit(1); }

    pid = fork();

    if (pid>0) { printf("daemon on duty!/n");

    fp = fopen(LOCK_FILE,"wt"); fprintf(fp,"%d",pid); fclose(fp); } else exit(0); if (pid<0) { printf("Can't fork!/n"); exit(-1); }

    act.sa_handler = quit; act.sa_flags = 0; sigemptyset(&act.sa_mask); sigaction(SIGTERM,&act,NULL); sigaction(SIGHUP,&act,NULL); sigaction(SIGINT,&act,NULL); sigaction(SIGQUIT,&act,NULL); sigaction(SIGUSR1,&act,NULL); sigaction(SIGUSR2,&act,NULL);

    for (;;) { sleep(3); } }

    编译: gcc -o ex1 lock.c 执行 ./ex1 daemon on duty!

    送信号 我们先找出该守护神程式的pid PID=`cat /var/run/lock.pid`

    接下来利用kill来送信号

    kill $PID

    Receive signal 15

    程式将会结束,并且/var/run/lock.pid将会被删除掉,以便下一次daemon再启动。注意到如果quit函数内,没有放exit(),程式将永远杀不掉。

    接下来送一些其它的信号试试看。 ./ex1 PID=`cat /var/run/lock.pid` kill -HUP $PID

    Receive signal 1

    您可以自行试试 kill -INT $PID kill -QUIT $PID kill -ILL $PID . . . 等等这些信号,看看他们的结果如何。

    信号的定义 在/usr/include/signum.h中有各种信号的定义 #define SIGHUP 1 &nb     不要忘记自己的目标,一切都得靠自己去争取~~~     langlang 查看公开信息 发送悄悄话给langlang 给langlang发送Email 访问langlang的个人网站 查找langlang发表的更多帖子 添加 langlang 到好友列表  05-05-10, 18:26    第 3 楼  langlang  管理员         帖子: 223精华: 12注册日期: 2005-03-01来自: 广州  

    --------------------------------------------------------------------------------

    Linux程式设计- 4.socket

    UNIX Socket Programming基本上是一本书名。Socket programming其实需要相当程度的基础,我不想在这包山包海地,如果您需要彻底研究,可以买这本书来看。在此我想提供一些简单的 Server/Client两端的简单写法,让你有个起点,做为进一步研究的基础。很多涉及较复杂的内容的,我在这便不详细说明,您可以照本宣科,照抄着 用,稍微熟悉时,再细细研究。

    --------------------------------------------------------------------------------

    Client int sock_connect(char *domain,int port) { int white_sock; struct hostent * site; struct sockaddr_in me; site = gethostbyname(domain); if (site==NULL) return -2;

    white_sock = socket(AF_INET,SOCK_STREAM,0); if (white_sock<0) return -1;

    memset(&me,0,sizeof(struct sockaddr_in)); memcpy(&me.sin_addr,site->h_addr_list[0],site->h_length); me.sin_family = AF_INET; me.sin_port = htons(port);

    return (connect(white_sock,(struct sockaddr *)&me,sizeof(struct sockaddr))<0) ? -1 : white_sock; }

    要由Client向伺服器端要求连线的步骤,首先您必须要找出对方的位址,可利用:

    gethostbyname()

    接下来要建立起一个socket,然後用这个socket来建立连线。

    接下来我们利用这个简单的socket程式来写一个读取WWW网页的简单浏览器(看html source)。 #include #include #include #include #include #include #include

    int htconnect(char *domain,int port) { int white_sock; struct hostent * site; struct sockaddr_in me;

    site = gethostbyname(domain); if (site==NULL) return -2;

    white_sock = socket(AF_INET,SOCK_STREAM,0); if (white_sock<0) return -1;

    memset(&me,0,sizeof(struct sockaddr_in)); memcpy(&me.sin_addr,site->h_addr_list[0],site->h_length); me.sin_family = AF_INET; me.sin_port = htons(port);

    return (connect(white_sock,(struct sockaddr *)&me,sizeof(struct sockaddr))<0) ? -1 : white_sock; }

    int htsend(int sock,char *fmt,...) { char BUF[1024]; va_list argptr; va_start(argptr,fmt); vsprintf(BUF,fmt,argptr); va_end(argptr); return send(sock,BUF,strlen(BUF),0); }

    void main(int argc,char **argv) { int black_sock; char bugs_bunny[3];

    if (argc<2) return;

    black_sock = htconnect(argv[1],80); if (black_sock<0) return; htsend(black_sock,"GET / HTTP/1.0%c",10); htsend(black_sock,"Host: %s%c",argv[1],10); htsend(black_sock,"%c",10); while (read(black_sock,bugs_bunny,1)>0) { printf("%c",bugs_bunny[0]); }

    close(black_sock); }

    编译: gcc -o ex1 client.c 执行 ./ex1 www.linux.org.tw

    --------------------------------------------------------------------------------

    Server Listen to a port 要建立起一个网路伺服器,第一步就是要"倾远方",也就是要Listen。 以下是一般建立服务的方法: int DaemonSocket; struct sockaddr_in DaemonAddr; int BindSocket(void) {

    DaemonSocket = socket(AF_INET,SOCK_STREAM,0); if (DaemonSocket==-1) return 0; DaemonAddr.sin_family = AF_INET; DaemonAddr.sin_port = htons(DAEMON_PORT); if (bind(DaemonSocket,&DaemonAddr,sizeof(DaemonAddr))<0) { printf("Can not bind!/n"); return 0; } if (listen(DaemonSocket,1024)!=0) { printf("Can not listen!/n"); return 0; }

    return 1; }

    Incoming call 要查看是否有连线进来,可用以下方式: int incoming_call(void) { fd_set sock; struct timeval tv; int t;

    FD_ZERO(&sock); FD_SET(DaemonSocket,&sock); tv.tv_sec = 60; tv.tv_usec = 0; t = select(DaemonSocket + 1,&sock,NULL,NULL,&tv); if (t<=0||!FD_ISSET(DaemonSocket,&sock)) return 0;

    printf("incoming.../n");

    return 1; }

    Connect Client 当我们确认有人进来要求服务时,会需要accept connection,可用以下方式 int ConnectClient(void) { int socksize=sizeof(HostAddr); unsigned char * addr;

    ClientSocket = accept(DaemonSocket,(struct sockaddr*)&HostAddr,&socksize); if (ClientSocket<0) return 0;

    addr = (unsigned char *)&HostAddr.sin_addr.s_addr;

    printf("incoming address:%d.%d.%d.%d/n",addr[0],addr[1],addr[2],addr[3]);

    return 1; }

    注意到当您accept connection之後,连线已建立起,此时要用的socket是ClientSocket,而非DaemonSocket,ClientSocket才是真正用来连线用的socket。

    这是个我才刚开始动手写的象棋伺服器。

    #include #include #include #include #include #include #include #include #include #include #include #include

    #define DAEMON_LOCK "/var/chess/daemon.lock" #define DAEMON_LOG "/var/chess/daemon.log" #define DAEMON_PORT 9901

    int DaemonSocket; struct sockaddr_in DaemonAddr;

    int ClientSocket=0; struct sockaddr_in HostAddr;

    void dlog(char *fmt,...) { va_list argptr; FILE *fp;

    fp = fopen(DAEMON_LOG,"a+t"); va_start(argptr,fmt); vfprintf(fp,fmt,argptr); va_end(argptr); fclose(fp); }

    pid_t CheckLock(void) { pid_t me; FILE * fp;

    fp = fopen(DAEMON_LOCK,"rt"); if (fp==NULL) return 0; fscanf(fp,"%d",&me); fclose(fp);

    return me; }

    pid_t WriteLock(void) { pid_t me; FILE *fp;

    me = getpid();

    fp = fopen(DAEMON_LOCK,"w"); fprintf(fp,"%d",me); fclose(fp);

    return me; }

    int CleanLock(void) { return (unlink(DAEMON_LOCK)==0); }

    void report_time(void) { time_t now; now = time(NULL); dlog("%s",asctime((const struct tm*)localtime(&now))); }

    static void signal_catch(int signo) { time_t now;

    close(DaemonSocket); if (ClientSocket>0) close(ClientSocket); CleanLock(); now = time(NULL); dlog("Catch signal %d, leave at %s/n",signo,asctime((const struct tm*)localti exit(-1); }

    void SetupSignal(void) { struct sigaction act;

    act.sa_handler = signal_catch; act.sa_flags = 0; sigemptyset(&act.sa_mask); sigaction(SIGHUP,&act,NULL); sigaction(SIGINT,&act,NULL); sigaction(SIGQUIT,&act,NULL); sigaction(SIGILL,&act,NULL); sigaction(SIGABRT,&act,NULL); sigaction(SIGIOT,&act,NULL); sigaction(SIGBUS,&act,NULL); sigaction(SIGFPE,&act,NULL); sigaction(SIGTERM,&act,NULL); }

    int BindSocket(void) {

    DaemonSocket = socket(AF_INET,SOCK_STREAM,0); if (DaemonSocket==-1) return 0; DaemonAddr.sin_family = AF_INET; DaemonAddr.sin_port = htons(DAEMON_PORT); if (bind(DaemonSocket,&DaemonAddr,sizeof(DaemonAddr))<0) { printf("Can not bind!/n"); return 0; } if (listen(DaemonSocket,1024)!=0) { printf("Can not listen!/n"); return 0; }

    return 1; }

    int incoming_call(void) { fd_set sock; struct timeval tv; int t;

    FD_ZERO(&sock); FD_SET(DaemonSocket,&sock); tv.tv_sec = 60; tv.tv_usec = 0; t = select(DaemonSocket + 1,&sock,NULL,NULL,&tv); if (t<=0||!FD_ISSET(DaemonSocket,&sock)) return 0;

    dlog("incoming.../n");

    return 1; }

    int ConnectClient(void) { int socksize=sizeof(HostAddr); unsigned char * addr;

    ClientSocket = accept(DaemonSocket,(struct sockaddr*)&HostAddr,&socksize); if (ClientSocket<0) return 0;

    addr = (unsigned char *)&HostAddr.sin_addr.s_addr;

    dlog("incoming address:%d.%d.%d.%d/n",addr[0],addr[1],addr[2],addr[3]);

    return 1; }

    int daemon_printf(char *fmt,...) { char BUF[4096]; va_list argptr;

    va_start(argptr,fmt); vsprintf(BUF,fmt,argptr); va_end(argptr); return write(ClientSocket,BUF,strlen(BUF)); }

    void Log(void) { char BUF[4096]; read(DaemonSocket,BUF,16); daemon_printf("%s",BUF[0]); }

    int main(int argc,char **argv) { pid_t myself; time_t now;

    /* find myself */ myself = CheckLock(); if (myself!=0) { printf("Existing a copy of chess daemon[pid=%d], leave now./n",myself); exit(1); }

    /* fork */ myself = fork(); if (myself>0) { exit(1); } else if (myself<0) { printf("Strange world! I don't like it. Quit because of pid=%d/n",myself); exit(1); } else { SetupSignal(); if (!BindSocket()) { printf("Can not bind socket!/n"); exit(1); } WriteLock(); }

    printf("Chess Daemon is up, have fun!/n");

    now = time(NULL);

    dlog("----------------------------------------------/n"); dlog( "I am back! %s" "Chess Daemon comes to alive again./n", asctime((const struct tm*)localtime(&now)) );

    do { if (incoming_call()) {

    if (ConnectClient()) {

    fd_set sock; struct timeval tv; int t; char BUF[128]; char CC[2]; int n;

    daemon_printf("Welcome to Chinese Chess Game Center!/n");

    FD_ZERO(&sock); FD_SET(ClientSocket,&sock); n = 0; do { tv.tv_sec = 60; tv.tv_usec = 0; t = select(ClientSocket+1,&sock,NULL,NULL,&tv); if (t<=0||!FD_ISSET(ClientSocket,&sock)) ; read(ClientSocket,CC,1); if (CC[0]==13||CC[0]==10||CC[0]==0) { BUF[n] = 0; dlog("%s/n",BUF); if (strncasecmp(BUF,"exit",4)==0) { close(ClientSocket); break; } n = 0; } else { BUF[n]=CC[0]; n++; } } while (1); } } } while (1);

    return 1; }

    检验 telnet localhost 9901

    在处理Connect Client时,事实上可以运用fork或thread来处理多个连线。

     

    Linux程式设计- 5.inetd

    inetd提供被动式的伺服器服务,也就是伺服器是被使用端所启动,平时则无须存在。例如,ftp, telnetd, pop3,imap, auth等等,这些服务没有人使用时,无须启动。此外,inetd将socket转换成stdin/stdout,因而使得网路服务程式设计大大简化,您 可以只用printf及fgets便可完成处理很复杂的网路协定。

    --------------------------------------------------------------------------------

    inetd programming 利用inetd来做网路程式设计是个既简单又稳定的设计方法,您不需要考虑到复杂的socket programming。您的设计工作几乎在设计好通讯协定後就完成了,所需要的技巧,仅为简单的文字分析技巧。 goodie inet service 首先,我们先来撰写一个称为goodie的服务程式。 goodie.c #include #include #include

    void main(void) { printf("Welcome to goodie service!/n"); }

    这个程式很简单,不是吗?

    编译 gcc -o goodie goodie.c 设定/etc/services及/etc/inetd.conf 在/etc/services中加入以下这一行 goodie 20001/tcp

    其意义为goodie这项服务是在port 20001、TCP协定。

    接下来在/etc/inetd.conf中加入以下这一行

    goodie stream tcp nowait root /full_goodie_path_name/goodie

    各项参数的意义为

    service_name需要为在services中存在的名称。 sock_type有很多种,大多用的是stream/dgram。 proto一般用tcp/udp。 flags有wait/nowait。 user是您指定该程式要以那一个使用者来启动,这个例子中用的是root,如果有安全性的考量,应该要改用nobody。一般来说,建议您用低权限的使用者,除非必要,不开放root使用权。 server_path及args,这是您的服务程式的位置及您所想加入的参数。

    接下来重新启动inetd

    killall inetd inetd

    这样我们便建立起一个port 20001的goodie service。 现在我们来检验一下goodie是否可以执行:

    telnet localhost 20001 或 telnet your_host_name 20001

    执行结果 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Welcome to goodie service! Connection closed by foreign host. 很简单不是吗? 信不信由您,telnet/pop3/imap/ftp都是靠这种方式建立起来的服务。

    我们现在来建立一点小小的"网路协定",这个协定使我们可以输入"exit"时,离开程式,而其他的指令都是输出与输入相同的字串。

    #include #include #include

    void main(void) { char buf[1024]; int ok;

    printf("Welcome to goodie service!/n"); fflush(stdout);

    ok=0; do { while (fgets(buf,1023,stdin)==NULL); if (strncasecmp(buf,"exit",4)==0) ok=1; printf(buf); fflush(stdout); } while (!ok); }

    执行结果 telnet localhost 20001 或 telnet your_host_name 20001

    Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Welcome to goodie service!

    输入"help"

    help help

    输入"exit"

    exit exit Connection closed by foreign host.

    接下来,我们将设计一个稍微复杂一点点的通讯协定,比较通用於一般用途。 #include #include #include

    char *cmds[]={ "help", "say", "hello", "bye", "exit", NULL };

    int getcmd(char *cmd) { int n=0; while (cmds[n]!=NULL) { if (strncasecmp(cmd,cmds[n],strlen(cmds[n]))==0) return n; n++; } return -1; }

    void main(void) { char buf[1024]; int ok;

    printf("Welcome to goodie service!/n"); fflush(stdout);

    ok=0; do { while (fgets(buf,1023,stdin)==NULL); switch (getcmd(buf)) { case -1: printf("Unknown command!/n"); break; case 0: printf("How may I help you, sir?/n"); break; case 1: printf("I will say %s",&buf[3]); break; case 2: printf("How're you doing today?/n"); break; case 3: printf("Si ya, mate!/n"); ok=1; break; case 4: printf("Go ahead!/n"); ok=1; break; } fflush(stdout); } while (!ok);

    }

    telnet localhost 20001 或 telnet your_host_name 20001

    试试看输入"help"、"say"、"hello"、"bye"、"exit"等等指令,及其它一些不在命令列中的指令。

    在设计inetd服务程式时,要特别注意buffer overflow的问题,也就是以下这种状况:

    char buffer_overflow[64]; fscanf(stdin,"%s",buffer_overflow);

    历来几乎所有的安全漏洞都是由此而来的。 你一定不可这样用,不论任何理由,类同的用法也不可以。Cracker可以透过将您的buffer塞爆,然後塞进他自己的程式进来执行。

     

     

    最新回复(0)