修改struct ftpuser结构体如下,将原来的connfd直接写到整个结构体中

struct ftpuser{
	char username[20];
	char userpass[20];
	char dataip[20];			//save ip for port mode
	char basedir[MAXLINE];			//basedir of current user
	int dataport;				//save port for port mode
	int loginok;				//whether user login
	int userok;				//user ok but no pass
	int transfor_mode;			//port or pasv
	int write_flag;				//write access control
	int maxspeed;				//speed limit
	int pasv_sockfd;			//pasv sockfd
	pthread_t pasv_accept;			//pasv listen thread id
        int connfd;                         //control sockfd
};
[/code]
pasv函数如下,当执行STOR,RETR,LIST后要关闭pasv_sockfd,特别是LIST用了一个子进程实现数据通信,父进程中也要关闭
[code=c]
void *pasv_listen(void *arg)		//create listen_thread for pasv data port
{
	struct ftpuser *myftp = (struct ftpuser *)arg;
	srand(time(NULL));
	int listenfd = -1;
	while(listenfd == -1)
	{
		myftp->dataport = rand()%45535 + 20000;			//generate a random port
		listenfd = initlisten(myftp->dataport);
	}
	char notifylisten[MAXLINE];
	memset(notifylisten,'\0',MAXLINE);
	snprintf(notifylisten,MAXLINE,"227 Entering Passive Mode (202,117,7,222,%d,%d)\r\n",(myftp->dataport)/256,(myftp->dataport)%256);
	write(myftp->connfd,notifylisten,strlen(notifylisten));
	int connfd = accept(listenfd,NULL,NULL);
	pthread_mutex_lock(&lock);
	myftp->pasv_sockfd = connfd;
	pthread_mutex_unlock(&lock);
	myftp->transfor_mode = 2;
	return;
}

void do_pasv(int connfd,struct ftpuser *myftp)
{
	cleanmode(myftp);
	//char *notsupport="500 passive mode not supported.\r\n";
	if(myftp->pasv_accept != 0)
		pthread_cancel(myftp->pasv_accept);					//ingore the error while the tid is not exist
	pthread_t tid;
	pthread_create(&tid,NULL,pasv_listen,(void *)myftp);
	myftp->pasv_accept = tid;
	return;
}

今天第一次知道这个,以前没用过,就想当然有了,看来碰到问题后才能累计和发现啊~~~

c99开始有了<stdbool.h>可以使用bool,true,false了,但其实只是一种扩展宏定义而已。


#ifndef _STDBOOL_H
#define _STDBOOL_H

#ifndef __cplusplus

#define bool    _Bool
#define true    1
#define false    0

#else /* __cplusplus */
/* Supporting <stdbool.h> in C++ is a GCC extension.  */
#define _Bool    bool
#define bool    bool
#define false    false
#define true    true

#endif /* __cplusplus */

/* Signal that all the definitions are present.  */
#define __bool_true_false_are_defined    1

#endif    /* stdbool.h */

其实这些功能函数实现都没什么技术含量,直接系统调用就好,只要umask设置对就OK。

实现了这些基本的功能,应该该建立一个权限模型的时候了,这个要好好学习,复杂啊…

不然所有的操作都是unix下运行ftpserver进程的用户权限,没意义,只能个人使用了。


void do_mkdir(int connfd,char *dirname)  //mkdir
{
char *mkdok = "257 diretory created ok.\r\n";
char *mkderror = "550 Create directory operation failed.\r\n";
umask(S_IWGRP | S_IWOTH);
if( mkdir(dirname,RWXRWXRWX) == 0 )
write(connfd,mkdok,strlen(mkdok));
else
write(connfd,mkderror,strlen(mkderror));
return;
}

void do_dele(int connfd,char *delname)   //rmdir or delete file
{
char *deleok = "250 Delete operation successful.\r\n";
char *delerror = "550 Delete operation failed.\r\n";
if( remove(delname) == 0)
write(connfd,deleok,strlen(deleok));
else
write(connfd,delerror,strlen(delerror));
return;
}

当执行一趟文件读取循环,文件读取到末尾的时候,例如 while(getline(ifstream &, string &  )  ! = NULL)以后,由于ifstream已经到达流尾端,会将ifstream&置 fail bit,因此执行seekg()将无效。

因此应在seekg之前执行以下 istream::clear()清除标志位,再执行seekg(), ok!

when create a new page at mediawiki, the following sql-statements will be created.

(从MySQL的log分析得出,不保证Mediawiki本身就一定按照此顺序执行,

其中也省略了一些临时的步骤,红色表示关键步骤,可以保证mediawiki的该page的正常查看以及查找)

1. insert into page。(page_latest = 0,len = 0 at this insert)

2.insert into text。

3.insert into revision。

(以上三个表有外键关联,

page.page_id = revision.rev_page ,

page.page_latest = revision.rev_id,

revsion.rev_text_id = text.old_id

)

4. update page set page_lastest, len.

5. insert logging.

6. update user set user_editcount = user_editcount + 1

7. update user set user_touch = nowdate()

8. insert into objectcache( this table is used for a few generic cache operations if not using Memcached)

9. update site_stats set ss_total_edit and ss_total_page ( add 1)

10. replace into searchindex.