Ejemplo n.º 1
0
Archivo: util.c Proyecto: crossmeta/sgi
/*
 * Get the file's change indicator
 */
int
get_dmchange(
	dm_sessid_t	 sid,
	void		*hanp, 
	size_t	 	 hlen, 
	dm_token_t	 token,
	u_int		*change_start)
{
	int		error;
	dm_stat_t	statbuf;


	error = dm_get_fileattr(sid, hanp, hlen, token, DM_AT_CFLAG, &statbuf);
	if (error == -1) {
		errno_msg("%s/%d: Can't stat file (%d)", __FILE__, __LINE__, errno);
		return(1);
	}
	*change_start = statbuf.dt_change;
	return(0);
}
Ejemplo n.º 2
0
static int
dmapi_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
	    unsigned long arg)
{
	sys_dmapi_args_t kargs;
	sys_dmapi_args_t *uap = &kargs;
	int error = 0;
	int rvp = -ENOSYS;
	int use_rvp = 0;

	if (!capable(CAP_MKNOD))
		return(-EPERM);

	if( copy_from_user( &kargs, (sys_dmapi_args_t*)arg,
			   sizeof(sys_dmapi_args_t) ) )
		return -EFAULT;

	switch (cmd) {
	case DM_CLEAR_INHERIT:
		error = dm_clear_inherit(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(dm_attrname_t *) uap->arg5);	/* attrnamep */
		break;
	case DM_CREATE_BY_HANDLE:
		error = dm_create_by_handle(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* dirhanp */
				(size_t)	uap->arg3,	/* dirhlen */
				(dm_token_t)	uap->arg4,	/* token */
				(void *)	uap->arg5,	/* hanp */
				(size_t)	uap->arg6,	/* hlen */
				(char *)	uap->arg7);	/* cname */
		break;
	case DM_CREATE_SESSION:
		error = dm_create_session(
				(dm_sessid_t)	uap->arg1,	/* oldsid */
				(char *)	uap->arg2,	/* sessinfop */
				(dm_sessid_t *)	uap->arg3);	/* newsidp */
		break;
	case DM_CREATE_USEREVENT:
		error = dm_create_userevent(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(size_t)	uap->arg2,	/* msglen */
				(void *)	uap->arg3,	/* msgdatap */
				(dm_token_t *)	uap->arg4);	/* tokenp */
		break;
	case DM_DESTROY_SESSION:
		error = dm_destroy_session(
				(dm_sessid_t)	uap->arg1);	/* sid */
		break;
	case DM_DOWNGRADE_RIGHT:
		error = dm_downgrade_right(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4);	/* token */
		break;
	case DM_FD_TO_HANDLE:
		error = dm_fd_to_hdl(
				(int)		uap->arg1,	/* fd */
				(void *)	uap->arg2,	/* hanp */
				(size_t *)	uap->arg3);	/* hlenp */
		break;
	case DM_FIND_EVENTMSG:
		error = dm_find_eventmsg(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(dm_token_t)	uap->arg2,	/* token */
				(size_t)	uap->arg3,	/* buflen */
				(void *)	uap->arg4,	/* bufp */
				(size_t *)	uap->arg5);	/* rlenp */
		break;
	case DM_GET_ALLOCINFO:
		use_rvp = 1;
		error = dm_get_allocinfo_rvp(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(dm_off_t *)	uap->arg5,	/* offp */
				(u_int)		uap->arg6,	/* nelem */
				(dm_extent_t *)	uap->arg7,	/* extentp */
				(u_int *)	uap->arg8,	/* nelemp */
						&rvp);
		break;
	case DM_GET_BULKALL:
		use_rvp = 1;
		error = dm_get_bulkall_rvp(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(u_int)		uap->arg5,	/* mask */
				(dm_attrname_t *) uap->arg6,	/* attrnamep */
				(dm_attrloc_t *) uap->arg7,	/* locp */
				(size_t)	uap->arg8,	/* buflen */
				(void *)	uap->arg9,	/* bufp */
				(size_t *)	uap->arg10,	/* rlenp */
						&rvp);
		break;
	case DM_GET_BULKATTR:
		use_rvp = 1;
		error = dm_get_bulkattr_rvp(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(u_int)		uap->arg5,	/* mask */
				(dm_attrloc_t *)uap->arg6,	/* locp */
				(size_t)	uap->arg7,	/* buflen */
				(void *)	uap->arg8,	/* bufp */
				(size_t *)	uap->arg9,	/* rlenp */
						&rvp);
		break;
	case DM_GET_CONFIG:
		error = dm_get_config(
				(void *)	uap->arg1,	/* hanp */
				(size_t)	uap->arg2,	/* hlen */
				(dm_config_t)	uap->arg3,	/* flagname */
				(dm_size_t *)	uap->arg4);	/* retvalp */
		break;
	case DM_GET_CONFIG_EVENTS:
		error = dm_get_config_events(
				(void *)	uap->arg1,	/* hanp */
				(size_t)	uap->arg2,	/* hlen */
				(u_int)		uap->arg3,	/* nelem */
				(dm_eventset_t *) uap->arg4,	/* eventsetp */
				(u_int *)	uap->arg5);	/* nelemp */
		break;
	case DM_GET_DIOINFO:
		error = dm_get_dioinfo(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(dm_dioinfo_t *)uap->arg5);	/* diop */
		break;
	case DM_GET_DIRATTRS:
		use_rvp = 1;
		error = dm_get_dirattrs_rvp(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(u_int)		uap->arg5,	/* mask */
				(dm_attrloc_t *)uap->arg6,	/* locp */
				(size_t)	uap->arg7,	/* buflen */
				(void *)	uap->arg8,	/* bufp */
				(size_t *)	uap->arg9,	/* rlenp */
						&rvp);
		break;
	case DM_GET_DMATTR:
		error = dm_get_dmattr(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(dm_attrname_t *) uap->arg5,	/* attrnamep */
				(size_t)	uap->arg6,	/* buflen */
				(void *)	uap->arg7,	/* bufp */
				(size_t *)	uap->arg8);	/* rlenp */

		break;
	case DM_GET_EVENTLIST:
		error = dm_get_eventlist(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(u_int)		uap->arg5,	/* nelem */
				(dm_eventset_t *) uap->arg6,	/* eventsetp */
				(u_int *)	uap->arg7);	/* nelemp */
		break;
	case DM_GET_EVENTS:
		error = dm_get_events(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(u_int)		uap->arg2,	/* maxmsgs */
				(u_int)		uap->arg3,	/* flags */
				(size_t)	uap->arg4,	/* buflen */
				(void *)	uap->arg5,	/* bufp */
				(size_t *)	uap->arg6);	/* rlenp */
		break;
	case DM_GET_FILEATTR:
		error = dm_get_fileattr(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(u_int)		uap->arg5,	/* mask */
				(dm_stat_t *)	uap->arg6);	/* statp */
		break;
	case DM_GET_MOUNTINFO:
		error = dm_get_mountinfo(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(size_t)	uap->arg5,	/* buflen */
				(void *)	uap->arg6,	/* bufp */
				(size_t *)	uap->arg7);	/* rlenp */
		break;
	case DM_GET_REGION:
		error = dm_get_region(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(u_int)		uap->arg5,	/* nelem */
				(dm_region_t *)	uap->arg6,	/* regbufp */
				(u_int *)	uap->arg7);	/* nelemp */
		break;
	case DM_GETALL_DISP:
		error = dm_getall_disp(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(size_t)	uap->arg2,	/* buflen */
				(void *)	uap->arg3,	/* bufp */
				(size_t *)	uap->arg4);	/* rlenp */
		break;
	case DM_GETALL_DMATTR:
		error = dm_getall_dmattr(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(size_t)	uap->arg5,	/* buflen */
				(void *)	uap->arg6,	/* bufp */
				(size_t *)	uap->arg7);	/* rlenp */
		break;
	case DM_GETALL_INHERIT:
		error = dm_getall_inherit(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(u_int)		uap->arg5,	/* nelem */
				(dm_inherit_t *)uap->arg6,	/* inheritbufp*/
				(u_int *)	uap->arg7);	/* nelemp */
		break;
	case DM_GETALL_SESSIONS:
		error = dm_getall_sessions(
				(u_int)		uap->arg1,	/* nelem */
				(dm_sessid_t *)	uap->arg2,	/* sidbufp */
				(u_int *)	uap->arg3);	/* nelemp */
		break;
	case DM_GETALL_TOKENS:
		error = dm_getall_tokens(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(u_int)		uap->arg2,	/* nelem */
				(dm_token_t *)	uap->arg3,	/* tokenbufp */
				(u_int *)	uap->arg4);	/* nelemp */
		break;
	case DM_INIT_ATTRLOC:
		error = dm_init_attrloc(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(dm_attrloc_t *) uap->arg5);	/* locp */
		break;
	case DM_MKDIR_BY_HANDLE:
		error = dm_mkdir_by_handle(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* dirhanp */
				(size_t)	uap->arg3,	/* dirhlen */
				(dm_token_t)	uap->arg4,	/* token */
				(void *)	uap->arg5,	/* hanp */
				(size_t)	uap->arg6,	/* hlen */
				(char *)	uap->arg7);	/* cname */
		break;
	case DM_MOVE_EVENT:
		error = dm_move_event(
				(dm_sessid_t)	uap->arg1,	/* srcsid */
				(dm_token_t)	uap->arg2,	/* token */
				(dm_sessid_t)	uap->arg3,	/* targetsid */
				(dm_token_t *)	uap->arg4);	/* rtokenp */
		break;
	case DM_OBJ_REF_HOLD:
		error = dm_obj_ref_hold(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(dm_token_t)	uap->arg2,	/* token */
				(void *)	uap->arg3,	/* hanp */
				(size_t)	uap->arg4);	/* hlen */
		break;
	case DM_OBJ_REF_QUERY:
		use_rvp = 1;
		error = dm_obj_ref_query_rvp(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(dm_token_t)	uap->arg2,	/* token */
				(void *)	uap->arg3,	/* hanp */
				(size_t)	uap->arg4,	/* hlen */
						&rvp);
		break;
	case DM_OBJ_REF_RELE:
		error = dm_obj_ref_rele(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(dm_token_t)	uap->arg2,	/* token */
				(void *)	uap->arg3,	/* hanp */
				(size_t)	uap->arg4);	/* hlen */
		break;
	case DM_PATH_TO_FSHANDLE:
		error = dm_path_to_fshdl(
				(char *)	uap->arg1,	/* path */
				(void *)	uap->arg2,	/* hanp */
				(size_t *)	uap->arg3);	/* hlenp */
		break;
	case DM_PATH_TO_HANDLE:
		error = dm_path_to_hdl(
				(char *)	uap->arg1,	/* path */
				(void *)	uap->arg2,	/* hanp */
				(size_t *)	uap->arg3);	/* hlenp */
		break;
	case DM_PENDING:
		error = dm_pending(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(dm_token_t)	uap->arg2,	/* token */
				(dm_timestruct_t *) uap->arg3);	/* delay */
		break;
	case DM_PROBE_HOLE:
		error = dm_probe_hole(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(dm_off_t)	uap->arg5,	/* off */
				(dm_size_t)	uap->arg6,	/* len */
				(dm_off_t *)	uap->arg7,	/* roffp */
				(dm_size_t *)	uap->arg8);	/* rlenp */
		break;
	case DM_PUNCH_HOLE:
		error = dm_punch_hole(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(dm_off_t)	uap->arg5,	/* off */
				(dm_size_t)	uap->arg6);	/* len */
		break;
	case DM_QUERY_RIGHT:
		error = dm_query_right(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(dm_right_t *)	uap->arg5);	/* rightp */
		break;
	case DM_QUERY_SESSION:
		error = dm_query_session(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(size_t)	uap->arg2,	/* buflen */
				(void *)	uap->arg3,	/* bufp */
				(size_t *)	uap->arg4);	/* rlenp */
		break;
	case DM_READ_INVIS:
		use_rvp = 1;
		error = dm_read_invis_rvp(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(dm_off_t)	uap->arg5,	/* off */
				(dm_size_t)	uap->arg6,	/* len */
				(void *)	uap->arg7,	/* bufp */
						&rvp);
		break;
	case DM_RELEASE_RIGHT:
		error = dm_release_right(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4);	/* token */
		break;
	case DM_REMOVE_DMATTR:
		error = dm_remove_dmattr(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(int)		uap->arg5,	/* setdtime */
				(dm_attrname_t *) uap->arg6);	/* attrnamep */
		break;
	case DM_REQUEST_RIGHT:
		error = dm_request_right(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(u_int)		uap->arg5,	/* flags */
				(dm_right_t)	uap->arg6);	/* right */
		break;
	case DM_RESPOND_EVENT:
		error = dm_respond_event(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(dm_token_t)	uap->arg2,	/* token */
				(dm_response_t)	uap->arg3,	/* response */
				(int)		uap->arg4,	/* reterror */
				(size_t)	uap->arg5,	/* buflen */
				(void *)	uap->arg6);	/* respbufp */
		break;
	case DM_SEND_MSG:
		error = dm_send_msg(
				(dm_sessid_t)	uap->arg1,	/* targetsid */
				(dm_msgtype_t)	uap->arg2,	/* msgtype */
				(size_t)	uap->arg3,	/* buflen */
				(void *)	uap->arg4);	/* bufp */
		break;
	case DM_SET_DISP:
		error = dm_set_disp(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(dm_eventset_t *) uap->arg5,	/* eventsetp */
				(u_int)		uap->arg6);	/* maxevent */
		break;
	case DM_SET_DMATTR:
		error = dm_set_dmattr(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(dm_attrname_t *) uap->arg5,	/* attrnamep */
				(int)		uap->arg6,	/* setdtime */
				(size_t)	uap->arg7,	/* buflen */
				(void *)	uap->arg8);	/* bufp */
		break;
	case DM_SET_EVENTLIST:
		error = dm_set_eventlist(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(dm_eventset_t *) uap->arg5,	/* eventsetp */
				(u_int)		uap->arg6);	/* maxevent */
		break;
	case DM_SET_FILEATTR:
		error = dm_set_fileattr(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(u_int)		uap->arg5,	/* mask */
				(dm_fileattr_t *)uap->arg6);	/* attrp */
		break;
	case DM_SET_INHERIT:
		error = dm_set_inherit(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(dm_attrname_t *)uap->arg5,	/* attrnamep */
				(mode_t)	uap->arg6);	/* mode */
		break;
	case DM_SET_REGION:
		error = dm_set_region(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(u_int)		uap->arg5,	/* nelem */
				(dm_region_t *)	uap->arg6,	/* regbufp */
				(dm_boolean_t *) uap->arg7);	/* exactflagp */
		break;
	case DM_SET_RETURN_ON_DESTROY:
		error = dm_set_return_on_destroy(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(dm_attrname_t *) uap->arg5,	/* attrnamep */
				(dm_boolean_t)	uap->arg6);	/* enable */
		break;
	case DM_SYMLINK_BY_HANDLE:
		error = dm_symlink_by_handle(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* dirhanp */
				(size_t)	uap->arg3,	/* dirhlen */
				(dm_token_t)	uap->arg4,	/* token */
				(void *)	uap->arg5,	/* hanp */
				(size_t)	uap->arg6,	/* hlen */
				(char *)	uap->arg7,	/* cname */
				(char *)	uap->arg8);	/* path */
		break;
	case DM_SYNC_BY_HANDLE:
		error = dm_sync_by_handle(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4);	/* token */
		break;
	case DM_UPGRADE_RIGHT:
		error = dm_upgrade_right(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4);	/* token */
		break;
	case DM_WRITE_INVIS:
		use_rvp = 1;
		error = dm_write_invis_rvp(
				(dm_sessid_t)	uap->arg1,	/* sid */
				(void *)	uap->arg2,	/* hanp */
				(size_t)	uap->arg3,	/* hlen */
				(dm_token_t)	uap->arg4,	/* token */
				(int)		uap->arg5,	/* flags */
				(dm_off_t)	uap->arg6,	/* off */
				(dm_size_t)	uap->arg7,	/* len */
				(void *)	uap->arg8,	/* bufp */
						&rvp);
		break;
	default:
		error = ENOSYS;
		break;
	}
	/* If it was an *_rvp() function, then
		if error==0, return |rvp|
	*/
	if( use_rvp && (error == 0) )
		return rvp;
	else
		return -error;
}
Ejemplo n.º 3
0
int
main(
	int	argc,
	char	**argv)
{
	dm_sessid_t	sid = DM_NO_SESSION;
	dm_token_t	token = DM_NO_TOKEN;
#if 0
	char		buffer[500];
#endif
	void		*hanp;
	size_t		hlen;
	dm_stat_t	dmstat;
	char		*pathname_obj;
	int		a_flag = 0;
	char		*name;
	int		opt;
	int		validate = 0;

	Progname = strrchr(argv[0], '/');
	if (Progname) {
		Progname++;
	} else {
		Progname = argv[0];
	}

	opterr = 0;
	while ((opt = getopt(argc, argv, "Aas:t:v")) != EOF) {
		switch (opt) {
		case 'A':
			a_flag = 2;
			break;
		case 'a':
			a_flag = 1;
			break;
		case 's':
			sid = atol(optarg);
			break;
		case 't':
			token = atol(optarg);
			break;
		case 'v':
			validate = 1;
			break;
		case '?':
			usage();
		}
	}
	if (optind + 1 != argc) {
		usage();
	}
	pathname_obj = argv[optind];

	if (dm_init_service(&name) == -1)  {
		fprintf(stderr, "Can't initialize the DMAPI\n");
		exit(1);
	}
	if (sid == DM_NO_SESSION)
		find_test_session(&sid);

	/* Get the file's handle or convert the external handle. */

	if (opaque_to_handle(pathname_obj, &hanp, &hlen)) {
		fprintf(stderr, "can't get handle for %s\n", pathname_obj);
		exit(1);
	}

	if (!a_flag) {
		fprintf(stdout, "path/handle            %s\n", pathname_obj);

		/* Get the file's state, print it, then verify it against
		   what is in the file's stat block.
		*/

		if (dm_get_fileattr(sid, hanp, hlen, token,
	DM_AT_EMASK|DM_AT_PMANR|DM_AT_PATTR|DM_AT_DTIME|DM_AT_CFLAG|DM_AT_STAT,
		    &dmstat)) {
			fprintf(stderr, "dm_get_fileattr failed, %s\n",
				strerror(errno));
			exit(1);
		}

		print_state(&dmstat);
		if(validate)
			(void)validate_state(&dmstat, pathname_obj, 1);
#if 0
	} else {
		if ((rc = filesys_bulkscan_init(pathname, &scanp)) != 0) {
			fprintf(stderr, "filesys_bulkscan failed, %s\n",
				fileio_err_image(rc));
			exit(1);
		}
		for (;;) {
			rc = filesys_bulkscan_read(scanp, &fhandle, &fullstat);
			if (rc != FILEIO_NOERROR)
				break;

			(void)fhandle_to_buffer(&fhandle, buffer, sizeof(buffer));
			if (a_flag == 1) {
				fprintf(stdout, "handle          %s\n", buffer);
				print_state(&fullstat);
				fprintf(stdout, "--------------------------\n");
			} else {
				fprintf(stdout, "%s|", buffer);
				print_line(&fullstat);
			}
		}

		if (rc != FILEIO_ENDOFSCAN) {
			fprintf(stderr, "filesys_bulkscan_read failed, %s\n",
				fileio_err_image(rc));
			exit(1);
		}
		if ((rc = filesys_bulkscan_close(&scanp)) != 0) {
			fprintf(stderr, "filesys_bulkscan_close failed, %s\n",
				fileio_err_image(rc));
			exit(1);
		}
#endif
	}
	exit(0);
}
Ejemplo n.º 4
0
int
main(
	int	argc,
	char	**argv)
{
	dm_sessid_t	sid, oldsid, targetsid, *newsidp, *sidbufp;
	dm_token_t	token, *tokenp, *rtokenp, *tokenbufp;
	dm_attrname_t	*attrnamep;
	dm_off_t	off, *offp, *roffp;
	dm_extent_t	*extentp;
	dm_inherit_t	*inheritbufp;
	dm_stat_t	*statp;
	dm_size_t	len, *dmrlenp, *retvalp;
	dm_attrloc_t	*locp;
	dm_eventset_t	*eventsetp;
	dm_config_t	flagname;
	dm_region_t	*regbufp;
	dm_response_t	response;
	dm_right_t	right, *rightp;
	dm_igen_t	igen, *igenp;
	dm_msgtype_t	msgtype;
	dm_fileattr_t	*attrp;
	dm_boolean_t	enable, *exactflagp;
	dm_timestruct_t	*delay;
	mode_t		mode;
	size_t		hlen, dirhlen, hlen1, hlen2, targhlen, *fshlenp, *hlenp;
	size_t		msglen, buflen, *rlenp;
	u_int		nelem, mask, maxmsgs, uflags, *nelemp, maxevent;
	void		*hanp, *dirhanp, *hanp1, *hanp2, *targhanp;
	void		*msgdatap, *bufp, **hanpp, *respbufp, **fshanpp;
	dm_fsid_t	fsid, *fsidp;
	dm_ino_t	ino, *inop;
	char		*cname, *sessinfop, *path, *pathbufp, **versionstrpp;
	int		flags, fd, setdtime, reterror;
	u_int	urc;
	int	rc;
	dm_ssize_t	ssrc;

/* Definitions per the prototypes in dmport.h, in the same order. */

	rc = dm_clear_inherit(sid, hanp, hlen, token, attrnamep);
	rc = dm_create_by_handle(sid, dirhanp, dirhlen, token,
		hanp, hlen, cname);
	rc = dm_create_session(oldsid, sessinfop, newsidp);
	rc = dm_create_userevent(sid, msglen, msgdatap, tokenp);
	rc = dm_destroy_session(sid);
	rc = dm_downgrade_right(sid, hanp, hlen, token);
	rc = dm_fd_to_handle(fd, hanpp, hlenp);
	rc = dm_find_eventmsg(sid, token, buflen, bufp, rlenp);
	rc = dm_get_allocinfo(sid, hanp, hlen,
		token, offp, nelem, extentp, nelemp);
	rc = dm_get_bulkall(sid, hanp, hlen, token, mask, attrnamep,
		locp, buflen, bufp, rlenp);
	rc = dm_get_bulkattr(sid, hanp, hlen, token, mask, locp, buflen, 
		bufp, rlenp);
	rc = dm_get_config(hanp, hlen, flagname, retvalp);
	rc = dm_get_config_events(hanp, hlen, nelem, eventsetp, nelemp);
	rc = dm_get_dirattrs(sid, hanp, hlen, token, mask, locp, buflen,
		bufp, rlenp);
	rc = dm_get_dmattr(sid, hanp, hlen, token, attrnamep, buflen,
		bufp, rlenp);
	rc = dm_get_eventlist(sid, hanp, hlen, token, nelem, eventsetp, nelemp);
	rc = dm_get_events(sid, maxmsgs, flags, buflen, bufp, rlenp);
	rc = dm_get_fileattr(sid, hanp, hlen, token, mask, statp);
	rc = dm_get_mountinfo(sid, hanp, hlen, token, buflen, bufp, rlenp);
	rc = dm_get_region(sid, hanp, hlen, token, nelem, regbufp, nelemp);
	rc = dm_getall_disp(sid, buflen, bufp, rlenp);
	rc = dm_getall_dmattr(sid, hanp, hlen, token, buflen, bufp, rlenp);
	rc = dm_getall_inherit(sid, hanp, hlen,
		token, nelem, inheritbufp, nelemp);
	rc = dm_getall_sessions(nelem, sidbufp, nelemp);
	rc = dm_getall_tokens(sid, nelem, tokenbufp, nelemp);
	rc = dm_handle_cmp(hanp1, hlen1, hanp2, hlen2);
	dm_handle_free(hanp, hlen);
	urc = dm_handle_hash(hanp, hlen);
	rc = dm_handle_is_valid(hanp, hlen);
	rc = dm_handle_to_fshandle(hanp, hlen, fshanpp, fshlenp);
	rc = dm_handle_to_fsid(hanp, hlen, fsidp);
	rc = dm_handle_to_igen(hanp, hlen, igenp);
	rc = dm_handle_to_ino(hanp, hlen, inop);
	rc = dm_handle_to_path(dirhanp, dirhlen, targhanp, targhlen, 
		buflen, pathbufp, rlenp);
	rc = dm_init_attrloc(sid, hanp, hlen, token, locp);
	rc = dm_init_service(versionstrpp);
	rc = dm_make_handle(&fsid, &ino, &igen, hanpp, hlenp);
	rc = dm_make_fshandle(&fsid, hanpp, hlenp);
	rc = dm_mkdir_by_handle(sid, dirhanp, dirhlen, token,
		hanp, hlen, cname); 
	rc = dm_move_event(sid, token, targetsid, rtokenp);
	rc = dm_obj_ref_hold(sid, token, hanp, hlen);
	rc = dm_obj_ref_query(sid, token, hanp, hlen);
	rc = dm_obj_ref_rele(sid, token, hanp, hlen);
	rc = dm_path_to_fshandle(path, hanpp, hlenp);
	rc = dm_path_to_handle(path, hanpp, hlenp);
	rc = dm_pending(sid, token, delay);
	rc = dm_probe_hole(sid, hanp, hlen, token, off, len, roffp, dmrlenp);
	rc = dm_punch_hole(sid, hanp, hlen, token, off, len);
	rc = dm_query_right(sid, hanp, hlen, token, rightp);
	rc = dm_query_session(sid, buflen, bufp, rlenp);
	ssrc = dm_read_invis(sid, hanp, hlen, token, off, len, bufp);
	rc =  dm_release_right(sid, hanp, hlen, token);
	rc = dm_remove_dmattr(sid, hanp, hlen, token, setdtime, attrnamep);
	rc = dm_request_right(sid, hanp, hlen, token, uflags, right);
	rc = dm_respond_event(sid, token, response, reterror, buflen, respbufp);
	rc = dm_send_msg(sid, msgtype, buflen, bufp);
	rc = dm_set_disp(sid, hanp, hlen, token, eventsetp, maxevent);
	rc = dm_set_dmattr(sid, hanp, hlen,
		token, attrnamep, setdtime, buflen, bufp);
	rc = dm_set_eventlist(sid, hanp, hlen, token, eventsetp, maxevent);
	rc = dm_set_fileattr(sid, hanp, hlen, token, mask, attrp);
	rc = dm_set_inherit(sid, hanp, hlen, token, attrnamep, mode);
	rc = dm_set_region(sid, hanp, hlen, token, nelem, regbufp, exactflagp);
	rc = dm_set_return_on_destroy(sid, hanp, hlen,
		token,  attrnamep, enable);
	rc = dm_symlink_by_handle(sid, dirhanp, dirhlen, token,
		hanp, hlen, cname, path); 
	rc = dm_sync_by_handle(sid, hanp, hlen, token);
	rc = dm_upgrade_right(sid, hanp, hlen, token);
	ssrc = dm_write_invis(sid, hanp, hlen, flags, token, off, len, bufp);
	exit(0);
}
Ejemplo n.º 5
0
// for a child and manage the supplied event
void spawn_child(dm_token_t token, void *hanp, size_t hlen, char *action) {
  pid_t mypid;
  pid_t pid;
  char sidbuf[32];
  char tokenbufh[32];
  char tokenbufl[32];
  dm_attrname_t attrname;
  dm_attrlist_t bufp[1024];
  size_t rlenp;
  dm_stat_t statp;
  FILE* mnttab;
  struct mntent *ent;
  struct statfs sbuf;
  dm_ino_t inop;
  char s[512];
  char hname[512];
  char *yamssRecallPath="/system/YAMSS_DMRECALL";
  char *yamssDMAPIPath="/system/YAMSS_DMERROR";
  int fd;
  int i;
  int ret;
  unsigned char c;
  char extobj[1024];
  char inode[32];
  time_t rectime, now;
  struct stat filebuf;

  // fork a new child
  pid = fork();
  if (pid == 0) {
    // fork succeeded, we are in the child now
    mypid=getpid();

    // block signals
    block_signals(mypid);

    sprintf(sidbuf, "%llx", sid);
    sprintf(tokenbufh, "%llx", token.high);
    sprintf(tokenbufl, "%llx", token.low);
    if (Verbose) {
       fprintf(stderr, "%d: New child spawn with action=%s, sidbuf=%s, tokenbufh=%s, tokenbufl=%s\n",
               mypid, action, sidbuf, tokenbufh, tokenbufl);
    }

    // green light to mount requests
    if(!strcmp(action,"MOUNT")) {
      if (dm_respond_event(sid, token, DM_RESP_CONTINUE, 0, 0, NULL)) {
        fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno));
        exit(1);
      }
      if(Verbose) fprintf(stderr,"%d: MOUNT request served\n", mypid);
      exit(0);
    }

    // give error message to write and truncate events
    // i.e. we don't allow modifications of files on tape
    if(strcmp(action,"READ")) {
      // tell client that writing is not permitted
      if (dm_respond_event(sid, token, DM_RESP_ABORT, EPERM, 0, NULL)) {
        fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno)); 
        exit(1);
      }
      if(Verbose) fprintf(stderr,"%d: %s event rejected with EPERM\n", mypid, action);
      exit(0);
    }

    // get file inode number
    ret = dm_handle_to_ino(hanp, hlen, &inop);
    if(ret==-1) {
      fprintf(stderr,"%d: dm_handle_to_ino: failed, %s\n", mypid, strerror(errno));
      // if filesystem is not mounted don't reply with error
      // it might be a normal mmshutdown and event will be taken over
      if(!filesystem_is_mounted()) exit(1);
      if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) {
        fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno));
      }
      exit(1);
    }

    // get dmapi extended attribute with tsm external object id
    memset((void *)&attrname.an_chars[0], 0, DM_ATTR_NAME_SIZE);
    memcpy((void *)&attrname.an_chars[0], "IBMObj", 6);
    ret = dm_get_dmattr(sid, hanp, hlen, DM_NO_TOKEN, &attrname, sizeof(bufp), bufp, &rlenp);
    if(ret==-1&&errno!=ENOENT) {
      fprintf(stderr,"%d: dm_get_dmattr: failed, %s\n", mypid, strerror(errno));
      // if filesystem is not mounted don't reply with error
      // it might be a normal mmshutdown and event will be taken over
      if(!filesystem_is_mounted()) exit(1);
      if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) {
        fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno));
      }
      exit(1);
    } else if(ret==-1) {
      // get file attributes structure
      ret=dm_get_fileattr(sid,hanp,hlen,DM_NO_TOKEN,DM_AT_STAT,&statp);
      if(ret==-1) {
        fprintf(stderr,"%d: dm_get_fileattr: failed, %s\n", mypid, strerror(errno));
        // if filesystem is not mounted don't reply with error
        // it might be a normal mmshutdown and event will be taken over
        if(!filesystem_is_mounted()) exit(1);
        if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) {
          fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno));
        }
        exit(1);
      }

      // IBMObj is not there, double-check if number of blocks on disk is OK
      if(statp.dt_blocks>=(statp.dt_size/statp.dt_blksize)) {
        // File has been recalled
        if (dm_respond_event(sid, token, DM_RESP_CONTINUE, 0, 0, NULL)) {
          fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno));
          // if filesystem is not mounted don't reply with error
          // it might be a normal mmshutdown and event will be taken over
          if(!filesystem_is_mounted()) exit(1);
          if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) {
            fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno));
          }
          exit(1);
        }
        printf("%d: %s event for inode %llu on mount point %s served correctly (file was found to be already on disk)\n", mypid, action, inop, fsname);
        exit(0);
      }

    }

    // get file attributes structure
    ret=dm_get_fileattr(sid,hanp,hlen,DM_NO_TOKEN,DM_AT_STAT,&statp);
    if(ret==-1) {
      fprintf(stderr,"%d: dm_get_fileattr: failed, %s\n", mypid, strerror(errno));
      // if filesystem is not mounted don't reply with error
      // it might be a normal mmshutdown and event will be taken over
      if(!filesystem_is_mounted()) exit(1);
      if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) {
        fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno));
      }
      exit(1);
    }

    // determine mount point for the requested file
    mnttab = fopen("/etc/mtab", "r");
    ent=getmntent(mnttab);
    while(ent) {
      if(!statfs(ent->mnt_dir, &sbuf)) {
        if(statp.dt_dev==*(int*)&sbuf.f_fsid) {
          break;
        }
      }
      ent = getmntent(mnttab);
    }
    fclose(mnttab);
    if(!ent) {
      fprintf(stderr,"%d: cannot determine mountpoint\n", mypid);
      // if filesystem is not mounted don't reply with error
      // it might be a normal mmshutdown and event will be taken over
      if(!filesystem_is_mounted()) exit(1);
      if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) {
        fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno));
      }
      exit(1);
    }

    printf("%d: serving %s event for file on mount point %s with inode number %llu and external object id ", mypid, action, ent->mnt_dir, inop);
    for(i=0;i<EXTOBJID_LEN;i++) {
      c=((unsigned char*)bufp)[i];
      sprintf(extobj+i*2,"%02X",c);
    }
    *(extobj+i*2)=0;
    printf("%s\n",extobj);

    // get host name
    if(gethostname(hname,512)) {
      // this should never happen... but don't need to fail
      fprintf(stderr,"%d: cannot get hostname. Setting to dummy\n", mypid);
      sprintf(hname,"dummy");      
    }

    // generate temporary file with unique name containing the external object id of the file to be recalled
    sprintf(s,"%s%s/%s.%d.XXXXXXXX",ent->mnt_dir,yamssRecallPath,hname,mypid);
    if((fd=mkstemp(s))<0) {
      fprintf(stderr,"%d: cannot generate temporary file %s\n",mypid, s);
      // if filesystem is not mounted don't reply with error
      // it might be a normal mmshutdown and event will be taken over
      if(!filesystem_is_mounted()) exit(1);      
      if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) {
        fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno));
      }
      exit(1);
    }

    // write external object id, mount point and inode number into temporary file
    sprintf(inode,"%llu",inop);
    if(write(fd,extobj,strlen(extobj))<0 || write(fd," ",1)<0 || 
       write(fd,ent->mnt_dir,strlen(ent->mnt_dir))<0 || write(fd," ",1)<0 ||
       write(fd,inode,strlen(inode))<0 || write(fd,"\n",1)<0) {

      fprintf(stderr,"%d: cannot write into temporary file %s, %d/%s\n",mypid, s,errno,strerror(errno));
      close(fd);
      if(unlink(s)<0) {
        fprintf(stderr,"%d: cannot unlink temporary file %s, %d/%s\n",mypid, s, errno,strerror(errno));
      }
      // if filesystem is not mounted don't reply with error
      // it might be a normal mmshutdown and event will be taken over
      if(!filesystem_is_mounted()) exit(1);
      if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) {
        fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno));
      }
      exit(1);
    }
    close(fd);

    // save start time
    rectime=time(NULL);

    // Poll until file is on disk
    while(1) {
      // get file attributes structure
      ret=dm_get_fileattr(sid,hanp,hlen,DM_NO_TOKEN,DM_AT_STAT,&statp);
      if(ret==-1) {
        fprintf(stderr,"%d: dm_get_fileattr: failed, %s\n", mypid, strerror(errno));
      // if filesystem is not mounted don't reply with error
      // it might be a normal mmshutdown and event will be taken over
      if(!filesystem_is_mounted()) exit(1);
        if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) {
          fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno));
        }
        exit(1);
      }

      if(Verbose&&statp.dt_blocks!=0) {
        fprintf(stderr,"%d: recalling inode %s dt_blocks %llu dt_size %lld dt_blksize %u\n", mypid, inode, statp.dt_blocks, statp.dt_size, statp.dt_blksize);
      }

      // check if IBMObj is there
      memset((void *)&attrname.an_chars[0], 0, DM_ATTR_NAME_SIZE);
      memcpy((void *)&attrname.an_chars[0], "IBMObj", 6);
      ret = dm_get_dmattr(sid, hanp, hlen, DM_NO_TOKEN, &attrname, sizeof(bufp), bufp, &rlenp);
      if(ret==-1&&errno!=ENOENT) {
        // if filesystem is not mounted don't reply with error
        // it might be a normal mmshutdown and event will be taken over
        if(!filesystem_is_mounted()) exit(1);
        fprintf(stderr,"%d: dm_get_dmattr: failed, %s\n", mypid, strerror(errno));
        if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) {
          fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno));
        }
        exit(1);
      } else if(ret==-1) {
        if(Verbose) {
          fprintf(stderr,"%d: IBMObj has been removed for inode %s\n", mypid, inode);
        }
      }

      // check if number of blocks on disk is OK and if IBMObj has been removed
      if(statp.dt_blocks>=(statp.dt_size/statp.dt_blksize)&&ret==-1&&errno==ENOENT) {
        // File has been recalled
        if (dm_respond_event(sid, token, DM_RESP_CONTINUE, 0, 0, NULL)) {
          fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno));
          // if filesystem is not mounted don't reply with error
          // it might be a normal mmshutdown and event will be taken over
          if(!filesystem_is_mounted()) exit(1);
          if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) {
            fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno));
          }
          exit(1);
        }
        printf("%d: %s event for inode %llu on mount point %s served correctly\n", mypid, action, inop, ent->mnt_dir);
        exit(0);
      }
      sleep(RECALL_CHECK_SLEEP_TIME);

      // check if an error flag file has been raised
      sprintf(s,"%s%s/%s",ent->mnt_dir,yamssDMAPIPath,inode);
      if(!stat(s, &filebuf) && filebuf.st_ctime>rectime) {
        fprintf(stderr,"%d: error flag found - cannot recall inode %s on disk\n", mypid, inode);
        // respond EIO in this case to differentiate with EBUSY generic errors
        if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) {
          fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno));
        }
        exit(1);
      }

      // check if recall timeout expired 
      now=time(NULL);
      if((now-rectime)>RECALL_TIMEOUT) {
        fprintf(stderr,"%d: timed out - cannot recall inode %s on disk after %d seconds\n", mypid, inode, RECALL_TIMEOUT);
        if (dm_respond_event(sid, token, DM_RESP_ABORT, ETIMEDOUT, 0, NULL)) {
          fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno));
        }
        exit(1);
      }
    }

  }
  // fork failed
  if (pid < 0) {
    fprintf(stderr,"Can't fork child\n");
    if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) {
      fprintf(stderr, "dm_respond_event failed, %d/%s\n", errno, strerror(errno));
    }
    return;
  }

  // only the father can reach here, increase child counter
  child_proc_count++;

  return;

}
Ejemplo n.º 6
0
int
main(
	int	argc, 
	char	**argv)
{
	dm_sessid_t	 sid = DM_NO_SESSION;
	dm_off_t 	startoff = 0;		/* starting offset */
	u_int		nelem = 100;
	char		*pathname;
	void		*hanp;
	size_t	 	 hlen;
	dm_stat_t	sbuf;
	char		*name;
	int		opt;

	if (Progname = strrchr(argv[0], '/')) {
		Progname++;
	} else {
		Progname = argv[0];
	}

	/* Crack and validate the command line options. */

	while ((opt = getopt(argc, argv, "Dn:o:s:")) != EOF) {
		switch(opt) {
		case 'D':
			Dflag++;
			break;
		case 'n':
			nelem = atol(optarg);
			break;
		case 'o':
			startoff = atoll(optarg);
			break;
		case 's':
			sid = atol(optarg);
			break;
		case '?':
			usage();
		}
	}
	if (optind + 1 != argc)
		usage();
	pathname = argv[optind];

	if (dm_init_service(&name)) {
		fprintf(stderr, "dm_init_service failed, %s\n",
			strerror(errno));
		exit(1);
	}

	if (sid == DM_NO_SESSION)
		find_test_session(&sid);

	/* Get the file's handle and verify that it is a regular file. */

	if (dm_path_to_handle(pathname, &hanp, &hlen)) {
		fprintf(stderr, "can't get handle for %s\n", pathname);
		exit(1);
	}
	if (dm_get_fileattr(sid, hanp, hlen, DM_NO_TOKEN, DM_AT_STAT, &sbuf)) {
		fprintf(stderr, "dm_get_fileattr failed\n");
		exit(1);
	}
	if (!S_ISREG(sbuf.dt_mode)) {
		fprintf(stderr, "%s is not a regular file\n", pathname);
		exit(1);
	}

	/* Print the allocation. */

	if (print_alloc(sid, hanp, hlen, pathname, startoff, nelem))
		exit(1);

	dm_handle_free(hanp, hlen);
	exit(0);
}