Example #1
0
int
main (void)
{
  char buf[80];
  int result;

  /* Remove any leftovers from a previous partial run.  */
  ignore_value (system ("rm -rf " BASE "*"));

  /* Perform same checks as counterpart functions.  */
  result = test_readlink (do_readlink, false);
  dfd = openat (AT_FDCWD, ".", O_RDONLY);
  ASSERT (0 <= dfd);
  ASSERT (test_readlink (do_readlink, false) == result);

  /* Now perform some cross-directory checks.  Skip everything else on
     mingw.  */
  if (HAVE_SYMLINK)
    {
      const char *contents = "don't matter!";
      ssize_t exp = strlen (contents);

      /* Create link while cwd is '.', then read it in '..'.  */
      ASSERT (symlinkat (contents, AT_FDCWD, BASE "link") == 0);
      errno = 0;
      ASSERT (symlinkat (contents, dfd, BASE "link") == -1);
      ASSERT (errno == EEXIST);
      ASSERT (chdir ("..") == 0);
      errno = 0;
      ASSERT (readlinkat (AT_FDCWD, BASE "link", buf, sizeof buf) == -1);
      ASSERT (errno == ENOENT);
      ASSERT (readlinkat (dfd, BASE "link", buf, sizeof buf) == exp);
      ASSERT (strncmp (contents, buf, exp) == 0);
      ASSERT (unlinkat (dfd, BASE "link", 0) == 0);

      /* Create link while cwd is '..', then read it in '.'.  */
      ASSERT (symlinkat (contents, dfd, BASE "link") == 0);
      ASSERT (fchdir (dfd) == 0);
      errno = 0;
      ASSERT (symlinkat (contents, AT_FDCWD, BASE "link") == -1);
      ASSERT (errno == EEXIST);
      buf[0] = '\0';
      ASSERT (readlinkat (AT_FDCWD, BASE "link", buf, sizeof buf) == exp);
      ASSERT (strncmp (contents, buf, exp) == 0);
      buf[0] = '\0';
      ASSERT (readlinkat (dfd, BASE "link", buf, sizeof buf) == exp);
      ASSERT (strncmp (contents, buf, exp) == 0);
      ASSERT (unlink (BASE "link") == 0);
    }

  ASSERT (close (dfd) == 0);
  if (result == 77)
    fputs ("skipping test: symlinks not supported on this file system\n",
           stderr);
  return result;
}
Example #2
0
CAMLprim value caml_extunix_symlinkat(value v_path, value v_newdirfd, value v_newname)
{
  CAMLparam3(v_path, v_newdirfd, v_newname);
  int ret = symlinkat(String_val(v_path), Int_val(v_newdirfd), String_val(v_newname));
  if (ret != 0) uerror("symlinkat", v_path);
  CAMLreturn(Val_unit);
}
Example #3
0
File: image.c Project: hqhq/criu
int open_image_dir(char *dir)
{
	int fd, ret;

	fd = open(dir, O_RDONLY);
	if (fd < 0) {
		pr_perror("Can't open dir %s", dir);
		return -1;
	}

	ret = install_service_fd(IMG_FD_OFF, fd);
	close(fd);
	fd = ret;

	if (opts.img_parent) {
		ret = symlinkat(opts.img_parent, fd, CR_PARENT_LINK);
		if (ret < 0 && errno != EEXIST) {
			pr_perror("Can't link parent snapshot");
			goto err;
		}

		if (opts.img_parent[0] == '/')
			pr_warn("Absolute paths for parent links "
					"may not work on restore!\n");
	}

	return 0;

err:
	close_image_dir();
	return -1;
}
Example #4
0
int open_image_dir(char *dir)
{
	int fd, ret;

	fd = open(dir, O_RDONLY);
	if (fd < 0) {
		pr_perror("Can't open dir %s", dir);
		return -1;
	}

	ret = install_service_fd(IMG_FD_OFF, fd);
	close(fd);
	fd = ret;

	if (opts.img_parent) {
		ret = symlinkat(opts.img_parent, fd, CR_PARENT_LINK);
		if (ret < 0 && errno != EEXIST) {
			pr_perror("Can't link parent snapshot");
			goto err;
		}
	}

	return 0;

err:
	close_image_dir();
	return -1;
}
Example #5
0
int
ast_symlinkat(const char* path, int cwd, const char* linkpath)
{
	int	r = -1;

	PATHIFY(cwd, path, 1, 1);
	RESTART(r, symlinkat(path, cwd, linkpath));
	PATHEND();

	return r;
}
Example #6
0
static int copyat(int olddirfd, const char* oldpath, int newdirfd, const char* newpath) {
    int err;
    int oldfd = openat(olddirfd, oldpath, O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NOATIME);
    if (oldfd == -1 && errno == EPERM) {
        oldfd = openat(olddirfd, oldpath, O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
    }
    if (oldfd == -1 && errno == ELOOP) {
        char oldtarget[PATH_MAX];
        ssize_t oldlen = readlinkat(olddirfd, oldpath, oldtarget, sizeof(oldtarget));
        if (oldlen == -1) {
            return -1;
        }
        oldtarget[oldlen] = '\0';
        return symlinkat(oldtarget, newdirfd, newpath);
    }
    if (oldfd == -1) {
        return -1;
    }
    struct stat oldstat;
    if (fstat(oldfd, &oldstat) == -1) {
        err = errno;
        close(oldfd);
        errno = err;
        return -1;
    }
    int newfd = openat(newdirfd, newpath, O_WRONLY | O_CLOEXEC | O_CREAT | O_TRUNC | O_NOATIME, oldstat.st_mode);
    if (newfd == -1 && errno == EPERM) {
        newfd = openat(newdirfd, newpath, O_WRONLY | O_CLOEXEC | O_CREAT | O_TRUNC, oldstat.st_mode);
    }
    if (newfd == -1) {
        err = errno;
        close(oldfd);
        errno = err;
        return -1;
    }
    if (fchown(newfd, oldstat.st_uid, oldstat.st_gid) == -1) {
        // ignore error
    }
    if (copyfile_sparse(oldfd, newfd) == -1) {
        err = errno;
        close(newfd);
        close(oldfd);
        errno = err;
        return -1;
    }
    close(newfd);
    close(oldfd);
    struct timespec times[2];
    times[0] = oldstat.st_atim;
    times[1] = oldstat.st_mtim;
    utimensat(newdirfd, newpath, times, 0); // ignore error
    return 0;
}
Example #7
0
CAMLprim value netsys_symlinkat(value oldpath,
				value newdirfd, value newpath)
{
#ifdef HAVE_AT
    if (symlinkat(String_val(oldpath),
		  Int_val(newdirfd), String_val(newpath)) == -1)
	uerror("symlinkat", oldpath);
    return Val_unit;
#else
    invalid_argument("Netsys_posix.symlinkat not available");
#endif
}
Example #8
0
/* Create a symlink, but reject trailing slash.  */
int
rpl_symlinkat (char const *contents, int fd, char const *name)
{
    size_t len = strlen (name);
    if (len && name[len - 1] == '/')
    {
        struct stat st;
        if (fstatat (fd, name, &st, 0) == 0)
            errno = EEXIST;
        return -1;
    }
    return symlinkat (contents, fd, name);
}
int main() {
  struct stat st;
  struct stat st2;

  openat(AT_FDCWD, PWD "openat.txt", O_CREAT | O_WRONLY, 0644);
  assert(stat("openat.txt", &st) == 0); // relative path

  assert(faccessat(AT_FDCWD, PWD "openat.txt", F_OK, 0) == 0);
  assert(fstatat(AT_FDCWD, PWD "openat.txt", &st2, 0) == 0);
  assert(fchmodat(AT_FDCWD, PWD "openat.txt", 0777, 0) == 0);

  struct timeval my_times[2];
  my_times[0].tv_sec = 0;
  my_times[0].tv_usec = 0;
  my_times[1].tv_sec = 0;
  my_times[1].tv_usec = 0;
  assert(futimesat(AT_FDCWD, PWD "openat.txt", my_times, 0) == 0);

  // see /etc/passwd, user 'pgbovine' is 508:100
  assert(fchownat(AT_FDCWD, PWD "openat.txt", 508, 100, 0) == 0);

  assert(linkat(AT_FDCWD, PWD "openat.txt", AT_FDCWD, PWD "openat_hardlink.txt", 0) == 0);
  assert(stat("openat_hardlink.txt", &st) == 0); // relative path

  assert(symlinkat(PWD "openat.txt", AT_FDCWD, PWD "openat_symlink.txt") == 0);
  assert(lstat("openat_symlink.txt", &st) == 0); // relative path

  char res[300];
  assert(readlinkat(AT_FDCWD, PWD "openat_symlink.txt", res, sizeof(res)) > 0);

  assert(renameat(AT_FDCWD, PWD "openat.txt", AT_FDCWD, PWD "openat_newname.txt", 0) == 0);
  assert(stat("openat.txt", &st) != 0); // should not exist anymore
  assert(stat("openat_newname.txt", &st) == 0); // relative path

  unlinkat(AT_FDCWD, PWD "openat_newname.txt", 0);
  unlinkat(AT_FDCWD, PWD "openat_hardlink.txt", 0);
  unlinkat(AT_FDCWD, PWD "openat_symlink.txt", 0);


  mknodat(AT_FDCWD, PWD "mknodat.fifo", S_IFIFO);
  assert(stat("mknodat.fifo", &st) == 0); // relative path
  unlinkat(AT_FDCWD, PWD "mknodat.fifo", 0);

  mkdirat(AT_FDCWD, PWD "mkdirat_dir", 0);
  assert(stat("mkdirat_dir", &st) == 0); // relative path
  unlinkat(AT_FDCWD, PWD "mkdirat_dir", AT_REMOVEDIR); // like 'rmdir'

  return 0;
}
Example #10
0
void compile_database(repo_t *repo, file_t *db, int contents)
{
    db_writer_t *writer = db_writer_new(repo, db);
    alpm_list_t *pkg, *pkgs = repo->pkgcache->list;

    for (pkg = pkgs; pkg; pkg = pkg->next) {
        alpm_pkg_meta_t *metadata = pkg->data;
        compile_database_entry(repo, writer, metadata, contents);
    }

    db_writer_close(writer);

    /* make the appropriate symlink for the database */
    if (symlinkat(db->file, repo->dirfd, db->link_file) < 0 && errno != EEXIST)
        err(EXIT_FAILURE, "symlink for %s failed", db->link_file);
}
Example #11
0
static int
callback_symlink (const char *from, const char *to)
{
  struct stat stbuf;

  to = ENSURE_RELPATH (to);

  if (symlinkat (from, basefd, to) == -1)
    return -errno;

  if (fstatat (basefd, to, &stbuf, AT_SYMLINK_NOFOLLOW) == -1)
    {
      fprintf (stderr, "Failed to find newly created symlink '%s': %s\n",
	       to, g_strerror (errno));
      exit (EXIT_FAILURE);
    }
  return 0;
}
Example #12
0
void sign_database(repo_t *repo, file_t *db, const char *key)
{
    int dbfd = openat(repo->dirfd, db->file, O_RDONLY);
    if (dbfd < 0)
        err(EXIT_FAILURE, "failed to open %s", db->file);

    int sigfd = openat(repo->dirfd, db->sig, O_CREAT | O_WRONLY | O_TRUNC, 0644);
    if (sigfd < 0)
        err(EXIT_FAILURE, "failed to open %s for writing", db->sig);

    /* XXX: check return type */
    gpgme_sign(dbfd, sigfd, key);

    close(sigfd);
    close(dbfd);

    if (symlinkat(db->sig, repo->dirfd, db->link_sig) < 0 && errno != EEXIST)
        err(EXIT_FAILURE, "symlink for %s failed", db->link_sig);
}
Example #13
0
void test_create_symlink_at()
{
  char *symlink_filename = alloc_filename("symlink");
  int dir_fd = get_dir_fd(".");
  const char *dest_path = "dest_path";
  t_check_zero(symlinkat(dest_path, dir_fd, symlink_filename));

  char buf[100];
  int got;
  got = readlinkat(dir_fd, symlink_filename, buf, sizeof(buf));
  t_check(got >= 0);
  assert(got == strlen(dest_path));
  buf[got] = 0;
  assert(strcmp(buf, dest_path) == 0);

  t_check_zero(unlinkat(dir_fd, symlink_filename, 0));
  close(dir_fd);
  free(symlink_filename);
}
/*
 * Like symlinkat() but overwrites (atomically) an existing
 * symlink.
 */
static gboolean
symlink_at_replace (const char    *oldpath,
                    int            parent_dfd,
                    const char    *newpath,
                    GCancellable  *cancellable,
                    GError       **error)
{
  gboolean ret = FALSE;
  int res;
  /* Possibly in the future generate a temporary random name here,
   * would need to move "generate a temporary name" code into
   * libglnx or glib?
   */
  const char *temppath = glnx_strjoina (newpath, ".tmp");

  /* Clean up any stale temporary links */ 
  (void) unlinkat (parent_dfd, temppath, 0);

  /* Create the temp link */ 
  do
    res = symlinkat (oldpath, parent_dfd, temppath);
  while (G_UNLIKELY (res == -1 && errno == EINTR));
  if (res == -1)
    {
      glnx_set_error_from_errno (error);
      goto out;
    }

  /* Rename it into place */ 
  do
    res = renameat (parent_dfd, temppath, parent_dfd, newpath);
  while (G_UNLIKELY (res == -1 && errno == EINTR));
  if (res == -1)
    {
      glnx_set_error_from_errno (error);
      goto out;
    }

  ret = TRUE;
 out:
  return ret;
}
Example #15
0
static int link_file(int dirfd, const char *filename, int type, unsigned long hash, unsigned char *digest)
{
	char linkfn[32];
	int id;

	id = get_link_id(type, hash, digest);
	if (id < 0) {
		fprintf(stderr, "WARNING: Skipping duplicate certificate in file %s\n",
			filename);
		return -1;
	}

	snprintf(linkfn, sizeof(linkfn),
		 "%08lx.%s%d", hash, prefixes[type], id);
	fprintf(stdout, "%s => %s\n", linkfn, filename);
	if (symlinkat(filename, dirfd, linkfn) < 0)
		perror(linkfn);

	return 0;
}
Example #16
0
static int fd_copy_symlink(int df, const char *from, const struct stat *st, int dt, const char *to) {
        _cleanup_free_ char *target = NULL;
        int r;

        assert(from);
        assert(st);
        assert(to);

        r = readlinkat_malloc(df, from, &target);
        if (r < 0)
                return r;

        if (symlinkat(target, dt, to) < 0)
                return -errno;

        if (fchownat(dt, to, st->st_uid, st->st_gid, AT_SYMLINK_NOFOLLOW) < 0)
                return -errno;

        return 0;
}
Example #17
0
int
main(int argc, char *argv[])
{
	int fd;

	if (!mkdtemp(dir))
		err(2, "mkdtemp");

	err_set_exit(cleanup);

	fd = open(dir, O_DIRECTORY | O_RDONLY);
	if (fd == -1)
		err(2, "open %s", dir);

	if (mkdirat(fd, "d1", 0777) == -1)
		err(2, "mkdirat d1");

	if (symlinkat(dir, fd, "d1/looper") == -1)
		err(2, "symlinkat looper");

	ftwflags = FTW_PHYS;
	if (nftw(dir, cb, 10, ftwflags) == -1)
		err(2, "nftw FTW_PHYS");
	ftwflags = FTW_PHYS | FTW_DEPTH;
	if (nftw(dir, cb, 10, ftwflags) == -1)
		err(2, "nftw FTW_PHYS | FTW_DEPTH");
	ftwflags = 0;
	if (nftw(dir, cb, 10, ftwflags) == -1)
		err(2, "nftw 0");
	ftwflags = FTW_DEPTH;
	if (nftw(dir, cb, 10, ftwflags) == -1)
		err(2, "nftw FTW_DEPTH");

	close(fd);

	printf("PASS nftw()\n");

	cleanup(failures != 0);

	return (failures != 0);
}
Example #18
0
int open_image_dir(char *dir)
{
	int fd, ret;

	fd = open(dir, O_RDONLY);
	if (fd < 0) {
		pr_perror("Can't open dir %s", dir);
		return -1;
	}

	ret = install_service_fd(IMG_FD_OFF, fd);

	if (opts.img_parent) {
		int pfd;

		ret = symlinkat(opts.img_parent, fd, CR_PARENT_LINK);
		if (ret < 0) {
			pr_perror("Can't link parent snapshot.");
			goto err;
		}

		pfd = openat(fd, CR_PARENT_LINK, O_RDONLY);
		if (pfd < 0) {
			pr_perror("Can't open parent snapshot.");
			goto err;
		}

		ret = install_service_fd(PARENT_FD_OFF, pfd);

		close(pfd);
	}

	close(fd);

	return ret;

err:
	close_image_dir();
	return -1;
}
Example #19
0
string writeScript(const string& ckptDir,
                   bool uniqueCkptFilenames,
                   const time_t& ckptTimeStamp,
                   const uint32_t theCheckpointInterval,
                   const int thePort,
                   const UniquePid& compId,
                   const map<string, vector<string> >& restartFilenames)
{
  ostringstream o;
  string uniqueFilename;

  o << string(ckptDir) << "/"
    << RESTART_SCRIPT_BASENAME << "_" << compId;
  if (uniqueCkptFilenames) {
    o << "_" << std::setw(5) << std::setfill('0') << compId.computationGeneration();
  }
  o << "." << RESTART_SCRIPT_EXT;
  uniqueFilename = o.str();

  const bool isSingleHost = (restartFilenames.size() == 1);

  map< string, vector<string> >::const_iterator host;

  size_t numPeers;
  for (host = restartFilenames.begin();
       host != restartFilenames.end();
       host++) {
    numPeers += host->second.size();
  }

  vector<string>::const_iterator file;

  char hostname[80];
  char timestamp[80];
  gethostname ( hostname, 80 );

  JTRACE ( "writing restart script" ) ( uniqueFilename );

  FILE* fp = fopen ( uniqueFilename.c_str(),"w" );
  JASSERT ( fp!=0 )(JASSERT_ERRNO)( uniqueFilename )
    .Text ( "failed to open file" );

  fprintf ( fp, "%s", header );
  fprintf ( fp, "%s", checkLocal );
  fprintf ( fp, "%s", slurmHelperContactFunction );
  fprintf ( fp, "%s", usage );

  ctime_r(&ckptTimeStamp, timestamp);
  // Remove the trailing '\n'
  timestamp[strlen(timestamp) - 1] = '\0';
  fprintf ( fp, "ckpt_timestamp=\"%s\"\n\n", timestamp );

  fprintf ( fp, "coord_host=$" ENV_VAR_NAME_HOST "\n"
                "if test -z \"$" ENV_VAR_NAME_HOST "\"; then\n"
                "  coord_host=%s\nfi\n\n"
                "coord_port=$" ENV_VAR_NAME_PORT "\n"
                "if test -z \"$" ENV_VAR_NAME_PORT "\"; then\n"
                "  coord_port=%d\nfi\n\n"
                "checkpoint_interval=$" ENV_VAR_CKPT_INTR "\n"
                "if test -z \"$" ENV_VAR_CKPT_INTR "\"; then\n"
                "  checkpoint_interval=%d\nfi\n"
                "export DMTCP_CHECKPOINT_INTERVAL=${checkpoint_interval}\n\n",
                hostname, thePort, theCheckpointInterval );

  fprintf ( fp, "%s", cmdlineArgHandler );

  fprintf ( fp, "dmt_rstr_cmd=%s/" DMTCP_RESTART_CMD "\n"
                "which $dmt_rstr_cmd > /dev/null 2>&1"
                " || dmt_rstr_cmd=" DMTCP_RESTART_CMD "\n"
                "which $dmt_rstr_cmd > /dev/null 2>&1"
                " || echo \"$0: $dmt_rstr_cmd not found\"\n"
                "which $dmt_rstr_cmd > /dev/null 2>&1 || exit 1\n\n",
                jalib::Filesystem::GetProgramDir().c_str());

  fprintf ( fp, "# Number of hosts in the computation = %zu\n"
                "# Number of processes in the computation = %zu\n\n",
                restartFilenames.size(), numPeers );

  if ( isSingleHost ) {
    JTRACE ( "Single HOST" );

    host=restartFilenames.begin();
    ostringstream o;
    for ( file=host->second.begin(); file!=host->second.end(); ++file ) {
      o << " " << *file;
    }
    fprintf ( fp, "given_ckpt_files=\"%s\"\n\n", o.str().c_str());

    fprintf ( fp, "%s", singleHostProcessing );
  }
  else
  {
    fprintf ( fp, "%s",
              "# SYNTAX:\n"
              "#  :: <HOST> :<MODE>: <CHECKPOINT_IMAGE> ...\n"
              "# Host names and filenames must not include \':\'\n"
              "# At most one fg (foreground) mode allowed; it must be last.\n"
              "# \'maybexterm\' and \'maybebg\' are set from <MODE>.\n");

    fprintf ( fp, "%s", "worker_ckpts=\'" );
    for ( host=restartFilenames.begin(); host!=restartFilenames.end(); ++host ) {
      fprintf ( fp, "\n :: %s :bg:", host->first.c_str() );
      for ( file=host->second.begin(); file!=host->second.end(); ++file ) {
        fprintf ( fp," %s", file->c_str() );
      }
    }
    fprintf ( fp, "%s", "\n\'\n\n" );

    fprintf( fp,  "# Check for resource manager\n"
                  "ibrun_path=$(which ibrun 2> /dev/null)\n"
                  "if [ ! -n \"$ibrun_path\" ]; then\n"
                  "  discover_rm_path=$(which dmtcp_discover_rm)\n"
                  "  if [ -n \"$discover_rm_path\" ]; then\n"
                  "    eval $(dmtcp_discover_rm -t)\n"
                  "    srun_path=$(which srun 2> /dev/null)\n"
                  "    llaunch=`which dmtcp_rm_loclaunch`\n"
                  "    if [ $RES_MANAGER = \"SLURM\" ] && [ -n \"$srun_path\" ]; then\n"
                  "      eval $(dmtcp_discover_rm -n \"$worker_ckpts\")\n"
                  "      if [ -n \"$DMTCP_DISCOVER_RM_ERROR\" ]; then\n"
                  "          echo \"Restart error: $DMTCP_DISCOVER_RM_ERROR\"\n"
                  "          echo \"Allocated resources: $manager_resources\"\n"
                  "          exit 0\n"
                  "      fi\n"
                  "      export DMTCP_REMLAUNCH_NODES=$DMTCP_REMLAUNCH_NODES\n"
                  "      bound=$(($DMTCP_REMLAUNCH_NODES - 1))\n"
                  "      for i in $(seq 0 $bound); do\n"
                  "        eval \"val=\\${DMTCP_REMLAUNCH_${i}_SLOTS}\"\n"
                  "        export DMTCP_REMLAUNCH_${i}_SLOTS=\"$val\"\n"
                  "        bound2=$(($val - 1))\n"
                  "        for j in $(seq 0 $bound2); do\n"
                  "          eval \"ckpts=\\${DMTCP_REMLAUNCH_${i}_${j}}\"\n"
                  "          export DMTCP_REMLAUNCH_${i}_${j}=\"$ckpts\"\n"
                  "        done\n"
                  "      done\n"
                  "      if [ \"$DMTCP_DISCOVER_PM_TYPE\" = \"HYDRA\" ]; then\n"
                  "        export DMTCP_SRUN_HELPER_SYNCFILE=`mktemp ./tmp.XXXXXXXXXX`\n"
                  "        rm $DMTCP_SRUN_HELPER_SYNCFILE\n"
                  "        dmtcp_srun_helper -r $srun_path \"$llaunch\"\n"
                  "        if [ ! -f $DMTCP_SRUN_HELPER_SYNCFILE ]; then\n"
                  "          echo \"Error launching application\"\n"
                  "          exit 1\n"
                  "        fi\n"
                  "        # export helper contact info\n"
                  "        . $DMTCP_SRUN_HELPER_SYNCFILE\n"
                  "        pass_slurm_helper_contact \"$DMTCP_LAUNCH_CKPTS\"\n"
                  "        rm $DMTCP_SRUN_HELPER_SYNCFILE\n"
                  "        dmtcp_restart --join --coord-host $DMTCP_COORD_HOST"
                              " --coord-port $DMTCP_COORD_PORT"
                              " $DMTCP_LAUNCH_CKPTS\n"
                  "      else\n"
                  "        DMTCP_REMLAUNCH_0_0=\"$DMTCP_REMLAUNCH_0_0"
                                                     " $DMTCP_LAUNCH_CKPTS\"\n"
                  "        $srun_path \"$llaunch\"\n"
                  "      fi\n"
                  "      exit 0\n"
                  "    elif [ $RES_MANAGER = \"TORQUE\" ]; then\n"
                  "      #eval $(dmtcp_discover_rm \"$worker_ckpts\")\n"
                  "      #if [ -n \"$new_worker_ckpts\" ]; then\n"
                  "      #  worker_ckpts=\"$new_worker_ckpts\"\n"
                  "      #fi\n"
                  "      eval $(dmtcp_discover_rm -n \"$worker_ckpts\")\n"
                  "      if [ -n \"$DMTCP_DISCOVER_RM_ERROR\" ]; then\n"
                  "          echo \"Restart error: $DMTCP_DISCOVER_RM_ERROR\"\n"
                  "          echo \"Allocated resources: $manager_resources\"\n"
                  "          exit 0\n"
                  "      fi\n"
                  "      arguments=\"PATH=$PATH DMTCP_COORD_HOST=$DMTCP_COORD_HOST"
                                      " DMTCP_COORD_PORT=$DMTCP_COORD_PORT\"\n"
                  "      arguments=$arguments\" DMTCP_CHECKPOINT_INTERVAL=$DMTCP_CHECKPOINT_INTERVAL\"\n"
                  "      arguments=$arguments\" DMTCP_TMPDIR=$DMTCP_TMPDIR\"\n"
                  "      arguments=$arguments\" DMTCP_REMLAUNCH_NODES=$DMTCP_REMLAUNCH_NODES\"\n"
                  "      bound=$(($DMTCP_REMLAUNCH_NODES - 1))\n"
                  "      for i in $(seq 0 $bound); do\n"
                  "        eval \"val=\\${DMTCP_REMLAUNCH_${i}_SLOTS}\"\n"
                  "        arguments=$arguments\" DMTCP_REMLAUNCH_${i}_SLOTS=\\\"$val\\\"\"\n"
                  "        bound2=$(($val - 1))\n"
                  "        for j in $(seq 0 $bound2); do\n"
                  "          eval \"ckpts=\\${DMTCP_REMLAUNCH_${i}_${j}}\"\n"
                  "          arguments=$arguments\" DMTCP_REMLAUNCH_${i}_${j}=\\\"$ckpts\\\"\"\n"
                  "        done\n"
                  "      done\n"
                  "      pbsdsh -u \"$llaunch\" \"$arguments\"\n"
                  "      exit 0\n"
                  "    fi\n"
                  "  fi\n"
                  "fi\n"
                  "\n\n"
             );

    fprintf ( fp, "%s", multiHostProcessing );
  }

  fclose ( fp );
  {
    string filename = RESTART_SCRIPT_BASENAME "." RESTART_SCRIPT_EXT;
    string dirname = jalib::Filesystem::DirName(uniqueFilename);
    int dirfd = open(dirname.c_str(), O_DIRECTORY | O_RDONLY);
    JASSERT(dirfd != -1) (dirname) (JASSERT_ERRNO);

    /* Set execute permission for user. */
    struct stat buf;
    JASSERT(::stat(uniqueFilename.c_str(), &buf) == 0);
    JASSERT(chmod(uniqueFilename.c_str(), buf.st_mode | S_IXUSR) == 0);
    // Create a symlink from
    //   dmtcp_restart_script.sh -> dmtcp_restart_script_<curCompId>.sh
    unlink(filename.c_str());
    JTRACE("linking \"dmtcp_restart_script.sh\" filename to uniqueFilename")
      (filename) (dirname) (uniqueFilename);
    // FIXME:  Handle error case of symlink()
    JWARNING(symlinkat(basename(uniqueFilename.c_str()), dirfd, filename.c_str()) == 0) (JASSERT_ERRNO);
    JASSERT(close(dirfd) == 0);
  }
  return uniqueFilename;
}
Example #20
0
int q_main(int argc, char **argv)
{
	int i, install;
	const char *p;
	APPLET func;

	if (argc == 0)
		return 1;

	argv0 = p = basename(argv[0]);

	if ((func = lookup_applet(p)) == NULL)
		return 1;
	if (strcmp("q", p) != 0)
		return (func)(argc, argv);

	if (argc == 1)
		q_usage(EXIT_FAILURE);

	install = 0;

	while ((i = GETOPT_LONG(Q, q, "+")) != -1) {
		switch (i) {
		COMMON_GETOPTS_CASES(q)
		case 'M': modpath = optarg; break;
		case 'i': install = 1; break;
		}
	}

	if (install) {
		char buf[_Q_PATH_MAX];
		const char *prog, *dir;
		ssize_t rret;
		int fd, ret;

		if (!quiet)
			printf("Installing symlinks:\n");

#if defined(__MACH__)
		rret = proc_pidpath(getpid(), buf, sizeof(buf));
		if (rret != -1)
			rret = strlen(buf);
#elif defined(__sun) && defined(__SVR4)
		prog = getexecname();
		rret = strlen(prog);
		if ((size_t)rret > sizeof(buf) - 1) {
			rret = -1;
		} else {
			snprintf(buf, sizeof(buf), "%s", prog);
		}
#else
		rret = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
#endif
		if (rret == -1) {
			warnfp("haha no symlink love for you");
			return 1;
		}
		buf[rret] = '\0';

		prog = basename(buf);
		dir = dirname(buf);
		fd = open(dir, O_RDONLY|O_CLOEXEC|O_PATH);
		if (fd < 0) {
			warnfp("open(%s) failed", dir);
			return 1;
		}

		ret = 0;
		for (i = 1; applets[i].desc; ++i) {
			int r = symlinkat(prog, fd, applets[i].name);
			if (!quiet)
				printf(" %s ...\t[%s]\n",
						applets[i].name, r ? strerror(errno) : "OK");
			if (r && errno != EEXIST)
				ret = 1;
		}

		close(fd);

		return ret;
	}

	if (argc == optind)
		q_usage(EXIT_FAILURE);
	if ((func = lookup_applet(argv[optind])) == NULL)
		return 1;

	/* In case of "q --option ... appletname ...", remove appletname from the
	 * applet's args. */
	if (optind > 1) {
		argv[0] = argv[optind];
		for (i = optind; i < argc; ++i)
			argv[i] = argv[i + 1];
	} else
		++argv;

	optind = 0; /* reset so the applets can call getopt */

	return (func)(argc - 1, argv);
}
Example #21
0
/*
 * Given a file descriptor, create a capability with specific rights and
 * make sure only those rights work. 
*/
static int
try_file_ops(int filefd, int dirfd, cap_rights_t rights)
{
	struct stat sb;
	struct statfs sf;
	cap_rights_t erights;
	int fd_cap, fd_capcap, dfd_cap;
	ssize_t ssize, ssize2;
	off_t off;
	void *p;
	char ch;
	int ret, is_nfs;
	struct pollfd pollfd;
	int success = -1;

	REQUIRE(fstatfs(filefd, &sf));
	is_nfs = (strcmp("nfs", sf.f_fstypename) == 0);

	REQUIRE(fd_cap = cap_new(filefd, rights));
	CHECK(cap_getrights(fd_cap, &erights) == 0);
	CHECK(rights == erights);
	REQUIRE(fd_capcap = cap_new(fd_cap, rights));
	CHECK(cap_getrights(fd_capcap, &erights) == 0);
	CHECK(rights == erights);
	CHECK(fd_capcap != fd_cap);
	REQUIRE(dfd_cap = cap_new(dirfd, rights));
	CHECK(cap_getrights(dfd_cap, &erights) == 0);
	CHECK(rights == erights);

	ssize = read(fd_cap, &ch, sizeof(ch));
	CHECK_RESULT(read, CAP_READ, ssize >= 0);

	ssize = write(fd_cap, &ch, sizeof(ch));
	CHECK_RESULT(write, CAP_WRITE, ssize >= 0);

	off = lseek(fd_cap, 0, SEEK_SET);
	CHECK_RESULT(lseek, CAP_SEEK, off >= 0);

	ssize = pread(fd_cap, &ch, sizeof(ch), 0);
	ssize2 = pread(fd_cap, &ch, sizeof(ch), 0);
	CHECK_RESULT(pread, CAP_PREAD, ssize >= 0);
	CHECK(ssize == ssize2);

	ssize = pwrite(fd_cap, &ch, sizeof(ch), 0);
	CHECK_RESULT(pwrite, CAP_PWRITE, ssize >= 0);

	p = mmap(NULL, getpagesize(), PROT_NONE, MAP_SHARED, fd_cap, 0);
	CHECK_MMAP_RESULT(CAP_MMAP);

	p = mmap(NULL, getpagesize(), PROT_READ, MAP_SHARED, fd_cap, 0);
	CHECK_MMAP_RESULT(CAP_MMAP_R);

	p = mmap(NULL, getpagesize(), PROT_WRITE, MAP_SHARED, fd_cap, 0);
	CHECK_MMAP_RESULT(CAP_MMAP_W);

	p = mmap(NULL, getpagesize(), PROT_EXEC, MAP_SHARED, fd_cap, 0);
	CHECK_MMAP_RESULT(CAP_MMAP_X);

	p = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED,
	    fd_cap, 0);
	CHECK_MMAP_RESULT(CAP_MMAP_RW);

	p = mmap(NULL, getpagesize(), PROT_READ | PROT_EXEC, MAP_SHARED,
	    fd_cap, 0);
	CHECK_MMAP_RESULT(CAP_MMAP_RX);

	p = mmap(NULL, getpagesize(), PROT_EXEC | PROT_WRITE, MAP_SHARED,
	    fd_cap, 0);
	CHECK_MMAP_RESULT(CAP_MMAP_WX);

	p = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC,
	    MAP_SHARED, fd_cap, 0);
	CHECK_MMAP_RESULT(CAP_MMAP_RWX);

	ret = openat(dfd_cap, "cap_create", O_CREAT | O_RDONLY, 0600);
	CHECK_RESULT(openat(O_CREATE | O_RDONLY),
	    CAP_CREATE | CAP_READ | CAP_LOOKUP, ret >= 0);
	CHECK(ret == -1 || close(ret) == 0);
	CHECK(ret == -1 || unlinkat(dirfd, "cap_create", 0) == 0);
	ret = openat(dfd_cap, "cap_create", O_CREAT | O_WRONLY | O_APPEND,
	    0600);
	CHECK_RESULT(openat(O_CREATE | O_WRONLY | O_APPEND),
	    CAP_CREATE | CAP_WRITE | CAP_LOOKUP, ret >= 0);
	CHECK(ret == -1 || close(ret) == 0);
	CHECK(ret == -1 || unlinkat(dirfd, "cap_create", 0) == 0);
	ret = openat(dfd_cap, "cap_create", O_CREAT | O_RDWR | O_APPEND, 0600);
	CHECK_RESULT(openat(O_CREATE | O_RDWR | O_APPEND),
	    CAP_CREATE | CAP_READ | CAP_WRITE | CAP_LOOKUP, ret >= 0);
	CHECK(ret == -1 || close(ret) == 0);
	CHECK(ret == -1 || unlinkat(dirfd, "cap_create", 0) == 0);

	ret = fsync(fd_cap);
	CHECK_RESULT(fsync, CAP_FSYNC, ret == 0);

	ret = openat(dirfd, "cap_fsync", O_CREAT, 0600);
	CHECK(ret >= 0);
	CHECK(close(ret) == 0);
	ret = openat(dfd_cap, "cap_fsync", O_FSYNC | O_RDONLY);
	CHECK_RESULT(openat(O_FSYNC | O_RDONLY),
	    CAP_FSYNC | CAP_READ | CAP_LOOKUP, ret >= 0);
	CHECK(ret == -1 || close(ret) == 0);
	ret = openat(dfd_cap, "cap_fsync", O_FSYNC | O_WRONLY | O_APPEND);
	CHECK_RESULT(openat(O_FSYNC | O_WRONLY | O_APPEND),
	    CAP_FSYNC | CAP_WRITE | CAP_LOOKUP, ret >= 0);
	CHECK(ret == -1 || close(ret) == 0);
	ret = openat(dfd_cap, "cap_fsync", O_FSYNC | O_RDWR | O_APPEND);
	CHECK_RESULT(openat(O_FSYNC | O_RDWR | O_APPEND),
	    CAP_FSYNC | CAP_READ | CAP_WRITE | CAP_LOOKUP, ret >= 0);
	CHECK(ret == -1 || close(ret) == 0);
	ret = openat(dfd_cap, "cap_fsync", O_SYNC | O_RDONLY);
	CHECK_RESULT(openat(O_SYNC | O_RDONLY),
	    CAP_FSYNC | CAP_READ | CAP_LOOKUP, ret >= 0);
	CHECK(ret == -1 || close(ret) == 0);
	ret = openat(dfd_cap, "cap_fsync", O_SYNC | O_WRONLY | O_APPEND);
	CHECK_RESULT(openat(O_SYNC | O_WRONLY | O_APPEND),
	    CAP_FSYNC | CAP_WRITE | CAP_LOOKUP, ret >= 0);
	CHECK(ret == -1 || close(ret) == 0);
	ret = openat(dfd_cap, "cap_fsync", O_SYNC | O_RDWR | O_APPEND);
	CHECK_RESULT(openat(O_SYNC | O_RDWR | O_APPEND),
	    CAP_FSYNC | CAP_READ | CAP_WRITE | CAP_LOOKUP, ret >= 0);
	CHECK(ret == -1 || close(ret) == 0);
	CHECK(unlinkat(dirfd, "cap_fsync", 0) == 0);

	ret = ftruncate(fd_cap, 0);
	CHECK_RESULT(ftruncate, CAP_FTRUNCATE, ret == 0);

	ret = openat(dirfd, "cap_ftruncate", O_CREAT, 0600);
	CHECK(ret >= 0);
	CHECK(close(ret) == 0);
	ret = openat(dfd_cap, "cap_ftruncate", O_TRUNC | O_RDONLY);
	CHECK_RESULT(openat(O_TRUNC | O_RDONLY),
	    CAP_FTRUNCATE | CAP_READ | CAP_LOOKUP, ret >= 0);
	CHECK(ret == -1 || close(ret) == 0);
	ret = openat(dfd_cap, "cap_ftruncate", O_TRUNC | O_WRONLY);
	CHECK_RESULT(openat(O_TRUNC | O_WRONLY),
	    CAP_FTRUNCATE | CAP_WRITE | CAP_LOOKUP, ret >= 0);
	CHECK(ret == -1 || close(ret) == 0);
	ret = openat(dfd_cap, "cap_ftruncate", O_TRUNC | O_RDWR);
	CHECK_RESULT(openat(O_TRUNC | O_RDWR),
	    CAP_FTRUNCATE | CAP_READ | CAP_WRITE | CAP_LOOKUP, ret >= 0);
	CHECK(ret == -1 || close(ret) == 0);
	CHECK(unlinkat(dirfd, "cap_ftruncate", 0) == 0);

	ret = openat(dfd_cap, "cap_create", O_CREAT | O_WRONLY, 0600);
	CHECK_RESULT(openat(O_CREATE | O_WRONLY),
	    CAP_CREATE | CAP_WRITE | CAP_SEEK | CAP_LOOKUP, ret >= 0);
	CHECK(ret == -1 || close(ret) == 0);
	CHECK(ret == -1 || unlinkat(dirfd, "cap_create", 0) == 0);
	ret = openat(dfd_cap, "cap_create", O_CREAT | O_RDWR, 0600);
	CHECK_RESULT(openat(O_CREATE | O_RDWR),
	    CAP_CREATE | CAP_READ | CAP_WRITE | CAP_SEEK | CAP_LOOKUP,
	    ret >= 0);
	CHECK(ret == -1 || close(ret) == 0);
	CHECK(ret == -1 || unlinkat(dirfd, "cap_create", 0) == 0);

	ret = openat(dirfd, "cap_fsync", O_CREAT, 0600);
	CHECK(ret >= 0);
	CHECK(close(ret) == 0);
	ret = openat(dfd_cap, "cap_fsync", O_FSYNC | O_WRONLY);
	CHECK_RESULT(openat(O_FSYNC | O_WRONLY),
	    CAP_FSYNC | CAP_WRITE | CAP_SEEK | CAP_LOOKUP, ret >= 0);
	CHECK(ret == -1 || close(ret) == 0);
	ret = openat(dfd_cap, "cap_fsync", O_FSYNC | O_RDWR);
	CHECK_RESULT(openat(O_FSYNC | O_RDWR),
	    CAP_FSYNC | CAP_READ | CAP_WRITE | CAP_SEEK | CAP_LOOKUP, ret >= 0);
	CHECK(ret == -1 || close(ret) == 0);
	ret = openat(dfd_cap, "cap_fsync", O_SYNC | O_WRONLY);
	CHECK_RESULT(openat(O_SYNC | O_WRONLY),
	    CAP_FSYNC | CAP_WRITE | CAP_SEEK | CAP_LOOKUP, ret >= 0);
	CHECK(ret == -1 || close(ret) == 0);
	ret = openat(dfd_cap, "cap_fsync", O_SYNC | O_RDWR);
	CHECK_RESULT(openat(O_SYNC | O_RDWR),
	    CAP_FSYNC | CAP_READ | CAP_WRITE | CAP_SEEK | CAP_LOOKUP, ret >= 0);
	CHECK(ret == -1 || close(ret) == 0);
	CHECK(unlinkat(dirfd, "cap_fsync", 0) == 0);

	/*
	 * Note: this is not expected to work over NFS.
	 */
	ret = fchflags(fd_cap, UF_NODUMP);
	CHECK_RESULT(fchflags, CAP_FCHFLAGS,
	    ret == 0 || (is_nfs && errno == EOPNOTSUPP));

	ret = openat(dirfd, "cap_chflagsat", O_CREAT, 0600);
	CHECK(ret >= 0);
	CHECK(close(ret) == 0);
	ret = chflagsat(dfd_cap, "cap_chflagsat", UF_NODUMP, 0);
	CHECK_RESULT(chflagsat, CAP_CHFLAGSAT | CAP_LOOKUP, ret == 0);
	CHECK(unlinkat(dirfd, "cap_chflagsat", 0) == 0);

	ret = fchown(fd_cap, -1, -1);
	CHECK_RESULT(fchown, CAP_FCHOWN, ret == 0);

	ret = openat(dirfd, "cap_fchownat", O_CREAT, 0600);
	CHECK(ret >= 0);
	CHECK(close(ret) == 0);
	ret = fchownat(dfd_cap, "cap_fchownat", -1, -1, 0);
	CHECK_RESULT(fchownat, CAP_FCHOWN | CAP_LOOKUP, ret == 0);
	CHECK(unlinkat(dirfd, "cap_fchownat", 0) == 0);

	ret = fchmod(fd_cap, 0644);
	CHECK_RESULT(fchmod, CAP_FCHMOD, ret == 0);

	ret = openat(dirfd, "cap_fchmodat", O_CREAT, 0600);
	CHECK(ret >= 0);
	CHECK(close(ret) == 0);
	ret = fchmodat(dfd_cap, "cap_fchmodat", 0600, 0);
	CHECK_RESULT(fchmodat, CAP_FCHMOD | CAP_LOOKUP, ret == 0);
	CHECK(unlinkat(dirfd, "cap_fchmodat", 0) == 0);

	ret = fcntl(fd_cap, F_GETFL);
	CHECK_RESULT(fcntl(F_GETFL), CAP_FCNTL, ret >= 0);
	ret = fcntl(fd_cap, F_SETFL, ret);
	CHECK_RESULT(fcntl(F_SETFL), CAP_FCNTL, ret == 0);

	/* XXX flock */

	ret = fstat(fd_cap, &sb);
	CHECK_RESULT(fstat, CAP_FSTAT, ret == 0);

	ret = openat(dirfd, "cap_fstatat", O_CREAT, 0600);
	CHECK(ret >= 0);
	CHECK(close(ret) == 0);
	ret = fstatat(dfd_cap, "cap_fstatat", &sb, 0);
	CHECK_RESULT(fstatat, CAP_FSTAT | CAP_LOOKUP, ret == 0);
	CHECK(unlinkat(dirfd, "cap_fstatat", 0) == 0);

	ret = fstatfs(fd_cap, &sf);
	CHECK_RESULT(fstatfs, CAP_FSTATFS, ret == 0);

	ret = fpathconf(fd_cap, _PC_NAME_MAX);
	CHECK_RESULT(fpathconf, CAP_FPATHCONF, ret >= 0);

	ret = futimes(fd_cap, NULL);
	CHECK_RESULT(futimes, CAP_FUTIMES, ret == 0);

	ret = openat(dirfd, "cap_futimesat", O_CREAT, 0600);
	CHECK(ret >= 0);
	CHECK(close(ret) == 0);
	ret = futimesat(dfd_cap, "cap_futimesat", NULL);
	CHECK_RESULT(futimesat, CAP_FUTIMES | CAP_LOOKUP, ret == 0);
	CHECK(unlinkat(dirfd, "cap_futimesat", 0) == 0);

	ret = openat(dirfd, "cap_linkat_src", O_CREAT, 0600);
	CHECK(ret >= 0);
	CHECK(close(ret) == 0);
	ret = linkat(dirfd, "cap_linkat_src", dfd_cap, "cap_linkat_dst", 0);
	CHECK_RESULT(linkat, CAP_LINKAT | CAP_LOOKUP, ret == 0);
	CHECK(unlinkat(dirfd, "cap_linkat_src", 0) == 0);
	CHECK(ret == -1 || unlinkat(dirfd, "cap_linkat_dst", 0) == 0);

	ret = mkdirat(dfd_cap, "cap_mkdirat", 0700);
	CHECK_RESULT(mkdirat, CAP_MKDIRAT | CAP_LOOKUP, ret == 0);
	CHECK(ret == -1 || unlinkat(dirfd, "cap_mkdirat", AT_REMOVEDIR) == 0);

	ret = mkfifoat(dfd_cap, "cap_mkfifoat", 0600);
	CHECK_RESULT(mkfifoat, CAP_MKFIFOAT | CAP_LOOKUP, ret == 0);
	CHECK(ret == -1 || unlinkat(dirfd, "cap_mkfifoat", 0) == 0);

	ret = mknodat(dfd_cap, "cap_mknodat", S_IFCHR | 0600, 0);
	CHECK_RESULT(mknodat, CAP_MKNODAT | CAP_LOOKUP, ret == 0);
	CHECK(ret == -1 || unlinkat(dirfd, "cap_mknodat", 0) == 0);

	/* TODO: renameat(2) */

	ret = symlinkat("test", dfd_cap, "cap_symlinkat");
	CHECK_RESULT(symlinkat, CAP_SYMLINKAT | CAP_LOOKUP, ret == 0);
	CHECK(ret == -1 || unlinkat(dirfd, "cap_symlinkat", 0) == 0);

	ret = openat(dirfd, "cap_unlinkat", O_CREAT, 0600);
	CHECK(ret >= 0);
	CHECK(close(ret) == 0);
	ret = unlinkat(dfd_cap, "cap_unlinkat", 0);
	CHECK_RESULT(unlinkat, CAP_UNLINKAT | CAP_LOOKUP, ret == 0);
	CHECK(ret == 0 || unlinkat(dirfd, "cap_unlinkat", 0) == 0);
	ret = mkdirat(dirfd, "cap_unlinkat", 0700);
	CHECK(ret == 0);
	ret = unlinkat(dfd_cap, "cap_unlinkat", AT_REMOVEDIR);
	CHECK_RESULT(unlinkat, CAP_UNLINKAT | CAP_LOOKUP, ret == 0);
	CHECK(ret == 0 || unlinkat(dirfd, "cap_unlinkat", AT_REMOVEDIR) == 0);

	pollfd.fd = fd_cap;
	pollfd.events = POLLIN | POLLERR | POLLHUP;
	pollfd.revents = 0;

	ret = poll(&pollfd, 1, 0);
	if (rights & CAP_EVENT)
		CHECK((pollfd.revents & POLLNVAL) == 0);
	else
		CHECK((pollfd.revents & POLLNVAL) != 0);

	/* XXX: select, kqueue */

	close(fd_cap);
	close(fd_capcap);

	if (success == -1) {
		fprintf(stderr, "No tests for rights 0x%jx.\n",
		    (uintmax_t)rights);
		success = FAILED;
	}
	return (success);
}
Example #22
0
int main(void)
{
	char dname_buf[] = "/tmp/test-mmap.XXXXXX";
	char *dname;
	int dir_fd;
	int file_fd;
	struct stat st[5];

	/* check whether *at(2) syscalls are available */
	dir_fd = openat(AT_FDCWD, "/", O_DIRECTORY|O_RDONLY);
	if (dir_fd == -1 && errno == ENOSYS)
		return EXIT_SUCCESS;	/* kernel too old */

	assert(dir_fd != -1);	
	close(dir_fd);

	/* create a tree like
	 * /
	 * +- tmp/
	 *    +- <tmpname>/
	 *       |- test/
	 *       |- some-file
	 *       +- some-link -> some-file
	 */
	dname = mkdtemp(dname_buf);
	assert(dname != NULL);

	dir_fd = open(dname, O_DIRECTORY|O_RDONLY);
	assert(dir_fd != -1);

	TEST(mkdirat(dir_fd, "test", 0700));
	TEST(chdir(dname));
	TEST(chdir("test"));

	file_fd = openat(dir_fd, "some-file", O_WRONLY|O_CREAT, 0400);
	assert(file_fd != -1);

	write(file_fd, "some text\n", 10);
	TEST(close(file_fd));

	TEST(symlinkat("some-file", dir_fd, "some-link"));
	TEST(symlinkat("dangling", dir_fd, "dangling-link"));

	/* now check, whether attributes of 'some-file' and 'some-link'
	 * returned by stat(2), lstat(2) and fstatat(2) are consistent */
	TEST(stat("../some-file", &st[0]));
	TEST(lstat("../some-link", &st[1]));

	TEST(fstatat(dir_fd, "some-file", &st[2], 0));
	TEST(fstatat(dir_fd, "some-link", &st[3], AT_SYMLINK_NOFOLLOW));
	TEST(fstatat(dir_fd, "some-link", &st[4], 0));

	TEST(faccessat(dir_fd, "some-file", R_OK, 0));
	TEST((faccessat(dir_fd, "some-file", W_OK, 0) == -1 &&
	      errno == EACCES) ? 0 : -1);;

	if (1)
		fputs("skipping faccessat(..., AT_SYMLINK_NOFOLLOW) checks for now...\n",
		      stderr);
	else {
		/* this is broken for dietlibc; the 'flags' parameter is not checked
		 * by the kernel but must be handled by the libc itself */
		TEST(faccessat(dir_fd, "some-link", W_OK, AT_SYMLINK_NOFOLLOW));
		TEST(faccessat(dir_fd, "dangling-link", R_OK, AT_SYMLINK_NOFOLLOW));
	}

	assert(st[0].st_mode == (0400 | S_IFREG));
	assert(S_ISLNK(st[1].st_mode));

	TEST(memne(&st[0], &st[1]));
	TEST(memeq(&st[0], &st[2]));
	TEST(memeq(&st[0], &st[4]));
	TEST(memeq(&st[1], &st[3]));

	/* and cleanup the mess... */
	TEST(unlinkat(dir_fd, "some-link", 0));
	TEST(unlinkat(dir_fd, "some-file", 0));
	TEST(unlinkat(dir_fd, "dangling-link", 0));
	TEST(unlinkat(dir_fd, "test", AT_REMOVEDIR));
	TEST(rmdir(dname));

	return EXIT_SUCCESS;
}
Example #23
0
static fsal_status_t makesymlink(struct fsal_obj_handle *dir_hdl,
				 const char *name, const char *link_path,
				 struct attrlist *attrib,
				 struct fsal_obj_handle **handle)
{
	struct vfs_fsal_obj_handle *myself, *hdl;
	int dir_fd = -1;
	struct stat stat;
	fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR;
	int retval = 0;
	int flags = O_PATH | O_NOACCESS;
	vfs_file_handle_t *fh = NULL;
	vfs_alloc_handle(fh);

	LogDebug(COMPONENT_FSAL, "create %s", name);

	*handle = NULL;		/* poison it first */
	if (!dir_hdl->obj_ops.handle_is(dir_hdl, DIRECTORY)) {
		LogCrit(COMPONENT_FSAL,
			"Parent handle is not a directory. hdl = 0x%p",
			dir_hdl);
		return fsalstat(ERR_FSAL_NOTDIR, 0);
	}
	myself = container_of(dir_hdl, struct vfs_fsal_obj_handle, obj_handle);
	if (dir_hdl->fsal != dir_hdl->fs->fsal) {
		LogDebug(COMPONENT_FSAL,
			 "FSAL %s operation for handle belonging to FSAL %s, return EXDEV",
			 dir_hdl->fsal->name,
			 dir_hdl->fs->fsal != NULL
				? dir_hdl->fs->fsal->name
				: "(none)");
		retval = EXDEV;
		goto hdlerr;
	}
	dir_fd = vfs_fsal_open(myself, flags, &fsal_error);
	if (dir_fd < 0)
		return fsalstat(fsal_error, -dir_fd);
	flags |= O_NOFOLLOW;	/* BSD needs O_NOFOLLOW for
				 * fhopen() of symlinks */
	retval = vfs_stat_by_handle(dir_fd, myself->handle, &stat, flags);
	if (retval < 0) {
		retval = errno;
		goto direrr;
	}
	/* Become the user because we are creating an object in this dir.
	 */
	fsal_set_credentials(op_ctx->creds);
	retval = symlinkat(link_path, dir_fd, name);
	if (retval < 0) {
		retval = errno;
		fsal_restore_ganesha_credentials();
		goto direrr;
	}
	fsal_restore_ganesha_credentials();
	retval = vfs_name_to_handle(dir_fd, dir_hdl->fs, name, fh);
	if (retval < 0) {
		retval = errno;
		goto linkerr;
	}
	/* now get attributes info,
	 * being careful to get the link, not the target */
	retval = fstatat(dir_fd, name, &stat, AT_SYMLINK_NOFOLLOW);
	if (retval < 0) {
		retval = errno;
		goto linkerr;
	}

	/* allocate an obj_handle and fill it up */
	hdl = alloc_handle(dir_fd, fh, dir_hdl->fs, &stat, NULL, name,
			   op_ctx->fsal_export);
	if (hdl == NULL) {
		retval = ENOMEM;
		goto linkerr;
	}
	*handle = &hdl->obj_handle;

	close(dir_fd);
	return fsalstat(ERR_FSAL_NO_ERROR, 0);

 linkerr:
	unlinkat(dir_fd, name, 0);

 direrr:
	close(dir_fd);
 hdlerr:
	if (retval == ENOENT)
		fsal_error = ERR_FSAL_STALE;
	else
		fsal_error = posix2fsal_error(retval);
	return fsalstat(fsal_error, retval);
}
Example #24
0
void
copymkdir(int rootfd, char const * dir, int skelfd, mode_t mode, uid_t uid,
    gid_t gid, int flags)
{
	char		*p, lnk[MAXPATHLEN], copybuf[4096];
	int		len, homefd, srcfd, destfd;
	ssize_t		sz;
	struct stat     st;
	struct dirent  *e;
	DIR		*d;

	if (*dir == '/')
		dir++;

	if (mkdirat(rootfd, dir, mode) != 0 && errno != EEXIST) {
		warn("mkdir(%s)", dir);
		return;
	}
	fchownat(rootfd, dir, uid, gid, AT_SYMLINK_NOFOLLOW);
	if (flags > 0)
		chflagsat(rootfd, dir, flags, AT_SYMLINK_NOFOLLOW);

	if (skelfd == -1)
		return;

	homefd = openat(rootfd, dir, O_DIRECTORY);
	if ((d = fdopendir(skelfd)) == NULL) {
		close(skelfd);
		close(homefd);
		return;
	}

	while ((e = readdir(d)) != NULL) {
		if (strcmp(e->d_name, ".") == 0 || strcmp(e->d_name, "..") == 0)
			continue;

		p = e->d_name;
		if (fstatat(skelfd, p, &st, AT_SYMLINK_NOFOLLOW) == -1)
			continue;

		if (strncmp(p, "dot.", 4) == 0)	/* Conversion */
			p += 3;

		if (S_ISDIR(st.st_mode)) {
			copymkdir(homefd, p, openat(skelfd, e->d_name, O_DIRECTORY),
			    st.st_mode & _DEF_DIRMODE, uid, gid, st.st_flags);
			continue;
		}

		if (S_ISLNK(st.st_mode) &&
		    (len = readlinkat(skelfd, e->d_name, lnk, sizeof(lnk) -1))
		    != -1) {
			lnk[len] = '\0';
			symlinkat(lnk, homefd, p);
			fchownat(homefd, p, uid, gid, AT_SYMLINK_NOFOLLOW);
			continue;
		}

		if (!S_ISREG(st.st_mode))
			continue;

		if ((srcfd = openat(skelfd, e->d_name, O_RDONLY)) == -1)
			continue;
		destfd = openat(homefd, p, O_RDWR | O_CREAT | O_EXCL,
		    st.st_mode);
		if (destfd == -1) {
			close(srcfd);
			continue;
		}

		while ((sz = read(srcfd, copybuf, sizeof(copybuf))) > 0)
			write(destfd, copybuf, sz);

		close(srcfd);
		/*
		 * Propagate special filesystem flags
		 */
		fchown(destfd, uid, gid);
		fchflags(destfd, st.st_flags);
		close(destfd);
	}
	closedir(d);
}
Example #25
0
static int
do_test (void)
{
  /* fdopendir takes over the descriptor, make a copy.  */
  int dupfd = dup (dir_fd);
  if (dupfd == -1)
    {
      puts ("dup failed");
      return 1;
    }
  if (lseek (dupfd, 0, SEEK_SET) != 0)
    {
      puts ("1st lseek failed");
      return 1;
    }

  /* The directory should be empty safe the . and .. files.  */
  DIR *dir = fdopendir (dupfd);
  if (dir == NULL)
    {
      puts ("fdopendir failed");
      return 1;
    }
  struct dirent64 *d;
  while ((d = readdir64 (dir)) != NULL)
    if (strcmp (d->d_name, ".") != 0 && strcmp (d->d_name, "..") != 0)
      {
	printf ("temp directory contains file \"%s\"\n", d->d_name);
	return 1;
      }
  closedir (dir);

  /* Try to create a file.  */
  int fd = openat (dir_fd, "some-file", O_CREAT|O_RDWR|O_EXCL, 0666);
  if (fd == -1)
    {
      if (errno == ENOSYS)
	{
	  puts ("*at functions not supported");
	  return 0;
	}

      puts ("file creation failed");
      return 1;
    }
  write (fd, "hello", 5);
  puts ("file created");

  struct stat64 st1;
  if (fstat64 (fd, &st1) != 0)
    {
      puts ("fstat64 failed");
      return 1;
    }

  close (fd);

  if (symlinkat ("some-file", dir_fd, "another-file") != 0)
    {
      puts ("symlinkat failed");
      return 1;
    }

  struct stat64 st2;
  if (fstatat64 (dir_fd, "some-file", &st2, 0) != 0)
    {
      puts ("fstatat64 failed");
      return 1;
    }
  if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino)
    {
      puts ("file changed after symlinkat");
      return 1;
    }

  if (fstatat64 (dir_fd, "another-file", &st2, AT_SYMLINK_NOFOLLOW) != 0)
    {
      puts ("2nd fstatat64 failed");
      return 1;
    }
  if (!S_ISLNK (st2.st_mode))
    {
      puts ("2nd fstatat64 does not show file is a symlink");
      return 1;
    }

  if (fstatat64 (dir_fd, "another-file", &st2, 0) != 0)
    {
      puts ("3rd fstatat64 failed");
      return 1;
    }
  if (st1.st_dev != st2.st_dev
      || st1.st_ino != st2.st_ino
      || st1.st_size != st2.st_size)
    {
      puts ("stat results do not match");
      return 1;
    }

  if (unlinkat (dir_fd, "another-file", 0) != 0)
    {
      puts ("unlinkat failed");
      return 1;
    }
  if (unlinkat (dir_fd, "some-file", 0) != 0)
    {
      puts ("2nd unlinkat failed");
      return 1;
    }

  close (dir_fd);

  return 0;
}
Example #26
0
static gboolean
checkout_file_from_input_at (OstreeRepo     *self,
                             OstreeRepoCheckoutOptions *options,
                             GFileInfo      *file_info,
                             GVariant       *xattrs,
                             GInputStream   *input,
                             int             destination_dfd,
                             const char     *destination_name,
                             GCancellable   *cancellable,
                             GError        **error)
{
  gboolean ret = FALSE;
  int res;

  if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_SYMBOLIC_LINK)
    {
      do
        res = symlinkat (g_file_info_get_symlink_target (file_info),
                         destination_dfd, destination_name);
      while (G_UNLIKELY (res == -1 && errno == EINTR));
      if (res == -1)
        {
          glnx_set_error_from_errno (error);
          goto out;
        }

      if (options->mode != OSTREE_REPO_CHECKOUT_MODE_USER)
        {
          if (G_UNLIKELY (fchownat (destination_dfd, destination_name,
                                    g_file_info_get_attribute_uint32 (file_info, "unix::uid"),
                                    g_file_info_get_attribute_uint32 (file_info, "unix::gid"),
                                    AT_SYMLINK_NOFOLLOW) == -1))
            {
              glnx_set_error_from_errno (error);
              goto out;
            }

          if (xattrs)
            {
              if (!glnx_dfd_name_set_all_xattrs (destination_dfd, destination_name,
                                                   xattrs, cancellable, error))
                goto out;
            }
        }
    }
  else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR)
    {
      g_autoptr(GOutputStream) temp_out = NULL;
      int fd;
      guint32 file_mode;

      file_mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
      /* Don't make setuid files on checkout when we're doing --user */
      if (options->mode == OSTREE_REPO_CHECKOUT_MODE_USER)
        file_mode &= ~(S_ISUID|S_ISGID);

      do
        fd = openat (destination_dfd, destination_name, O_WRONLY | O_CREAT | O_EXCL, file_mode);
      while (G_UNLIKELY (fd == -1 && errno == EINTR));
      if (fd == -1)
        {
          glnx_set_error_from_errno (error);
          goto out;
        }
      temp_out = g_unix_output_stream_new (fd, TRUE);
      fd = -1; /* Transfer ownership */

      if (!write_regular_file_content (self, options, temp_out, file_info, xattrs, input,
                                       cancellable, error))
        goto out;
    }
  else
    g_assert_not_reached ();
  
  ret = TRUE;
 out:
  return ret;
}
Example #27
0
static unsigned int
call_syscall(struct syscall_desc *scall, char *argv[])
{
	struct stat64 sb;
	long long flags;
	unsigned int i;
	char *endp;
	int name, rval;
	union {
		char *str;
		long long num;
	} args[MAX_ARGS];
#ifdef HAS_FREEBSD_ACL
	int entry_id = ACL_FIRST_ENTRY;
	acl_t acl, newacl;
	acl_entry_t entry, newentry;
#endif

	/*
	 * Verify correctness of the arguments.
	 */
	for (i = 0; i < sizeof(args)/sizeof(args[0]); i++) {
		if (scall->sd_args[i] == TYPE_NONE) {
			if (argv[i] == NULL || strcmp(argv[i], ":") == 0)
				break;
			fprintf(stderr, "too many arguments [%s]\n", argv[i]);
			exit(1);
		} else {
			if (argv[i] == NULL || strcmp(argv[i], ":") == 0) {
				if (scall->sd_args[i] & TYPE_OPTIONAL)
					break;
				fprintf(stderr, "too few arguments\n");
				exit(1);
			}
			if ((scall->sd_args[i] & TYPE_MASK) == TYPE_STRING) {
				if (strcmp(argv[i], "NULL") == 0)
					args[i].str = NULL;
				else if (strcmp(argv[i], "DEADCODE") == 0)
					args[i].str = (void *)0xdeadc0de;
				else
					args[i].str = argv[i];
			} else if ((scall->sd_args[i] & TYPE_MASK) ==
			    TYPE_NUMBER) {
				args[i].num = strtoll(argv[i], &endp, 0);
				if (*endp != '\0' &&
				    !isspace((unsigned char)*endp)) {
					fprintf(stderr,
					    "invalid argument %u, number expected [%s]\n",
					    i, endp);
					exit(1);
				}
			} else if ((scall->sd_args[i] & TYPE_MASK) ==
			    TYPE_DESCRIPTOR) {
				if (strcmp(argv[i], "AT_FDCWD") == 0) {
					args[i].num = AT_FDCWD;
				} else if (strcmp(argv[i], "BADFD") == 0) {
					/* In case AT_FDCWD is -1 on some systems... */
					if (AT_FDCWD == -1)
						args[i].num = -2;
					else
						args[i].num = -1;
				} else {
					int pos;

					pos = strtoll(argv[i], &endp, 0);
					if (*endp != '\0' &&
					    !isspace((unsigned char)*endp)) {
						fprintf(stderr,
						    "invalid argument %u, number expected [%s]\n",
						    i, endp);
						exit(1);
					}
					args[i].num = descriptor_get(pos);
				}
			}
		}
	}
	/*
	 * Call the given syscall.
	 */
#define	NUM(n)	(args[(n)].num)
#define	STR(n)	(args[(n)].str)
	switch (scall->sd_action) {
	case ACTION_OPEN:
		flags = str2flags(open_flags, STR(1));
		if (flags & O_CREAT) {
			if (i == 2) {
				fprintf(stderr, "too few arguments\n");
				exit(1);
			}
			rval = open(STR(0), (int)flags, (mode_t)NUM(2));
		} else {
			if (i == 3) {
				fprintf(stderr, "too many arguments\n");
				exit(1);
			}
			rval = open(STR(0), (int)flags);
		}
		if (rval >= 0)
			descriptor_add(rval);
		break;
	case ACTION_OPENAT:
		flags = str2flags(open_flags, STR(2));
		if (flags & O_CREAT) {
			if (i == 3) {
				fprintf(stderr, "too few arguments\n");
				exit(1);
			}
			rval = openat(NUM(0), STR(1), (int)flags,
			    (mode_t)NUM(3));
		} else {
			if (i == 4) {
				fprintf(stderr, "too many arguments\n");
				exit(1);
			}
			rval = openat(NUM(0), STR(1), (int)flags);
		}
		if (rval >= 0)
			descriptor_add(rval);
		break;
	case ACTION_CREATE:
		rval = open(STR(0), O_CREAT | O_EXCL, (mode_t)NUM(1));
		if (rval >= 0)
			close(rval);
		break;
	case ACTION_UNLINK:
		rval = unlink(STR(0));
		break;
	case ACTION_UNLINKAT:
		rval = unlinkat(NUM(0), STR(1),
		    (int)str2flags(unlinkat_flags, STR(2)));
		break;
	case ACTION_MKDIR:
		rval = mkdir(STR(0), (mode_t)NUM(1));
		break;
	case ACTION_MKDIRAT:
		rval = mkdirat(NUM(0), STR(1), (mode_t)NUM(2));
		break;
	case ACTION_RMDIR:
		rval = rmdir(STR(0));
		break;
	case ACTION_LINK:
		rval = link(STR(0), STR(1));
		break;
	case ACTION_LINKAT:
		rval = linkat(NUM(0), STR(1), NUM(2), STR(3),
		    (int)str2flags(linkat_flags, STR(4)));
		break;
	case ACTION_SYMLINK:
		rval = symlink(STR(0), STR(1));
		break;
	case ACTION_SYMLINKAT:
		rval = symlinkat(STR(0), NUM(1), STR(2));
		break;
	case ACTION_RENAME:
		rval = rename(STR(0), STR(1));
		break;
	case ACTION_RENAMEAT:
		rval = renameat(NUM(0), STR(1), NUM(2), STR(3));
		break;
	case ACTION_MKFIFO:
		rval = mkfifo(STR(0), (mode_t)NUM(1));
		break;
	case ACTION_MKFIFOAT:
		rval = mkfifoat(NUM(0), STR(1), (mode_t)NUM(2));
		break;
	case ACTION_MKNOD:
	case ACTION_MKNODAT:
	    {
		mode_t ntype;
		dev_t dev;
		int fa;

		switch (scall->sd_action) {
		case ACTION_MKNOD:
			fa = 0;
			break;
		case ACTION_MKNODAT:
			fa = 1;
			break;
		default:
			abort();
		}

		dev = makedev(NUM(fa + 3), NUM(fa + 4));
		if (strcmp(STR(fa + 1), "c") == 0)	/* character device */
			ntype = S_IFCHR;
		else if (strcmp(STR(fa + 1), "b") == 0)	/* block device */
			ntype = S_IFBLK;
		else if (strcmp(STR(fa + 1), "f") == 0)	/* fifo special */
			ntype = S_IFIFO;
		else if (strcmp(STR(fa + 1), "d") == 0)	/* directory */
			ntype = S_IFDIR;
		else if (strcmp(STR(fa + 1), "o") == 0)	/* regular file */
			ntype = S_IFREG;
		else {
			fprintf(stderr, "wrong argument 1\n");
			exit(1);
		}
		switch (scall->sd_action) {
		case ACTION_MKNOD:
			rval = mknod(STR(0), ntype | NUM(2), dev);
			break;
		case ACTION_MKNODAT:
			rval = mknodat(NUM(0), STR(1), ntype | NUM(3), dev);
			break;
		default:
			abort();
		}
		break;
	    }
	case ACTION_BIND:
	    {
		struct sockaddr_un sunx;

		sunx.sun_family = AF_UNIX;
		strncpy(sunx.sun_path, STR(0), sizeof(sunx.sun_path) - 1);
		sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0';
		rval = socket(AF_UNIX, SOCK_STREAM, 0);
		if (rval < 0)
			break;
		rval = bind(rval, (struct sockaddr *)&sunx, sizeof(sunx));
		break;
	    }
#ifdef HAS_BINDAT
	case ACTION_BINDAT:
	    {
		struct sockaddr_un sunx;

		sunx.sun_family = AF_UNIX;
		strncpy(sunx.sun_path, STR(1), sizeof(sunx.sun_path) - 1);
		sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0';
		rval = socket(AF_UNIX, SOCK_STREAM, 0);
		if (rval < 0)
			break;
		rval = bindat(NUM(0), rval, (struct sockaddr *)&sunx,
		    sizeof(sunx));
		break;
	    }
#endif
	case ACTION_CONNECT:
	    {
		struct sockaddr_un sunx;

		sunx.sun_family = AF_UNIX;
		strncpy(sunx.sun_path, STR(0), sizeof(sunx.sun_path) - 1);
		sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0';
		rval = socket(AF_UNIX, SOCK_STREAM, 0);
		if (rval < 0)
			break;
		rval = connect(rval, (struct sockaddr *)&sunx, sizeof(sunx));
		break;
	    }
#ifdef HAS_CONNECTAT
	case ACTION_CONNECTAT:
	    {
		struct sockaddr_un sunx;

		sunx.sun_family = AF_UNIX;
		strncpy(sunx.sun_path, STR(1), sizeof(sunx.sun_path) - 1);
		sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0';
		rval = socket(AF_UNIX, SOCK_STREAM, 0);
		if (rval < 0)
			break;
		rval = connectat(NUM(0), rval, (struct sockaddr *)&sunx,
		    sizeof(sunx));
		break;
	    }
#endif
	case ACTION_CHMOD:
		rval = chmod(STR(0), (mode_t)NUM(1));
		break;
	case ACTION_FCHMOD:
		rval = fchmod(NUM(0), (mode_t)NUM(1));
		break;
#ifdef HAS_LCHMOD
	case ACTION_LCHMOD:
		rval = lchmod(STR(0), (mode_t)NUM(1));
		break;
#endif
	case ACTION_FCHMODAT:
		rval = fchmodat(NUM(0), STR(1), (mode_t)NUM(2),
		    str2flags(fchmodat_flags, STR(3)));
		break;
	case ACTION_CHOWN:
		rval = chown(STR(0), (uid_t)NUM(1), (gid_t)NUM(2));
		break;
	case ACTION_FCHOWN:
		rval = fchown(NUM(0), (uid_t)NUM(1), (gid_t)NUM(2));
		break;
	case ACTION_LCHOWN:
		rval = lchown(STR(0), (uid_t)NUM(1), (gid_t)NUM(2));
		break;
	case ACTION_FCHOWNAT:
		rval = fchownat(NUM(0), STR(1), (uid_t)NUM(2), (gid_t)NUM(3),
		    (int)str2flags(fchownat_flags, STR(4)));
		break;
#ifdef HAS_CHFLAGS
	case ACTION_CHFLAGS:
		rval = chflags(STR(0),
		    (unsigned long)str2flags(chflags_flags, STR(1)));
		break;
#endif
#ifdef HAS_FCHFLAGS
	case ACTION_FCHFLAGS:
		rval = fchflags(NUM(0),
		    (unsigned long)str2flags(chflags_flags, STR(1)));
		break;
#endif
#ifdef HAS_CHFLAGSAT
	case ACTION_CHFLAGSAT:
		rval = chflagsat(NUM(0), STR(1),
		    (unsigned long)str2flags(chflags_flags, STR(2)),
		    (int)str2flags(chflagsat_flags, STR(3)));
		break;
#endif
#ifdef HAS_LCHFLAGS
	case ACTION_LCHFLAGS:
		rval = lchflags(STR(0),
		    (unsigned long)str2flags(chflags_flags, STR(1)));
		break;
#endif
	case ACTION_TRUNCATE:
		rval = truncate64(STR(0), NUM(1));
		break;
	case ACTION_FTRUNCATE:
		rval = ftruncate64(NUM(0), NUM(1));
		break;
	case ACTION_STAT:
		rval = stat64(STR(0), &sb);
		if (rval == 0) {
			show_stats(&sb, STR(1));
			return (i);
		}
		break;
	case ACTION_FSTAT:
		rval = fstat64(NUM(0), &sb);
		if (rval == 0) {
			show_stats(&sb, STR(1));
			return (i);
		}
		break;
	case ACTION_LSTAT:
		rval = lstat64(STR(0), &sb);
		if (rval == 0) {
			show_stats(&sb, STR(1));
			return (i);
		}
		break;
	case ACTION_FSTATAT:
		rval = fstatat(NUM(0), STR(1), &sb,
		    (int)str2flags(fstatat_flags, STR(2)));
		if (rval == 0) {
			show_stats(&sb, STR(3));
			return (i);
		}
		break;
	case ACTION_PATHCONF:
	case ACTION_FPATHCONF:
	case ACTION_LPATHCONF:
	    {
		long lrval;

		name = str2name(pathconf_names, STR(1));
		if (name == -1) {
			fprintf(stderr, "unknown name %s", STR(1));
			exit(1);
		}
		errno = 0;
		switch (scall->sd_action) {
		case ACTION_PATHCONF:
			lrval = pathconf(STR(0), name);
			break;
		case ACTION_FPATHCONF:
			lrval = fpathconf(NUM(0), name);
			break;
		case ACTION_LPATHCONF:
			lrval = lpathconf(STR(0), name);
			break;
		default:
			abort();
		}
		if (lrval == -1 && errno == 0) {
			printf("unlimited\n");
			return (i);
		} else if (lrval >= 0) {
			printf("%ld\n", lrval);
			return (i);
		}
		rval = -1;
		break;
	    }
#ifdef HAS_FREEBSD_ACL
	case ACTION_PREPENDACL:
		rval = -1;

		acl = acl_get_file(STR(0), ACL_TYPE_NFS4);
		if (acl == NULL)
			break;

		newacl = acl_from_text(STR(1));
		if (acl == NULL)
			break;

		while (acl_get_entry(newacl, entry_id, &newentry) == 1) {
			entry_id = ACL_NEXT_ENTRY;

			if (acl_create_entry_np(&acl, &entry, 0))
				break;

			if (acl_copy_entry(entry, newentry))
				break;
		}

		rval = acl_set_file(STR(0), ACL_TYPE_NFS4, acl);
		break;
	case ACTION_READACL:
		acl = acl_get_file(STR(0), ACL_TYPE_NFS4);
		if (acl == NULL)
			rval = -1;
		else
			rval = 0;
		break;
#endif
	case ACTION_WRITE:
		rval = write(NUM(0), STR(1), strlen(STR(1)));
		break;
	default:
		fprintf(stderr, "unsupported syscall\n");
		exit(1);
	}
#undef STR
#undef NUM
	if (rval < 0) {
		const char *serrno;

		serrno = err2str(errno);
		fprintf(stderr, "%s returned %d\n", scall->sd_name, rval);
		printf("%s\n", serrno);
		exit(1);
	}
	printf("0\n");
	return (i);
}
Example #28
0
static void
mkdir_home_parents(int dfd, const char *dir)
{
	struct stat st;
	char *dirs, *tmp;

	if (*dir != '/')
		errx(EX_DATAERR, "invalid base directory for home '%s'", dir);

	dir++;

	if (fstatat(dfd, dir, &st, 0) != -1) {
		if (S_ISDIR(st.st_mode))
			return;
		errx(EX_OSFILE, "root home `/%s' is not a directory", dir);
	}

	dirs = strdup(dir);
	if (dirs == NULL)
		errx(EX_UNAVAILABLE, "out of memory");

	tmp = strrchr(dirs, '/');
	if (tmp == NULL) {
		free(dirs);
		return;
	}
	tmp[0] = '\0';

	/*
	 * This is a kludge especially for Joerg :)
	 * If the home directory would be created in the root partition, then
	 * we really create it under /usr which is likely to have more space.
	 * But we create a symlink from cnf->home -> "/usr" -> cnf->home
	 */
	if (strchr(dirs, '/') == NULL) {
		asprintf(&tmp, "usr/%s", dirs);
		if (tmp == NULL)
			errx(EX_UNAVAILABLE, "out of memory");
		if (mkdirat(dfd, tmp, _DEF_DIRMODE) != -1 || errno == EEXIST) {
			fchownat(dfd, tmp, 0, 0, 0);
			symlinkat(tmp, dfd, dirs);
		}
		free(tmp);
	}
	tmp = dirs;
	if (fstatat(dfd, dirs, &st, 0) == -1) {
		while ((tmp = strchr(tmp + 1, '/')) != NULL) {
			*tmp = '\0';
			if (fstatat(dfd, dirs, &st, 0) == -1) {
				if (mkdirat(dfd, dirs, _DEF_DIRMODE) == -1)
					err(EX_OSFILE,  "'%s' (root home parent) is not a directory", dirs);
			}
			*tmp = '/';
		}
	}
	if (fstatat(dfd, dirs, &st, 0) == -1) {
		if (mkdirat(dfd, dirs, _DEF_DIRMODE) == -1)
			err(EX_OSFILE,  "'%s' (root home parent) is not a directory", dirs);
		fchownat(dfd, dirs, 0, 0, 0);
	}

	free(dirs);
}
Example #29
0
int
main(int argc, char *argv[])
{
	char *targetdir = ".", *target = NULL;
	int ret = 0, sflag = 0, fflag = 0, dirfd = AT_FDCWD,
	    hastarget = 0, flags = AT_SYMLINK_FOLLOW;
	struct stat st, tst;

	ARGBEGIN {
	case 'f':
		fflag = 1;
		break;
	case 'L':
		flags |= AT_SYMLINK_FOLLOW;
		break;
	case 'P':
		flags &= ~AT_SYMLINK_FOLLOW;
		break;
	case 's':
		sflag = 1;
		break;
	default:
		usage();
	} ARGEND

	if (!argc)
		usage();

	if (argc > 1) {
		if (!stat(argv[argc - 1], &st) && S_ISDIR(st.st_mode)) {
			if ((dirfd = open(argv[argc - 1], O_RDONLY)) < 0)
				eprintf("open %s:", argv[argc - 1]);
			targetdir = argv[argc - 1];
			if (targetdir[strlen(targetdir) - 1] == '/')
				targetdir[strlen(targetdir) - 1] = '\0';
		} else if (argc == 2) {
			hastarget = 1;
			target = argv[argc - 1];
		} else {
			eprintf("%s: not a directory\n", argv[argc - 1]);
		}
		argv[argc - 1] = NULL;
		argc--;
	}

	for (; *argv; argc--, argv++) {
		if (!hastarget)
			target = basename(*argv);

		if (!sflag) {
			if (stat(*argv, &st) < 0) {
				weprintf("stat %s:", *argv);
				ret = 1;
				continue;
			} else if (fstatat(dirfd, target, &tst, AT_SYMLINK_NOFOLLOW) < 0) {
				if (errno != ENOENT) {
					weprintf("fstatat %s %s:", targetdir, target);
					ret = 1;
					continue;
				}
			} else if (st.st_dev == tst.st_dev && st.st_ino == tst.st_ino) {
				if (!fflag) {
					weprintf("%s and %s/%s are the same file\n",
							*argv, targetdir, target);
					ret = 1;
				}
				continue;
			}
		}

		if (fflag && unlinkat(dirfd, target, 0) < 0 && errno != ENOENT) {
			weprintf("unlinkat %s %s:", targetdir, target);
			ret = 1;
			continue;
		}
		if ((sflag ? symlinkat(*argv, dirfd, target) :
		             linkat(AT_FDCWD, *argv, dirfd, target, flags)) < 0) {
			weprintf("%s %s <- %s/%s:", sflag ? "symlinkat" : "linkat",
			         *argv, targetdir, target);
			ret = 1;
		}
	}

	return ret;
}
Example #30
0
int symlink(const char* old_path, const char* new_path) {
  return symlinkat(old_path, AT_FDCWD, new_path);
}