⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pathdup.c

📁 具有IDE功能的编辑器
💻 C
字号:
/* pathdup.c - reproduces a path stripping /../ /./ and resolving symlinks   Copyright (C) 1996-2000 Paul Sheer   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA   02111-1307, USA. */#include <config.h>#include "global.h"#include "pipe-headers.h"#include <my_string.h>#include "mad.h"struct comp {    struct comp *prev;    struct comp *next;    char name[2];};static struct comp *comp_last (struct comp *p){    while (p->next)	p = p->next;    return p;}static struct comp *comp_first (struct comp *p){    while (p->prev)	p = p->prev;    return p;}static inline struct comp *comp_cat (struct comp *s, struct comp *t){    s = comp_last (s);    t = comp_first (t);    s->next = t;    t->prev = s;    return comp_first (s);}static inline struct comp *comp_insert (struct comp *p, struct comp *s){    struct comp *t;    t = comp_last (s);    s = comp_first (s);    if (p->prev)	p->prev->next = s;    if (p->next)	p->next->prev = t;    t->next = p->next;    s->prev = p->prev;    memset (p, 0, sizeof (*p));    free (p);    return t;}static inline struct comp *comp_replace (struct comp *p, struct comp *s){    struct comp *t, *prev, *r;    t = comp_last (s);    if (p->next)	p->next->prev = t;    t->next = p->next;    for (r = p; r; r = prev) {	prev = r->prev;	memset (r, 0, sizeof (*r));	free (r);    }    return t;}static inline void comp_free (struct comp *p){    struct comp *next;    p = comp_first (p);    for (; p; p = next) {	next = p->next;	memset (p, 0, sizeof (*p));	free (p);    }}#define COMP_DUMP(p)					\	    if (u == p)					\		u = p->next;				\	    if (p->next)				\		p->next->prev = p->prev;		\	    if (p->prev)				\		p->prev->next = p->next;		\	    memset (p, 0, sizeof (*p));			\	    free (p);/* dump  ..  .  and nothings, but remember the place in the list of p */static struct comp *comp_strip (struct comp *p){    struct comp *u = p, *next;    for (p = comp_first (p); p; p = next) {	next = p->next;	if (!*p->name || !strcmp (p->name, ".")) {	    COMP_DUMP (p);	} else if (!strcmp (p->name, "..")) {	    struct comp *t;	    if ((t = p->prev)) {		COMP_DUMP (t);	    }	    COMP_DUMP (p);	}    }    if (!u) {/* mustn't strip everything */	u = malloc (sizeof (struct comp));	memset (u, 0, sizeof (struct comp));    }    return u;}/* split into a list along / */#ifdef HAVE_MADstatic char *mad_comp_combine (struct comp *s, char *file, int line)#define comp_combine(s) mad_comp_combine(s, __FILE__, __LINE__)#elsestatic char *comp_combine (struct comp *s)#endif{    int n;    struct comp *t, *f;    char *p, *r;    f = comp_first (s);    for (n = 0, t = f; t != s->next; t = t->next)	n += strlen (t->name) + 1;#ifdef HAVE_MAD    r = mad_alloc (n + 2, file, line);#else    r = malloc (n + 2);#endif    for (p = r, t = f; t != s->next; t = t->next) {	*p++ = '/';	strcpy (p, t->name);	p += strlen (p);    }    return r;}/* split into a list along / */static struct comp *comp_tize (char *s){    struct comp *u, *p = 0;    char *t;    int done = 0;    while (!done) {	int l;	t = (char *) strchr (s, '/');	if (!t) {	    t = s + strlen (s);	    done = 1;	}	l = (unsigned long) t - (unsigned long) s;	u = malloc (sizeof (struct comp) + l);	u->prev = p;	u->next = 0;	if (p)	    p->next = u;	p = u;	memcpy (u->name, s, l);	u->name[l] = '\0';	s = t + 1;    }    return p;}static inline char *comp_readlink (struct comp *p){    char *s;    int r;    static char buf[2048];    s = comp_combine (p);    r = readlink (s, buf, 2047);    if (r == -1 && errno == EINVAL) {	free (s);	return "";    }    if (r == -1) {	free (s);	return 0;    }    buf[r] = '\0';    free (s);    return buf;}/* if there is an error, this just returns as far as it got */static inline struct comp *resolve_symlink (struct comp *path){    int i;    struct comp *t;    path = comp_strip (comp_first (path));    path = comp_last (path);    for (i = 0;; i++) {	char *l;	if (i >= 1000)	    break;	l = comp_readlink (path);	if (!l)	    break;	if (l[0] == '/') {/* absolute symlink */	    t = comp_tize (l);	    path = comp_replace (path, t);	    path = comp_strip (path);	    continue;	} else if (*l) {/* relative symlink */	    t = comp_tize (l);	    path = comp_insert (path, t);	    path = comp_strip (path);	    continue;	} else if (path->prev) {/* not a symlink */	    path = path->prev;	    continue;	}	break;    }    return path;}extern char *home_dir;#ifdef HAVE_MADchar *mad_pathdup (char *p, char *file, int line)#elsechar *pathdup (char *p)#endif{    struct comp *s;    s = comp_tize (p);    if (!strcmp (comp_first (s)->name, "~")) {	s = comp_replace (comp_first (s), comp_tize (home_dir));    } else if (*p != '/') {	char *cwd;	cwd = malloc (2048);#ifdef HAVE_GETCWD	getcwd (cwd, 2047);#else	getwd (cwd);#endif	s = comp_cat (comp_tize (cwd), comp_tize (p));	free (cwd);    }    s = resolve_symlink (s);#ifdef HAVE_MAD    p = mad_comp_combine (comp_last (s), file, line);#else    p = comp_combine (comp_last (s));#endif    comp_free (s);    return p;}#if 0int main (int argc, char **argv){    printf ("%s\n", pathdup (argv[1]));    return 0;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -