真实路径()不解决符号链接? [英] realpath() without resolving symlinks?

查看:135
本文介绍了真实路径()不解决符号链接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经读到的真实路径(),但没有办法,我可以通过一个基本目录和文件名,这将使我下面的结果不解决符号链接的函数或检查是否实际存在的文件吗?还是我必须使用修改的真实路径()

 的/ var /,../etc///././/passwd=> / etc / passwd文件


解决方案

下面是一个normalize_path()函数:

如果给定的路径是相对的,功能由prepending当前的工作目录启动。

随后的特殊的如 .. 路径组件。或空组件处理,并返回结果。

有关 .. ,如果有一个( / .. 将只返回删除最后一个组件 / )。结果
对于或空组件(双 / ),这仅仅是跳过。

该功能确保不空车返回的路径( / 而是返回)。

 的#define _GNU_SOURCE / *了memrchr()* /#包括LT&;&stdlib.h中GT;
#包括LT&;&string.h中GT;
#包括LT&;&unistd.h中GT;
#包括LT&;&limits.h中GT;字符* normalize_path(为const char * SRC,为size_t src_len){        字符*资源;
        为size_t res_len;        为const char * PTR = SRC;
        为const char *年底=放大器; SRC [src_len]
        为const char *接下来的;        如果(src_len == 0 || SRC [0]!='/'){                //相对路径                焦炭PWD [PATH_MAX];
                为size_t pwd_len;                如果(GETCWD(PWD,sizeof的(PWD))== NULL){
                        返回NULL;
                }                pwd_len = strlen的(PWD);
                解析度= malloc的(pwd_len + 1 + src_len + 1);
                的memcpy(RES,PWD,pwd_len);
                res_len = pwd_len;
        }其他{
                解析度= malloc的((src_len大于0 src_len:1)+ 1);
                res_len = 0;
        }        对于(PTR = SRC; PTR< END; PTR =下一个+ 1){
                为size_t LEN;
                接下来=了memchr(PTR,'/',最终PTR);
                如果(下一== NULL){
                        接下来=结束;
                }
                LEN =下一个PTR;
                开关(LEN){
                案例2:
                        如果(PTR [0] ==&放大器'。';&放大器;'。'ptr的[1] ==){
                                为const char *斜杠=了memrchr(RES,'/',res_len);
                                如果(斜线!= NULL){
                                        res_len =斜线 - 资源;
                                }
                                继续;
                        }
                        打破;
                情况1:
                        如果(PTR [0] =='。'){
                                继续;                        }
                        打破;
                情况下0:
                        继续;
                }
                RES [res_len ++] ='/';
                的memcpy(安培; RES [res_len],PTR,LEN);
                res_len + = LEN;
        }        如果(res_len == 0){
                RES [res_len ++] ='/';
        }
        RES [res_len] ='\\ 0';
        返回水库;
}

I already read about realpath(), but is there a function that I can pass a base directory and a filename that would give me the following result without resolving symlinks or checking whether files actually exist? Or do I have to use a modified realpath()?

"/var/", "../etc///././/passwd" => "/etc/passwd"

解决方案

Here is a normalize_path() function:

If the given path is relative, the function starts by prepending the current working directory to it.

Then the special path components like .., . or empty components are treated, and the result is returned.

For .., the last component is removed if there is one (/.. will just return /).
For . or empty components (double /), this is just skipped.

The function ensures to not return empty an path (/ is returned instead).

#define _GNU_SOURCE /* memrchr() */

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>

char * normalize_path(const char * src, size_t src_len) {

        char * res;
        size_t res_len;

        const char * ptr = src;
        const char * end = &src[src_len];
        const char * next;

        if (src_len == 0 || src[0] != '/') {

                // relative path

                char pwd[PATH_MAX];
                size_t pwd_len;

                if (getcwd(pwd, sizeof(pwd)) == NULL) {
                        return NULL;
                }

                pwd_len = strlen(pwd);
                res = malloc(pwd_len + 1 + src_len + 1);
                memcpy(res, pwd, pwd_len);
                res_len = pwd_len;
        } else {
                res = malloc((src_len > 0 ? src_len : 1) + 1);
                res_len = 0;
        }

        for (ptr = src; ptr < end; ptr=next+1) {
                size_t len;
                next = memchr(ptr, '/', end-ptr);
                if (next == NULL) {
                        next = end;
                }
                len = next-ptr;
                switch(len) {
                case 2:
                        if (ptr[0] == '.' && ptr[1] == '.') {
                                const char * slash = memrchr(res, '/', res_len);
                                if (slash != NULL) {
                                        res_len = slash - res;
                                }
                                continue;
                        }
                        break;
                case 1:
                        if (ptr[0] == '.') {
                                continue;

                        }
                        break;
                case 0:
                        continue;
                }
                res[res_len++] = '/';
                memcpy(&res[res_len], ptr, len);
                res_len += len;
        }

        if (res_len == 0) {
                res[res_len++] = '/';
        }
        res[res_len] = '\0';
        return res;
}

这篇关于真实路径()不解决符号链接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆