Ejemplo n.º 1
0
struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
                           unsigned int mode, dev_t dev)
{
    struct inode *inode = NULL;
    struct gfs2_inode *dip = ghs->gh_gl->gl_object;
    struct inode *dir = &dip->i_inode;
    struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
    struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 };
    int error;
    u64 generation;
    struct buffer_head *bh = NULL;

    if (!name->len || name->len > GFS2_FNAMESIZE)
        return ERR_PTR(-ENAMETOOLONG);

    gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, ghs);
    error = gfs2_glock_nq(ghs);
    if (error)
        goto fail;

    error = create_ok(dip, name, mode);
    if (error)
        goto fail_gunlock;

    error = pick_formal_ino(sdp, &inum.no_formal_ino);
    if (error)
        goto fail_gunlock;

    error = alloc_dinode(dip, &inum.no_addr, &generation);
    if (error)
        goto fail_gunlock;

    error = gfs2_glock_nq_num(sdp, inum.no_addr, &gfs2_inode_glops,
                              LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1);
    if (error)
        goto fail_gunlock;

    error = make_dinode(dip, ghs[1].gh_gl, mode, &inum, &generation, dev, &bh);
    if (error)
        goto fail_gunlock2;

    inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode),
                              inum.no_addr,
                              inum.no_formal_ino, 0);
    if (IS_ERR(inode))
        goto fail_gunlock2;

    error = gfs2_inode_refresh(GFS2_I(inode));
    if (error)
        goto fail_gunlock2;

    error = gfs2_acl_create(dip, GFS2_I(inode));
    if (error)
        goto fail_gunlock2;

    error = gfs2_security_init(dip, GFS2_I(inode));
    if (error)
        goto fail_gunlock2;

    error = link_dinode(dip, name, GFS2_I(inode));
    if (error)
        goto fail_gunlock2;

    if (bh)
        brelse(bh);
    if (!inode)
        return ERR_PTR(-ENOMEM);
    return inode;

fail_gunlock2:
    gfs2_glock_dq_uninit(ghs + 1);
    if (inode)
        iput(inode);
fail_gunlock:
    gfs2_glock_dq(ghs);
fail:
    if (bh)
        brelse(bh);
    return ERR_PTR(error);
}

/**
 * gfs2_rmdiri - Remove a directory
 * @dip: The parent directory of the directory to be removed
 * @name: The name of the directory to be removed
 * @ip: The GFS2 inode of the directory to be removed
 *
 * Assumes Glocks on dip and ip are held
 *
 * Returns: errno
 */

int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name,
                struct gfs2_inode *ip)
{
    struct qstr dotname;
    int error;

    if (ip->i_di.di_entries != 2) {
        if (gfs2_consist_inode(ip))
            gfs2_dinode_print(ip);
        return -EIO;
    }

    error = gfs2_dir_del(dip, name);
    if (error)
        return error;

    error = gfs2_change_nlink(dip, -1);
    if (error)
        return error;

    gfs2_str2qstr(&dotname, ".");
    error = gfs2_dir_del(ip, &dotname);
    if (error)
        return error;

    gfs2_str2qstr(&dotname, "..");
    error = gfs2_dir_del(ip, &dotname);
    if (error)
        return error;

    /* It looks odd, but it really should be done twice */
    error = gfs2_change_nlink(ip, -1);
    if (error)
        return error;

    error = gfs2_change_nlink(ip, -1);
    if (error)
        return error;

    return error;
}

/*
 * gfs2_unlink_ok - check to see that a inode is still in a directory
 * @dip: the directory
 * @name: the name of the file
 * @ip: the inode
 *
 * Assumes that the lock on (at least) @dip is held.
 *
 * Returns: 0 if the parent/child relationship is correct, errno if it isn't
 */

int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
                   const struct gfs2_inode *ip)
{
    int error;

    if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode))
        return -EPERM;

    if ((dip->i_inode.i_mode & S_ISVTX) &&
            dip->i_inode.i_uid != current->fsuid &&
            ip->i_inode.i_uid != current->fsuid && !capable(CAP_FOWNER))
        return -EPERM;

    if (IS_APPEND(&dip->i_inode))
        return -EPERM;

    error = permission(&dip->i_inode, MAY_WRITE | MAY_EXEC, NULL);
    if (error)
        return error;

    error = gfs2_dir_check(&dip->i_inode, name, ip);
    if (error)
        return error;

    return 0;
}
Ejemplo n.º 2
0
static void
decompress(const char *in, const char *out, int bits)
{
	size_t nr;
	struct stat sb;
	FILE *ifp, *ofp;
	int exists, isreg, oreg;
	u_char buf[1024];

	exists = !stat(out, &sb);
	if (!force && exists && S_ISREG(sb.st_mode) && !permission(out))
		return;
	isreg = oreg = !exists || S_ISREG(sb.st_mode);

	ifp = ofp = NULL;
	if ((ifp = zopen(in, "r", bits)) == NULL) {
		cwarn("%s", in);
		return;
	}
	if (stat(in, &sb)) {
		cwarn("%s", in);
		goto err;
	}
	if (!S_ISREG(sb.st_mode))
		isreg = 0;

	/*
	 * Try to read the first few uncompressed bytes from the input file
	 * before blindly truncating the output file.
	 */
	if ((nr = fread(buf, 1, sizeof(buf), ifp)) == 0) {
		cwarn("%s", in);
		(void)fclose(ifp);
		return;
	}
	if ((ofp = fopen(out, "w")) == NULL ||
	    (nr != 0 && fwrite(buf, 1, nr, ofp) != nr)) {
		cwarn("%s", out);
		(void)fclose(ifp);
		return;
	}

	while ((nr = fread(buf, 1, sizeof(buf), ifp)) != 0)
		if (fwrite(buf, 1, nr, ofp) != nr) {
			cwarn("%s", out);
			goto err;
		}

	if (ferror(ifp) || fclose(ifp)) {
		cwarn("%s", in);
		goto err;
	}
	ifp = NULL;

	if (fclose(ofp)) {
		cwarn("%s", out);
		goto err;
	}

	if (isreg) {
		setfile(out, &sb);

		if (unlink(in))
			cwarn("%s", in);
	}
	return;

err:	if (ofp) {
		if (oreg)
			(void)unlink(out);
		(void)fclose(ofp);
	}
	if (ifp)
		(void)fclose(ifp);
}
Ejemplo n.º 3
0
static int gfs2_rename(struct inode *odir, struct dentry *odentry,
		       struct inode *ndir, struct dentry *ndentry)
{
	struct gfs2_inode *odip = GFS2_I(odir);
	struct gfs2_inode *ndip = GFS2_I(ndir);
	struct gfs2_inode *ip = GFS2_I(odentry->d_inode);
	struct gfs2_inode *nip = NULL;
	struct gfs2_sbd *sdp = GFS2_SB(odir);
	struct gfs2_holder ghs[5], r_gh;
	struct gfs2_rgrpd *nrgd;
	unsigned int num_gh;
	int dir_rename = 0;
	int alloc_required;
	unsigned int x;
	int error;

	if (ndentry->d_inode) {
		nip = GFS2_I(ndentry->d_inode);
		if (ip == nip)
			return 0;
	}

	/* Make sure we aren't trying to move a dirctory into it's subdir */

	if (S_ISDIR(ip->i_inode.i_mode) && odip != ndip) {
		dir_rename = 1;

		error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE, 0,
					   &r_gh);
		if (error)
			goto out;

		error = gfs2_ok_to_move(ip, ndip);
		if (error)
			goto out_gunlock_r;
	}

	num_gh = 1;
	gfs2_holder_init(odip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
	if (odip != ndip) {
		gfs2_holder_init(ndip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh);
		num_gh++;
	}
	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh);
	num_gh++;

	if (nip) {
		gfs2_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh);
		num_gh++;
		/* grab the resource lock for unlink flag twiddling 
		 * this is the case of the target file already existing
		 * so we unlink before doing the rename
		 */
		nrgd = gfs2_blk2rgrpd(sdp, nip->i_no_addr);
		if (nrgd)
			gfs2_holder_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh++);
	}

	error = gfs2_glock_nq_m(num_gh, ghs);
	if (error)
		goto out_uninit;

	/* Check out the old directory */

	error = gfs2_unlink_ok(odip, &odentry->d_name, ip);
	if (error)
		goto out_gunlock;

	/* Check out the new directory */

	if (nip) {
		error = gfs2_unlink_ok(ndip, &ndentry->d_name, nip);
		if (error)
			goto out_gunlock;

		if (S_ISDIR(nip->i_inode.i_mode)) {
			if (nip->i_di.di_entries < 2) {
				if (gfs2_consist_inode(nip))
					gfs2_dinode_print(nip);
				error = -EIO;
				goto out_gunlock;
			}
			if (nip->i_di.di_entries > 2) {
				error = -ENOTEMPTY;
				goto out_gunlock;
			}
		}
	} else {
		error = permission(ndir, MAY_WRITE | MAY_EXEC, NULL);
		if (error)
			goto out_gunlock;

		error = gfs2_dir_check(ndir, &ndentry->d_name, NULL);
		switch (error) {
		case -ENOENT:
			error = 0;
			break;
		case 0:
			error = -EEXIST;
		default:
			goto out_gunlock;
		};

		if (odip != ndip) {
			if (!ndip->i_inode.i_nlink) {
				error = -EINVAL;
				goto out_gunlock;
			}
			if (ndip->i_di.di_entries == (u32)-1) {
				error = -EFBIG;
				goto out_gunlock;
			}
			if (S_ISDIR(ip->i_inode.i_mode) &&
			    ndip->i_inode.i_nlink == (u32)-1) {
				error = -EMLINK;
				goto out_gunlock;
			}
		}
	}

	/* Check out the dir to be renamed */

	if (dir_rename) {
		error = permission(odentry->d_inode, MAY_WRITE, NULL);
		if (error)
			goto out_gunlock;
	}

	alloc_required = error = gfs2_diradd_alloc_required(ndir, &ndentry->d_name);
	if (error < 0)
		goto out_gunlock;
	error = 0;

	if (alloc_required) {
		struct gfs2_alloc *al = gfs2_alloc_get(ndip);

		error = gfs2_quota_lock(ndip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
		if (error)
			goto out_alloc;

		error = gfs2_quota_check(ndip, ndip->i_inode.i_uid, ndip->i_inode.i_gid);
		if (error)
			goto out_gunlock_q;

		al->al_requested = sdp->sd_max_dirres;

		error = gfs2_inplace_reserve(ndip);
		if (error)
			goto out_gunlock_q;

		error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
					 al->al_rgd->rd_length +
					 4 * RES_DINODE + 4 * RES_LEAF +
					 RES_STATFS + RES_QUOTA + 4, 0);
		if (error)
			goto out_ipreserv;
	} else {
		error = gfs2_trans_begin(sdp, 4 * RES_DINODE +
					 5 * RES_LEAF + 4, 0);
		if (error)
			goto out_gunlock;
	}

	/* Remove the target file, if it exists */

	if (nip) {
		if (S_ISDIR(nip->i_inode.i_mode))
			error = gfs2_rmdiri(ndip, &ndentry->d_name, nip);
		else {
			error = gfs2_dir_del(ndip, &ndentry->d_name);
			if (error)
				goto out_end_trans;
			error = gfs2_change_nlink(nip, -1);
		}
		if (error)
			goto out_end_trans;
	}

	if (dir_rename) {
		struct qstr name;
		gfs2_str2qstr(&name, "..");

		error = gfs2_change_nlink(ndip, +1);
		if (error)
			goto out_end_trans;
		error = gfs2_change_nlink(odip, -1);
		if (error)
			goto out_end_trans;

		error = gfs2_dir_mvino(ip, &name, ndip, DT_DIR);
		if (error)
			goto out_end_trans;
	} else {
		struct buffer_head *dibh;
		error = gfs2_meta_inode_buffer(ip, &dibh);
		if (error)
			goto out_end_trans;
		ip->i_inode.i_ctime = CURRENT_TIME;
		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
		gfs2_dinode_out(ip, dibh->b_data);
		brelse(dibh);
	}

	error = gfs2_dir_del(odip, &odentry->d_name);
	if (error)
		goto out_end_trans;

	error = gfs2_dir_add(ndir, &ndentry->d_name, ip, IF2DT(ip->i_inode.i_mode));
	if (error)
		goto out_end_trans;

out_end_trans:
	gfs2_trans_end(sdp);
out_ipreserv:
	if (alloc_required)
		gfs2_inplace_release(ndip);
out_gunlock_q:
	if (alloc_required)
		gfs2_quota_unlock(ndip);
out_alloc:
	if (alloc_required)
		gfs2_alloc_put(ndip);
out_gunlock:
	gfs2_glock_dq_m(num_gh, ghs);
out_uninit:
	for (x = 0; x < num_gh; x++)
		gfs2_holder_uninit(ghs + x);
out_gunlock_r:
	if (dir_rename)
		gfs2_glock_dq_uninit(&r_gh);
out:
	return error;
}
Ejemplo n.º 4
0
int CmdModify::execute (std::string& output)
{
  int rc = 0;
  int count = 0;

  // Apply filter.
  std::vector <Task> filtered;
  filter (filtered);
  if (filtered.size () == 0)
  {
    context.footnote (STRING_FEEDBACK_NO_TASKS_SP);
    return 1;
  }

  // Apply the command line modifications to the new task.
  A3 modifications = context.a3.extract_modifications ();
  if (!modifications.size ())
    throw std::string (STRING_CMD_MODIFY_NEED_TEXT);

  // Accumulated project change notifications.
  std::map <std::string, std::string> projectChanges;

  std::vector <Task>::iterator task;
  for (task = filtered.begin (); task != filtered.end (); ++task)
  {
    Task before (*task);
    modify_task_description_replace (*task, modifications);
    if (taskDiff (before, *task))
    {
      // Perform some logical consistency checks.
      if (task->has ("recur")  &&
          !task->has ("due")   &&
          !before.has ("due"))
        throw std::string (STRING_CMD_MODIFY_NO_DUE);

      if (task->has ("until")  &&
          !task->has ("recur") &&
          !before.has ("recur"))
        throw std::string (STRING_CMD_MODIFY_UNTIL);

      if (before.has ("recur") &&
          before.has ("due")   &&
          (!task->has ("due")  ||
           task->get ("due") == ""))
        throw std::string (STRING_CMD_MODIFY_REM_DUE);

      if (before.has ("recur")  &&
          (!task->has ("recur") ||
           task->get ("recur") == ""))
        throw std::string (STRING_CMD_MODIFY_REC_ALWAYS);

      // Delete the specified task.
      std::string question = format (STRING_CMD_MODIFY_CONFIRM,
                                     task->id,
                                     task->get ("description"));

      if (permission (*task, taskDifferences (before, *task) + question, filtered.size ()))
      {
        updateRecurrenceMask (*task);
        dependencyChainOnModify (before, *task);
        ++count;
        feedback_affected (STRING_CMD_MODIFY_TASK, *task);
        feedback_unblocked (*task);
        context.tdb2.modify (*task);
        if (context.verbose ("project"))
          projectChanges[task->get ("project")] = onProjectChange (before, *task);

        // Task potentially has siblings - modify them.
        if (task->has ("parent"))
        {
          std::vector <Task> siblings = context.tdb2.siblings (*task);
          if (siblings.size () &&
              confirm (STRING_CMD_MODIFY_RECUR))
          {
            std::vector <Task>::iterator sibling;
            for (sibling = siblings.begin (); sibling != siblings.end (); ++sibling)
            {
              Task alternate (*sibling);
              modify_task_description_replace (*sibling, modifications);
              updateRecurrenceMask (*sibling);
              dependencyChainOnModify (alternate, *sibling);
              ++count;
              feedback_affected (STRING_CMD_MODIFY_TASK_R, *sibling);
              feedback_unblocked (*sibling);
              context.tdb2.modify (*sibling);
              if (context.verbose ("project"))
                projectChanges[sibling->get ("project")] = onProjectChange (alternate, *sibling);
            }
          }
        }

        // Task potentially has child tasks - modify them.
        else if (task->get ("status") == "recurring")
        {
          std::vector <Task> children = context.tdb2.children (*task);
          if (children.size () &&
              confirm (STRING_CMD_MODIFY_RECUR))
          {
            std::vector <Task>::iterator child;
            for (child = children.begin (); child != children.end (); ++child)
            {
              Task alternate (*child);
              modify_task_description_replace (*child, modifications);
              updateRecurrenceMask (*child);
              context.tdb2.modify (*child);
              dependencyChainOnModify (alternate, *child);
              if (context.verbose ("project"))
                projectChanges[child->get ("project")] = onProjectChange (alternate, *child);
              ++count;
              feedback_affected (STRING_CMD_MODIFY_TASK_R, *child);
            }
          }
        }
      }
      else
      {
        std::cout << STRING_CMD_MODIFY_NO << "\n";
        rc  = 1;
      }
    }
  }

  // Now list the project changes.
  std::map <std::string, std::string>::iterator i;
  for (i = projectChanges.begin (); i != projectChanges.end (); ++i)
    if (i->first != "")
      context.footnote (i->second);

  context.tdb2.commit ();
  feedback_affected (count == 1 ? STRING_CMD_MODIFY_1 : STRING_CMD_MODIFY_N, count);
  return rc;
}
Ejemplo n.º 5
0
int CmdStop::execute (std::string& output)
{
  int rc = 0;
  int count = 0;

  // Apply filter.
  std::vector <Task> filtered;
  filter (filtered);
  if (filtered.size () == 0)
  {
    context.footnote (STRING_FEEDBACK_NO_TASKS_SP);
    return 1;
  }

  // Apply the command line modifications to the new task.
  A3 modifications = context.a3.extract_modifications ();

  // Accumulated project change notifications.
  std::map <std::string, std::string> projectChanges;

  std::vector <Task>::iterator task;
  for (task = filtered.begin (); task != filtered.end (); ++task)
  {
    if (task->has ("start"))
    {
      Task before (*task);

      // Stop the specified task.
      std::string question = format (STRING_CMD_STOP_CONFIRM,
                                     task->id,
                                     task->get ("description"));

      modify_task_annotate (*task, modifications);
      task->remove ("start");

      if (context.config.getBoolean ("journal.time"))
        task->addAnnotation (context.config.get ("journal.time.stop.annotation"));

      if (permission (*task, taskDifferences (before, *task) + question, filtered.size ()))
      {
        updateRecurrenceMask (*task);
        context.tdb2.modify (*task);
        ++count;
        feedback_affected (STRING_CMD_STOP_TASK, *task);
        dependencyChainOnStart (*task);
        if (context.verbose ("project"))
          projectChanges[task->get ("project")] = onProjectChange (*task, false);
      }
      else
      {
        std::cout << STRING_CMD_STOP_NO << "\n";
        rc = 1;
        if (_permission_quit)
          break;
      }
    }
    else
    {
      std::cout << format (STRING_CMD_STOP_ALREADY,
                           task->id,
                           task->get ("description"))
                << "\n";
      rc = 1;
    }
  }

  // Now list the project changes.
  std::map <std::string, std::string>::iterator i;
  for (i = projectChanges.begin (); i != projectChanges.end (); ++i)
    if (i->first != "")
      context.footnote (i->second);

  context.tdb2.commit ();
  feedback_affected (count == 1 ? STRING_CMD_STOP_1 : STRING_CMD_STOP_N, count);
  return rc;
}
Ejemplo n.º 6
0
static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
		     struct dentry *dentry)
{
	struct gfs2_inode *dip = GFS2_I(dir);
	struct gfs2_sbd *sdp = GFS2_SB(dir);
	struct inode *inode = old_dentry->d_inode;
	struct gfs2_inode *ip = GFS2_I(inode);
	struct gfs2_holder ghs[2];
	int alloc_required;
	int error;

	if (S_ISDIR(inode->i_mode))
		return -EPERM;

	gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);

	error = gfs2_glock_nq_m(2, ghs);
	if (error)
		goto out;

	error = permission(dir, MAY_WRITE | MAY_EXEC, NULL);
	if (error)
		goto out_gunlock;

	error = gfs2_dir_check(dir, &dentry->d_name, NULL);
	switch (error) {
	case -ENOENT:
		break;
	case 0:
		error = -EEXIST;
	default:
		goto out_gunlock;
	}

	error = -EINVAL;
	if (!dip->i_inode.i_nlink)
		goto out_gunlock;
	error = -EFBIG;
	if (dip->i_di.di_entries == (u32)-1)
		goto out_gunlock;
	error = -EPERM;
	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
		goto out_gunlock;
	error = -EINVAL;
	if (!ip->i_inode.i_nlink)
		goto out_gunlock;
	error = -EMLINK;
	if (ip->i_inode.i_nlink == (u32)-1)
		goto out_gunlock;

	alloc_required = error = gfs2_diradd_alloc_required(dir, &dentry->d_name);
	if (error < 0)
		goto out_gunlock;
	error = 0;

	if (alloc_required) {
		struct gfs2_alloc *al = gfs2_alloc_get(dip);

		error = gfs2_quota_lock(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
		if (error)
			goto out_alloc;

		error = gfs2_quota_check(dip, dip->i_inode.i_uid, dip->i_inode.i_gid);
		if (error)
			goto out_gunlock_q;

		al->al_requested = sdp->sd_max_dirres;

		error = gfs2_inplace_reserve(dip);
		if (error)
			goto out_gunlock_q;

		error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
					 al->al_rgd->rd_length +
					 2 * RES_DINODE + RES_STATFS +
					 RES_QUOTA, 0);
		if (error)
			goto out_ipres;
	} else {
		error = gfs2_trans_begin(sdp, 2 * RES_DINODE + RES_LEAF, 0);
		if (error)
			goto out_ipres;
	}

	error = gfs2_dir_add(dir, &dentry->d_name, ip, IF2DT(inode->i_mode));
	if (error)
		goto out_end_trans;

	error = gfs2_change_nlink(ip, +1);

out_end_trans:
	gfs2_trans_end(sdp);
out_ipres:
	if (alloc_required)
		gfs2_inplace_release(dip);
out_gunlock_q:
	if (alloc_required)
		gfs2_quota_unlock(dip);
out_alloc:
	if (alloc_required)
		gfs2_alloc_put(dip);
out_gunlock:
	gfs2_glock_dq_m(2, ghs);
out:
	gfs2_holder_uninit(ghs);
	gfs2_holder_uninit(ghs + 1);
	if (!error) {
		atomic_inc(&inode->i_count);
		d_instantiate(dentry, inode);
		mark_inode_dirty(inode);
	}
	return error;
}
Ejemplo n.º 7
0
Py::Object pysvn_client::cmd_move2( const Py::Tuple &a_args, const Py::Dict &a_kws )
{
    static argument_description args_desc[] =
    {
    { true, name_sources },
    { true, name_dest_url_or_path },
    { false, name_force },
    { false, name_move_as_child },
    { false, name_make_parents },
    { false, name_revprops },
    { false, NULL }
    };
    FunctionArguments args( "move2", args_desc, a_args, a_kws );
    args.check();

    SvnPool pool( m_context );
    pysvn_commit_info_t *commit_info = NULL;

    std::string type_error_message;
    try
    {
        type_error_message = "expecting list for sources (arg 1)";
        Py::List list_all_sources = args.getArg( name_sources );

        apr_array_header_t *all_sources =
            apr_array_make( pool, list_all_sources.length(), sizeof(const char *) );

        for( unsigned int index=0; index<list_all_sources.length(); index++ )
        {
            type_error_message = "expecting string in sources list";
            Py::String py_src_url_or_path( list_all_sources[ index ] );

            std::string src_url_or_path;
            if( py_src_url_or_path.isUnicode() )
            {
                Py::String utf8( py_src_url_or_path.encode( name_utf8 ) );
                src_url_or_path = py_src_url_or_path.as_std_string();
            }
            else
            {
                src_url_or_path = py_src_url_or_path.as_std_string();
            }

            std::string norm_src_url_or_path( svnNormalisedIfPath( src_url_or_path, pool ) );

            const char *src_path_copy = apr_pstrdup( pool, norm_src_url_or_path.c_str() );

            APR_ARRAY_PUSH( all_sources, const char *) = src_path_copy;
        }

        type_error_message = "expecting string for dest_url_or_path";
        Py::String dest_path( args.getUtf8String( name_dest_url_or_path ) );

        type_error_message = "expecting boolean for keyword force";
        bool force = args.getBoolean( name_force, false );

        type_error_message = "expecting boolean for keyword move_as_child";
        bool move_as_child = args.getBoolean( name_move_as_child, false );

        type_error_message = "expecting boolean for keyword make_parents";
        bool make_parents = args.getBoolean( name_make_parents, false );

        apr_hash_t *revprops = NULL;
        if( args.hasArg( name_revprops ) )
        {
            Py::Object py_revprop = args.getArg( name_revprops );
            if( !py_revprop.isNone() )
            {
                revprops = hashOfStringsFromDistOfStrings( py_revprop, pool );
            }
        }

        try
        {
            std::string norm_dest_path( svnNormalisedIfPath( dest_path, pool ) );

            checkThreadPermission();
            PythonAllowThreads permission( m_context );

            // behavior changed
            svn_error_t *error = svn_client_move5
                (
                &commit_info,
                all_sources,
                norm_dest_path.c_str(),
                force,
                move_as_child,
                make_parents,
                revprops,
                m_context,
                pool
                );
            permission.allowThisThread();
            if( error != NULL )
            {
                throw SvnException( error );
            }
        }
        catch( SvnException &e )
        {
            // use callback error over ClientException
            m_context.checkForError( m_module.client_error );

            throw_client_error( e );
        }
    }
    catch( Py::TypeError & )
    {
        throw Py::TypeError( type_error_message );
    }

    return toObject( commit_info );
}
Ejemplo n.º 8
0
static int proc_follow_link(struct inode * dir, struct inode * inode,
	int flag, int mode, struct inode ** res_inode)
{
	unsigned int pid, ino;
	struct task_struct * p;
	struct inode * new_inode;
	int i, error;

	*res_inode = NULL;
	if (dir)
		iput(dir);
	if (!inode)
		return -ENOENT;
	if ((error = permission(inode, MAY_EXEC)) != 0){
		iput(inode);
		return error;
	}
	ino = inode->i_ino;
	pid = ino >> 16;
	ino &= 0x0000ffff;
	for (i = 0 ; i < NR_TASKS ; i++)
		if ((p = task[i]) && p->pid == pid)
			break;
	if (i >= NR_TASKS) {
		iput(inode);
		return -ENOENT;
	}
	new_inode = NULL;
	switch (ino) {
		case PROC_PID_CWD:
			if (!p->fs)
				break;
			new_inode = p->fs->pwd;
			break;
		case PROC_PID_ROOT:
			if (!p->fs)
				break;
			new_inode = p->fs->root;
			break;
		case PROC_PID_EXE: {
			struct vm_area_struct * vma;
			if (!p->mm)
				break;
			vma = p->mm->mmap;
			while (vma) {
				if (vma->vm_flags & VM_EXECUTABLE) {
					new_inode = vma->vm_inode;
					break;
				}
				vma = vma->vm_next;
			}
			break;
		}
		default:
			switch (ino >> 8) {
			case PROC_PID_FD_DIR:
				if (!p->files)
					break;
				ino &= 0xff;
				if (ino < NR_OPEN && p->files && p->files->fd[ino]) {
					new_inode = p->files->fd[ino]->f_inode;
				}
				break;
			}
	}
	iput(inode);
	if (!new_inode)
		return -ENOENT;
	*res_inode = new_inode;
	new_inode->i_count++;
	return 0;
}
Ejemplo n.º 9
0
Py::Object pysvn_client::cmd_copy( const Py::Tuple &a_args, const Py::Dict &a_kws )
{
    static argument_description args_desc[] =
    {
    { true,  name_src_url_or_path },
    { true,  name_dest_url_or_path },
    { false, name_src_revision },
    { false, NULL }
    };
    FunctionArguments args( "copy", args_desc, a_args, a_kws );
    args.check();

    SvnPool pool( m_context );
    pysvn_commit_info_t *commit_info = NULL;

    std::string type_error_message;
    try
    {
        type_error_message = "expecting string for src_path (arg 1)";
        Py::String src_path( args.getUtf8String( name_src_url_or_path ) );

        type_error_message = "expecting string for dest_path (arg 2)";
        Py::String dest_path( args.getUtf8String( name_dest_url_or_path ) );

        type_error_message = "expecting revision for keyword src_revision";
        svn_opt_revision_t revision;
        if( is_svn_url( src_path ) )
            revision = args.getRevision( name_src_revision, svn_opt_revision_head );
        else
            revision = args.getRevision( name_src_revision, svn_opt_revision_working );

        try
        {
            std::string norm_src_path( svnNormalisedIfPath( src_path, pool ) );
            std::string norm_dest_path( svnNormalisedIfPath( dest_path, pool ) );

            checkThreadPermission();

            PythonAllowThreads permission( m_context );

#if defined( PYSVN_HAS_CLIENT_COPY3 )
            // behavior changed
            svn_error_t *error = svn_client_copy3
                (
                &commit_info,
                norm_src_path.c_str(),
                &revision,
                norm_dest_path.c_str(),
                m_context,
                pool
                );
#elif defined( PYSVN_HAS_CLIENT_COPY2 )
            svn_error_t *error = svn_client_copy2
                (
                &commit_info,       // commit info type changed
                norm_src_path.c_str(),
                &revision,
                norm_dest_path.c_str(),
                m_context,
                pool
                );
#else
            svn_error_t *error = svn_client_copy
                (
                &commit_info,
                norm_src_path.c_str(),
                &revision,
                norm_dest_path.c_str(),
                m_context,
                pool
                );
#endif
            permission.allowThisThread();
            if( error != NULL )
                throw SvnException( error );
        }
        catch( SvnException &e )
        {
            // use callback error over ClientException
            m_context.checkForError( m_module.client_error );

            throw_client_error( e );
        }
    }
    catch( Py::TypeError & )
    {
        throw Py::TypeError( type_error_message );
    }

    return toObject( commit_info );
}
Ejemplo n.º 10
0
Py::Object pysvn_client::cmd_copy2( const Py::Tuple &a_args, const Py::Dict &a_kws )
{
    static argument_description args_desc[] =
    {
    { true, name_sources },
    { true, name_dest_url_or_path },
    { false, name_copy_as_child },
    { false, name_make_parents },
    { false, name_revprops },
    { false, NULL }
    };
    FunctionArguments args( "copy2", args_desc, a_args, a_kws );
    args.check();

    SvnPool pool( m_context );
    pysvn_commit_info_t *commit_info = NULL;

    std::string type_error_message;
    try
    {
        type_error_message = "expecting list for sources (arg 1)";
        Py::List list_all_sources = args.getArg( name_sources );

        apr_array_header_t *all_sources =
            apr_array_make( pool, list_all_sources.length(), sizeof(svn_client_copy_source_t *) );

        for( unsigned int index=0; index<list_all_sources.length(); index++ )
        {
            Py::Tuple tuple_src_rev_pegrev( list_all_sources[ index ] );

            std::string src_url_or_path;
            svn_opt_revision_t *revision = reinterpret_cast<svn_opt_revision_t *>( apr_palloc( pool, sizeof( svn_opt_revision_t ) ) );
            svn_opt_revision_t *peg_revision = reinterpret_cast<svn_opt_revision_t *>( apr_palloc( pool, sizeof( svn_opt_revision_t ) ) );

            if( tuple_src_rev_pegrev.length() > 3 )
            {
                std::string msg = "copy2() expecting tuple with 2 or 3 values in sources list";
                throw Py::AttributeError( msg );
            }

            type_error_message = "expecting string for 1st tuple value in sources list";
            Py::String py_src_url_or_path( tuple_src_rev_pegrev[0] );
            if( py_src_url_or_path.isUnicode() )
            {
                Py::String utf8( py_src_url_or_path.encode( name_utf8 ) );
                src_url_or_path = py_src_url_or_path.as_std_string();
            }
            else
            {
                src_url_or_path = py_src_url_or_path.as_std_string();
            }
            std::string norm_src_url_or_path( svnNormalisedIfPath( src_url_or_path, pool ) );
            bool is_url = is_svn_url( norm_src_url_or_path );

            if( tuple_src_rev_pegrev.length() >= 2 )
            {
                Py::Object obj( tuple_src_rev_pegrev[1] );

                if( pysvn_revision::check( obj ) )
                {
                    pysvn_revision *rev = static_cast<pysvn_revision *>( obj.ptr() );
                    *revision = rev->getSvnRevision();

                    revisionKindCompatibleCheck( is_url, *revision,
                        "sources list 2nd tuple value", "sources list 1st tuple value" );
                }
                else
                {
                    std::string msg = "copy2() expecting revision for 2nd tuple value in sources list";
                    throw Py::AttributeError( msg );
                }
            }
            else
            {
                if( is_url )
                {
                    revision->kind = svn_opt_revision_head;
                }
                else
                {
                    revision->kind = svn_opt_revision_working;
                }
            }

            if( tuple_src_rev_pegrev.length() >= 3 )
            {
                Py::Object obj( tuple_src_rev_pegrev[2] );

                if( pysvn_revision::check( obj ) )
                {
                    pysvn_revision *rev = static_cast<pysvn_revision *>( obj.ptr() );
                    *peg_revision = rev->getSvnRevision();

                    revisionKindCompatibleCheck( is_url, *peg_revision,
                        "sources list 2nd tuple value", "sources list 1st tuple value" );
                }
                else
                {
                    std::string msg = "copy2() expecting revision for 3rd tuple value in sources list";
                    throw Py::AttributeError( msg );
                }
            }
            else
            {
                *peg_revision = *revision;
            }

            svn_client_copy_source_t *source = reinterpret_cast<svn_client_copy_source_t *>( apr_palloc( pool, sizeof(*source) ) );
            source->path = apr_pstrdup( pool, norm_src_url_or_path.c_str() );
            source->revision = revision;
            source->peg_revision = peg_revision;

            APR_ARRAY_PUSH( all_sources, svn_client_copy_source_t *) = source;
        }

        type_error_message = "expecting string for dest_url_or_path";
        Py::String dest_path( args.getUtf8String( name_dest_url_or_path ) );

        type_error_message = "expecting boolean for keyword copy_as_child";
        bool copy_as_child = args.getBoolean( name_copy_as_child, false );

        type_error_message = "expecting boolean for keyword make_parents";
        bool make_parents = args.getBoolean( name_make_parents, false );

        apr_hash_t *revprops = NULL;
        if( args.hasArg( name_revprops ) )
        {
            Py::Object py_revprop = args.getArg( name_revprops );
            if( !py_revprop.isNone() )
            {
                revprops = hashOfStringsFromDistOfStrings( py_revprop, pool );
            }
        }

        try
        {
            std::string norm_dest_path( svnNormalisedIfPath( dest_path, pool ) );

            checkThreadPermission();

            PythonAllowThreads permission( m_context );

            // behavior changed
            svn_error_t *error = svn_client_copy4
                (
                &commit_info,
                all_sources,
                norm_dest_path.c_str(),
                copy_as_child,
                make_parents,
                revprops,
                m_context,
                pool
                );
            permission.allowThisThread();
            if( error != NULL )
            {
                throw SvnException( error );
            }
        }
        catch( SvnException &e )
        {
            // use callback error over ClientException
            m_context.checkForError( m_module.client_error );

            throw_client_error( e );
        }
    }
    catch( Py::TypeError & )
    {
        throw Py::TypeError( type_error_message );
    }

    return toObject( commit_info );
}
Ejemplo n.º 11
0
int CmdDelete::execute (std::string& output)
{
  int rc = 0;
  int count = 0;

  // Apply filter.
  std::vector <Task> filtered;
  filter (filtered);
  if (filtered.size () == 0)
  {
    context.footnote (STRING_FEEDBACK_NO_TASKS_SP);
    return 1;
  }

  // Apply the command line modifications to the new task.
  A3 modifications = context.a3.extract_modifications ();

  // Accumulated project change notifications.
  std::map <std::string, std::string> projectChanges;

  std::vector <Task>::iterator task;
  for (task = filtered.begin (); task != filtered.end (); ++task)
  {
    Task before (*task);

    if (task->getStatus () == Task::pending   ||
        task->getStatus () == Task::completed ||
        task->getStatus () == Task::waiting)
    {
      // Delete the specified task.
      std::string question;
      if (task->id)
        question = format (STRING_CMD_DELETE_CONFIRM,
                           task->id,
                           task->get ("description"));
      else
        question = format (STRING_CMD_DELETE_CONFIRM,
                           task->get ("uuid"),
                           task->get ("description"));

      modify_task_annotate (*task, modifications);
      task->setStatus (Task::deleted);
      if (! task->has ("end"))
        task->setEnd ();

      if (permission (*task, question, filtered.size ()))
      {
        updateRecurrenceMask (*task);
        ++count;
        context.tdb2.modify (*task);
        feedback_affected (STRING_CMD_DELETE_TASK, *task);
        feedback_unblocked (*task);
        dependencyChainOnComplete (*task);
        if (context.verbose ("project"))
          projectChanges[task->get ("project")] = onProjectChange (*task, true);

        // Delete siblings.
        if (task->has ("parent"))
        {
          std::vector <Task> siblings = context.tdb2.siblings (*task);
          if (siblings.size () &&
              confirm (STRING_CMD_DELETE_CONFIRM_R))
          {
            std::vector <Task>::iterator sibling;
            for (sibling = siblings.begin (); sibling != siblings.end (); ++sibling)
            {
              modify_task_annotate (*sibling, modifications);
              sibling->setStatus (Task::deleted);
              if (! sibling->has ("end"))
                sibling->setEnd ();

              updateRecurrenceMask (*sibling);
              context.tdb2.modify (*sibling);
              feedback_affected (STRING_CMD_DELETE_TASK_R, *sibling);
              feedback_unblocked (*sibling);
              ++count;
            }

            // Delete the parent
            Task parent;
            context.tdb2.get (task->get ("parent"), parent);
            parent.setStatus (Task::deleted);
            if (! parent.has ("end"))
              parent.setEnd ();

            context.tdb2.modify (parent);
          }
        }
      }
      else
      {
        std::cout << STRING_CMD_DELETE_NO << "\n";
        rc  = 1;
      }
    }
    else
    {
      std::cout << format (STRING_CMD_DELETE_NOT_DEL,
                           task->id,
                           task->get ("description"))
          << "\n";
      rc = 1;
    }
  }

  // Now list the project changes.
  std::map <std::string, std::string>::iterator i;
  for (i = projectChanges.begin (); i != projectChanges.end (); ++i)
    if (i->first != "")
      context.footnote (i->second);

  context.tdb2.commit ();
  feedback_affected (count == 1 ? STRING_CMD_DELETE_1 : STRING_CMD_DELETE_N, count);
  return rc;
}
Ejemplo n.º 12
0
static void do_dir_line (tux_req_t *req, int cachemiss)
{
	struct linux_dirent64 *dirp, *dirp0;
	char string0[MAX_OBJECTNAME_LEN+200], *tmp;
	int len, curroff, total, str_len = 0;
	int err, flag = cachemiss ? 0 : LOOKUP_ATOMIC;
	struct nameidata base = { };
	struct dentry *dentry = NULL;
	struct inode *inode = NULL;
	struct vfsmount *mnt = NULL;

	if (req->proto->check_req_err(req, cachemiss))
		return;

	tmp = NULL;
	dirp0 = req->dirp0;
	curroff = req->curroff;
	total = req->total;

	dirp = (struct linux_dirent64 *)((char *)dirp0 + curroff);
	if (!dirp->d_name || !dirp->d_name[0])
		goto next_dir;
	/*
	 * Hide .xxxxx files:
	 */
	if (dirp->d_name[0] == '.')
		goto next_dir;
	Dprintk("<%s T:%d (off:%Ld) (len:%d)>\n", dirp->d_name, dirp->d_type, dirp->d_off, dirp->d_reclen);
	if (tux_hide_unreadable) {
		switch (dirp->d_type) {
			default:
				goto next_dir;
			case DT_UNKNOWN:
			case DT_REG:
			case DT_DIR:
			case DT_LNK:
			/* valid entries - fall through. */
				;
		}
	}
	len = strlen(dirp->d_name);
	if (len >= MAX_OBJECTNAME_LEN) {
		dirp->d_name[MAX_OBJECTNAME_LEN] = 0;
		len = MAX_OBJECTNAME_LEN-1;
	}

	if (!req->dentry)
		TUX_BUG();

	base.flags = flag;
	base.last_type = LAST_ROOT;
	base.dentry = dget(req->dentry);
	base.mnt = mntget(req->cwd_mnt);

	switch_docroot(req);
	err = path_walk(dirp->d_name, &base);

	Dprintk("path_walk() returned %d.\n", err);

	if (err) {
		if (err == -EWOULDBLOCKIO) {
			add_tux_atom(req, do_dir_line);
			queue_cachemiss(req);
			return;
		}
		goto next_dir;
	}

	dentry = base.dentry;
	mnt = base.mnt;
	if (!dentry)
		TUX_BUG();
	if (IS_ERR(dentry))
		TUX_BUG();
	inode = dentry->d_inode;
	if (!inode)
		TUX_BUG();
	if (!dirp->d_type)
		dirp->d_type = get_d_type(dentry);
	if (tux_hide_unreadable) {
		umode_t mode;

		mode = inode->i_mode;
		if (mode & tux_mode_forbidden)
			goto out_dput;
		if (!(mode & tux_mode_allowed))
			goto out_dput;

		err = permission(inode, MAY_READ, NULL);
		if (err)
			goto out_dput;
		if (dirp->d_type == DT_DIR) {
			err = permission(inode, MAY_EXEC, NULL);
			if (err)
				goto out_dput;
		}
	}

	tmp = req->proto->print_dir_line(req, string0, dirp->d_name, len, dirp->d_type, dentry, inode);
	if (tmp)
		str_len = tmp-string0;
out_dput:
	dput(dentry);
	mntput(mnt);
next_dir:
	curroff += dirp->d_reclen;

	if (tmp && (tmp != string0))
		Dprintk("writing line (len: %d): <%s>\n", strlen(string0), string0);

	if (curroff < total) {
		req->dirp0 = dirp0;
		req->curroff = curroff;
		add_tux_atom(req, do_dir_line);
	} else {
		kfree(dirp0);
		req->dirp0 = NULL;
		req->curroff = 0;
		// falls back to the list_directory atom
	}
	if (tmp && (tmp != string0))
		__send_async_message(req, string0, 200, str_len, 0);
	else
		add_req_to_workqueue(req);
}
Ejemplo n.º 13
0
Barrier::~Barrier ()
throw (permission)
{
	size_t waiters = barrier.waiting.count;
	assert(waiters == 0, permission());
}
Ejemplo n.º 14
0
static int hpfs_unlink(struct inode *dir, struct dentry *dentry)
{
	const char *name = dentry->d_name.name;
	unsigned len = dentry->d_name.len;
	struct quad_buffer_head qbh;
	struct hpfs_dirent *de;
	struct inode *inode = dentry->d_inode;
	dnode_secno dno;
	fnode_secno fno;
	int r;
	int rep = 0;
	int err;

	lock_kernel();
	hpfs_adjust_length((char *)name, &len);
again:
	mutex_lock(&hpfs_i(inode)->i_parent_mutex);
	mutex_lock(&hpfs_i(dir)->i_mutex);
	err = -ENOENT;
	de = map_dirent(dir, hpfs_i(dir)->i_dno, (char *)name, len, &dno, &qbh);
	if (!de)
		goto out;

	err = -EPERM;
	if (de->first)
		goto out1;

	err = -EISDIR;
	if (de->directory)
		goto out1;

	fno = de->fnode;
	r = hpfs_remove_dirent(dir, dno, de, &qbh, 1);
	switch (r) {
	case 1:
		hpfs_error(dir->i_sb, "there was error when removing dirent");
		err = -EFSERROR;
		break;
	case 2:		/* no space for deleting, try to truncate file */

		err = -ENOSPC;
		if (rep++)
			break;

		mutex_unlock(&hpfs_i(dir)->i_mutex);
		mutex_unlock(&hpfs_i(inode)->i_parent_mutex);
		d_drop(dentry);
		spin_lock(&dentry->d_lock);
		if (atomic_read(&dentry->d_count) > 1 ||
		    permission(inode, MAY_WRITE, NULL) ||
		    !S_ISREG(inode->i_mode) ||
		    get_write_access(inode)) {
			spin_unlock(&dentry->d_lock);
			d_rehash(dentry);
		} else {
			struct iattr newattrs;
			spin_unlock(&dentry->d_lock);
			/*printk("HPFS: truncating file before delete.\n");*/
			newattrs.ia_size = 0;
			newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
			err = notify_change(dentry, &newattrs);
			put_write_access(inode);
			if (!err)
				goto again;
		}
		unlock_kernel();
		return -ENOSPC;
	default:
		drop_nlink(inode);
		err = 0;
	}
	goto out;

out1:
	hpfs_brelse4(&qbh);
out:
	mutex_unlock(&hpfs_i(dir)->i_mutex);
	mutex_unlock(&hpfs_i(inode)->i_parent_mutex);
	unlock_kernel();
	return err;
}
Ejemplo n.º 15
0
Py::Object pysvn_client::cmd_move( const Py::Tuple &a_args, const Py::Dict &a_kws )
{
    static argument_description args_desc[] =
    {
    { true,  name_src_url_or_path },
    { true,  name_dest_url_or_path },
    { false, name_force },
    { false, NULL }
    };
    FunctionArguments args( "move", args_desc, a_args, a_kws );
    args.check();

    SvnPool pool( m_context );
    pysvn_commit_info_t *commit_info = NULL;

    std::string type_error_message;
    try
    {
        type_error_message = "expecting string for src_url_or_path (arg 1)";
        Py::String src_path( args.getUtf8String( name_src_url_or_path ) );

        type_error_message = "expecting string for dest_url_or_path (arg 2)";
        Py::String dest_path( args.getUtf8String( name_dest_url_or_path ) );

#ifndef PYSVN_HAS_CLIENT_MOVE2
        svn_opt_revision_t revision;
        revision.kind = svn_opt_revision_head;
#endif

        type_error_message = "expecting boolean for keyword force";
        bool force = args.getBoolean( name_force, false );

        try
        {
            std::string norm_src_path( svnNormalisedIfPath( src_path, pool ) );
            std::string norm_dest_path( svnNormalisedIfPath( dest_path, pool ) );

            checkThreadPermission();

            PythonAllowThreads permission( m_context );

#if defined( PYSVN_HAS_CLIENT_MOVE4 )
            // behavior changed
            svn_error_t *error = svn_client_move4
                (
                &commit_info,
                norm_src_path.c_str(),
                norm_dest_path.c_str(),
                force,
                m_context,
                pool
                );
#elif defined( PYSVN_HAS_CLIENT_MOVE3 )
            svn_error_t *error = svn_client_move3
                (
                &commit_info,               // changed type
                norm_src_path.c_str(),
                norm_dest_path.c_str(),
                force,
                m_context,
                pool
                );
#elif defined( PYSVN_HAS_CLIENT_MOVE2 )
            svn_error_t *error = svn_client_move2
                (
                &commit_info,
                norm_src_path.c_str(),
                norm_dest_path.c_str(),
                force,
                m_context,
                pool
                );
#else
            svn_error_t *error = svn_client_move
                (
                &commit_info,
                norm_src_path.c_str(),
                &revision,
                norm_dest_path.c_str(),
                force,
                m_context,
                pool
                );
#endif
            permission.allowThisThread();
            if( error != NULL )
                throw SvnException( error );
        }
        catch( SvnException &e )
        {
            // use callback error over ClientException
            m_context.checkForError( m_module.client_error );

            throw_client_error( e );
        }
    }
    catch( Py::TypeError & )
    {
        throw Py::TypeError( type_error_message );
    }

    return toObject( commit_info );
}
Ejemplo n.º 16
0
void
compress(const char *in, const char *out, int bits)
{
	size_t nr;
	struct stat isb, sb;
	FILE *ifp = NULL, *ofp = NULL;
	int exists, isreg, oreg;
	u_char buf[1024];

	exists = !stat(out, &sb);
	if (!force && exists && S_ISREG(sb.st_mode) && !cat && !permission(out)) {
		cwarnx("%s already exists", out);
		return;
	}
	isreg = oreg = !exists || S_ISREG(sb.st_mode);

	if ((ifp = fopen(in, "r")) == NULL) {
		cwarn("%s", in);
		return;
	}
	if (stat(in, &isb)) {		/* DON'T FSTAT! */
		cwarn("%s", in);
		goto err;
	}
	if (!S_ISREG(isb.st_mode))
		isreg = 0;

	if ((ofp = zopen(out, "w", bits)) == NULL) {
		cwarn("%s", out);
		goto err;
	}
	while ((nr = fread(buf, 1, sizeof(buf), ifp)) != 0)
		if (fwrite(buf, 1, nr, ofp) != nr) {
			cwarn("%s", out);
			goto err;
		}

	if (ferror(ifp) || fclose(ifp)) {
		cwarn("%s", in);
		goto err;
	}
	ifp = NULL;

	if (fclose(ofp)) {
		cwarn("%s", out);
		goto err;
	}
	ofp = NULL;

	if (!cat && isreg) {
		if (stat(out, &sb)) {
			cwarn("%s", out);
			goto err;
		}

		if (!force && sb.st_size >= isb.st_size) {
			if (verbose)
		(void)fprintf(stderr, "%s: file would grow; left unmodified\n",
		    in);
			eval = 2;
			if (unlink(out))
				cwarn("%s", out);
			goto err;
		}

		setfile(out, &isb);

		if (unlink(in))
			cwarn("%s", in);

		if (verbose) {
			(void)fprintf(stderr, "%s: ", out);
			if (isb.st_size > sb.st_size)
				(void)fprintf(stderr, "%.0f%% compression\n",
				    ((float)sb.st_size / isb.st_size) * 100.0);
			else
				(void)fprintf(stderr, "%.0f%% expansion\n",
				    ((float)isb.st_size / sb.st_size) * 100.0);
		}
	}
	return;

err:	if (ofp) {
		if (!cat && oreg)
			(void)unlink(out);
		(void)fclose(ofp);
	}
	if (ifp)
		(void)fclose(ifp);
}
Ejemplo n.º 17
0
/**
 * gfs2_set_flags - set flags on an inode
 * @inode: The inode
 * @flags: The flags to set
 * @mask: Indicates which flags are valid
 *
 */
static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask)
{
	struct inode *inode = filp->f_path.dentry->d_inode;
	struct gfs2_inode *ip = GFS2_I(inode);
	struct gfs2_sbd *sdp = GFS2_SB(inode);
	struct buffer_head *bh;
	struct gfs2_holder gh;
	int error;
	u32 new_flags, flags;

	error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
	if (error)
		return error;

	flags = ip->i_di.di_flags;
	new_flags = (flags & ~mask) | (reqflags & mask);
	if ((new_flags ^ flags) == 0)
		goto out;

	if (S_ISDIR(inode->i_mode)) {
		if ((new_flags ^ flags) & GFS2_DIF_JDATA)
			new_flags ^= (GFS2_DIF_JDATA|GFS2_DIF_INHERIT_JDATA);
		if ((new_flags ^ flags) & GFS2_DIF_DIRECTIO)
			new_flags ^= (GFS2_DIF_DIRECTIO|GFS2_DIF_INHERIT_DIRECTIO);
	}

	error = -EINVAL;
	if ((new_flags ^ flags) & ~GFS2_FLAGS_USER_SET)
		goto out;

	error = -EPERM;
	if (IS_IMMUTABLE(inode) && (new_flags & GFS2_DIF_IMMUTABLE))
		goto out;
	if (IS_APPEND(inode) && (new_flags & GFS2_DIF_APPENDONLY))
		goto out;
	if (((new_flags ^ flags) & GFS2_DIF_IMMUTABLE) &&
	    !capable(CAP_LINUX_IMMUTABLE))
		goto out;
	if (!IS_IMMUTABLE(inode)) {
		error = permission(inode, MAY_WRITE, NULL);
		if (error)
			goto out;
	}

	error = gfs2_trans_begin(sdp, RES_DINODE, 0);
	if (error)
		goto out;
	error = gfs2_meta_inode_buffer(ip, &bh);
	if (error)
		goto out_trans_end;
	gfs2_trans_add_bh(ip->i_gl, bh, 1);
	ip->i_di.di_flags = new_flags;
	gfs2_dinode_out(ip, bh->b_data);
	brelse(bh);
	gfs2_set_inode_flags(inode);
out_trans_end:
	gfs2_trans_end(sdp);
out:
	gfs2_glock_dq_uninit(&gh);
	return error;
}