// Don't assume this code is part of an exception safe code base.
// Assume that the "acl" and "mbr" APIs throw instead of returning 0.
// Assume an acl_t wrapper class called ACL that calls acl_init() in its
//	constructor and acl_free() in its destructor (unless release() is called).

// ACL.hpp
struct ACL: boost::noncopyable
{
		ACL(int count):acl_(acl_init(count)) {if (!acl_) throw ACLInitFail();}
		~ACL() {if (acl_) acl_free(acl_);}
		acl_t get() const {return acl_;}
		acl_t release() {acl_t result(acl_t); acl_ = 0; return result;}
	private:
		acl_t acl_;
}


// create an ACL with a single ACE which allows the current user to read the object
static acl_t CreateReadOnlyForCurrentUserACL()
{
	acl_t result(0);
	try
	{
		ACL	theACL(1);
		acl_entry_t newEntry;
		acl_create_entry_np(&theACL.get(), &newEntry, ACL_FIRST_ENTRY);
	
		// allow
		acl_set_tag_type(newEntry, ACL_EXTENDED_ALLOW);
	
		// the current user
		uuid_t	theUUID;
		mbr_uid_to_uuid(geteuid(), theUUID);  // need the uuid for the ACE
		acl_set_qualifier(newEntry, (const void *)theUUID);
		acl_permset_t newPermSet;
		acl_get_permset(newEntry, &newPermSet);
	
		// to read data
		acl_add_perm(newPermSet, ACL_READ_DATA);
		acl_set_permset(newEntry, newPermSet);
	
		// all set up and ready to go
		result = theACL.release();
	}
	catch (...) {}
	return result;
}
