Example #1
0
char* realpath(const char* file, char* dest) {
  int fd=open(".",O_RDONLY);	/* save directory */
  char* res=myrealpath(file,dest,31);
  fchdir(fd);
  close(fd);
  return res;
}
Example #2
0
char *
canonicalize_path(const char *path)
{
    char *canonical;
    char *p;

    if (path == NULL)
        return NULL;

    canonical = malloc(PATH_MAX+2);
    if (!canonical)
        return NULL;
    if (!myrealpath(path, canonical, PATH_MAX+1))
    {
        free(canonical);
        return strdup(path);
    }


    p = strrchr(canonical, '/');
    if (p && strncmp(p, "/dm-", 4) == 0 && isdigit(*(p + 4)))
    {
        p = canonicalize_dm_name(p+1);
        if (p)
        {
            free(canonical);
            return p;
        }
    }

    return canonical;
}
Example #3
0
char *
canonicalize_path(const char *path)
{
	char canonical[PATH_MAX+2];
	char *p;

	if (path == NULL)
		return NULL;

	if (!myrealpath(path, canonical, PATH_MAX+1)) {
		char *res = strdup(path);
		if (res) {
			p = strrchr(res, '/');
			/* delete trailing slash */
			if (p && p > res && *(p + 1) == '\0')
				*p = '\0';
		}
		return res;
	}

	p = strrchr(canonical, '/');
	if (p && strncmp(p, "/dm-", 4) == 0 && isdigit(*(p + 4))) {
		p = canonicalize_dm_name(p+1);
		if (p)
			return p;
	}

	return strdup(canonical);
}
Example #4
0
void set_cmdfile_history_file(int linenr, char *cmd, char *par)
{
    if (par[0] == 0x00)
    {
        cmdfile_h.history_file = NULL;
        cmdfile_h.history_size = 0;
    }
    else
    {
        cmdfile_h.history_file = myrealpath(par);
    }
}
Example #5
0
void set_searchhistory_file(int linenr, char *cmd, char *par)
{
    if (par[0] == 0x00)
    {
        search_h.history_file = NULL;
        search_h.history_size = 0;
    }
    else
    {
        search_h.history_file = myrealpath(par);
    }
}
Example #6
0
int nilfs_cleaner_reload(struct nilfs_cleaner *cleaner, const char *conffile)
{
	struct nilfs_cleaner_request_with_path req;
	struct nilfs_cleaner_response res;
	size_t pathlen, reqsz;
	int bytes, ret = -1;

	if (cleaner->sendq < 0 || cleaner->recvq < 0) {
		errno = EBADF;
		goto out;
	}
	if (nilfs_cleaner_clear_queueu(cleaner) < 0)
		goto out;

	if (conffile) {
		if (myrealpath(conffile, req.pathname,
			       NILFS_CLEANER_MSG_MAX_PATH) == NULL)
			goto out;

		pathlen = strlen(req.pathname);
		req.hdr.argsize = pathlen + 1;
		reqsz = sizeof(req.hdr) + pathlen + 1;
	} else {
		req.hdr.argsize = 0;
		reqsz = sizeof(req.hdr);
	}
	req.hdr.cmd = NILFS_CLEANER_CMD_RELOAD;
	uuid_copy(req.hdr.client_uuid, cleaner->client_uuid);

	ret = mq_send(cleaner->sendq, (char *)&req, reqsz,
		      NILFS_CLEANER_PRIO_NORMAL);
	if (ret < 0)
		goto out;

	bytes = mq_receive(cleaner->recvq, (char *)&res, sizeof(res), NULL);
	if (bytes < sizeof(res)) {
		if (bytes >= 0)
			errno = EIO;
		ret = -1;
		goto out;
	}
	if (res.result == NILFS_CLEANER_RSP_NACK) {
		ret = -1;
		errno = res.err;
	}
out:
	return ret;
}
Example #7
0
static int
is_in_proc_swaps(const char *fname) {
	int i;
	char canonical[PATH_MAX + 2];

	if (!myrealpath(fname, canonical, PATH_MAX + 1)) {
		fprintf(stderr, _("%s: cannot canonicalize %s: %s\n"),
			progname, fname, strerror(errno));
		strncpy(canonical, fname, PATH_MAX + 1);
		*(canonical + (PATH_MAX + 1)) = '\0';
	}

	for (i = 0; i < numSwaps; i++)
		if (swapFiles[i] && !strcmp(canonical, swapFiles[i]))
			return 1;
	return 0;
}
Example #8
0
char *canonicalize_path(const char *path)
{
	char canonical[PATH_MAX+2];
	char *p;

	if (path == NULL)
		return NULL;

	if (!myrealpath(path, canonical, PATH_MAX+1))
		return strdup(path);


	p = strrchr(canonical, '/');
	if (p && strncmp(p, "/dm-", 4) == 0 && isdigit(*(p + 4))) {
		p = canonicalize_dm_name(p+1);
		if (p)
			return p;
	}

	return strdup(canonical);
}
Example #9
0
/*
 * "Resolve" a pathname.
 *
 * Makes sure that 'path' falls within the 'dir' after application of
 * realpath to resolve "..", symlinks, etc. If 'create' is set, it will
 * create missing intermediate directories. In detail:
 *
 * The path (and dir) must be absolute, or it is an error.
 * If 'create' is zero, then all components of the path must exist
 *   or it is an error.
 * If 'create' is non-zero, then missing components except the last
 *   will be created.
 * If 'dir' is non-null, the existing part of the path must resolve
 *   within this directory or it is an error.
 * If 'dir' is null, then the path is resolved as far as it exists
 *  ('create' is ignored and assumed to be zero).
 *   
 * Returns NULL on an error, a malloc'ed pointer to a canonicalized
 * path otherwise.
 */
char *
resolvepath(char *path, char *dir, int create)
{
	char rpath[PATH_MAX], *next, *ep, *pathcopy;
	struct stat sb;
	int pathlen = strlen(path);
	int dirlen = 0;
	int rpathlen;
	mode_t omask, cmask;
	char *npath;

	if (debug > 1)
		info("resolvepath '%s' in dir '%s'", path, dir);
	/* validate path */
	if (path == NULL) {
		if (debug > 1)
			info(" null path");
		return NULL;
	}
	if (path[0] != '/') {
		if (debug > 1)
			info(" path is not absolute");
		return NULL;
	}
	if (pathlen >= sizeof rpath) {
		if (debug > 1)
			info(" path is too long");
		return NULL;
	}

	/* validate dir */
	if (dir) {
		dirlen = strlen(dir);
		if (dir[0] != '/') {
			if (debug > 1)
				info(" path and dir (%s) must be absolute",
				     dir);
			return NULL;
		}
		/* XXX make dir=='/' work */
		if (dirlen == 1)
			dirlen = 0;
	} else {
		create = 0;
	}

	/*
	 * If the full path resolves, make sure it falls in dir (if given)
	 * and is a regular file.
	 */
	if (myrealpath(path, rpath) != NULL) {
		if (dir && !INDIR(dir, dirlen, rpath)) {
			if (debug > 1)
				info(" resolved path (%s) not in dir (%s)",
				     rpath, dir);
			return NULL;
		}
		if (stat(rpath, &sb) < 0 || !S_ISREG(sb.st_mode)) {
			if (debug > 1)
				info(" not a regular file");
			return NULL;
		}
		return strdup(rpath);
	}
	if (debug > 1) {
		int oerrno = errno;
		info(" partially resolved to '%s' (errno %d)", rpath, errno);
		errno = oerrno;
	}

	/*
	 * If create is not set or we failed for any reason other than
	 * a non-existent component, we return an error.
	 */
	if (!create || errno != ENOENT) {
		if (debug > 1)
			info(" realpath failed at %s with %d",
			     rpath, errno);
		return NULL;
	}

	/*
	 * Need to create intermediate directories.
	 *
	 * First, check that what does exist of the path falls within
	 * the directory given.
	 */
	assert(dir != NULL);
	if (!INDIR(dir, dirlen, rpath)) {
		if (debug > 1)
			info(" resolved path (%s) not in dir (%s)",
			     rpath, dir);
		return NULL;
	}

	/*
	 * Establish permission (mode) for new directories.
	 * Start with permission of 'dir'; this will get updated with
	 * every component that resolves, so that new directories will
	 * get created with the permission of the most recent ancestor.
	 */
	if (stat(dir, &sb) < 0) {
		if (debug > 1)
			info(" stat failed on dir (%s)?!", dir);
		return NULL;
	}
	cmask = (sb.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IRWXU;
	omask = umask(0);
	if (debug > 1)
		info(" umask=0 (was 0%o), initial cmask=0%o", omask, cmask);

	/*
	 * Find the first component of the original path that does not
	 * exist (i.e., what part of the original path maps to what realpath
	 * returned) and create everything from there on.
	 *
	 * Note that if what realpath returned is a prefix of the original
	 * path then nothing was translated and we are already at the first
	 * component that needs creation. So we find the appropriate location
	 * in the original string and go from there.
	 */
	npath = NULL;
	if ((pathcopy = strdup(path)) == NULL)
		goto done;
	rpathlen = strlen(rpath);
	assert(rpathlen <= pathlen);
	if (rpathlen > 1 && strncmp(pathcopy, rpath, rpathlen) == 0 &&
	    (pathcopy[rpathlen] == '\0' || pathcopy[rpathlen] == '/')) {
		/* same string, start at last slash in path */
		if (pathcopy[rpathlen] == '\0') {
			next = rindex(pathcopy, '/');
			assert(next != NULL);
		}
		/* rpath is a prefix, start at last slash in that prefix */
		else {
			next = rindex(rpath, '/');
			assert(next != NULL);
			next = &pathcopy[next-rpath];
		}
	}
	/* rpath is not a prefix, must scan entire path */
	else {
		next = pathcopy;
	}
	assert(next >= pathcopy && next < &pathcopy[pathlen]);
	assert(*next == '/');
	next++;
	if (debug > 1)
		info(" pathscan: path='%s', rpath='%s', start at '%s'",
		     pathcopy, rpath, next);

	while ((ep = index(next, '/')) != NULL) {
		*ep = '\0';
		if (debug > 1)
			info(" testing: %s", pathcopy);

		/*
		 * We use realpath here instead of just stat to make
		 * sure someone isn't actively tweaking the filesystem
		 * and messing with our head.
		 *
		 * If realpath fails, it should fail with ENOENT and
		 * the realpath-ified part should fall in our directory.
		 * Otherwise, someone really is playing games.
		 */
		if (myrealpath(pathcopy, rpath) == NULL) {
			if (errno != ENOENT ||
			    (dir && !INDIR(dir, dirlen, rpath))) {
				if (debug > 1)
					info("  resolves bad (%s)\n",
					     rpath);
				goto done;
			}
			/*
			 * We have hit a missing component.
			 * Create the component and carry on.
			 */
			if (mkdir(rpath, cmask) < 0) {
				if (debug > 1)
					info("  create failed (%s)\n",
					     rpath);
				goto done;
			}
			if (debug > 1)
				info("  created (%s)", rpath);
		} else {
			if (debug > 1)
				info("  exists (%s)", rpath);
			/*
			 * Update the creation permission; see comment above.
			 */
			if (stat(rpath, &sb) < 0) {
				if (debug > 1)
					info(" stat failed (%s)?!", rpath);
				goto done;
			}
			cmask = (sb.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) |
				S_IRWXU;
		}
		*ep = '/';
		next = ep+1;
	}

	/*
	 * We are down to the final component of the original path.
	 * It should either exist and be a regular file or not
	 * exist at all.
	 */
	if (myrealpath(pathcopy, rpath) == NULL &&
	    (errno != ENOENT || !INDIR(dir, dirlen, rpath))) {
		if (debug > 1)
			info(" final resolved path (%s) bad (%d)",
			     rpath, errno);
		goto done;
	}

	/*
	 * We are in our happy place. rpath is the canonicalized path.
	 */
	npath = strdup(rpath);
	if (debug > 1)
		info("resolvepath: '%s' resolved to '%s'", path, npath);

 done:
	umask(omask);
	if (pathcopy)
		free(pathcopy);
	return npath;
}
Example #10
0
int
main (int argc, char ** argv)
{
  char * result;
  int fd, i, errors = 0;
  char buf[PATH_MAX];

  getcwd (cwd, sizeof(buf));
  cwd_len = strlen (cwd);

/* this segfaults with dietlibc 
man page documents:
  EINVAL Either path or resolved_path is NULL. (In libc5 this would  just
                cause a segfault.)
  errno = 0;
  if (myrealpath (NULL, buf) != NULL || errno != EINVAL)
    {
      printf ("%s: expected return value NULL and errno set to EINVAL"
	      " for myrealpath(NULL,...)\n", argv[0]);
      ++errors;
    }
*/   

/* according to glibc, this test is invalid 
  errno = 0;
  if (myrealpath ("/", NULL) != NULL || errno != EINVAL)
    {
      printf ("%s: expected return value NULL and errno set to EINVAL"
	      " for myrealpath(...,NULL)\n", argv[0]);
      ++errors;
    }
*/    

  errno = 0;
  if (myrealpath ("", buf) != NULL || errno != ENOENT)
    {
      printf ("%s: expected return value NULL and set errno to ENOENT"
	      " for myrealpath(\"\",...)\n", argv[0]);
      ++errors;
    }

  for (i = 0; i < (int) (sizeof (symlinks) / sizeof (symlinks[0])); ++i)
    symlink (symlinks[i].value, symlinks[i].name);

  fd = open("doesExist", O_CREAT | O_EXCL, 0777);

  for (i = 0; i < (int) (sizeof (tests) / sizeof (tests[0])); ++i)
    {
      buf[0] = '\0';
      result = myrealpath (tests[i].in, buf);

      if (!check_path (result, tests[i].out))
	{
	  printf ("%s: flunked test %d (expected `%s', got `%s')\n",
		  argv[0], i, tests[i].out ? tests[i].out : "NULL",
		  result ? result : "NULL");
	  ++errors;
	  continue;
	}

      if (!check_path (buf, tests[i].out ? tests[i].out : tests[i].resolved))
	{
	  printf ("%s: flunked test %d (expected resolved `%s', got `%s')\n",
		  argv[0], i, tests[i].out ? tests[i].out : tests[i].resolved,
		  buf);
	  ++errors;
	  continue;
	}

      if (!tests[i].out && errno != tests[i].error)
	{
	  printf ("%s: flunked test %d (expected errno %d, got %d)\n",
		  argv[0], i, tests[i].error, errno);
	  ++errors;
	  continue;
	}
    }

  getcwd (buf, sizeof(buf));
  if (strcmp (buf, cwd))
    {
      printf ("%s: current working directory changed from %s to %s\n",
	      argv[0], cwd, buf);
      ++errors;
    }

  if (fd >= 0)
    unlink("doesExist");

  for (i = 0; i < (int) (sizeof (symlinks) / sizeof (symlinks[0])); ++i)
    unlink (symlinks[i].name);

  if (errors != 0)
    {
      printf ("%d errors.\n", errors);
      return EXIT_FAILURE;
    }

  puts ("No errors.");
  return EXIT_SUCCESS;
}
Example #11
0
static int nilfs_cleaner_find_fs(struct nilfs_cleaner *cleaner,
				 const char *device, const char *mntdir)
{
	struct mntent *mntent, mntbuf;
	char buf[LINE_MAX];
	char canonical[PATH_MAX + 2];
	char *cdev = NULL, *cdir = NULL;
	char *mdir, *mdev;
	char *last_match_dev = NULL, *last_match_dir = NULL;
	pid_t last_match_pid = 0;
	FILE *fp = NULL;
	int ret = -1, nfound = 0;

	if (device && myrealpath(device, canonical, sizeof(canonical))) {
		cdev = strdup(canonical);
		if (!cdev)
			goto error;
		cleaner->device = cdev;
	}

	if (mntdir && myrealpath(mntdir, canonical, sizeof(canonical))) {
		cdir = strdup(canonical);
		if (!cdir)
			goto error;
		cleaner->mountdir = cdir;
	}

	fp = fopen(MTAB, "r");
	if (fp == NULL) {
		nilfs_cleaner_logger(LOG_ERR, _("Error: cannot open " MTAB
						"."));
		goto abort;
	}

	while ((mntent = getmntent_r(fp, &mntbuf, buf, sizeof(buf))) != NULL) {
		if (strcmp(mntent->mnt_type, MNTTYPE_NILFS) != 0)
			continue;

		if (cleaner->mountdir != NULL) {
			mdir = mntent->mnt_dir;
			if (myrealpath(mdir, canonical, sizeof(canonical)))
				mdir = canonical;
			if (strcmp(mdir, cleaner->mountdir) != 0)
				continue;
		}
			
		if (cleaner->device != NULL) {
			mdev = mntent->mnt_fsname;
			if (myrealpath(mdev, canonical, sizeof(canonical)))
				mdev = canonical;
			if (strcmp(mdev, cleaner->device) != 0)
				continue;
		}

		if (hasmntopt(mntent, MNTOPT_RW)) {
			/* we found a candidate */
			nfound++;

			if (cleaner->device == NULL) {
				mdev = mntent->mnt_fsname;
				if (myrealpath(mdev, canonical,
					       sizeof(canonical))) {
					mdev = canonical;
				}
				if (last_match_dev)
					free(last_match_dev);
				last_match_dev = strdup(mdev);
				if (!last_match_dev)
					goto error;
			}
			if (cleaner->mountdir == NULL) {
				mdir = mntent->mnt_dir;
				if (myrealpath(mdir, canonical,
					       sizeof(canonical))) {
					mdir = canonical;
				}
				if (last_match_dir)
					free(last_match_dir);
				last_match_dir = strdup(mdir);
				if (!last_match_dir)
					goto error;
			}
			last_match_pid = 0;
			ret = nilfs_find_gcpid_opt(mntent->mnt_opts,
						   &last_match_pid);
			if (ret < 0)
				goto error;
		}
	}
	if (nfound == 0) {
		nilfs_cleaner_logger(LOG_ERR,
				     _("Error: no valid nilfs mountpoint "
				       "found."));
		goto abort;
	}
	if (last_match_dir)
		cleaner->mountdir = last_match_dir;
	if (last_match_dev)
		cleaner->device = last_match_dev;
	if (last_match_pid)
		cleaner->cleanerd_pid = last_match_pid;

	endmntent(fp);
	return 0;
error:
	nilfs_cleaner_logger(LOG_ERR,  _("Error: failed to find fs: %s."),
			     strerror(errno));
abort:
	free(last_match_dir); /* free(NULL) is just ignored */
	free(last_match_dev);
	if (fp)
		endmntent(fp);
	return -1;
}