xref: /onnv-gate/usr/src/cmd/ndmpd/ndmp/ndmpd_callbacks.c (revision 12475:04dc77ec5ed9)
17917SReza.Sabdar@Sun.COM /*
2*12475SReza.Sabdar@Sun.COM  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
37917SReza.Sabdar@Sun.COM  */
47917SReza.Sabdar@Sun.COM 
57917SReza.Sabdar@Sun.COM /*
67917SReza.Sabdar@Sun.COM  * BSD 3 Clause License
77917SReza.Sabdar@Sun.COM  *
87917SReza.Sabdar@Sun.COM  * Copyright (c) 2007, The Storage Networking Industry Association.
97917SReza.Sabdar@Sun.COM  *
107917SReza.Sabdar@Sun.COM  * Redistribution and use in source and binary forms, with or without
117917SReza.Sabdar@Sun.COM  * modification, are permitted provided that the following conditions
127917SReza.Sabdar@Sun.COM  * are met:
137917SReza.Sabdar@Sun.COM  * 	- Redistributions of source code must retain the above copyright
147917SReza.Sabdar@Sun.COM  *	  notice, this list of conditions and the following disclaimer.
157917SReza.Sabdar@Sun.COM  *
167917SReza.Sabdar@Sun.COM  * 	- Redistributions in binary form must reproduce the above copyright
177917SReza.Sabdar@Sun.COM  *	  notice, this list of conditions and the following disclaimer in
187917SReza.Sabdar@Sun.COM  *	  the documentation and/or other materials provided with the
197917SReza.Sabdar@Sun.COM  *	  distribution.
207917SReza.Sabdar@Sun.COM  *
217917SReza.Sabdar@Sun.COM  *	- Neither the name of The Storage Networking Industry Association (SNIA)
227917SReza.Sabdar@Sun.COM  *	  nor the names of its contributors may be used to endorse or promote
237917SReza.Sabdar@Sun.COM  *	  products derived from this software without specific prior written
247917SReza.Sabdar@Sun.COM  *	  permission.
257917SReza.Sabdar@Sun.COM  *
267917SReza.Sabdar@Sun.COM  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
277917SReza.Sabdar@Sun.COM  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
287917SReza.Sabdar@Sun.COM  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
297917SReza.Sabdar@Sun.COM  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
307917SReza.Sabdar@Sun.COM  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
317917SReza.Sabdar@Sun.COM  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
327917SReza.Sabdar@Sun.COM  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
337917SReza.Sabdar@Sun.COM  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
347917SReza.Sabdar@Sun.COM  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
357917SReza.Sabdar@Sun.COM  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
367917SReza.Sabdar@Sun.COM  * POSSIBILITY OF SUCH DAMAGE.
377917SReza.Sabdar@Sun.COM  */
387917SReza.Sabdar@Sun.COM /* Copyright (c) 2007, The Storage Networking Industry Association. */
397917SReza.Sabdar@Sun.COM /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
407917SReza.Sabdar@Sun.COM 
417917SReza.Sabdar@Sun.COM #include <sys/types.h>
427917SReza.Sabdar@Sun.COM #include <stdlib.h>
437917SReza.Sabdar@Sun.COM #include <errno.h>
447917SReza.Sabdar@Sun.COM #include <stdarg.h>
457917SReza.Sabdar@Sun.COM #include <stdio.h>
467917SReza.Sabdar@Sun.COM #include <string.h>
477917SReza.Sabdar@Sun.COM #include "ndmpd.h"
487917SReza.Sabdar@Sun.COM 
497917SReza.Sabdar@Sun.COM 
507917SReza.Sabdar@Sun.COM /*
517917SReza.Sabdar@Sun.COM  * Message Id counter.  This number is increased by MOD_LOGV3 macro.
527917SReza.Sabdar@Sun.COM  * MOD_LOGCONTV3 macro uses the number generated by the last MOD_LOGV3.
537917SReza.Sabdar@Sun.COM  *
547917SReza.Sabdar@Sun.COM  */
557917SReza.Sabdar@Sun.COM int ndmp_log_msg_id = 0;
567917SReza.Sabdar@Sun.COM 
577917SReza.Sabdar@Sun.COM 
587917SReza.Sabdar@Sun.COM /*
597917SReza.Sabdar@Sun.COM  * ************************************************************************
607917SReza.Sabdar@Sun.COM  * NDMP V2 CALLBACKS
617917SReza.Sabdar@Sun.COM  * ************************************************************************
627917SReza.Sabdar@Sun.COM  */
637917SReza.Sabdar@Sun.COM 
647917SReza.Sabdar@Sun.COM /*
657917SReza.Sabdar@Sun.COM  * ndmpd_api_done_v2
667917SReza.Sabdar@Sun.COM  *
677917SReza.Sabdar@Sun.COM  * Called when dump/restore has completed.
687917SReza.Sabdar@Sun.COM  * Sends a notify_halt request to the NDMP client.
697917SReza.Sabdar@Sun.COM  *
707917SReza.Sabdar@Sun.COM  * Parameters:
717917SReza.Sabdar@Sun.COM  *   session (input) - session pointer.
727917SReza.Sabdar@Sun.COM  *   err     (input) - UNIX error code.
737917SReza.Sabdar@Sun.COM  *
747917SReza.Sabdar@Sun.COM  * Returns:
757917SReza.Sabdar@Sun.COM  *   void
767917SReza.Sabdar@Sun.COM  */
777917SReza.Sabdar@Sun.COM void
ndmpd_api_done_v2(void * cookie,int err)787917SReza.Sabdar@Sun.COM ndmpd_api_done_v2(void *cookie, int err)
797917SReza.Sabdar@Sun.COM {
807917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
817917SReza.Sabdar@Sun.COM 	ndmp_notify_data_halted_request req_v2;
827917SReza.Sabdar@Sun.COM 
837917SReza.Sabdar@Sun.COM 	if (session == NULL)
847917SReza.Sabdar@Sun.COM 		return;
857917SReza.Sabdar@Sun.COM 
867917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_state == NDMP_DATA_STATE_IDLE ||
877917SReza.Sabdar@Sun.COM 	    session->ns_data.dd_state == NDMP_DATA_STATE_HALTED)
887917SReza.Sabdar@Sun.COM 		return;
897917SReza.Sabdar@Sun.COM 
907917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "data.operation: %d",
917917SReza.Sabdar@Sun.COM 	    session->ns_data.dd_operation);
927917SReza.Sabdar@Sun.COM 
937917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_operation == NDMP_DATA_OP_BACKUP) {
947917SReza.Sabdar@Sun.COM 		/*
957917SReza.Sabdar@Sun.COM 		 * Send/discard any buffered file history data.
967917SReza.Sabdar@Sun.COM 		 */
977917SReza.Sabdar@Sun.COM 		ndmpd_file_history_cleanup(session, (err == 0 ? TRUE : FALSE));
987917SReza.Sabdar@Sun.COM 
997917SReza.Sabdar@Sun.COM 		/*
1007917SReza.Sabdar@Sun.COM 		 * If mover local and successfull backup, write any
1017917SReza.Sabdar@Sun.COM 		 * remaining buffered data to tape.
1027917SReza.Sabdar@Sun.COM 		 */
1037917SReza.Sabdar@Sun.COM 		if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_LOCAL &&
1047917SReza.Sabdar@Sun.COM 		    err == 0) {
1057917SReza.Sabdar@Sun.COM 			if (ndmpd_local_write(session, 0, 0) < 0)
1067917SReza.Sabdar@Sun.COM 				err = EIO;
1077917SReza.Sabdar@Sun.COM 		}
1087917SReza.Sabdar@Sun.COM 	}
1097917SReza.Sabdar@Sun.COM 
1107917SReza.Sabdar@Sun.COM 	session->ns_data.dd_state = NDMP_DATA_STATE_HALTED;
1117917SReza.Sabdar@Sun.COM 
1127917SReza.Sabdar@Sun.COM 	switch (err) {
1137917SReza.Sabdar@Sun.COM 	case 0:
1147917SReza.Sabdar@Sun.COM 		session->ns_data.dd_halt_reason = NDMP_DATA_HALT_SUCCESSFUL;
1157917SReza.Sabdar@Sun.COM 		break;
1167917SReza.Sabdar@Sun.COM 	case EINTR:
1177917SReza.Sabdar@Sun.COM 		session->ns_data.dd_halt_reason = NDMP_DATA_HALT_ABORTED;
1187917SReza.Sabdar@Sun.COM 		break;
1197917SReza.Sabdar@Sun.COM 	case EIO:
1207917SReza.Sabdar@Sun.COM 		session->ns_data.dd_halt_reason = NDMP_DATA_HALT_CONNECT_ERROR;
1217917SReza.Sabdar@Sun.COM 		break;
1227917SReza.Sabdar@Sun.COM 	default:
1237917SReza.Sabdar@Sun.COM 		session->ns_data.dd_halt_reason = NDMP_DATA_HALT_INTERNAL_ERROR;
1247917SReza.Sabdar@Sun.COM 	}
1257917SReza.Sabdar@Sun.COM 
1267917SReza.Sabdar@Sun.COM 	req_v2.reason = session->ns_data.dd_halt_reason;
1277917SReza.Sabdar@Sun.COM 	req_v2.text_reason = "";
1287917SReza.Sabdar@Sun.COM 
1297917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "ndmp_send_request(NDMP_NOTIFY_DATA_HALTED)");
1307917SReza.Sabdar@Sun.COM 
1317917SReza.Sabdar@Sun.COM 	if (ndmp_send_request_lock(session->ns_connection,
1327917SReza.Sabdar@Sun.COM 	    NDMP_NOTIFY_DATA_HALTED, NDMP_NO_ERR, (void *)&req_v2, 0) < 0)
1337917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Sending notify_data_halted request");
1347917SReza.Sabdar@Sun.COM 
1357917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) {
1367917SReza.Sabdar@Sun.COM 
1377917SReza.Sabdar@Sun.COM 		if (session->ns_mover.md_sock != session->ns_data.dd_sock) {
1387917SReza.Sabdar@Sun.COM 			(void) close(session->ns_data.dd_sock);
1397917SReza.Sabdar@Sun.COM 		} else {
1407917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "Not closing as used by mover");
1417917SReza.Sabdar@Sun.COM 		}
1427917SReza.Sabdar@Sun.COM 
1437917SReza.Sabdar@Sun.COM 		session->ns_data.dd_sock = -1;
1447917SReza.Sabdar@Sun.COM 	} else {
1457917SReza.Sabdar@Sun.COM 		ndmpd_mover_error(session, NDMP_MOVER_HALT_CONNECT_CLOSED);
1467917SReza.Sabdar@Sun.COM 	}
1477917SReza.Sabdar@Sun.COM }
1487917SReza.Sabdar@Sun.COM 
1497917SReza.Sabdar@Sun.COM 
1507917SReza.Sabdar@Sun.COM /*
1517917SReza.Sabdar@Sun.COM  * ndmpd_api_log_v2
1527917SReza.Sabdar@Sun.COM  *
1537917SReza.Sabdar@Sun.COM  * Sends a log request to the NDMP client.
1547917SReza.Sabdar@Sun.COM  *
1557917SReza.Sabdar@Sun.COM  * Parameters:
1567917SReza.Sabdar@Sun.COM  *   cookie (input) - session pointer.
1577917SReza.Sabdar@Sun.COM  *   str    (input) - null terminated string
1587917SReza.Sabdar@Sun.COM  *   format (input) - printf style format.
1597917SReza.Sabdar@Sun.COM  *   ...    (input) - format arguments.
1607917SReza.Sabdar@Sun.COM  *
1617917SReza.Sabdar@Sun.COM  * Returns:
1627917SReza.Sabdar@Sun.COM  *   0 - success.
1637917SReza.Sabdar@Sun.COM  *  -1 - error.
1647917SReza.Sabdar@Sun.COM  */
1657917SReza.Sabdar@Sun.COM /*ARGSUSED*/
1667917SReza.Sabdar@Sun.COM int
ndmpd_api_log_v2(void * cookie,char * format,...)1677917SReza.Sabdar@Sun.COM ndmpd_api_log_v2(void *cookie, char *format, ...)
1687917SReza.Sabdar@Sun.COM {
1697917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
1707917SReza.Sabdar@Sun.COM 	ndmp_log_log_request request;
1717917SReza.Sabdar@Sun.COM 	static char buf[1024];
1727917SReza.Sabdar@Sun.COM 	va_list ap;
1737917SReza.Sabdar@Sun.COM 
1747917SReza.Sabdar@Sun.COM 	if (session == NULL)
1757917SReza.Sabdar@Sun.COM 		return (-1);
1767917SReza.Sabdar@Sun.COM 
1777917SReza.Sabdar@Sun.COM 	va_start(ap, format);
1787917SReza.Sabdar@Sun.COM 
1797917SReza.Sabdar@Sun.COM 	/*LINTED variable format specifier */
1807917SReza.Sabdar@Sun.COM 	(void) vsnprintf(buf, sizeof (buf), format, ap);
1817917SReza.Sabdar@Sun.COM 	va_end(ap);
1827917SReza.Sabdar@Sun.COM 
1837917SReza.Sabdar@Sun.COM 	request.entry = buf;
1847917SReza.Sabdar@Sun.COM 
1857917SReza.Sabdar@Sun.COM 
1867917SReza.Sabdar@Sun.COM 	if (ndmp_send_request(session->ns_connection, _NDMP_LOG_LOG,
1877917SReza.Sabdar@Sun.COM 	    NDMP_NO_ERR, (void *)&request, 0) < 0) {
1887917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Sending log request");
1897917SReza.Sabdar@Sun.COM 		return (-1);
1907917SReza.Sabdar@Sun.COM 	}
1917917SReza.Sabdar@Sun.COM 	return (0);
1927917SReza.Sabdar@Sun.COM 
1937917SReza.Sabdar@Sun.COM }
1947917SReza.Sabdar@Sun.COM 
1957917SReza.Sabdar@Sun.COM 
1967917SReza.Sabdar@Sun.COM /*
1977917SReza.Sabdar@Sun.COM  * ndmpd_api_read_v2
1987917SReza.Sabdar@Sun.COM  *
1997917SReza.Sabdar@Sun.COM  * Callback function called by the backup/recover module.
2007917SReza.Sabdar@Sun.COM  * Reads data from the mover.
2017917SReza.Sabdar@Sun.COM  * If the mover is remote, the data is read from the data connection.
2027917SReza.Sabdar@Sun.COM  * If the mover is local, the data is read from the tape device.
2037917SReza.Sabdar@Sun.COM  *
2047917SReza.Sabdar@Sun.COM  * Parameters:
2057917SReza.Sabdar@Sun.COM  *   client_data (input) - session pointer.
2067917SReza.Sabdar@Sun.COM  *   data       (input) - data to be written.
2077917SReza.Sabdar@Sun.COM  *   length     (input) - data length.
2087917SReza.Sabdar@Sun.COM  *
2097917SReza.Sabdar@Sun.COM  * Returns:
2107917SReza.Sabdar@Sun.COM  *   0 - data successfully read.
2117917SReza.Sabdar@Sun.COM  *  -1 - error.
2127917SReza.Sabdar@Sun.COM  *   1 - session terminated or operation aborted.
2137917SReza.Sabdar@Sun.COM  */
2147917SReza.Sabdar@Sun.COM int
ndmpd_api_read_v2(void * client_data,char * data,ulong_t length)2157917SReza.Sabdar@Sun.COM ndmpd_api_read_v2(void *client_data, char *data, ulong_t length)
2167917SReza.Sabdar@Sun.COM {
2177917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = (ndmpd_session_t *)client_data;
2187917SReza.Sabdar@Sun.COM 
2197917SReza.Sabdar@Sun.COM 	if (session == NULL)
2207917SReza.Sabdar@Sun.COM 		return (-1);
2217917SReza.Sabdar@Sun.COM 
2227917SReza.Sabdar@Sun.COM 	/*
2237917SReza.Sabdar@Sun.COM 	 * Read the data from the data connection if the mover is remote.
2247917SReza.Sabdar@Sun.COM 	 */
2257917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP)
2267917SReza.Sabdar@Sun.COM 		return (ndmpd_remote_read(session, data, length));
2277917SReza.Sabdar@Sun.COM 	else
2287917SReza.Sabdar@Sun.COM 		return (ndmpd_local_read(session, data, length));
2297917SReza.Sabdar@Sun.COM }
2307917SReza.Sabdar@Sun.COM 
2317917SReza.Sabdar@Sun.COM 
2327917SReza.Sabdar@Sun.COM /*
2337917SReza.Sabdar@Sun.COM  * ndmpd_api_seek_v2
2347917SReza.Sabdar@Sun.COM  *
2357917SReza.Sabdar@Sun.COM  * Seek to the specified position in the data stream and start a
2367917SReza.Sabdar@Sun.COM  * read for the specified amount of data.
2377917SReza.Sabdar@Sun.COM  *
2387917SReza.Sabdar@Sun.COM  * Parameters:
2397917SReza.Sabdar@Sun.COM  *   cookie (input) - session pointer.
2407917SReza.Sabdar@Sun.COM  *   offset (input) - stream position to seek to.
2417917SReza.Sabdar@Sun.COM  *   length (input) - amount of data that will be read using ndmpd_api_read
2427917SReza.Sabdar@Sun.COM  *
2437917SReza.Sabdar@Sun.COM  * Returns:
2447917SReza.Sabdar@Sun.COM  *   0 - seek successful.
2457917SReza.Sabdar@Sun.COM  *  -1 - error.
2467917SReza.Sabdar@Sun.COM  */
2477917SReza.Sabdar@Sun.COM int
ndmpd_api_seek_v2(void * cookie,u_longlong_t offset,u_longlong_t length)2487917SReza.Sabdar@Sun.COM ndmpd_api_seek_v2(void *cookie, u_longlong_t offset, u_longlong_t length)
2497917SReza.Sabdar@Sun.COM {
2507917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
2517917SReza.Sabdar@Sun.COM 	int err;
2527917SReza.Sabdar@Sun.COM 
2537917SReza.Sabdar@Sun.COM 	if (session == NULL)
2547917SReza.Sabdar@Sun.COM 		return (-1);
2557917SReza.Sabdar@Sun.COM 
2567917SReza.Sabdar@Sun.COM 	session->ns_data.dd_read_offset = offset;
2577917SReza.Sabdar@Sun.COM 	session->ns_data.dd_read_length = length;
2587917SReza.Sabdar@Sun.COM 
2597917SReza.Sabdar@Sun.COM 	/*
2607917SReza.Sabdar@Sun.COM 	 * Send a notify_data_read request if the mover is remote.
2617917SReza.Sabdar@Sun.COM 	 */
2627917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) {
2637917SReza.Sabdar@Sun.COM 		ndmp_notify_data_read_request request;
2647917SReza.Sabdar@Sun.COM 
2657917SReza.Sabdar@Sun.COM 		session->ns_mover.md_discard_length =
2667917SReza.Sabdar@Sun.COM 		    session->ns_mover.md_bytes_left_to_read;
2677917SReza.Sabdar@Sun.COM 		session->ns_mover.md_bytes_left_to_read = length;
2687917SReza.Sabdar@Sun.COM 		session->ns_mover.md_position = offset;
2697917SReza.Sabdar@Sun.COM 
2707917SReza.Sabdar@Sun.COM 		request.offset = long_long_to_quad(offset);
2717917SReza.Sabdar@Sun.COM 		request.length = long_long_to_quad(length);
2727917SReza.Sabdar@Sun.COM 
2738193SReza.Sabdar@Sun.COM 		if (ndmp_send_request_lock(session->ns_connection,
2747917SReza.Sabdar@Sun.COM 		    NDMP_NOTIFY_DATA_READ, NDMP_NO_ERR,
2757917SReza.Sabdar@Sun.COM 		    (void *)&request, 0) < 0) {
2768193SReza.Sabdar@Sun.COM 
2777917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG,
2787917SReza.Sabdar@Sun.COM 			    "Sending notify_data_read request");
2797917SReza.Sabdar@Sun.COM 			return (-1);
2807917SReza.Sabdar@Sun.COM 		}
2817917SReza.Sabdar@Sun.COM 		return (0);
2827917SReza.Sabdar@Sun.COM 	}
2837917SReza.Sabdar@Sun.COM 	/* Mover is local. */
2847917SReza.Sabdar@Sun.COM 
2857917SReza.Sabdar@Sun.COM 	err = ndmpd_mover_seek(session, offset, length);
2867917SReza.Sabdar@Sun.COM 	if (err < 0) {
2877917SReza.Sabdar@Sun.COM 		ndmpd_mover_error(session, NDMP_MOVER_HALT_INTERNAL_ERROR);
2887917SReza.Sabdar@Sun.COM 		return (-1);
2897917SReza.Sabdar@Sun.COM 	}
2907917SReza.Sabdar@Sun.COM 	if (err == 0)
2917917SReza.Sabdar@Sun.COM 		return (0);
2927917SReza.Sabdar@Sun.COM 
2937917SReza.Sabdar@Sun.COM 	/*
2947917SReza.Sabdar@Sun.COM 	 * NDMP client intervention is required to perform the seek.
2957917SReza.Sabdar@Sun.COM 	 * Wait for the client to either do the seek and send a continue
2967917SReza.Sabdar@Sun.COM 	 * request or send an abort request.
2977917SReza.Sabdar@Sun.COM 	 */
2987917SReza.Sabdar@Sun.COM 	nlp_ref_nw(session);
2997917SReza.Sabdar@Sun.COM 	for (; ; ) {
3007917SReza.Sabdar@Sun.COM 		nlp_wait_nw(session);
3017917SReza.Sabdar@Sun.COM 
3027917SReza.Sabdar@Sun.COM 		if (nlp_event_rv_get(session) < 0) {
3037917SReza.Sabdar@Sun.COM 			nlp_unref_nw(session);
3047917SReza.Sabdar@Sun.COM 			return (-1);
3057917SReza.Sabdar@Sun.COM 		}
3067917SReza.Sabdar@Sun.COM 
3077917SReza.Sabdar@Sun.COM 		if (session->ns_eof == TRUE) {
3087917SReza.Sabdar@Sun.COM 			nlp_unref_nw(session);
3097917SReza.Sabdar@Sun.COM 			return (-1);
3107917SReza.Sabdar@Sun.COM 		}
3117917SReza.Sabdar@Sun.COM 
3127917SReza.Sabdar@Sun.COM 		switch (session->ns_mover.md_state) {
3137917SReza.Sabdar@Sun.COM 		case NDMP_MOVER_STATE_ACTIVE:
3147917SReza.Sabdar@Sun.COM 			/*
3157917SReza.Sabdar@Sun.COM 			 * There is a bug in the original SDK code which
3167917SReza.Sabdar@Sun.COM 			 * causes to fall in an infinite loop after the
3177917SReza.Sabdar@Sun.COM 			 * break.
3187917SReza.Sabdar@Sun.COM 			 */
3197917SReza.Sabdar@Sun.COM 			nlp_unref_nw(session);
3207917SReza.Sabdar@Sun.COM 			break;
3217917SReza.Sabdar@Sun.COM 
3227917SReza.Sabdar@Sun.COM 		case NDMP_MOVER_STATE_PAUSED:
3237917SReza.Sabdar@Sun.COM 			continue;
3247917SReza.Sabdar@Sun.COM 
3257917SReza.Sabdar@Sun.COM 		default:
3267917SReza.Sabdar@Sun.COM 			nlp_unref_nw(session);
3277917SReza.Sabdar@Sun.COM 			return (-1);
3287917SReza.Sabdar@Sun.COM 		}
3297917SReza.Sabdar@Sun.COM 	}
3307917SReza.Sabdar@Sun.COM }
3317917SReza.Sabdar@Sun.COM 
3327917SReza.Sabdar@Sun.COM 
3337917SReza.Sabdar@Sun.COM /*
3347917SReza.Sabdar@Sun.COM  * ndmpd_api_file_recovered_v2
3357917SReza.Sabdar@Sun.COM  *
3367917SReza.Sabdar@Sun.COM  * Notify the NDMP client that the specified file was recovered.
3377917SReza.Sabdar@Sun.COM  *
3387917SReza.Sabdar@Sun.COM  * Parameters:
3397917SReza.Sabdar@Sun.COM  *   cookie (input) - session pointer.
3407917SReza.Sabdar@Sun.COM  *   name   (input) - name of recovered file.
3417917SReza.Sabdar@Sun.COM  *   error  (input) - 0 if file successfully recovered.
3427917SReza.Sabdar@Sun.COM  *		    otherwise, error code indicating why recovery failed.
3437917SReza.Sabdar@Sun.COM  *
3447917SReza.Sabdar@Sun.COM  * Returns:
3457917SReza.Sabdar@Sun.COM  *   void.
3467917SReza.Sabdar@Sun.COM  */
3477917SReza.Sabdar@Sun.COM int
ndmpd_api_file_recovered_v2(void * cookie,char * name,int error)3487917SReza.Sabdar@Sun.COM ndmpd_api_file_recovered_v2(void *cookie, char *name, int error)
3497917SReza.Sabdar@Sun.COM {
3507917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
3517917SReza.Sabdar@Sun.COM 	ndmp_log_file_request_v2 request;
3527917SReza.Sabdar@Sun.COM 
3537917SReza.Sabdar@Sun.COM 	if (session == NULL)
3547917SReza.Sabdar@Sun.COM 		return (-1);
3557917SReza.Sabdar@Sun.COM 
3567917SReza.Sabdar@Sun.COM 	request.name = name;
3577917SReza.Sabdar@Sun.COM 	request.ssid = 0;
3587917SReza.Sabdar@Sun.COM 
3597917SReza.Sabdar@Sun.COM 	switch (error) {
3607917SReza.Sabdar@Sun.COM 	case 0:
3617917SReza.Sabdar@Sun.COM 		request.error = NDMP_NO_ERR;
3627917SReza.Sabdar@Sun.COM 		break;
3637917SReza.Sabdar@Sun.COM 	case ENOENT:
3647917SReza.Sabdar@Sun.COM 		request.error = NDMP_FILE_NOT_FOUND_ERR;
3657917SReza.Sabdar@Sun.COM 		break;
3667917SReza.Sabdar@Sun.COM 	default:
3677917SReza.Sabdar@Sun.COM 		request.error = NDMP_PERMISSION_ERR;
3687917SReza.Sabdar@Sun.COM 	}
3697917SReza.Sabdar@Sun.COM 
370*12475SReza.Sabdar@Sun.COM 	if (ndmp_send_request_lock(session->ns_connection, NDMP_LOG_FILE,
3717917SReza.Sabdar@Sun.COM 	    NDMP_NO_ERR, (void *)&request, 0) < 0) {
3727917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Sending log file request");
3737917SReza.Sabdar@Sun.COM 		return (-1);
3747917SReza.Sabdar@Sun.COM 	}
3757917SReza.Sabdar@Sun.COM 	return (0);
3767917SReza.Sabdar@Sun.COM }
3777917SReza.Sabdar@Sun.COM 
3787917SReza.Sabdar@Sun.COM 
3797917SReza.Sabdar@Sun.COM /*
3807917SReza.Sabdar@Sun.COM  * ndmpd_api_write_v2
3817917SReza.Sabdar@Sun.COM  *
3827917SReza.Sabdar@Sun.COM  * Callback function called by the backup/restore module.
3837917SReza.Sabdar@Sun.COM  * Writes data to the mover.
3847917SReza.Sabdar@Sun.COM  * If the mover is remote, the data is written to the data connection.
3857917SReza.Sabdar@Sun.COM  * If the mover is local, the data is buffered and written to the
3867917SReza.Sabdar@Sun.COM  * tape device after a full record has been buffered.
3877917SReza.Sabdar@Sun.COM  *
3887917SReza.Sabdar@Sun.COM  * Parameters:
3897917SReza.Sabdar@Sun.COM  *   client_data (input) - session pointer.
3907917SReza.Sabdar@Sun.COM  *   data       (input) - data to be written.
3917917SReza.Sabdar@Sun.COM  *   length     (input) - data length.
3927917SReza.Sabdar@Sun.COM  *
3937917SReza.Sabdar@Sun.COM  * Returns:
3947917SReza.Sabdar@Sun.COM  *   0 - data successfully written.
3957917SReza.Sabdar@Sun.COM  *  -1 - error.
3967917SReza.Sabdar@Sun.COM  */
3977917SReza.Sabdar@Sun.COM int
ndmpd_api_write_v2(void * client_data,char * data,ulong_t length)3987917SReza.Sabdar@Sun.COM ndmpd_api_write_v2(void *client_data, char *data, ulong_t length)
3997917SReza.Sabdar@Sun.COM {
4007917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = (ndmpd_session_t *)client_data;
4017917SReza.Sabdar@Sun.COM 
4027917SReza.Sabdar@Sun.COM 	if (session == NULL)
4037917SReza.Sabdar@Sun.COM 		return (-1);
4047917SReza.Sabdar@Sun.COM 
4057917SReza.Sabdar@Sun.COM 	/*
4067917SReza.Sabdar@Sun.COM 	 * Write the data to the data connection if the mover is remote.
4077917SReza.Sabdar@Sun.COM 	 */
4087917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP)
4097917SReza.Sabdar@Sun.COM 		return (ndmpd_remote_write(session, data, length));
4107917SReza.Sabdar@Sun.COM 	else
4117917SReza.Sabdar@Sun.COM 		return (ndmpd_local_write(session, data, length));
4127917SReza.Sabdar@Sun.COM }
4137917SReza.Sabdar@Sun.COM 
4147917SReza.Sabdar@Sun.COM 
4157917SReza.Sabdar@Sun.COM /*
4167917SReza.Sabdar@Sun.COM  * ************************************************************************
4177917SReza.Sabdar@Sun.COM  * NDMP V3 CALLBACKS
4187917SReza.Sabdar@Sun.COM  * ************************************************************************
4197917SReza.Sabdar@Sun.COM  */
4207917SReza.Sabdar@Sun.COM 
4217917SReza.Sabdar@Sun.COM /*
4227917SReza.Sabdar@Sun.COM  * ndmpd_api_done_v3
4237917SReza.Sabdar@Sun.COM  *
4247917SReza.Sabdar@Sun.COM  * Called when the data module has completed.
4257917SReza.Sabdar@Sun.COM  * Sends a notify_halt request to the NDMP client.
4267917SReza.Sabdar@Sun.COM  *
4277917SReza.Sabdar@Sun.COM  * Parameters:
4287917SReza.Sabdar@Sun.COM  *   session (input) - session pointer.
4297917SReza.Sabdar@Sun.COM  *   err     (input) - UNIX error code.
4307917SReza.Sabdar@Sun.COM  *
4317917SReza.Sabdar@Sun.COM  * Returns:
4327917SReza.Sabdar@Sun.COM  *   void
4337917SReza.Sabdar@Sun.COM  */
4347917SReza.Sabdar@Sun.COM void
ndmpd_api_done_v3(void * cookie,int err)4357917SReza.Sabdar@Sun.COM ndmpd_api_done_v3(void *cookie, int err)
4367917SReza.Sabdar@Sun.COM {
4377917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
4387917SReza.Sabdar@Sun.COM 	ndmp_data_halt_reason reason;
4397917SReza.Sabdar@Sun.COM 
4407917SReza.Sabdar@Sun.COM 	switch (err) {
4417917SReza.Sabdar@Sun.COM 	case 0:
4427917SReza.Sabdar@Sun.COM 		reason = NDMP_DATA_HALT_SUCCESSFUL;
4437917SReza.Sabdar@Sun.COM 		break;
4447917SReza.Sabdar@Sun.COM 
4457917SReza.Sabdar@Sun.COM 	case EINTR:
4467917SReza.Sabdar@Sun.COM 		reason = NDMP_DATA_HALT_ABORTED;
4477917SReza.Sabdar@Sun.COM 		break;
4487917SReza.Sabdar@Sun.COM 
4497917SReza.Sabdar@Sun.COM 	case EIO:
4507917SReza.Sabdar@Sun.COM 		reason = NDMP_DATA_HALT_CONNECT_ERROR;
4517917SReza.Sabdar@Sun.COM 		break;
4527917SReza.Sabdar@Sun.COM 
4537917SReza.Sabdar@Sun.COM 	default:
4547917SReza.Sabdar@Sun.COM 		reason = NDMP_DATA_HALT_INTERNAL_ERROR;
4557917SReza.Sabdar@Sun.COM 	}
4567917SReza.Sabdar@Sun.COM 
4577917SReza.Sabdar@Sun.COM 	ndmpd_data_error(session, reason);
4587917SReza.Sabdar@Sun.COM }
4597917SReza.Sabdar@Sun.COM 
4607917SReza.Sabdar@Sun.COM /*
4617917SReza.Sabdar@Sun.COM  * ndmpd_api_log_v3
4627917SReza.Sabdar@Sun.COM  *
4637917SReza.Sabdar@Sun.COM  * Sends a log request to the NDMP client.
4647917SReza.Sabdar@Sun.COM  *
4657917SReza.Sabdar@Sun.COM  * Parameters:
4667917SReza.Sabdar@Sun.COM  *   cookie (input) - session pointer.
4677917SReza.Sabdar@Sun.COM  *   format (input) - printf style format.
4687917SReza.Sabdar@Sun.COM  *   ...    (input) - format arguments.
4697917SReza.Sabdar@Sun.COM  *
4707917SReza.Sabdar@Sun.COM  * Returns:
4717917SReza.Sabdar@Sun.COM  *   0 - success.
4727917SReza.Sabdar@Sun.COM  *  -1 - error.
4737917SReza.Sabdar@Sun.COM  */
4747917SReza.Sabdar@Sun.COM /*ARGSUSED*/
4757917SReza.Sabdar@Sun.COM int
ndmpd_api_log_v3(void * cookie,ndmp_log_type type,ulong_t msg_id,char * format,...)4767917SReza.Sabdar@Sun.COM ndmpd_api_log_v3(void *cookie, ndmp_log_type type, ulong_t msg_id,
4777917SReza.Sabdar@Sun.COM     char *format, ...)
4787917SReza.Sabdar@Sun.COM {
4797917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
4807917SReza.Sabdar@Sun.COM 	ndmp_log_message_request_v3 request;
4817917SReza.Sabdar@Sun.COM 	static char buf[1024];
4827917SReza.Sabdar@Sun.COM 	va_list ap;
4837917SReza.Sabdar@Sun.COM 
4847917SReza.Sabdar@Sun.COM 	if (session == NULL)
4857917SReza.Sabdar@Sun.COM 		return (-1);
4867917SReza.Sabdar@Sun.COM 
4877917SReza.Sabdar@Sun.COM 	va_start(ap, format);
4887917SReza.Sabdar@Sun.COM 
4897917SReza.Sabdar@Sun.COM 	/*LINTED variable format specifier */
4907917SReza.Sabdar@Sun.COM 	(void) vsnprintf(buf, sizeof (buf), format, ap);
4917917SReza.Sabdar@Sun.COM 	va_end(ap);
4927917SReza.Sabdar@Sun.COM 
4937917SReza.Sabdar@Sun.COM 	request.entry = buf;
4947917SReza.Sabdar@Sun.COM 	request.log_type = type;
4957917SReza.Sabdar@Sun.COM 	request.message_id = msg_id;
4967917SReza.Sabdar@Sun.COM 
4977917SReza.Sabdar@Sun.COM 	if (ndmp_send_request(session->ns_connection, NDMP_LOG_MESSAGE,
4987917SReza.Sabdar@Sun.COM 	    NDMP_NO_ERR, (void *)&request, 0) < 0) {
4997917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Error sending log message request.");
5007917SReza.Sabdar@Sun.COM 		return (-1);
5017917SReza.Sabdar@Sun.COM 	}
5027917SReza.Sabdar@Sun.COM 	return (0);
5037917SReza.Sabdar@Sun.COM }
5047917SReza.Sabdar@Sun.COM 
5057917SReza.Sabdar@Sun.COM 
5067917SReza.Sabdar@Sun.COM /*
5077917SReza.Sabdar@Sun.COM  * ndmpd_api_write_v3
5087917SReza.Sabdar@Sun.COM  *
5097917SReza.Sabdar@Sun.COM  * Callback function called by the backup/restore module.
5107917SReza.Sabdar@Sun.COM  * Writes data to the mover.
5117917SReza.Sabdar@Sun.COM  * If the mover is remote, the data is written to the data connection.
5127917SReza.Sabdar@Sun.COM  * If the mover is local, the data is buffered and written to the
5137917SReza.Sabdar@Sun.COM  * tape device after a full record has been buffered.
5147917SReza.Sabdar@Sun.COM  *
5157917SReza.Sabdar@Sun.COM  * Parameters:
5167917SReza.Sabdar@Sun.COM  *   client_data (input) - session pointer.
5177917SReza.Sabdar@Sun.COM  *   data       (input) - data to be written.
5187917SReza.Sabdar@Sun.COM  *   length     (input) - data length.
5197917SReza.Sabdar@Sun.COM  *
5207917SReza.Sabdar@Sun.COM  * Returns:
5217917SReza.Sabdar@Sun.COM  *   0 - data successfully written.
5227917SReza.Sabdar@Sun.COM  *  -1 - error.
5237917SReza.Sabdar@Sun.COM  */
5247917SReza.Sabdar@Sun.COM int
ndmpd_api_write_v3(void * client_data,char * data,ulong_t length)5257917SReza.Sabdar@Sun.COM ndmpd_api_write_v3(void *client_data, char *data, ulong_t length)
5267917SReza.Sabdar@Sun.COM {
5277917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = (ndmpd_session_t *)client_data;
5287917SReza.Sabdar@Sun.COM 
5297917SReza.Sabdar@Sun.COM 	if (session == NULL)
5307917SReza.Sabdar@Sun.COM 		return (-1);
5317917SReza.Sabdar@Sun.COM 
5327917SReza.Sabdar@Sun.COM 	/*
5337917SReza.Sabdar@Sun.COM 	 * Write the data to the tape if the mover is local, otherwise,
5347917SReza.Sabdar@Sun.COM 	 * write the data to the data connection.
5357917SReza.Sabdar@Sun.COM 	 *
5367917SReza.Sabdar@Sun.COM 	 * The same write function for of v2 can be used in V3
5377917SReza.Sabdar@Sun.COM 	 * for writing data to the data connection to the mover.
5387917SReza.Sabdar@Sun.COM 	 * So we don't need ndmpd_remote_write_v3().
5397917SReza.Sabdar@Sun.COM 	 */
5407917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_data_addr.addr_type == NDMP_ADDR_LOCAL)
5417917SReza.Sabdar@Sun.COM 		return (ndmpd_local_write_v3(session, data, length));
5427917SReza.Sabdar@Sun.COM 	else
5437917SReza.Sabdar@Sun.COM 		return (ndmpd_remote_write(session, data, length));
5447917SReza.Sabdar@Sun.COM }
5457917SReza.Sabdar@Sun.COM 
5467917SReza.Sabdar@Sun.COM 
5477917SReza.Sabdar@Sun.COM /*
5487917SReza.Sabdar@Sun.COM  * ndmpd_api_read_v3
5497917SReza.Sabdar@Sun.COM  *
5507917SReza.Sabdar@Sun.COM  * Callback function called by the backup/recover module.
5517917SReza.Sabdar@Sun.COM  * Reads data from the mover.
5527917SReza.Sabdar@Sun.COM  * If the mover is remote, the data is read from the data connection.
5537917SReza.Sabdar@Sun.COM  * If the mover is local, the data is read from the tape device.
5547917SReza.Sabdar@Sun.COM  *
5557917SReza.Sabdar@Sun.COM  * Parameters:
5567917SReza.Sabdar@Sun.COM  *   client_data (input) - session pointer.
5577917SReza.Sabdar@Sun.COM  *   data       (input) - data to be written.
5587917SReza.Sabdar@Sun.COM  *   length     (input) - data length.
5597917SReza.Sabdar@Sun.COM  *
5607917SReza.Sabdar@Sun.COM  * Returns:
5617917SReza.Sabdar@Sun.COM  *   0 - data successfully read.
5627917SReza.Sabdar@Sun.COM  *  -1 - error.
5637917SReza.Sabdar@Sun.COM  *   1 - session terminated or operation aborted.
5647917SReza.Sabdar@Sun.COM  */
5657917SReza.Sabdar@Sun.COM int
ndmpd_api_read_v3(void * client_data,char * data,ulong_t length)5667917SReza.Sabdar@Sun.COM ndmpd_api_read_v3(void *client_data, char *data, ulong_t length)
5677917SReza.Sabdar@Sun.COM {
5687917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = (ndmpd_session_t *)client_data;
5697917SReza.Sabdar@Sun.COM 
5707917SReza.Sabdar@Sun.COM 	if (session == NULL)
5717917SReza.Sabdar@Sun.COM 		return (-1);
5727917SReza.Sabdar@Sun.COM 
5737917SReza.Sabdar@Sun.COM 	/*
5747917SReza.Sabdar@Sun.COM 	 * Read the data from the data connection if the mover is remote.
5757917SReza.Sabdar@Sun.COM 	 */
5767917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_data_addr.addr_type == NDMP_ADDR_LOCAL)
5777917SReza.Sabdar@Sun.COM 		return (ndmpd_local_read_v3(session, data, length));
5787917SReza.Sabdar@Sun.COM 	else
5797917SReza.Sabdar@Sun.COM 		return (ndmpd_remote_read_v3(session, data, length));
5807917SReza.Sabdar@Sun.COM }
5817917SReza.Sabdar@Sun.COM 
5827917SReza.Sabdar@Sun.COM 
5837917SReza.Sabdar@Sun.COM /*
5847917SReza.Sabdar@Sun.COM  * ndmpd_api_get_name_v3
5857917SReza.Sabdar@Sun.COM  *
5867917SReza.Sabdar@Sun.COM  * Return the name entry at the specified index from the
5877917SReza.Sabdar@Sun.COM  * recover file name list.
5887917SReza.Sabdar@Sun.COM  *
5897917SReza.Sabdar@Sun.COM  * Parameters:
5907917SReza.Sabdar@Sun.COM  *       cookie    (input) - NDMP session pointer.
5917917SReza.Sabdar@Sun.COM  *       name_index (input) - index of entry to be returned.
5927917SReza.Sabdar@Sun.COM  *
5937917SReza.Sabdar@Sun.COM  * Returns:
5947917SReza.Sabdar@Sun.COM  *   Pointer to name entry.
5957917SReza.Sabdar@Sun.COM  *   0 if requested entry does not exist.
5967917SReza.Sabdar@Sun.COM  */
5977917SReza.Sabdar@Sun.COM void *
ndmpd_api_get_name_v3(void * cookie,ulong_t name_index)5987917SReza.Sabdar@Sun.COM ndmpd_api_get_name_v3(void *cookie, ulong_t name_index)
5997917SReza.Sabdar@Sun.COM {
6007917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
6017917SReza.Sabdar@Sun.COM 
6027917SReza.Sabdar@Sun.COM 	if (session == NULL)
6037917SReza.Sabdar@Sun.COM 		return (NULL);
6047917SReza.Sabdar@Sun.COM 
6057917SReza.Sabdar@Sun.COM 	if (name_index >= session->ns_data.dd_nlist_len)
6067917SReza.Sabdar@Sun.COM 		return (NULL);
6077917SReza.Sabdar@Sun.COM 
6087917SReza.Sabdar@Sun.COM 	return (&session->ns_data.dd_nlist_v3[name_index]);
6097917SReza.Sabdar@Sun.COM }
6107917SReza.Sabdar@Sun.COM 
6117917SReza.Sabdar@Sun.COM 
6127917SReza.Sabdar@Sun.COM /*
6137917SReza.Sabdar@Sun.COM  * ndmpd_api_file_recovered_v3
6147917SReza.Sabdar@Sun.COM  *
6157917SReza.Sabdar@Sun.COM  * Notify the NDMP client that the specified file was recovered.
6167917SReza.Sabdar@Sun.COM  *
6177917SReza.Sabdar@Sun.COM  * Parameters:
6187917SReza.Sabdar@Sun.COM  *   cookie (input) - session pointer.
6197917SReza.Sabdar@Sun.COM  *   name   (input) - name of recovered file.
6207917SReza.Sabdar@Sun.COM  *   ssid   (input) - selection set id.
6217917SReza.Sabdar@Sun.COM  *   error  (input) - 0 if file successfully recovered.
6227917SReza.Sabdar@Sun.COM  *		    otherwise, error code indicating why recovery failed.
6237917SReza.Sabdar@Sun.COM  *
6247917SReza.Sabdar@Sun.COM  * Returns:
6257917SReza.Sabdar@Sun.COM  *   0 - success.
6267917SReza.Sabdar@Sun.COM  *  -1 - error.
6277917SReza.Sabdar@Sun.COM  */
6287917SReza.Sabdar@Sun.COM int
ndmpd_api_file_recovered_v3(void * cookie,char * name,int error)6297917SReza.Sabdar@Sun.COM ndmpd_api_file_recovered_v3(void *cookie, char *name, int error)
6307917SReza.Sabdar@Sun.COM {
6317917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
6327917SReza.Sabdar@Sun.COM 	ndmp_log_file_request_v3 request;
6337917SReza.Sabdar@Sun.COM 
6347917SReza.Sabdar@Sun.COM 	if (session == NULL)
6357917SReza.Sabdar@Sun.COM 		return (-1);
6367917SReza.Sabdar@Sun.COM 
6377917SReza.Sabdar@Sun.COM 	request.name  = name;
6387917SReza.Sabdar@Sun.COM 
6397917SReza.Sabdar@Sun.COM 	switch (error) {
6407917SReza.Sabdar@Sun.COM 	case 0:
6417917SReza.Sabdar@Sun.COM 		request.error = NDMP_NO_ERR;
6427917SReza.Sabdar@Sun.COM 		break;
6437917SReza.Sabdar@Sun.COM 	case ENOENT:
6447917SReza.Sabdar@Sun.COM 		request.error = NDMP_FILE_NOT_FOUND_ERR;
6457917SReza.Sabdar@Sun.COM 		break;
6467917SReza.Sabdar@Sun.COM 	default:
6477917SReza.Sabdar@Sun.COM 		request.error = NDMP_PERMISSION_ERR;
6487917SReza.Sabdar@Sun.COM 	}
6497917SReza.Sabdar@Sun.COM 
650*12475SReza.Sabdar@Sun.COM 	if (ndmp_send_request_lock(session->ns_connection, NDMP_LOG_FILE,
6517917SReza.Sabdar@Sun.COM 	    NDMP_NO_ERR, (void *)&request, 0) < 0) {
6527917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Error sending log file request");
6537917SReza.Sabdar@Sun.COM 		return (-1);
6547917SReza.Sabdar@Sun.COM 	}
6557917SReza.Sabdar@Sun.COM 
6567917SReza.Sabdar@Sun.COM 	return (0);
6577917SReza.Sabdar@Sun.COM }
6587917SReza.Sabdar@Sun.COM 
6597917SReza.Sabdar@Sun.COM 
6607917SReza.Sabdar@Sun.COM /*
6617917SReza.Sabdar@Sun.COM  * ndmpd_api_seek_v3
6627917SReza.Sabdar@Sun.COM  *
6637917SReza.Sabdar@Sun.COM  * Seek to the specified position in the data stream and start a
6647917SReza.Sabdar@Sun.COM  * read for the specified amount of data.
6657917SReza.Sabdar@Sun.COM  *
6667917SReza.Sabdar@Sun.COM  * Parameters:
6677917SReza.Sabdar@Sun.COM  *   cookie (input) - session pointer.
6687917SReza.Sabdar@Sun.COM  *   offset (input) - stream position to seek to.
6697917SReza.Sabdar@Sun.COM  *   length (input) - amount of data that will be read using ndmpd_api_read
6707917SReza.Sabdar@Sun.COM  *
6717917SReza.Sabdar@Sun.COM  * Returns:
6727917SReza.Sabdar@Sun.COM  *   0 - seek successful.
6737917SReza.Sabdar@Sun.COM  *   1 - seek needed DMA(client) intervention.
6747917SReza.Sabdar@Sun.COM  *  -1 - error.
6757917SReza.Sabdar@Sun.COM  */
6767917SReza.Sabdar@Sun.COM int
ndmpd_api_seek_v3(void * cookie,u_longlong_t offset,u_longlong_t length)6777917SReza.Sabdar@Sun.COM ndmpd_api_seek_v3(void *cookie, u_longlong_t offset, u_longlong_t length)
6787917SReza.Sabdar@Sun.COM {
6797917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
6807917SReza.Sabdar@Sun.COM 	int err;
6817917SReza.Sabdar@Sun.COM 	ndmp_notify_data_read_request request;
6827917SReza.Sabdar@Sun.COM 
6837917SReza.Sabdar@Sun.COM 	if (session == NULL)
6847917SReza.Sabdar@Sun.COM 		return (-1);
6857917SReza.Sabdar@Sun.COM 
6867917SReza.Sabdar@Sun.COM 	session->ns_data.dd_read_offset = offset;
6877917SReza.Sabdar@Sun.COM 	session->ns_data.dd_read_length = length;
6887917SReza.Sabdar@Sun.COM 
6897917SReza.Sabdar@Sun.COM 	/*
6907917SReza.Sabdar@Sun.COM 	 * Send a notify_data_read request if the mover is remote.
6917917SReza.Sabdar@Sun.COM 	 */
6927917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_data_addr.addr_type != NDMP_ADDR_LOCAL) {
6937917SReza.Sabdar@Sun.COM 		session->ns_data.dd_discard_length =
6947917SReza.Sabdar@Sun.COM 		    session->ns_data.dd_bytes_left_to_read;
6957917SReza.Sabdar@Sun.COM 		session->ns_data.dd_bytes_left_to_read = length;
6967917SReza.Sabdar@Sun.COM 		session->ns_data.dd_position = offset;
6977917SReza.Sabdar@Sun.COM 
6987917SReza.Sabdar@Sun.COM 		request.offset = long_long_to_quad(offset);
6997917SReza.Sabdar@Sun.COM 		request.length = long_long_to_quad(length);
7007917SReza.Sabdar@Sun.COM 
7018193SReza.Sabdar@Sun.COM 		if (ndmp_send_request_lock(session->ns_connection,
7027917SReza.Sabdar@Sun.COM 		    NDMP_NOTIFY_DATA_READ, NDMP_NO_ERR,
7037917SReza.Sabdar@Sun.COM 		    (void *)&request, 0) < 0) {
7047917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG,
7057917SReza.Sabdar@Sun.COM 			    "Sending notify_data_read request");
7067917SReza.Sabdar@Sun.COM 			return (-1);
7077917SReza.Sabdar@Sun.COM 		}
7087917SReza.Sabdar@Sun.COM 
7097917SReza.Sabdar@Sun.COM 		return (0);
7107917SReza.Sabdar@Sun.COM 	}
7117917SReza.Sabdar@Sun.COM 
7127917SReza.Sabdar@Sun.COM 	/* Mover is local. */
7137917SReza.Sabdar@Sun.COM 
7147917SReza.Sabdar@Sun.COM 	err = ndmpd_mover_seek(session, offset, length);
7157917SReza.Sabdar@Sun.COM 	if (err < 0) {
7167917SReza.Sabdar@Sun.COM 		ndmpd_mover_error(session, NDMP_MOVER_HALT_INTERNAL_ERROR);
7177917SReza.Sabdar@Sun.COM 		return (-1);
7187917SReza.Sabdar@Sun.COM 	}
7197917SReza.Sabdar@Sun.COM 
7207917SReza.Sabdar@Sun.COM 	if (err == 0)
7217917SReza.Sabdar@Sun.COM 		return (0);
7227917SReza.Sabdar@Sun.COM 
7237917SReza.Sabdar@Sun.COM 	/*
7247917SReza.Sabdar@Sun.COM 	 * NDMP client intervention is required to perform the seek.
7257917SReza.Sabdar@Sun.COM 	 * Wait for the client to either do the seek and send a continue
7267917SReza.Sabdar@Sun.COM 	 * request or send an abort request.
7277917SReza.Sabdar@Sun.COM 	 */
7287917SReza.Sabdar@Sun.COM 	err = ndmpd_mover_wait_v3(session);
7297917SReza.Sabdar@Sun.COM 
7307917SReza.Sabdar@Sun.COM 	/*
7317917SReza.Sabdar@Sun.COM 	 * If we needed a client intervention, then we should be able to
7327917SReza.Sabdar@Sun.COM 	 * detect this in DAR.
7337917SReza.Sabdar@Sun.COM 	 */
7347917SReza.Sabdar@Sun.COM 	if (err == 0)
7357917SReza.Sabdar@Sun.COM 		err = 1;
7367917SReza.Sabdar@Sun.COM 	return (err);
7377917SReza.Sabdar@Sun.COM }
7387917SReza.Sabdar@Sun.COM 
7397917SReza.Sabdar@Sun.COM 
7407917SReza.Sabdar@Sun.COM /*
7417917SReza.Sabdar@Sun.COM  * ************************************************************************
7427917SReza.Sabdar@Sun.COM  * NDMP V4 CALLBACKS
7437917SReza.Sabdar@Sun.COM  * ************************************************************************
7447917SReza.Sabdar@Sun.COM  */
7457917SReza.Sabdar@Sun.COM 
7467917SReza.Sabdar@Sun.COM /*
7477917SReza.Sabdar@Sun.COM  * ndmpd_api_log_v4
7487917SReza.Sabdar@Sun.COM  *
7497917SReza.Sabdar@Sun.COM  * Sends a log request to the NDMP client.
7507917SReza.Sabdar@Sun.COM  * No message association is supported now, but can be added later on
7517917SReza.Sabdar@Sun.COM  * in this function.
7527917SReza.Sabdar@Sun.COM  *
7537917SReza.Sabdar@Sun.COM  * Parameters:
7547917SReza.Sabdar@Sun.COM  *   cookie (input) - session pointer.
7557917SReza.Sabdar@Sun.COM  *   format (input) - printf style format.
7567917SReza.Sabdar@Sun.COM  *   ...    (input) - format arguments.
7577917SReza.Sabdar@Sun.COM  *
7587917SReza.Sabdar@Sun.COM  * Returns:
7597917SReza.Sabdar@Sun.COM  *   0 - success.
7607917SReza.Sabdar@Sun.COM  *  -1 - error.
7617917SReza.Sabdar@Sun.COM  */
7627917SReza.Sabdar@Sun.COM /*ARGSUSED*/
7637917SReza.Sabdar@Sun.COM int
ndmpd_api_log_v4(void * cookie,ndmp_log_type type,ulong_t msg_id,char * format,...)7647917SReza.Sabdar@Sun.COM ndmpd_api_log_v4(void *cookie, ndmp_log_type type, ulong_t msg_id,
7657917SReza.Sabdar@Sun.COM     char *format, ...)
7667917SReza.Sabdar@Sun.COM {
7677917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
7687917SReza.Sabdar@Sun.COM 	ndmp_log_message_request_v4 request;
7697917SReza.Sabdar@Sun.COM 	static char buf[1024];
7707917SReza.Sabdar@Sun.COM 	va_list ap;
7717917SReza.Sabdar@Sun.COM 
7727917SReza.Sabdar@Sun.COM 	if (session == NULL)
7737917SReza.Sabdar@Sun.COM 		return (-1);
7747917SReza.Sabdar@Sun.COM 
7757917SReza.Sabdar@Sun.COM 	va_start(ap, format);
7767917SReza.Sabdar@Sun.COM 
7777917SReza.Sabdar@Sun.COM 	/*LINTED variable format specifier */
7787917SReza.Sabdar@Sun.COM 	(void) vsnprintf(buf, sizeof (buf), format, ap);
7797917SReza.Sabdar@Sun.COM 	va_end(ap);
7807917SReza.Sabdar@Sun.COM 
7817917SReza.Sabdar@Sun.COM 	request.entry = buf;
7827917SReza.Sabdar@Sun.COM 	request.log_type = type;
7837917SReza.Sabdar@Sun.COM 	request.message_id = msg_id;
7847917SReza.Sabdar@Sun.COM 	request.associated_message_valid = NDMP_NO_ASSOCIATED_MESSAGE;
7857917SReza.Sabdar@Sun.COM 	request.associated_message_sequence = 0;
7867917SReza.Sabdar@Sun.COM 
7877917SReza.Sabdar@Sun.COM 	if (ndmp_send_request(session->ns_connection, NDMP_LOG_MESSAGE,
7887917SReza.Sabdar@Sun.COM 	    NDMP_NO_ERR, (void *)&request, 0) < 0) {
7897917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Error sending log message request.");
7907917SReza.Sabdar@Sun.COM 		return (-1);
7917917SReza.Sabdar@Sun.COM 	}
7927917SReza.Sabdar@Sun.COM 	return (0);
7937917SReza.Sabdar@Sun.COM }
7947917SReza.Sabdar@Sun.COM 
7957917SReza.Sabdar@Sun.COM 
7967917SReza.Sabdar@Sun.COM /*
7977917SReza.Sabdar@Sun.COM  * ndmpd_api_file_recovered_v4
7987917SReza.Sabdar@Sun.COM  *
7997917SReza.Sabdar@Sun.COM  * Notify the NDMP client that the specified file was recovered.
8007917SReza.Sabdar@Sun.COM  *
8017917SReza.Sabdar@Sun.COM  * Parameters:
8027917SReza.Sabdar@Sun.COM  *   cookie (input) - session pointer.
8037917SReza.Sabdar@Sun.COM  *   name   (input) - name of recovered file.
8047917SReza.Sabdar@Sun.COM  *   ssid   (input) - selection set id.
8057917SReza.Sabdar@Sun.COM  *   error  (input) - 0 if file successfully recovered.
8067917SReza.Sabdar@Sun.COM  *		    otherwise, error code indicating why recovery failed.
8077917SReza.Sabdar@Sun.COM  *
8087917SReza.Sabdar@Sun.COM  * Returns:
8097917SReza.Sabdar@Sun.COM  *   void.
8107917SReza.Sabdar@Sun.COM  */
8117917SReza.Sabdar@Sun.COM int
ndmpd_api_file_recovered_v4(void * cookie,char * name,int error)8127917SReza.Sabdar@Sun.COM ndmpd_api_file_recovered_v4(void *cookie, char *name, int error)
8137917SReza.Sabdar@Sun.COM {
8147917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
8157917SReza.Sabdar@Sun.COM 	ndmp_log_file_request_v4 request;
8167917SReza.Sabdar@Sun.COM 
8177917SReza.Sabdar@Sun.COM 	if (session == NULL)
8187917SReza.Sabdar@Sun.COM 		return (-1);
8197917SReza.Sabdar@Sun.COM 
8207917SReza.Sabdar@Sun.COM 	request.name  = name;
8217917SReza.Sabdar@Sun.COM 
8227917SReza.Sabdar@Sun.COM 	switch (error) {
8237917SReza.Sabdar@Sun.COM 	case 0:
8247917SReza.Sabdar@Sun.COM 		request.recovery_status = NDMP_RECOVERY_SUCCESSFUL;
8257917SReza.Sabdar@Sun.COM 		break;
8267917SReza.Sabdar@Sun.COM 	case EPERM:
8277917SReza.Sabdar@Sun.COM 		request.recovery_status = NDMP_RECOVERY_FAILED_PERMISSION;
8287917SReza.Sabdar@Sun.COM 		break;
8297917SReza.Sabdar@Sun.COM 	case ENOENT:
8307917SReza.Sabdar@Sun.COM 		request.recovery_status = NDMP_RECOVERY_FAILED_NOT_FOUND;
8317917SReza.Sabdar@Sun.COM 		break;
8327917SReza.Sabdar@Sun.COM 	case ENOTDIR:
8337917SReza.Sabdar@Sun.COM 		request.recovery_status = NDMP_RECOVERY_FAILED_NO_DIRECTORY;
8347917SReza.Sabdar@Sun.COM 		break;
8357917SReza.Sabdar@Sun.COM 	case ENOMEM:
8367917SReza.Sabdar@Sun.COM 		request.recovery_status = NDMP_RECOVERY_FAILED_OUT_OF_MEMORY;
8377917SReza.Sabdar@Sun.COM 		break;
8387917SReza.Sabdar@Sun.COM 	case EIO:
8397917SReza.Sabdar@Sun.COM 		request.recovery_status = NDMP_RECOVERY_FAILED_IO_ERROR;
8407917SReza.Sabdar@Sun.COM 		break;
8417917SReza.Sabdar@Sun.COM 	case EEXIST:
8427917SReza.Sabdar@Sun.COM 		request.recovery_status = NDMP_RECOVERY_FAILED_FILE_PATH_EXISTS;
8437917SReza.Sabdar@Sun.COM 		break;
8447917SReza.Sabdar@Sun.COM 	default:
8457917SReza.Sabdar@Sun.COM 		request.recovery_status = NDMP_RECOVERY_FAILED_UNDEFINED_ERROR;
8467917SReza.Sabdar@Sun.COM 		break;
8477917SReza.Sabdar@Sun.COM 	}
8487917SReza.Sabdar@Sun.COM 
849*12475SReza.Sabdar@Sun.COM 	if (ndmp_send_request_lock(session->ns_connection, NDMP_LOG_FILE,
8507917SReza.Sabdar@Sun.COM 	    NDMP_NO_ERR, (void *)&request, 0) < 0) {
8517917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Error sending log file request");
8527917SReza.Sabdar@Sun.COM 		return (-1);
8537917SReza.Sabdar@Sun.COM 	}
8547917SReza.Sabdar@Sun.COM 
8557917SReza.Sabdar@Sun.COM 	return (0);
8567917SReza.Sabdar@Sun.COM }
8577917SReza.Sabdar@Sun.COM 
8587917SReza.Sabdar@Sun.COM 
8597917SReza.Sabdar@Sun.COM /*
8607917SReza.Sabdar@Sun.COM  * ************************************************************************
8617917SReza.Sabdar@Sun.COM  * LOCALS
8627917SReza.Sabdar@Sun.COM  * ************************************************************************
8637917SReza.Sabdar@Sun.COM  */
8647917SReza.Sabdar@Sun.COM 
8657917SReza.Sabdar@Sun.COM /*
8667917SReza.Sabdar@Sun.COM  * ndmpd_api_find_env
8677917SReza.Sabdar@Sun.COM  *
8687917SReza.Sabdar@Sun.COM  * Return the pointer of the environment variable from the variable
8697917SReza.Sabdar@Sun.COM  * array for the spcified environment variable.
8707917SReza.Sabdar@Sun.COM  *
8717917SReza.Sabdar@Sun.COM  * Parameters:
8727917SReza.Sabdar@Sun.COM  *       cookie (input) - NDMP session pointer.
8737917SReza.Sabdar@Sun.COM  *       name   (input) - name of variable.
8747917SReza.Sabdar@Sun.COM  *
8757917SReza.Sabdar@Sun.COM  * Returns:
8767917SReza.Sabdar@Sun.COM  *   Pointer to variable.
8777917SReza.Sabdar@Sun.COM  *   NULL if variable not found.
8787917SReza.Sabdar@Sun.COM  *
8797917SReza.Sabdar@Sun.COM  */
8807917SReza.Sabdar@Sun.COM ndmp_pval *
ndmpd_api_find_env(void * cookie,char * name)8817917SReza.Sabdar@Sun.COM ndmpd_api_find_env(void *cookie, char *name)
8827917SReza.Sabdar@Sun.COM {
8837917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
8847917SReza.Sabdar@Sun.COM 	ulong_t i;
8857917SReza.Sabdar@Sun.COM 	ndmp_pval *envp;
8867917SReza.Sabdar@Sun.COM 
8877917SReza.Sabdar@Sun.COM 	if (session == NULL)
8887917SReza.Sabdar@Sun.COM 		return (NULL);
8897917SReza.Sabdar@Sun.COM 
8907917SReza.Sabdar@Sun.COM 	envp = session->ns_data.dd_env;
8917917SReza.Sabdar@Sun.COM 	for (i = 0; envp && i < session->ns_data.dd_env_len; envp++, i++)
8927917SReza.Sabdar@Sun.COM 		if (strcmp(name, envp->name) == NULL)
8937917SReza.Sabdar@Sun.COM 			return (envp);
8947917SReza.Sabdar@Sun.COM 
8957917SReza.Sabdar@Sun.COM 	return (NULL);
8967917SReza.Sabdar@Sun.COM }
8977917SReza.Sabdar@Sun.COM 
8987917SReza.Sabdar@Sun.COM 
8997917SReza.Sabdar@Sun.COM /*
9007917SReza.Sabdar@Sun.COM  * ndmpd_api_get_env
9017917SReza.Sabdar@Sun.COM  *
9027917SReza.Sabdar@Sun.COM  * Return the value of an environment variable from the variable array.
9037917SReza.Sabdar@Sun.COM  *
9047917SReza.Sabdar@Sun.COM  * Parameters:
9057917SReza.Sabdar@Sun.COM  *       cookie (input) - NDMP session pointer.
9067917SReza.Sabdar@Sun.COM  *       name   (input) - name of variable.
9077917SReza.Sabdar@Sun.COM  *
9087917SReza.Sabdar@Sun.COM  * Returns:
9097917SReza.Sabdar@Sun.COM  *   Pointer to variable value.
9107917SReza.Sabdar@Sun.COM  *   0 if variable not found.
9117917SReza.Sabdar@Sun.COM  *
9127917SReza.Sabdar@Sun.COM  */
9137917SReza.Sabdar@Sun.COM char *
ndmpd_api_get_env(void * cookie,char * name)9147917SReza.Sabdar@Sun.COM ndmpd_api_get_env(void *cookie, char *name)
9157917SReza.Sabdar@Sun.COM {
9167917SReza.Sabdar@Sun.COM 	ndmp_pval *envp;
9177917SReza.Sabdar@Sun.COM 
9187917SReza.Sabdar@Sun.COM 	envp = ndmpd_api_find_env(cookie, name);
9197917SReza.Sabdar@Sun.COM 	if (envp)
9207917SReza.Sabdar@Sun.COM 		return (envp->value);
9217917SReza.Sabdar@Sun.COM 
9227917SReza.Sabdar@Sun.COM 	return (NULL);
9237917SReza.Sabdar@Sun.COM }
9247917SReza.Sabdar@Sun.COM 
9257917SReza.Sabdar@Sun.COM 
9267917SReza.Sabdar@Sun.COM /*
9277917SReza.Sabdar@Sun.COM  * ndmpd_api_add_env
9287917SReza.Sabdar@Sun.COM  *
9297917SReza.Sabdar@Sun.COM  * Adds an environment variable name/value pair to the environment
9307917SReza.Sabdar@Sun.COM  * variable list.
9317917SReza.Sabdar@Sun.COM  *
9327917SReza.Sabdar@Sun.COM  * Parameters:
9337917SReza.Sabdar@Sun.COM  *   session (input) - session pointer.
9347917SReza.Sabdar@Sun.COM  *   name    (input) - variable name.
9357917SReza.Sabdar@Sun.COM  *   val     (input) - value.
9367917SReza.Sabdar@Sun.COM  *
9377917SReza.Sabdar@Sun.COM  * Returns:
9387917SReza.Sabdar@Sun.COM  *   0 - success.
9397917SReza.Sabdar@Sun.COM  *  -1 - error.
9407917SReza.Sabdar@Sun.COM  */
9417917SReza.Sabdar@Sun.COM int
ndmpd_api_add_env(void * cookie,char * name,char * value)9427917SReza.Sabdar@Sun.COM ndmpd_api_add_env(void *cookie, char *name, char *value)
9437917SReza.Sabdar@Sun.COM {
9447917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
9457917SReza.Sabdar@Sun.COM 	char *namebuf;
9467917SReza.Sabdar@Sun.COM 	char *valbuf;
9477917SReza.Sabdar@Sun.COM 
9487917SReza.Sabdar@Sun.COM 	if (session == NULL)
9497917SReza.Sabdar@Sun.COM 		return (-1);
9507917SReza.Sabdar@Sun.COM 
9517917SReza.Sabdar@Sun.COM 	session->ns_data.dd_env = realloc((void *)session->ns_data.dd_env,
9527917SReza.Sabdar@Sun.COM 	    sizeof (ndmp_pval) * (session->ns_data.dd_env_len + 1));
9537917SReza.Sabdar@Sun.COM 
9547917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_env == NULL) {
9557917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Out of memory.");
9567917SReza.Sabdar@Sun.COM 		return (-1);
9577917SReza.Sabdar@Sun.COM 	}
9587917SReza.Sabdar@Sun.COM 	namebuf = strdup(name);
9597917SReza.Sabdar@Sun.COM 	if (namebuf == NULL)
9607917SReza.Sabdar@Sun.COM 		return (-1);
9617917SReza.Sabdar@Sun.COM 
9627917SReza.Sabdar@Sun.COM 	valbuf = strdup(value);
9637917SReza.Sabdar@Sun.COM 	if (valbuf == NULL) {
9647917SReza.Sabdar@Sun.COM 		free(namebuf);
9657917SReza.Sabdar@Sun.COM 		return (-1);
9667917SReza.Sabdar@Sun.COM 	}
9677917SReza.Sabdar@Sun.COM 
9687917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&session->ns_lock);
9697917SReza.Sabdar@Sun.COM 	session->ns_data.dd_env[session->ns_data.dd_env_len].name = namebuf;
9707917SReza.Sabdar@Sun.COM 	session->ns_data.dd_env[session->ns_data.dd_env_len].value = valbuf;
9717917SReza.Sabdar@Sun.COM 	session->ns_data.dd_env_len++;
9727917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&session->ns_lock);
9737917SReza.Sabdar@Sun.COM 
9747917SReza.Sabdar@Sun.COM 	return (0);
9757917SReza.Sabdar@Sun.COM }
9767917SReza.Sabdar@Sun.COM 
9777917SReza.Sabdar@Sun.COM 
9787917SReza.Sabdar@Sun.COM /*
9797917SReza.Sabdar@Sun.COM  * ndmpd_api_set_env
9807917SReza.Sabdar@Sun.COM  *
9817917SReza.Sabdar@Sun.COM  * Sets an environment variable name/value pair in the environment
9827917SReza.Sabdar@Sun.COM  * variable list.  If the variable exists, it gets the new value,
9837917SReza.Sabdar@Sun.COM  * otherwise it's added as a new variable.
9847917SReza.Sabdar@Sun.COM  *
9857917SReza.Sabdar@Sun.COM  * Parameters:
9867917SReza.Sabdar@Sun.COM  *   session (input) - session pointer.
9877917SReza.Sabdar@Sun.COM  *   name    (input) - variable name.
9887917SReza.Sabdar@Sun.COM  *   val     (input) - value.
9897917SReza.Sabdar@Sun.COM  *
9907917SReza.Sabdar@Sun.COM  * Returns:
9917917SReza.Sabdar@Sun.COM  *   0 - success.
9927917SReza.Sabdar@Sun.COM  *  -1 - error.
9937917SReza.Sabdar@Sun.COM  */
9947917SReza.Sabdar@Sun.COM int
ndmpd_api_set_env(void * cookie,char * name,char * value)9957917SReza.Sabdar@Sun.COM ndmpd_api_set_env(void *cookie, char *name, char *value)
9967917SReza.Sabdar@Sun.COM {
9977917SReza.Sabdar@Sun.COM 	char *valbuf;
9987917SReza.Sabdar@Sun.COM 	int rv;
9997917SReza.Sabdar@Sun.COM 	ndmp_pval *envp;
10007917SReza.Sabdar@Sun.COM 
10017917SReza.Sabdar@Sun.COM 	envp = ndmpd_api_find_env(cookie, name);
10027917SReza.Sabdar@Sun.COM 	if (!envp) {
10037917SReza.Sabdar@Sun.COM 		rv = ndmpd_api_add_env(cookie, name, value);
10047917SReza.Sabdar@Sun.COM 	} else if (!(valbuf = strdup(value))) {
10057917SReza.Sabdar@Sun.COM 		rv = -1;
10067917SReza.Sabdar@Sun.COM 	} else {
10077917SReza.Sabdar@Sun.COM 		rv = 0;
10087917SReza.Sabdar@Sun.COM 		free(envp->value);
10097917SReza.Sabdar@Sun.COM 		envp->value = valbuf;
10107917SReza.Sabdar@Sun.COM 	}
10117917SReza.Sabdar@Sun.COM 
10127917SReza.Sabdar@Sun.COM 	return (rv);
10137917SReza.Sabdar@Sun.COM }
10147917SReza.Sabdar@Sun.COM 
10157917SReza.Sabdar@Sun.COM 
10167917SReza.Sabdar@Sun.COM /*
10177917SReza.Sabdar@Sun.COM  * ndmpd_api_get_name
10187917SReza.Sabdar@Sun.COM  *
10197917SReza.Sabdar@Sun.COM  * Return the name entry at the specified index from the
10207917SReza.Sabdar@Sun.COM  * recover file name list.
10217917SReza.Sabdar@Sun.COM  *
10227917SReza.Sabdar@Sun.COM  * Parameters:
10237917SReza.Sabdar@Sun.COM  *   cookie    (input) - NDMP session pointer.
10247917SReza.Sabdar@Sun.COM  *   name_index (input) - index of entry to be returned.
10257917SReza.Sabdar@Sun.COM  *
10267917SReza.Sabdar@Sun.COM  * Returns:
10277917SReza.Sabdar@Sun.COM  *   Pointer to name entry.
10287917SReza.Sabdar@Sun.COM  *   0 if requested entry does not exist.
10297917SReza.Sabdar@Sun.COM  */
10307917SReza.Sabdar@Sun.COM void *
ndmpd_api_get_name(void * cookie,ulong_t name_index)10317917SReza.Sabdar@Sun.COM ndmpd_api_get_name(void *cookie, ulong_t name_index)
10327917SReza.Sabdar@Sun.COM {
10337917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
10347917SReza.Sabdar@Sun.COM 
10357917SReza.Sabdar@Sun.COM 	if (session == NULL)
10367917SReza.Sabdar@Sun.COM 		return (NULL);
10377917SReza.Sabdar@Sun.COM 
10387917SReza.Sabdar@Sun.COM 	if (name_index >= session->ns_data.dd_nlist_len)
10397917SReza.Sabdar@Sun.COM 		return (NULL);
10407917SReza.Sabdar@Sun.COM 
10417917SReza.Sabdar@Sun.COM 	return (&session->ns_data.dd_nlist[name_index]);
10427917SReza.Sabdar@Sun.COM }
10437917SReza.Sabdar@Sun.COM 
10447917SReza.Sabdar@Sun.COM 
10457917SReza.Sabdar@Sun.COM /*
10467917SReza.Sabdar@Sun.COM  * ndmpd_api_dispatch
10477917SReza.Sabdar@Sun.COM  *
10487917SReza.Sabdar@Sun.COM  * Process pending NDMP client requests and check registered files for
10497917SReza.Sabdar@Sun.COM  * data availability.
10507917SReza.Sabdar@Sun.COM  *
10517917SReza.Sabdar@Sun.COM  * Parameters:
10527917SReza.Sabdar@Sun.COM  *   cookie (input) - session pointer.
10537917SReza.Sabdar@Sun.COM  *   block  (input) -
10547917SReza.Sabdar@Sun.COM  * 		TRUE 	block until a request has been processed or
10557917SReza.Sabdar@Sun.COM  *			until a file handler has been called.
10567917SReza.Sabdar@Sun.COM  *		FALSE	don't block.
10577917SReza.Sabdar@Sun.COM  *
10587917SReza.Sabdar@Sun.COM  * Returns:
10597917SReza.Sabdar@Sun.COM  *  -1 - abort request received or connection closed.
10607917SReza.Sabdar@Sun.COM  *   0 - success.
10617917SReza.Sabdar@Sun.COM  */
10627917SReza.Sabdar@Sun.COM int
ndmpd_api_dispatch(void * cookie,boolean_t block)10637917SReza.Sabdar@Sun.COM ndmpd_api_dispatch(void *cookie, boolean_t block)
10647917SReza.Sabdar@Sun.COM {
10657917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
10667917SReza.Sabdar@Sun.COM 	int err;
10677917SReza.Sabdar@Sun.COM 
10687917SReza.Sabdar@Sun.COM 	if (session == NULL)
10697917SReza.Sabdar@Sun.COM 		return (-1);
10707917SReza.Sabdar@Sun.COM 
10717917SReza.Sabdar@Sun.COM 	for (; ; ) {
10727917SReza.Sabdar@Sun.COM 		err = ndmpd_select(session, block, HC_ALL);
10737917SReza.Sabdar@Sun.COM 		if (err < 0 || session->ns_data.dd_abort == TRUE ||
10747917SReza.Sabdar@Sun.COM 		    session->ns_eof)
10757917SReza.Sabdar@Sun.COM 			return (-1);
10767917SReza.Sabdar@Sun.COM 
10777917SReza.Sabdar@Sun.COM 		if (err == 0)
10787917SReza.Sabdar@Sun.COM 			return (0);
10797917SReza.Sabdar@Sun.COM 
10807917SReza.Sabdar@Sun.COM 		/*
10817917SReza.Sabdar@Sun.COM 		 * Something was processed.
10827917SReza.Sabdar@Sun.COM 		 * Set the block flag to false so that we will return as
10837917SReza.Sabdar@Sun.COM 		 * soon as everything available to be processed has been
10847917SReza.Sabdar@Sun.COM 		 * processed.
10857917SReza.Sabdar@Sun.COM 		 */
10867917SReza.Sabdar@Sun.COM 		block = FALSE;
10877917SReza.Sabdar@Sun.COM 	}
10887917SReza.Sabdar@Sun.COM }
10897917SReza.Sabdar@Sun.COM 
10907917SReza.Sabdar@Sun.COM 
10917917SReza.Sabdar@Sun.COM /*
10927917SReza.Sabdar@Sun.COM  * ndmpd_api_add_file_handler
10937917SReza.Sabdar@Sun.COM  *
10947917SReza.Sabdar@Sun.COM  * Adds a file handler to the file handler list.
10957917SReza.Sabdar@Sun.COM  * The file handler list is used by ndmpd_api_dispatch.
10967917SReza.Sabdar@Sun.COM  *
10977917SReza.Sabdar@Sun.COM  * Parameters:
10987917SReza.Sabdar@Sun.COM  *   daemon_cookie (input) - session pointer.
10997917SReza.Sabdar@Sun.COM  *   cookie  (input) - opaque data to be passed to file hander when called.
11007917SReza.Sabdar@Sun.COM  *   fd      (input) - file descriptor.
11017917SReza.Sabdar@Sun.COM  *   mode    (input) - bitmask of the following:
11027917SReza.Sabdar@Sun.COM  *	NDMP_SELECT_MODE_READ = watch file for ready for reading
11037917SReza.Sabdar@Sun.COM  *	NDMP_SELECT_MODE_WRITE = watch file for ready for writing
11047917SReza.Sabdar@Sun.COM  *	NDMP_SELECT_MODE_EXCEPTION = watch file for exception
11057917SReza.Sabdar@Sun.COM  *   func    (input) - function to call when the file meets one of the
11067917SReza.Sabdar@Sun.COM  *		     conditions specified by mode.
11077917SReza.Sabdar@Sun.COM  *
11087917SReza.Sabdar@Sun.COM  * Returns:
11097917SReza.Sabdar@Sun.COM  *   0 - success.
11107917SReza.Sabdar@Sun.COM  *  -1 - error.
11117917SReza.Sabdar@Sun.COM  */
11127917SReza.Sabdar@Sun.COM int
ndmpd_api_add_file_handler(void * daemon_cookie,void * cookie,int fd,ulong_t mode,ndmpd_file_handler_func_t * func)11137917SReza.Sabdar@Sun.COM ndmpd_api_add_file_handler(void *daemon_cookie, void *cookie, int fd,
11147917SReza.Sabdar@Sun.COM     ulong_t mode, ndmpd_file_handler_func_t *func)
11157917SReza.Sabdar@Sun.COM {
11167917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = (ndmpd_session_t *)daemon_cookie;
11177917SReza.Sabdar@Sun.COM 
11187917SReza.Sabdar@Sun.COM 	return (ndmpd_add_file_handler(session, cookie, fd, mode, HC_MODULE,
11197917SReza.Sabdar@Sun.COM 	    func));
11207917SReza.Sabdar@Sun.COM }
11217917SReza.Sabdar@Sun.COM 
11227917SReza.Sabdar@Sun.COM 
11237917SReza.Sabdar@Sun.COM /*
11247917SReza.Sabdar@Sun.COM  * ndmpd_api_remove_file_handler
11257917SReza.Sabdar@Sun.COM  *
11267917SReza.Sabdar@Sun.COM  * Removes a file handler from the file handler list.
11277917SReza.Sabdar@Sun.COM  *
11287917SReza.Sabdar@Sun.COM  * Parameters:
11297917SReza.Sabdar@Sun.COM  *   cookie  (input) - session pointer.
11307917SReza.Sabdar@Sun.COM  *   fd      (input) - file descriptor.
11317917SReza.Sabdar@Sun.COM  *
11327917SReza.Sabdar@Sun.COM  * Returns:
11337917SReza.Sabdar@Sun.COM  *   0 - success.
11347917SReza.Sabdar@Sun.COM  *  -1 - error.
11357917SReza.Sabdar@Sun.COM  */
11367917SReza.Sabdar@Sun.COM int
ndmpd_api_remove_file_handler(void * cookie,int fd)11377917SReza.Sabdar@Sun.COM ndmpd_api_remove_file_handler(void *cookie, int fd)
11387917SReza.Sabdar@Sun.COM {
11397917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = (ndmpd_session_t *)cookie;
11407917SReza.Sabdar@Sun.COM 
11417917SReza.Sabdar@Sun.COM 	return (ndmpd_remove_file_handler(session, fd));
11427917SReza.Sabdar@Sun.COM }
1143