18.3.11 SHTTPD生成目录下文件列表文件的实现

18.3.11  SHTTPD生成目录下文件列表文件的实现

当客户端请求的是一个目录名的时候,需要判断是否当前目录下有一个与默认文件名一致的文件。如果没有,则需要将当前目录下面的所有目录列表出来,并形成超级链接,目录文件列表的实现代码如下:

1)先打开目录,并打开一个临时文件。

 

int GenerateDirFile(struct worker_ctl *wctl)

{

    struct conn_request *req = &wctl->conn.con_req;

    struct conn_response *res = &wctl->conn.con_res;

    char *command = strstr(req->uri, CGISTR) + strlen(CGISTR);

    char *arg[ARGNUM];

    int num = 0;

    char *rpath = wctl->conn.con_req.rpath;

    stat *fs = &wctl->conn.con_res.fsate;

    /*打开目录*/

    DIR *dir = opendir(rpath);

    if(dir == NULL)

    {

        /*错误*/

        res->status = 500;

        retval = -1;

        goto EXITgenerateIndex;

    }

    /*建立临时文件保存目录列表*/

    File *tmpfile;

    char tmpbuff[2048];

    int filesize = 0;

    char *uri = wctl->conn.con_req.uri;

    tmpfile = tmpfile();

 

2)建立标题部分字符串,标题为当前的URI

 

/*标题部分*/

sprintf(tmpbuff,

    "%s%s%s",

    "<!DOCTYPE HTML PUBLIC /"-//W3C//DTD HTML 3.2 Final//EN/">/n<HTML>
    <HEAD><TITLE>",

    uri,

    "</TITLE></HEAD>/n"    );

fprintf(tmpfile, "%s", tmpbuff);

filesize += strlen(tmpbuff);

 

目录下的文件列表的格式为:

 

文件名      日期      大小

 

形式的东西,先将上述的格式打印出来。

 

/*标识部分*/

sprintf(tmpbuff,

    "%s %s %s",

    "<BODY><H1>Index of:",

    uri,

    " </H1> <HR><P><I>Date: </I> <I>Size: </I></P><HR>");

fprintf(tmpfile, "%s", tmpbuff);

filesize += strlen(tmpbuff);

 

 

3)下面进入主要的部分获得目录下面的文件列表。

这个文件列表主要分为3类:一类为“.”和“..”等特殊的目录;一类为正常的目录;最后一类为正规文件。其中当前目录“.”不用显示,而表示其上层目录的“..”需要显示的将其名称用“父目录”表示出来。

对于正规的文件需要获得文件的日期和大小等参数。最后,当目录下所有的文件遍历完毕之后,需要更新用于表示客户端访问资源属性的参数fs,将它的修改时间、建立时间等设置为当前,主要是设置其大小,以便之后进行访问。为了防止出现问题,需要将文件的指针移到文件的首部。

 

    /* 读取目录中的文件列表 */

    struct dirent *de;

#define PATHLENGTH 2048

    char path[PATHLENGTH];

    char tmpath[PATHLENGTH];

    char linkname[PATHLENGTH];

    struct stat fs;

    strcpy(path, rpath);

    if(rpath[strlen(rpath)]!='/')

    {

        rpath[strlen(rpath)]='/';

    }

    while ((de = readdir(dir)) != NULL)       /*读取一个文件*/

    {

        menset(tmpath, 0, sizeof(tmpath));

        menset(linkname, 0, sizeof(linkname));

        if(strcmp(de->d_name, "."))               /*不是当前目录*/

        {

            if(strcmp(de->d_name, ".."))      /*不是父目录*/

            {

                strcpy(linkname,de->d_name);    /*将目录名称作为链接名称*/

            }

            else/*是父目录*/

            {

                strcpy(linkname, "Parent Directory");
                                                /
*将父目录作为链接名称*/

            }

            sprintf(tmpath, "%s%s",path, de->d_name);
                                                /
*构建当前文件的全路径*/

            stat(tmpath, &fs);                   /*获得文件信息*/

            if(S_ISDIR(fs.st_mode))                /*是一个目录*/

            {

                /*打印目录的链接为目录名称*/

                sprintf(tmpbuff, "<A HREF=/"%s//">%s/</A><BR>/n", de->d_
                name,tmpath);

            }

            else/*正常文件*/

            {

                char size_str[32];

                off_t size_int;

                size_int = fs.st_size;          /*文件大小*/

                if (size_int < 1024)         /*不到1K*/

                    sprintf(size_str, "%d bytes", (int) size_int);

                else if (size_int < 1024*1024)    /*不到1M*/

                    sprintf(size_str, "%1.2f Kbytes", (float) size_int /
                    1024);

                else/*其他*/

                    sprintf(size_str, "%1.2f Mbytes", (float) size_int /
                    (1024
*1024));

                /*输出文件大小*/

                sprintf(tmpbuff, "<A HREF=/"%s/">%s</A> (%s)<BR>/n", de->
                d_name, linkname, size_int);

            }

            /*将形成的字符串写入临时文件*/

            fprintf(tmpfile, "%s", tmpbuff);

            filesize += strlen(tmpbuff);            

        }

    }

    /*生成临时的文件信息,主要是文件大小*/

    fs.st_ctime = time(NULL);

    fs.st_mtime = time(NULL);

    fs.st_size = filesize;

    fseek(tmpfile, (long) 0, SEEK_SET);        /*移动文件指针到头部*/

}

  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linuxdianc

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值