pathsub.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 303 行

C
303
字号
/*  * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is the Netscape security libraries. *  * The Initial Developer of the Original Code is Netscape * Communications Corporation.  Portions created by Netscape are  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All * Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable  * instead of those above.  If you wish to allow use of your  * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL.  If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. *//*** Pathname subroutines.*/#include <assert.h>#ifdef FREEBSD#include <sys/types.h>#endif /* FREEBSD */#include <dirent.h>#include <errno.h>#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include "pathsub.h"#ifdef USE_REENTRANT_LIBC#include "libc_r.h"#endif /* USE_REENTRANT_LIBC */char *program;voidfail(char *format, ...){    int error;    va_list ap;#ifdef USE_REENTRANT_LIBC    R_STRERROR_INIT_R();#endif    error = errno;    fprintf(stderr, "%s: ", program);    va_start(ap, format);    vfprintf(stderr, format, ap);    va_end(ap);    if (error)#ifdef USE_REENTRANT_LIBC    R_STRERROR_R(errno);	fprintf(stderr, ": %s", r_strerror_r);#else	fprintf(stderr, ": %s", strerror(errno));#endif    putc('\n', stderr);    abort();    exit(1);}char *getcomponent(char *path, char *name){    if (*path == '\0')	return 0;    if (*path == '/') {	*name++ = '/';    } else {	do {	    *name++ = *path++;	} while (*path != '/' && *path != '\0');    }    *name = '\0';    while (*path == '/')	path++;    return path;}#ifdef UNIXWARE/* The static buffer in Unixware's readdir is too small. */struct dirent * readdir(DIR *d){    static struct dirent *buf = NULL;#define MAX_PATH_LEN 1024    if (buf == NULL)	buf = (struct dirent *)xmalloc(sizeof(struct dirent) + MAX_PATH_LEN) ;    return readdir_r(d, buf);}#endif/* APPARENT BUG - ignores argument "dir", uses ".." instead. */char *ino2name(ino_t ino, char *dir){    DIR *dp;    struct dirent *ep;    char *name;    dp = opendir("..");		/* XXX */    if (!dp)	fail("cannot read parent directory");    for (;;) {	if (!(ep = readdir(dp)))	    fail("cannot find current directory");	if (ep->d_ino == ino)	    break;    }    name = xstrdup(ep->d_name);    closedir(dp);    return name;}void *xmalloc(size_t size){    void *p;    if (size <= 0)	fail("attempted to allocate %u bytes", size);    p = malloc(size);    if (!p)	fail("cannot allocate %u bytes", size);    return p;}char *xstrdup(char *s){    if (!s || !s[0]) 	fail("Null pointer or empty string passed to xstrdup()");    return strcpy((char*)xmalloc(strlen(s) + 1), s);}char *xbasename(char *path){    char *cp;    if (!path || !path[0]) 	fail("Null pointer or empty string passed to xbasename()");    while ((cp = strrchr(path, '/')) && cp[1] == '\0')	*cp = '\0';    if (!cp) return path;    return cp + 1;}voidxchdir(char *dir){    if (!dir || !dir[0]) 	fail("Null pointer or empty string passed to xchdir()");    if (chdir(dir) < 0)	fail("cannot change directory to %s", dir);}intrelatepaths(char *from, char *to, char *outpath){    char *cp, *cp2;    int len;    char buf[NAME_MAX];    assert(*from == '/' && *to == '/');    if (!from || *from != '/')	fail("relatepaths: from path does not start with /");    if (!to || *to != '/')	fail("relatepaths: to   path does not start with /");    for (cp = to, cp2 = from; *cp == *cp2; cp++, cp2++)	if (*cp == '\0')	    break;    while (cp[-1] != '/')	cp--, cp2--;    if (cp - 1 == to) {	/* closest common ancestor is /, so use full pathname */	len = strlen(strcpy(outpath, to));	if (outpath[len] != '/') {	    outpath[len++] = '/';	    outpath[len] = '\0';	}    } else {	len = 0;	while ((cp2 = getcomponent(cp2, buf)) != 0) {	    strcpy(outpath + len, "../");	    len += 3;	}	while ((cp = getcomponent(cp, buf)) != 0) {	    sprintf(outpath + len, "%s/", buf);	    len += strlen(outpath + len);	}    }    return len;}voidreversepath(char *inpath, char *name, int len, char *outpath){    char *cp, *cp2;    char buf[NAME_MAX];    struct stat sb;    cp = strcpy(outpath + PATH_MAX - (len + 1), name);    cp2 = inpath;    while ((cp2 = getcomponent(cp2, buf)) != 0) {	if (strcmp(buf, ".") == 0)	    continue;	if (strcmp(buf, "..") == 0) {	    if (stat(".", &sb) < 0)		fail("cannot stat current directory");	    name = ino2name(sb.st_ino, "..");	    len = strlen(name);	    cp -= len + 1;	    strcpy(cp, name);	    cp[len] = '/';	    free(name);	    xchdir("..");	} else {	    cp -= 3;	    strncpy(cp, "../", 3);	    xchdir(buf);	}    }    strcpy(outpath, cp);}voiddiagnosePath(const char * path){    char *	myPath;    char *      slash;    int		rv;    struct stat sb;    char 	buf[BUFSIZ];    if (!path || !path[0]) 	fail("Null pointer or empty string passed to mkdirs()");    myPath = strdup(path);    if (!myPath)	fail("strdup() failed!");    do {    	rv = lstat(myPath, &sb);	if (rv < 0) {	    perror(myPath);	} else if (S_ISLNK(sb.st_mode)) {	    rv = readlink(myPath, buf, sizeof buf);	    if (rv < 0) {	    	perror("readlink");		buf[0] = 0;	    } else {	    	buf[rv] = 0;	    }	    fprintf(stderr, "%s is a link to %s\n", myPath, buf);	} else if (S_ISDIR(sb.st_mode)) {	    fprintf(stderr, "%s is a directory\n", myPath);	    rv = access(myPath, X_OK);	    if (rv < 0) {	    	fprintf(stderr, "%s: no search permission\n", myPath);	    }	} else {	    fprintf(stderr, "%s is a file !?!\n", myPath);	    rv = access(myPath, F_OK);	    if (rv < 0) {	    	fprintf(stderr, "%s does not exist\n", myPath);	    }	}	/* chop path off one level. */	slash = strrchr(myPath, '/');	if (!slash)	    slash = strrchr(myPath, '\\');	if (!slash)	    slash = myPath;	*slash = 0;    } while (myPath[0]);    free(myPath);}

⌨️ 快捷键说明

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