コード例 #1
0
ファイル: Matcher.cpp プロジェクト: sdasgup3/llvm-slicer
bool endswith(const char *path1, const char *path2)
{
  if (canonpath(path1, PBUF)) {
    int len1 = strlen(PBUF);
    int len2 = strlen(path2);
    if (len1 < len2)
      return false;
    int i = len1 - len2;
    int j = 0;
    if (PBUF[0] == '/' && i > 0 && path2[j] != '/' && PBUF[i - 1] != '/') {
      // A: /tmp/atest.c
      // B: test.c
      return false;
    }
    while (i < len1 && j < len2 && PBUF[i] == path2[j]) {
      i++;
      j++;
    }
    if (i != len1) {
      return false;
    }
    return true;
  }
  else
    return false;
}
コード例 #2
0
ファイル: readlink.c プロジェクト: Nils-TUD/Escape
int main(int argc,char *argv[]) {
	bool follow = false;

	int opt;
	while((opt = getopt(argc,argv,"f")) != -1) {
		switch(opt) {
			case 'f': follow = true; break;
			default:
				usage(argv[0]);
		}
	}
	if(optind >= argc)
		usage(argv[0]);

	for(int i = optind; i < argc; ++i) {
		char tmp[MAX_PATH_LEN];
		if(follow) {
			if(canonpath(tmp,sizeof(tmp),argv[i]) < 0) {
				printe("readlink for '%s' failed",argv[i]);
				continue;
			}
			puts(tmp);
		}
		else {
			if(!islink(argv[i]))
				printe("'%s' is no symbolic link",argv[i]);
			else if(readlink(argv[i],tmp,sizeof(tmp)) < 0)
				printe("readlink for '%s' failed",argv[i]);
			else
				puts(tmp);
		}
	}
	return EXIT_SUCCESS;
}
コード例 #3
0
ファイル: Matcher.cpp プロジェクト: sdasgup3/llvm-slicer
bool pathneq(const char *path1, const char *path2, int n)
{
    if (canonpath(path1, PBUF)) {
        return strcmp(stripname(PBUF, n), path2) == 0;
    }
    else
        return false;
}
コード例 #4
0
ファイル: path.c プロジェクト: luckyzhylu/emacs-config
/**
 * realpath: get the complete path
 */
char *
realpath(const char *in_path, char *out_path)
{
#ifdef __DJGPP__
	/*
	 * I don't use _fixpath or _truename in LFN because neither guarantee
	 * a complete long name. This is mainly DOS's fault, since the cwd can
	 * be a mixture of long and short components.
	 */
	if (_USE_LFN) {
		strlimcpy(out_path, in_path, MAXPATHLEN);
		canonpath(out_path);
	} else
		_fixpath(in_path, out_path);
#else
	_fullpath(out_path, in_path, MAXPATHLEN);
	canonpath(out_path);
#endif
	return out_path;
}
コード例 #5
0
ファイル: Matcher.cpp プロジェクト: sdasgup3/llvm-slicer
bool Matcher::initName(StringRef fname)
{
  char *canon = canonpath(fname.data(), NULL);  
  if (canon == NULL) {
    errs() << "Warning: patchname is NULL\n";
    return false;
  }
  filename.assign(canon);
  free(canon);
  patchname = stripname(filename.c_str(), patchstrips);
  if (strlen(patchname) == 0) {
    errs() << "Warning: patchname is empty after strip\n";
    return false;
  }
  return true;
}
コード例 #6
0
ファイル: relative-path.c プロジェクト: MarkSymsCtx/blktap
/*
 * return a relative path from @from to @to
 * result should be freed
 */
char *
relative_path_to(char *from, char *to, int *err)
{
	int from_nodes, common;
	char *to_absolute, __to_absolute[PATH_MAX];
	char *from_absolute, __from_absolute[PATH_MAX];
	char *up, *common_target_path, *relative_path;

	*err          = 0;
	up            = NULL;
	to_absolute   = NULL;
	from_absolute = NULL;
	relative_path = NULL;

	if (strnlen(to, MAX_NAME_LEN)   == MAX_NAME_LEN ||
	    strnlen(from, MAX_NAME_LEN) == MAX_NAME_LEN) {
		EPRINTF("invalid input; max path length is %d\n",
			MAX_NAME_LEN);
		*err = -ENAMETOOLONG;
		return NULL;
	}

	to_absolute = canonpath(to, __to_absolute);
	if (!to_absolute) {
		EPRINTF("failed to get absolute path of %s\n", to);
		*err = -errno;
		goto out;
	}

	from_absolute = canonpath(from, __from_absolute);
	if (!from_absolute) {
		EPRINTF("failed to get absolute path of %s\n", from);
		*err = -errno;
		goto out;
	}

	if (strnlen(to_absolute, MAX_NAME_LEN)   == MAX_NAME_LEN ||
	    strnlen(from_absolute, MAX_NAME_LEN) == MAX_NAME_LEN) {
		EPRINTF("invalid input; max path length is %d\n",
			MAX_NAME_LEN);
		*err = -ENAMETOOLONG;
		goto out;
	}

	/* count nodes in source path */
	from_nodes = count_nodes(from_absolute);

	/* count nodes in common */
	common = count_common_nodes(to_absolute + 1, from_absolute + 1);
	if (common < 0) {
		EPRINTF("failed to count common nodes of %s and %s: %d\n",
			to_absolute, from_absolute, common);
		*err = common;
		goto out;
	}

	/* move up to common node */
	up = up_nodes(from_nodes - common - 1);
	if (!up) {
		EPRINTF("failed to allocate relative path for %s: %d\n",
			from_absolute, -ENOMEM);
		*err = -ENOMEM;
		goto out;
	}

	/* get path from common node to target */
	common_target_path = node_offset(to_absolute, common + 1);
	if (!common_target_path) {
		EPRINTF("failed to find common target path to %s: %d\n",
			to_absolute, -EINVAL);
		*err = -EINVAL;
		goto out;
	}

	/* get relative path */
	if (asprintf(&relative_path, "%s%s", up, common_target_path) == -1) {
		EPRINTF("failed to construct final path %s%s: %d\n",
			up, common_target_path, -ENOMEM);
		relative_path = NULL;
		*err = -ENOMEM;
		goto out;
	}

out:
	sfree(up);

	return relative_path;
}
コード例 #7
0
ファイル: kern_pledge.c プロジェクト: mosconi/openbsd
/*
 * Need to make it more obvious that one cannot get through here
 * without the right flags set
 */
int
pledge_namei(struct proc *p, struct nameidata *ni, char *origpath)
{
	char path[PATH_MAX];
	int error;

	if ((p->p_p->ps_flags & PS_PLEDGE) == 0 ||
	    (p->p_p->ps_flags & PS_COREDUMP))
		return (0);

	if (!ni || (ni->ni_pledge == 0))
		panic("ni_pledge");

	/* Doing a permitted execve() */
	if ((ni->ni_pledge & PLEDGE_EXEC) &&
	    (p->p_p->ps_pledge & PLEDGE_EXEC))
		return (0);

	error = canonpath(origpath, path, sizeof(path));
	if (error)
		return (error);

	/* Detect what looks like a mkstemp(3) family operation */
	if ((p->p_p->ps_pledge & PLEDGE_TMPPATH) &&
	    (p->p_pledge_syscall == SYS_open) &&
	    (ni->ni_pledge & PLEDGE_CPATH) &&
	    strncmp(path, "/tmp/", sizeof("/tmp/") - 1) == 0) {
		return (0);
	}

	/* Allow unlinking of a mkstemp(3) file...
	 * Good opportunity for strict checks here.
	 */
	if ((p->p_p->ps_pledge & PLEDGE_TMPPATH) &&
	    (p->p_pledge_syscall == SYS_unlink) &&
	    strncmp(path, "/tmp/", sizeof("/tmp/") - 1) == 0) {
		return (0);
	}

	/* Whitelisted paths */
	switch (p->p_pledge_syscall) {
	case SYS_access:
		/* tzset() needs this. */
		if ((ni->ni_pledge == PLEDGE_RPATH) &&
		    strcmp(path, "/etc/localtime") == 0)
			return (0);

		/* when avoiding YP mode, getpw* functions touch this */
		if (ni->ni_pledge == PLEDGE_RPATH &&
		    strcmp(path, "/var/run/ypbind.lock") == 0) {
			if (p->p_p->ps_pledge & PLEDGE_GETPW)
				return (0);
			else
				return (pledge_fail(p, error, PLEDGE_GETPW));
		}
		break;
	case SYS_open:
		/* daemon(3) or other such functions */
		if ((ni->ni_pledge & ~(PLEDGE_RPATH | PLEDGE_WPATH)) == 0 &&
		    strcmp(path, "/dev/null") == 0) {
			return (0);
		}

		/* readpassphrase(3), getpass(3) */
		if ((p->p_p->ps_pledge & PLEDGE_TTY) &&
		    (ni->ni_pledge & ~(PLEDGE_RPATH | PLEDGE_WPATH)) == 0 &&
		    strcmp(path, "/dev/tty") == 0) {
			return (0);
		}

		/* getpw* and friends need a few files */
		if ((ni->ni_pledge == PLEDGE_RPATH) &&
		    (p->p_p->ps_pledge & PLEDGE_GETPW)) {
			if (strcmp(path, "/etc/spwd.db") == 0)
				return (EPERM); /* don't call pledge_fail */
			if (strcmp(path, "/etc/pwd.db") == 0)
				return (0);
			if (strcmp(path, "/etc/group") == 0)
				return (0);
			if (strcmp(path, "/etc/netid") == 0)
				return (0);
		}

		/* DNS needs /etc/{resolv.conf,hosts,services}. */
		if ((ni->ni_pledge == PLEDGE_RPATH) &&
		    (p->p_p->ps_pledge & PLEDGE_DNS)) {
			if (strcmp(path, "/etc/resolv.conf") == 0)
				return (0);
			if (strcmp(path, "/etc/hosts") == 0)
				return (0);
			if (strcmp(path, "/etc/services") == 0)
				return (0);
		}

		if ((ni->ni_pledge == PLEDGE_RPATH) &&
		    (p->p_p->ps_pledge & PLEDGE_GETPW)) {
			if (strcmp(path, "/var/run/ypbind.lock") == 0) {
				/*
				 * XXX
				 * The current hack for YP support in "getpw"
				 * is to enable some "inet" features until
				 * next pledge call.  This is not considered
				 * worse than pre-pledge, but is a work in
				 * progress, needing a clever design.
				 */
				p->p_p->ps_pledge |= PLEDGE_YPACTIVE;
				return (0);
			}
			if (strncmp(path, "/var/yp/binding/",
			    sizeof("/var/yp/binding/") - 1) == 0)
				return (0);
		}

		/* tzset() needs these. */
		if ((ni->ni_pledge == PLEDGE_RPATH) &&
		    strncmp(path, "/usr/share/zoneinfo/",
		    sizeof("/usr/share/zoneinfo/") - 1) == 0)
			return (0);
		if ((ni->ni_pledge == PLEDGE_RPATH) &&
		    strcmp(path, "/etc/localtime") == 0)
			return (0);

		break;
	case SYS_readlink:
		/* Allow /etc/malloc.conf for malloc(3). */
		if ((ni->ni_pledge == PLEDGE_RPATH) &&
		    strcmp(path, "/etc/malloc.conf") == 0)
			return (0);
		break;
	case SYS_stat:
		/* DNS needs /etc/resolv.conf. */
		if ((ni->ni_pledge == PLEDGE_RPATH) &&
		    (p->p_p->ps_pledge & PLEDGE_DNS) &&
		    strcmp(path, "/etc/resolv.conf") == 0)
			return (0);
		break;
	}

	/*
	 * Ensure each flag of p_pledgenote has counterpart allowing it in
	 * ps_pledge
	 */
	if (ni->ni_pledge & ~p->p_p->ps_pledge)
		return (pledge_fail(p, EPERM, (ni->ni_pledge & ~p->p_p->ps_pledge)));

	return (0);
}
コード例 #8
0
ファイル: file.c プロジェクト: dptechnics/DPT-WoodBOX-SERV
/**
 * Given a url this functions tries to find the physical path on the server.
 * @cl the client that made the request
 * @url the requested URL
 * @return NULL on error
 */
static struct path_info *path_lookup(struct client *cl, const char *url)
{
	static char path_phys[PATH_MAX];
	static char path_info[PATH_MAX];
	static struct path_info p;

	int docroot_len = strlen(DOCUMENT_ROOT);
	char *pathptr = NULL;
	bool slash;

	int i = 0;
	int len;
	struct stat s;

	/* Return NULL when the URL is undefined */
	if (url == NULL)
		return NULL;

	memset(&p, 0, sizeof(p));
	path_phys[0] = 0;
	path_info[0] = 0;

	/* Start the canonical path with the document root */
	strcpy(uh_buf, DOCUMENT_ROOT);

	/* Separate query string from url */
	if ((pathptr = strchr(url, '?')) != NULL) {
		p.query = pathptr[1] ? pathptr + 1 : NULL;

		/* URL decode component without query */
		if (pathptr > url) {
			if (uh_urldecode(&uh_buf[docroot_len],
					 sizeof(uh_buf) - docroot_len - 1,
					 url, pathptr - url ) < 0)
				return NULL;

		}
	}

	/* Decode the full url when  there is no querystring */
	else if (uh_urldecode(&uh_buf[docroot_len],
			      sizeof(uh_buf) - docroot_len - 1,
			      url, strlen(url) ) < 0)
		return NULL;

	/* Create canonical path */
	len = strlen(uh_buf);
	slash = len && uh_buf[len - 1] == '/';
	len = min(len, sizeof(path_phys) - 1);

	for (i = len; i >= 0; i--) {
		char ch = uh_buf[i];
		bool exists;

		if (ch != 0 && ch != '/')
			continue;

		uh_buf[i] = 0;
		exists = !!canonpath(uh_buf, path_phys);
		uh_buf[i] = ch;

		if (!exists)
			continue;

		/* Test the current path */
		if (stat(path_phys, &p.stat))
			continue;

		snprintf(path_info, sizeof(path_info), "%s", uh_buf + i);
		break;
	}

	/* Check whether found path is within docroot */
	if (strncmp(path_phys, DOCUMENT_ROOT, docroot_len) != 0 ||
	    (path_phys[docroot_len] != 0 &&
	     path_phys[docroot_len] != '/')){
		return NULL;
	}

	/* Check if the found file is a regular file */
	if (p.stat.st_mode & S_IFREG) {
		p.root = DOCUMENT_ROOT;
		p.phys = path_phys;
		p.name = &path_phys[docroot_len];
		p.info = path_info[0] ? path_info : NULL;
		return &p;
	}

	/* Make sure it is not a directory */
	if (!(p.stat.st_mode & S_IFDIR)){
		return NULL;
	}

	if (path_info[0]){
	    return NULL;
	}

	pathptr = path_phys + strlen(path_phys);

	/* ensure trailing slash */
	if (pathptr[-1] != '/') {
		pathptr[0] = '/';
		pathptr[1] = 0;
		pathptr++;
	}

	/* if requested url resolves to a directory and a trailing slash
	   is missing in the request url, redirect the client to the same
	   url with trailing slash appended */
	if (!slash) {
		write_http_header(cl, 302, "Found");
		ustream_printf(cl->us, "Content-Length: 0\r\n");
		ustream_printf(cl->us, "Location: %s%s%s\r\n\r\n",
				&path_phys[docroot_len],
				p.query ? "?" : "",
				p.query ? p.query : "");
		request_done(cl);
		p.redirected = 1;
		return &p;
	}

	/* Check if the folder contains an index file */
	len = path_phys + sizeof(path_phys) - pathptr - 1;
	if(strlen(INDEX_FILE) <= len){

		strcpy(pathptr, INDEX_FILE);
		if (!stat(path_phys, &s) && (s.st_mode & S_IFREG)) {
			memcpy(&p.stat, &s, sizeof(p.stat));
		} else {
			/* Stop when strcpy is not needed */
			*pathptr = 0;
		}
	}

	p.root = DOCUMENT_ROOT;
	p.phys = path_phys;
	p.name = &path_phys[docroot_len];

	return p.phys ? &p : NULL;
}
コード例 #9
0
ファイル: vhd-util-snapshot.c プロジェクト: cywzl/blktap3
int
vhd_util_snapshot(int argc, char **argv)
{
	vhd_flag_creat_t flags;
	int c, err, prt_raw, limit, empty_check;
#ifdef XS_VHD
	uint8_t encrypt_method;
#endif
	char *name, *pname, *backing;
	char *ppath, __ppath[PATH_MAX];
	uint64_t size, msize;
	vhd_context_t vhd;

	name        = NULL;
	pname       = NULL;
	ppath       = NULL;
	backing     = NULL;
	size        = 0;
	msize       = 0;
	flags       = 0;
	limit       = 0;
	empty_check = 1;
#ifdef XS_VHD
	encrypt_method	= 0;
#endif

	if (!argc || !argv) {
		err = -EINVAL;
		goto usage;
	}

	optind = 0;
#ifndef XS_VHD
	while ((c = getopt(argc, argv, "n:p:S:l:meh")) != -1) {
#else
	while ((c = getopt(argc, argv, "n:p:S:E:l:meh")) != -1) {
#endif

		switch (c) {
		case 'n':
			name = optarg;
			break;
		case 'p':
			pname = optarg;
			break;
		case 'S':
			msize = strtoull(optarg, NULL, 10);
#ifdef XS_VHD
		case 'E':
			encrypt_method = atoi(optarg);
			break;
#endif
		case 'l':
			limit = strtol(optarg, NULL, 10);
			break;
		case 'm':
			vhd_flag_set(flags, VHD_FLAG_CREAT_PARENT_RAW);
			break;
		case 'e':
			empty_check = 0;
			break;
		case 'h':
			err = 0;
			goto usage;
		default:
			err = -EINVAL;
			goto usage;
		}
	}

	if (!name || !pname || optind != argc) {
		err = -EINVAL;
		goto usage;
	}

	ppath = canonpath(pname, __ppath);
	if (!ppath)
		return -errno;

	if (vhd_flag_test(flags, VHD_FLAG_CREAT_PARENT_RAW) || !empty_check) {
		backing = strdup(ppath);
		if (!backing) {
			err = -ENOMEM;
			goto out;
		}
	} else {
		err = vhd_util_find_snapshot_target(ppath, &backing, &prt_raw);
		if (err) {
			backing = NULL;
			goto out;
		}

		/* 
		 * if the sizes of the parent chain are non-uniform, we need to 
		 * pick the right size: that of the supplied parent
		 */
		if (strcmp(ppath, backing)) {
			err = vhd_open(&vhd, ppath, VHD_OPEN_RDONLY);
			if (err)
				goto out;
			size = vhd.footer.curr_size;
			vhd_close(&vhd);
		}

		if (prt_raw)
			vhd_flag_set(flags, VHD_FLAG_CREAT_PARENT_RAW);
	}

	if (limit && !vhd_flag_test(flags, VHD_FLAG_CREAT_PARENT_RAW)) {
		int depth;

		err = vhd_util_check_depth(backing, &depth);
		if (err)
			printf("error checking snapshot depth: %d\n", err);
		else if (depth + 1 > limit) {
			err = -ENOSPC;
			printf("snapshot depth exceeded: "
			       "current depth: %d, limit: %d\n", depth, limit);
		}

		if (err)
			goto out;
	}

#ifndef XS_VHD
	err = vhd_snapshot(name, size, backing, msize << 20, flags);
#else
	err = vhd_snapshot(name, size, backing, msize << 20, flags, encrypt_method);
#endif

out:
	free(backing);

	return err;

usage:
	printf("options: <-n name> <-p parent name> [-l snapshot depth limit]"
	       " [-m parent_is_raw] [-S size (MB) for metadata preallocation "
	       "(see vhd-util resize)] [-e link to supplied parent name even "
	       "if it's empty] [-h help]\n");
	return err;
}
コード例 #10
0
ファイル: tdir.c プロジェクト: Nils-TUD/Escape
static void test_canonpath(void) {
	char path[MAX_PATH_LEN];
	size_t count;

	test_caseStart("Testing canonpath");

	setenv("CWD","/");

	count = canonpath(path,sizeof(path),"/");
	test_assertUInt(count,SSTRLEN("/"));
	test_assertStr(path,"/");

	count = canonpath(path,sizeof(path),"/bin/ls");
	test_assertUInt(count,SSTRLEN("/bin/ls"));
	test_assertStr(path,"/bin/ls");

	count = canonpath(path,sizeof(path),"/../bin/../.././home");
	test_assertUInt(count,SSTRLEN("/home"));
	test_assertStr(path,"/home");

	count = canonpath(path,sizeof(path),"bin/..///.././home");
	test_assertUInt(count,SSTRLEN("/home"));
	test_assertStr(path,"/home");

	count = canonpath(path,sizeof(path),"bin/./ls");
	test_assertUInt(count,SSTRLEN("/bin/ls"));
	test_assertStr(path,"/bin/ls");

	setenv("CWD","/home");

	count = canonpath(path,sizeof(path),"hrniels/./scripts");
	test_assertUInt(count,SSTRLEN("/home/hrniels/scripts"));
	test_assertStr(path,"/home/hrniels/scripts");

	setenv("CWD","/home/");

	count = canonpath(path,sizeof(path),"hrniels/./scripts");
	test_assertUInt(count,SSTRLEN("/home/hrniels/scripts"));
	test_assertStr(path,"/home/hrniels/scripts");

	count = canonpath(path,sizeof(path),"..");
	test_assertUInt(count,SSTRLEN("/"));
	test_assertStr(path,"/");

	count = canonpath(path,sizeof(path),"../../.");
	test_assertUInt(count,SSTRLEN("/"));
	test_assertStr(path,"/");

	count = canonpath(path,sizeof(path),"./../bin");
	test_assertUInt(count,SSTRLEN("/bin"));
	test_assertStr(path,"/bin");

	count = canonpath(path,3,"/");
	if(count > 3)
		test_caseFailed("Copied too much");

	count = canonpath(path,8,"/bin/ls");
	if(count > 8)
		test_caseFailed("Copied too much");

	count = canonpath(path,8,"/bin/../home");
	if(count > 8)
		test_caseFailed("Copied too much");

	count = canonpath(path,8,"///../bin/ls");
	if(count > 8)
		test_caseFailed("Copied too much");

	test_caseSucceeded();
}
コード例 #11
0
ファイル: gtags.c プロジェクト: baohaojun/ajoke-global
int
main(int argc, char **argv)
{
	char dbpath[MAXPATHLEN];
	char cwd[MAXPATHLEN];
	STRBUF *sb = strbuf_open(0);
	int optchar;
	int option_index = 0;
	STATISTICS_TIME *tim;

	while ((optchar = getopt_long(argc, argv, "cd:f:iuIn:oOqvwse", long_options, &option_index)) != EOF) {
		switch (optchar) {
		case 0:
			/* already flags set */
			break;
		case OPT_CONFIG:
			show_config = 1;
			if (optarg)
				config_name = optarg;
			break;
		case OPT_GTAGSCONF:
			gtagsconf = optarg;
			break;
		case OPT_GTAGSLABEL:
			gtagslabel = optarg;
			break;
		case OPT_PATH:
			do_path = 1;
			if (!strcmp("absolute", optarg))
				convert_type = PATH_ABSOLUTE;
			else if (!strcmp("relative", optarg))
				convert_type = PATH_RELATIVE;
			else if (!strcmp("through", optarg))
				convert_type = PATH_THROUGH;
			else
				die("Unknown path type.");
			break;
		case OPT_SINGLE_UPDATE:
			iflag++;
			single_update = optarg;
			break;
		case OPT_ENCODE_PATH:
			if (strlen(optarg) > 255)
				die("too many encode chars.");
			if (strchr(optarg, '/') || strchr(optarg, '.'))
				die("cannot encode '/' and '.' in the path.");
			set_encode_chars((unsigned char *)optarg);
			break;
		case 'c':
			cflag++;
			break;
		case 'd':
			dump_target = optarg;
			break;
		case 'f':
			file_list = optarg;
			break;
		case 'i':
			iflag++;
			break;
		case 'u':
			uflag++;
			iflag++;
			break;
		case 'I':
			Iflag++;
			break;
		case 'o':
			/*
			 * Though the -o(--omit-gsyms) was removed, this code
			 * is left for compatibility.
			 */
			break;
		case 'O':
			Oflag++;
			break;
		case 'q':
			qflag++;
			setquiet();
			break;
		case 'w':
			wflag++;
			break;
		case 'v':
			vflag++;
			setverbose();
			break;
		default:
			usage();
			break;
		}
	}
	if (gtagsconf) {
		char path[MAXPATHLEN];

		if (realpath(gtagsconf, path) == NULL)
			die("%s not found.", gtagsconf);
		set_env("GTAGSCONF", path);
	}
	if (gtagslabel) {
		set_env("GTAGSLABEL", gtagslabel);
	}
	if (qflag)
		vflag = 0;
	if (show_version)
		version(NULL, vflag);
	if (show_help)
		help();

	argc -= optind;
        argv += optind;

	/* If dbpath is specified, -O(--objdir) option is ignored. */
	if (argc > 0)
		Oflag = 0;
	if (show_config) {
		if (config_name)
			printconf(config_name);
		else
			fprintf(stdout, "%s\n", getconfline());
		exit(0);
	} else if (do_path) {
		/*
		 * This is the main body of path filter.
		 * This code extract path name from tag line and
		 * replace it with the relative or the absolute path name.
		 *
		 * By default, if we are in src/ directory, the output
		 * should be converted like follws:
		 *
		 * main      10 ./src/main.c  main(argc, argv)\n
		 * main      22 ./libc/func.c   main(argc, argv)\n
		 *		v
		 * main      10 main.c  main(argc, argv)\n
		 * main      22 ../libc/func.c   main(argc, argv)\n
		 *
		 * Similarly, the --path=absolute option specified, then
		 *		v
		 * main      10 /prj/xxx/src/main.c  main(argc, argv)\n
		 * main      22 /prj/xxx/libc/func.c   main(argc, argv)\n
		 */
		STRBUF *ib = strbuf_open(MAXBUFLEN);
		CONVERT *cv;
		char *ctags_x;

		if (argc < 3)
			die("gtags --path: 3 arguments needed.");
		cv = convert_open(convert_type, FORMAT_CTAGS_X, argv[0], argv[1], argv[2], stdout);
		while ((ctags_x = strbuf_fgets(ib, stdin, STRBUF_NOCRLF)) != NULL)
			convert_put(cv, ctags_x);
		convert_close(cv);
		strbuf_close(ib);
		exit(0);
	} else if (dump_target) {
		/*
		 * Dump a tag file.
		 */
		DBOP *dbop = NULL;
		const char *dat = 0;
		int is_gpath = 0;

		char* target_file = NULL;
		if (!test("f", dump_target)) {
			target_file = strchr(dump_target, ':');
			if (target_file == NULL) 
				die("file '%s' not found", dump_target);

			*target_file++ = 0; //move to the next char, which starts the target file.
			if (!test("f", dump_target)) {
				die("file '%s' not found.", dump_target);
			}
		}

		if ((dbop = dbop_open(dump_target, 0, 0, DBOP_RAW)) == NULL)
			die("file '%s' is not a tag file.", dump_target);
		/*
		 * The file which has a NEXTKEY record is GPATH.
		 */
		if (dbop_get(dbop, NEXTKEY))
			is_gpath = 1;

		if (target_file && !is_gpath) {
			die("dump target_file can only be used with GPATH");
		}

		if (target_file) {
			dat = dbop_get(dbop, target_file);
			if (dat == NULL) {
				die("target_file %s not found in GPATH", target_file);
			}
			time_t t = gpath_mtime(dbop, target_file);
			printf("%d\n", t);
		} else {
			for (dat = dbop_first(dbop, NULL, NULL, 0); dat != NULL; dat = dbop_next(dbop)) {
				const char *flag = is_gpath ? dbop_getflag(dbop) : "";

				if (*flag)
					if (is_gpath) {
						time_t t = gpath_mtime(dbop, dbop->lastkey);
						printf("%s\t%s\t%s\t%s\n", dbop->lastkey, dat, flag, ctime(&t));
					} else
						printf("%s\t%s\t%s\n", dbop->lastkey, dat, flag);
				else
					printf("%s\t%s\n", dbop->lastkey, dat);
			}
		}
		dbop_close(dbop);
		exit(0);
	} else if (Iflag) {
		if (!usable("mkid"))
			die("mkid not found.");
	}

	/*
	 * If 'gtags.files' exists, use it as a file list.
	 * If the file_list other than "-" is given, it must be readable file.
	 */
	if (file_list == NULL && test("f", GTAGSFILES))
		file_list = GTAGSFILES;
	if (file_list && strcmp(file_list, "-")) {
		if (test("d", file_list))
			die("'%s' is a directory.", file_list);
		else if (!test("f", file_list))
			die("'%s' not found.", file_list);
		else if (!test("r", file_list))
			die("'%s' is not readable.", file_list);
	}
	/*
	 * Regularize the path name for single updating (--single-update).
	 */
	if (single_update) {
		static char regular_path_name[MAXPATHLEN];
		char *p = single_update;
		
		if (!test("f", p))
			die("'%s' not found.", p);
		if (isabspath(p))
			die("--single-update requires relative path name.");
		if (!(p[0] == '.' && p[1] == '/')) {
			snprintf(regular_path_name, MAXPATHLEN, "./%s", p);
			p = regular_path_name;
		}
		single_update = p;
	}
	if (!getcwd(cwd, MAXPATHLEN))
		die("cannot get current directory.");
	canonpath(cwd);
	/*
	 * Decide directory (dbpath) in which gtags make tag files.
	 *
	 * Gtags create tag files at current directory by default.
	 * If dbpath is specified as an argument then use it.
	 * If the -i option specified and both GTAGS and GRTAGS exists
	 * at one of the candidate directories then gtags use existing
	 * tag files.
	 */
	if (iflag) {
		if (argc > 0)
			realpath(*argv, dbpath);
		else if (!gtagsexist(cwd, dbpath, MAXPATHLEN, vflag))
			strlimcpy(dbpath, cwd, sizeof(dbpath));
	} else {
		if (argc > 0)
			realpath(*argv, dbpath);
		else if (Oflag) {
			char *objdir = getobjdir(cwd, vflag);

			if (objdir == NULL)
				die("Objdir not found.");
			strlimcpy(dbpath, objdir, sizeof(dbpath));
		} else
			strlimcpy(dbpath, cwd, sizeof(dbpath));
	}
	if (iflag && (!test("f", makepath(dbpath, dbname(GTAGS), NULL)) ||
		!test("f", makepath(dbpath, dbname(GRTAGS), NULL)) ||
		!test("f", makepath(dbpath, dbname(GPATH), NULL)))) {
		if (wflag)
			warning("GTAGS, GRTAGS or GPATH not found. -i option ignored.");
		iflag = 0;
	}
	if (!test("d", dbpath))
		die("directory '%s' not found.", dbpath);
	if (vflag)
		fprintf(stderr, "[%s] Gtags started.\n", now());
	/*
	 * load configuration file.
	 */
	openconf();
	if (getconfb("extractmethod"))
		extractmethod = 1;
	strbuf_reset(sb);
	if (getconfs("langmap", sb))
		langmap = check_strdup(strbuf_value(sb));
	strbuf_reset(sb);
	if (getconfs("gtags_parser", sb))
		gtags_parser = check_strdup(strbuf_value(sb));
	/*
	 * initialize parser.
	 */
	if (vflag && gtags_parser)
		fprintf(stderr, " Using plug-in parser.\n");
	parser_init(langmap, gtags_parser);
	if (vflag && file_list)
		fprintf(stderr, " Using '%s' as a file list.\n", file_list);
	/*
	 * Start statistics.
	 */
	init_statistics();
	/*
	 * incremental update.
	 */
	if (iflag) {
		/*
		 * Version check. If existing tag files are old enough
		 * gtagsopen() abort with error message.
		 */
		GTOP *gtop = gtags_open(dbpath, cwd, GTAGS, GTAGS_MODIFY, 0);
		gtags_close(gtop);
		/*
		 * GPATH is needed for incremental updating.
		 * Gtags check whether or not GPATH exist, since it may be
		 * removed by mistake.
		 */
		if (!test("f", makepath(dbpath, dbname(GPATH), NULL)))
			die("Old version tag file found. Please remake it.");
		(void)incremental(dbpath, cwd);
		print_statistics(statistics);
		exit(0);
	}
	/*
	 * create GTAGS and GRTAGS
	 */
	createtags(dbpath, cwd);
	/*
	 * create idutils index.
	 */
	if (Iflag) {
		tim = statistics_time_start("Time of creating ID");
		if (vflag)
			fprintf(stderr, "[%s] Creating indexes for idutils.\n", now());
		strbuf_reset(sb);
		strbuf_puts(sb, "mkid");
		if (vflag)
			strbuf_puts(sb, " -v");
		strbuf_sprintf(sb, " --file='%s/ID'", dbpath);
		if (vflag) {
#ifdef __DJGPP__
			if (is_unixy())	/* test for 4DOS as well? */
#endif
			strbuf_puts(sb, " 1>&2");
		} else {
			strbuf_puts(sb, " >/dev/null");
		}
		if (debug)
			fprintf(stderr, "executing mkid like: %s\n", strbuf_value(sb));
		if (system(strbuf_value(sb)))
			die("mkid failed: %s", strbuf_value(sb));
		if (chmod(makepath(dbpath, "ID", NULL), 0644) < 0)
			die("cannot chmod ID file.");
		statistics_time_end(tim);
	}
	if (vflag)
		fprintf(stderr, "[%s] Done.\n", now());
	closeconf();
	strbuf_close(sb);
	print_statistics(statistics);

	return 0;
}
コード例 #12
0
ファイル: gtags.c プロジェクト: lianhongHou/Emacs
int
main(int argc, char **argv)
{
    char dbpath[MAXPATHLEN];
    char cwd[MAXPATHLEN];
    STRBUF *sb = strbuf_open(0);
    int optchar;
    int option_index = 0;
    STATISTICS_TIME *tim;

    /*
     * Setup GTAGSCONF and GTAGSLABEL environment variable
     * according to the --gtagsconf and --gtagslabel option.
     */
    preparse_options(argc, argv);
    /*
     * Get the project root directory.
     */
    if (!vgetcwd(cwd, MAXPATHLEN))
        die("cannot get current directory.");
    canonpath(cwd);
    /*
     * Load configuration file.
     */
    openconf(cwd);
    configuration();
    setenv_from_config();
    {
        char *env = getenv("GTAGS_OPTIONS");
        if (env && *env)
            argv = prepend_options(&argc, argv, env);
    }
    logging_arguments(argc, argv);
    while ((optchar = getopt_long(argc, argv, "cd:f:iIn:oOqvwse", long_options, &option_index)) != EOF) {
        switch (optchar) {
        case 0:
            /* already flags set */
            break;
        case OPT_CONFIG:
            show_config = 1;
            if (optarg)
                config_name = optarg;
            break;
        case OPT_GTAGSCONF:
        case OPT_GTAGSLABEL:
            /* These options are already parsed in preparse_options() */
            break;
        case OPT_SINGLE_UPDATE:
            iflag++;
            single_update = optarg;
            break;
        case OPT_ACCEPT_DOTFILES:
            set_accept_dotfiles();
            break;
        case 'c':
            cflag++;
            break;
        case 'd':
            dump_target = optarg;
            break;
        case 'f':
            file_list = optarg;
            break;
        case 'i':
            iflag++;
            break;
        case 'I':
            Iflag++;
            break;
        case 'o':
            /*
             * Though the -o(--omit-gsyms) was removed, this code
             * is left for compatibility.
             */
            break;
        case 'O':
            Oflag++;
            break;
        case 'q':
            qflag++;
            setquiet();
            break;
        case 'w':
            wflag++;
            break;
        case 'v':
            vflag++;
            setverbose();
            break;
        default:
            usage();
            break;
        }
    }
    if (qflag)
        vflag = 0;
    if (show_version)
        version(NULL, vflag);
    if (show_help)
        help();

    argc -= optind;
    argv += optind;

    /* If dbpath is specified, -O(--objdir) option is ignored. */
    if (argc > 0)
        Oflag = 0;
    if (show_config) {
        openconf(setupdbpath(0) == 0 ? get_root() : NULL);
        if (config_name)
            printconf(config_name);
        else
            fprintf(stdout, "%s\n", getconfline());
        exit(0);
    } else if (dump_target) {
        /*
         * Dump a tag file.
         */
        DBOP *dbop = NULL;
        const char *dat = 0;
        int is_gpath = 0;

        if (!test("f", dump_target))
            die("file '%s' not found.", dump_target);
        if ((dbop = dbop_open(dump_target, 0, 0, DBOP_RAW)) == NULL)
            die("file '%s' is not a tag file.", dump_target);
        /*
         * The file which has a NEXTKEY record is GPATH.
         */
        if (dbop_get(dbop, NEXTKEY))
            is_gpath = 1;
        for (dat = dbop_first(dbop, NULL, NULL, 0); dat != NULL; dat = dbop_next(dbop)) {
            const char *flag = is_gpath ? dbop_getflag(dbop) : "";

            if (*flag)
                printf("%s\t%s\t%s\n", dbop->lastkey, dat, flag);
            else
                printf("%s\t%s\n", dbop->lastkey, dat);
        }
        dbop_close(dbop);
        exit(0);
    } else if (Iflag) {
#define REQUIRED_MKID_VERSION "4.5"
        char *p;

        if (!usable("mkid"))
            die("mkid not found.");
        if (read_first_line("mkid --version", sb))
            die("mkid cannot executed.");
        p = strrchr(strbuf_value(sb), ' ');
        if (p == NULL)
            die("invalid version string of mkid: %s", strbuf_value(sb));
        switch (check_version(p + 1, REQUIRED_MKID_VERSION)
#ifdef _WIN32
                || strcmp(p + 1, "3.2.99") == 0
#endif
               )  {
        case 1:
            break;	/* OK */
        case 0:
            die("mkid version %s or later is required.", REQUIRED_MKID_VERSION);
        default:
            die("invalid version string of mkid: %s", strbuf_value(sb));
        }
    }

    /*
     * If 'gtags.files' exists, use it as a file list.
     * If the file_list other than "-" is given, it must be readable file.
     */
    if (file_list == NULL && test("f", GTAGSFILES))
        file_list = GTAGSFILES;
    if (file_list && strcmp(file_list, "-")) {
        if (test("d", file_list))
            die("'%s' is a directory.", file_list);
        else if (!test("f", file_list))
            die("'%s' not found.", file_list);
        else if (!test("r", file_list))
            die("'%s' is not readable.", file_list);
    }
    /*
     * Regularize the path name for single updating (--single-update).
     */
    if (single_update) {
        static char regular_path_name[MAXPATHLEN];
        char *p = single_update;

        if (!test("f", p))
            die("'%s' not found.", p);
#if _WIN32 || __DJGPP__
        for (; *p; p++)
            if (*p == '\\')
                *p = '/';
        p = single_update;
#define LOCATEFLAG MATCH_AT_FIRST|IGNORE_CASE
#else
#define LOCATEFLAG MATCH_AT_FIRST
#endif
        if (isabspath(p)) {
            char *q = locatestring(p, cwd, LOCATEFLAG);

            if (q && *q == '/')
                snprintf(regular_path_name, MAXPATHLEN, "./%s", q + 1);
            else
                die("path '%s' is out of the project.", p);

        } else {
            if (p[0] == '.' && p[1] == '/')
                snprintf(regular_path_name, MAXPATHLEN, "%s", p);
            else
                snprintf(regular_path_name, MAXPATHLEN, "./%s", p);
        }
        single_update = regular_path_name;
    }
    /*
     * Decide directory (dbpath) in which gtags make tag files.
     *
     * Gtags create tag files at current directory by default.
     * If dbpath is specified as an argument then use it.
     * If the -i option specified and both GTAGS and GRTAGS exists
     * at one of the candidate directories then gtags use existing
     * tag files.
     */
    if (iflag) {
        if (argc > 0)
            realpath(*argv, dbpath);
        else if (!gtagsexist(cwd, dbpath, MAXPATHLEN, vflag))
            strlimcpy(dbpath, cwd, sizeof(dbpath));
    } else {
        if (argc > 0)
            realpath(*argv, dbpath);
        else if (Oflag) {
            char *objdir = getobjdir(cwd, vflag);

            if (objdir == NULL)
                die("Objdir not found.");
            strlimcpy(dbpath, objdir, sizeof(dbpath));
        } else
            strlimcpy(dbpath, cwd, sizeof(dbpath));
    }
    if (iflag && (!test("f", makepath(dbpath, dbname(GTAGS), NULL)) ||
                  !test("f", makepath(dbpath, dbname(GRTAGS), NULL)) ||
                  !test("f", makepath(dbpath, dbname(GPATH), NULL)))) {
        if (wflag)
            warning("GTAGS, GRTAGS or GPATH not found. -i option ignored.");
        iflag = 0;
    }
    if (!test("d", dbpath))
        die("directory '%s' not found.", dbpath);
    if (vflag)
        fprintf(stderr, "[%s] Gtags started.\n", now());
    /*
     * initialize parser.
     */
    if (vflag && gtags_parser)
        fprintf(stderr, " Using plug-in parser.\n");
    parser_init(langmap, gtags_parser);
    if (vflag && file_list)
        fprintf(stderr, " Using '%s' as a file list.\n", file_list);
    /*
     * Start statistics.
     */
    init_statistics();
    /*
     * incremental update.
     */
    if (iflag) {
        /*
         * Version check. If existing tag files are old enough
         * gtagsopen() abort with error message.
         */
        GTOP *gtop = gtags_open(dbpath, cwd, GTAGS, GTAGS_MODIFY, 0);
        gtags_close(gtop);
        /*
         * GPATH is needed for incremental updating.
         * Gtags check whether or not GPATH exist, since it may be
         * removed by mistake.
         */
        if (!test("f", makepath(dbpath, dbname(GPATH), NULL)))
            die("Old version tag file found. Please remake it.");
        (void)incremental(dbpath, cwd);
        print_statistics(statistics);
        exit(0);
    }
    /*
     * create GTAGS and GRTAGS
     */
    createtags(dbpath, cwd);
    /*
     * create idutils index.
     */
    if (Iflag) {
        FILE *op;
        GFIND *gp;
        const char *path;

        tim = statistics_time_start("Time of creating ID");
        if (vflag)
            fprintf(stderr, "[%s] Creating indexes for idutils.\n", now());
        strbuf_reset(sb);
        /*
         * Since idutils stores the value of PWD in ID file, we need to
         * force idutils to follow our style.
         */
#if _WIN32 || __DJGPP__
        strbuf_puts(sb, "mkid --files0-from=-");
#else
        strbuf_sprintf(sb, "PWD=%s mkid --files0-from=-", quote_shell(cwd));
#endif
        if (vflag)
            strbuf_puts(sb, " -v");
        strbuf_sprintf(sb, " --file=%s/ID", quote_shell(dbpath));
        if (vflag) {
#ifdef __DJGPP__
            if (is_unixy())	/* test for 4DOS as well? */
#endif
                strbuf_puts(sb, " 1>&2");
        } else {
            strbuf_puts(sb, " >" NULL_DEVICE);
#ifdef __DJGPP__
            if (is_unixy())	/* test for 4DOS as well? */
#endif
                strbuf_puts(sb, " 2>&1");
        }
        if (debug)
            fprintf(stderr, "executing mkid like: %s\n", strbuf_value(sb));
        op = popen(strbuf_value(sb), "w");
        if (op == NULL)
            die("cannot execute '%s'.", strbuf_value(sb));
        gp = gfind_open(dbpath, NULL, GPATH_BOTH);
        while ((path = gfind_read(gp)) != NULL) {
            fputs(path, op);
            fputc('\0', op);
        }
        gfind_close(gp);
        if (pclose(op) != 0)
            die("terminated abnormally '%s' (errno = %d).", strbuf_value(sb), errno);
        if (test("f", makepath(dbpath, "ID", NULL)))
            if (chmod(makepath(dbpath, "ID", NULL), 0644) < 0)
                die("cannot chmod ID file.");
        statistics_time_end(tim);
    }
    if (vflag)
        fprintf(stderr, "[%s] Done.\n", now());
    closeconf();
    strbuf_close(sb);
    print_statistics(statistics);

    return 0;
}