Fix NULL pointer constant issues in cmd
[unleashed.git] / usr / src / cmd / ndmpd / ndmp / ndmpd_callbacks.c
blob29e7c4f21b0aaf7b01c6f819572dfaa8f8e7b048
1 /*
2 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
3 */
5 /*
6 * BSD 3 Clause License
8 * Copyright (c) 2007, The Storage Networking Industry Association.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * - Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
16 * - Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
21 * - Neither the name of The Storage Networking Industry Association (SNIA)
22 * nor the names of its contributors may be used to endorse or promote
23 * products derived from this software without specific prior written
24 * permission.
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
38 /* Copyright (c) 2007, The Storage Networking Industry Association. */
39 /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
40 /* Copyright 2014 Nexenta Systems, Inc. All rights reserved. */
42 #include <sys/types.h>
43 #include <stdlib.h>
44 #include <errno.h>
45 #include <stdarg.h>
46 #include <stdio.h>
47 #include <string.h>
48 #include "ndmpd.h"
52 * Message Id counter. This number is increased by MOD_LOGV3 macro.
53 * MOD_LOGCONTV3 macro uses the number generated by the last MOD_LOGV3.
56 int ndmp_log_msg_id = 0;
60 * ************************************************************************
61 * NDMP V2 CALLBACKS
62 * ************************************************************************
66 * ndmpd_api_done_v2
68 * Called when dump/restore has completed.
69 * Sends a notify_halt request to the NDMP client.
71 * Parameters:
72 * session (input) - session pointer.
73 * err (input) - UNIX error code.
75 * Returns:
76 * void
78 void
79 ndmpd_api_done_v2(void *cookie, int err)
81 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
82 ndmp_notify_data_halted_request req_v2;
84 if (session == NULL)
85 return;
87 if (session->ns_data.dd_state == NDMP_DATA_STATE_IDLE ||
88 session->ns_data.dd_state == NDMP_DATA_STATE_HALTED)
89 return;
91 NDMP_LOG(LOG_DEBUG, "data.operation: %d",
92 session->ns_data.dd_operation);
94 if (session->ns_data.dd_operation == NDMP_DATA_OP_BACKUP) {
96 * Send/discard any buffered file history data.
98 ndmpd_file_history_cleanup(session, (err == 0 ? TRUE : FALSE));
101 * If mover local and successfull backup, write any
102 * remaining buffered data to tape.
104 if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_LOCAL &&
105 err == 0) {
106 if (ndmpd_local_write(session, 0, 0) < 0)
107 err = EIO;
111 session->ns_data.dd_state = NDMP_DATA_STATE_HALTED;
113 switch (err) {
114 case 0:
115 session->ns_data.dd_halt_reason = NDMP_DATA_HALT_SUCCESSFUL;
116 break;
117 case EINTR:
118 session->ns_data.dd_halt_reason = NDMP_DATA_HALT_ABORTED;
119 break;
120 case EIO:
121 session->ns_data.dd_halt_reason = NDMP_DATA_HALT_CONNECT_ERROR;
122 break;
123 default:
124 session->ns_data.dd_halt_reason = NDMP_DATA_HALT_INTERNAL_ERROR;
127 req_v2.reason = session->ns_data.dd_halt_reason;
128 req_v2.text_reason = "";
130 NDMP_LOG(LOG_DEBUG, "ndmp_send_request(NDMP_NOTIFY_DATA_HALTED)");
132 if (ndmp_send_request_lock(session->ns_connection,
133 NDMP_NOTIFY_DATA_HALTED, NDMP_NO_ERR, (void *)&req_v2, 0) < 0)
134 NDMP_LOG(LOG_DEBUG, "Sending notify_data_halted request");
136 if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) {
138 if (session->ns_mover.md_sock != session->ns_data.dd_sock) {
139 (void) close(session->ns_data.dd_sock);
140 } else {
141 NDMP_LOG(LOG_DEBUG, "Not closing as used by mover");
144 session->ns_data.dd_sock = -1;
145 } else {
146 ndmpd_mover_error(session, NDMP_MOVER_HALT_CONNECT_CLOSED);
152 * ndmpd_api_log_v2
154 * Sends a log request to the NDMP client.
156 * Parameters:
157 * cookie (input) - session pointer.
158 * str (input) - null terminated string
159 * format (input) - printf style format.
160 * ... (input) - format arguments.
162 * Returns:
163 * 0 - success.
164 * -1 - error.
166 /*ARGSUSED*/
168 ndmpd_api_log_v2(void *cookie, char *format, ...)
170 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
171 ndmp_log_log_request request;
172 static char buf[1024];
173 va_list ap;
175 if (session == NULL)
176 return (-1);
178 va_start(ap, format);
180 /*LINTED variable format specifier */
181 (void) vsnprintf(buf, sizeof (buf), format, ap);
182 va_end(ap);
184 request.entry = buf;
187 if (ndmp_send_request(session->ns_connection, _NDMP_LOG_LOG,
188 NDMP_NO_ERR, (void *)&request, 0) < 0) {
189 NDMP_LOG(LOG_DEBUG, "Sending log request");
190 return (-1);
192 return (0);
198 * ndmpd_api_read_v2
200 * Callback function called by the backup/recover module.
201 * Reads data from the mover.
202 * If the mover is remote, the data is read from the data connection.
203 * If the mover is local, the data is read from the tape device.
205 * Parameters:
206 * client_data (input) - session pointer.
207 * data (input) - data to be written.
208 * length (input) - data length.
210 * Returns:
211 * 0 - data successfully read.
212 * -1 - error.
213 * 1 - session terminated or operation aborted.
216 ndmpd_api_read_v2(void *client_data, char *data, ulong_t length)
218 ndmpd_session_t *session = (ndmpd_session_t *)client_data;
220 if (session == NULL)
221 return (-1);
224 * Read the data from the data connection if the mover is remote.
226 if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP)
227 return (ndmpd_remote_read(session, data, length));
228 else
229 return (ndmpd_local_read(session, data, length));
234 * ndmpd_api_seek_v2
236 * Seek to the specified position in the data stream and start a
237 * read for the specified amount of data.
239 * Parameters:
240 * cookie (input) - session pointer.
241 * offset (input) - stream position to seek to.
242 * length (input) - amount of data that will be read using ndmpd_api_read
244 * Returns:
245 * 0 - seek successful.
246 * -1 - error.
249 ndmpd_api_seek_v2(void *cookie, u_longlong_t offset, u_longlong_t length)
251 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
252 int err;
254 if (session == NULL)
255 return (-1);
257 session->ns_data.dd_read_offset = offset;
258 session->ns_data.dd_read_length = length;
261 * Send a notify_data_read request if the mover is remote.
263 if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) {
264 ndmp_notify_data_read_request request;
266 session->ns_mover.md_discard_length =
267 session->ns_mover.md_bytes_left_to_read;
268 session->ns_mover.md_bytes_left_to_read = length;
269 session->ns_mover.md_position = offset;
271 request.offset = long_long_to_quad(offset);
272 request.length = long_long_to_quad(length);
274 if (ndmp_send_request_lock(session->ns_connection,
275 NDMP_NOTIFY_DATA_READ, NDMP_NO_ERR,
276 (void *)&request, 0) < 0) {
278 NDMP_LOG(LOG_DEBUG,
279 "Sending notify_data_read request");
280 return (-1);
282 return (0);
284 /* Mover is local. */
286 err = ndmpd_mover_seek(session, offset, length);
287 if (err < 0) {
288 ndmpd_mover_error(session, NDMP_MOVER_HALT_INTERNAL_ERROR);
289 return (-1);
291 if (err == 0)
292 return (0);
295 * NDMP client intervention is required to perform the seek.
296 * Wait for the client to either do the seek and send a continue
297 * request or send an abort request.
299 return (ndmp_wait_for_mover(session));
304 * ndmpd_api_file_recovered_v2
306 * Notify the NDMP client that the specified file was recovered.
308 * Parameters:
309 * cookie (input) - session pointer.
310 * name (input) - name of recovered file.
311 * error (input) - 0 if file successfully recovered.
312 * otherwise, error code indicating why recovery failed.
314 * Returns:
315 * void.
318 ndmpd_api_file_recovered_v2(void *cookie, char *name, int error)
320 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
321 ndmp_log_file_request_v2 request;
323 if (session == NULL)
324 return (-1);
326 request.name = name;
327 request.ssid = 0;
329 switch (error) {
330 case 0:
331 request.error = NDMP_NO_ERR;
332 break;
333 case ENOENT:
334 request.error = NDMP_FILE_NOT_FOUND_ERR;
335 break;
336 default:
337 request.error = NDMP_PERMISSION_ERR;
340 if (ndmp_send_request_lock(session->ns_connection, NDMP_LOG_FILE,
341 NDMP_NO_ERR, (void *)&request, 0) < 0) {
342 NDMP_LOG(LOG_DEBUG, "Sending log file request");
343 return (-1);
345 return (0);
350 * ndmpd_api_write_v2
352 * Callback function called by the backup/restore module.
353 * Writes data to the mover.
354 * If the mover is remote, the data is written to the data connection.
355 * If the mover is local, the data is buffered and written to the
356 * tape device after a full record has been buffered.
358 * Parameters:
359 * client_data (input) - session pointer.
360 * data (input) - data to be written.
361 * length (input) - data length.
363 * Returns:
364 * 0 - data successfully written.
365 * -1 - error.
368 ndmpd_api_write_v2(void *client_data, char *data, ulong_t length)
370 ndmpd_session_t *session = (ndmpd_session_t *)client_data;
372 if (session == NULL)
373 return (-1);
376 * Write the data to the data connection if the mover is remote.
378 if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP)
379 return (ndmpd_remote_write(session, data, length));
380 else
381 return (ndmpd_local_write(session, data, length));
386 * ************************************************************************
387 * NDMP V3 CALLBACKS
388 * ************************************************************************
392 * ndmpd_api_done_v3
394 * Called when the data module has completed.
395 * Sends a notify_halt request to the NDMP client.
397 * Parameters:
398 * session (input) - session pointer.
399 * err (input) - UNIX error code.
401 * Returns:
402 * void
404 void
405 ndmpd_api_done_v3(void *cookie, int err)
407 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
408 ndmp_data_halt_reason reason;
410 switch (err) {
411 case 0:
412 reason = NDMP_DATA_HALT_SUCCESSFUL;
413 break;
415 case EINTR:
416 reason = NDMP_DATA_HALT_ABORTED;
417 break;
419 case EIO:
420 reason = NDMP_DATA_HALT_CONNECT_ERROR;
421 break;
423 default:
424 reason = NDMP_DATA_HALT_INTERNAL_ERROR;
427 ndmpd_data_error(session, reason);
431 * ndmpd_api_log_v3
433 * Sends a log request to the NDMP client.
435 * Parameters:
436 * cookie (input) - session pointer.
437 * format (input) - printf style format.
438 * ... (input) - format arguments.
440 * Returns:
441 * 0 - success.
442 * -1 - error.
444 /*ARGSUSED*/
446 ndmpd_api_log_v3(void *cookie, ndmp_log_type type, ulong_t msg_id,
447 char *format, ...)
449 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
450 ndmp_log_message_request_v3 request;
451 static char buf[1024];
452 va_list ap;
454 if (session == NULL)
455 return (-1);
457 va_start(ap, format);
459 /*LINTED variable format specifier */
460 (void) vsnprintf(buf, sizeof (buf), format, ap);
461 va_end(ap);
463 request.entry = buf;
464 request.log_type = type;
465 request.message_id = msg_id;
467 if (ndmp_send_request(session->ns_connection, NDMP_LOG_MESSAGE,
468 NDMP_NO_ERR, (void *)&request, 0) < 0) {
469 NDMP_LOG(LOG_DEBUG, "Error sending log message request.");
470 return (-1);
472 return (0);
477 * ndmpd_api_write_v3
479 * Callback function called by the backup/restore module.
480 * Writes data to the mover.
481 * If the mover is remote, the data is written to the data connection.
482 * If the mover is local, the data is buffered and written to the
483 * tape device after a full record has been buffered.
485 * Parameters:
486 * client_data (input) - session pointer.
487 * data (input) - data to be written.
488 * length (input) - data length.
490 * Returns:
491 * 0 - data successfully written.
492 * -1 - error.
495 ndmpd_api_write_v3(void *client_data, char *data, ulong_t length)
497 ndmpd_session_t *session = (ndmpd_session_t *)client_data;
499 if (session == NULL)
500 return (-1);
503 * Write the data to the tape if the mover is local, otherwise,
504 * write the data to the data connection.
506 * The same write function for of v2 can be used in V3
507 * for writing data to the data connection to the mover.
508 * So we don't need ndmpd_remote_write_v3().
510 if (session->ns_data.dd_data_addr.addr_type == NDMP_ADDR_LOCAL)
511 return (ndmpd_local_write_v3(session, data, length));
512 else
513 return (ndmpd_remote_write(session, data, length));
518 * ndmpd_api_read_v3
520 * Callback function called by the backup/recover module.
521 * Reads data from the mover.
522 * If the mover is remote, the data is read from the data connection.
523 * If the mover is local, the data is read from the tape device.
525 * Parameters:
526 * client_data (input) - session pointer.
527 * data (input) - data to be written.
528 * length (input) - data length.
530 * Returns:
531 * 0 - data successfully read.
532 * -1 - error.
533 * 1 - session terminated or operation aborted.
536 ndmpd_api_read_v3(void *client_data, char *data, ulong_t length)
538 ndmpd_session_t *session = (ndmpd_session_t *)client_data;
540 if (session == NULL)
541 return (-1);
544 * Read the data from the data connection if the mover is remote.
546 if (session->ns_data.dd_data_addr.addr_type == NDMP_ADDR_LOCAL)
547 return (ndmpd_local_read_v3(session, data, length));
548 else
549 return (ndmpd_remote_read_v3(session, data, length));
554 * ndmpd_api_get_name_v3
556 * Return the name entry at the specified index from the
557 * recover file name list.
559 * Parameters:
560 * cookie (input) - NDMP session pointer.
561 * name_index (input) - index of entry to be returned.
563 * Returns:
564 * Pointer to name entry.
565 * 0 if requested entry does not exist.
567 void *
568 ndmpd_api_get_name_v3(void *cookie, ulong_t name_index)
570 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
572 if (session == NULL)
573 return (NULL);
575 if (name_index >= session->ns_data.dd_nlist_len)
576 return (NULL);
578 return (&session->ns_data.dd_nlist_v3[name_index]);
583 * ndmpd_api_file_recovered_v3
585 * Notify the NDMP client that the specified file was recovered.
587 * Parameters:
588 * cookie (input) - session pointer.
589 * name (input) - name of recovered file.
590 * ssid (input) - selection set id.
591 * error (input) - 0 if file successfully recovered.
592 * otherwise, error code indicating why recovery failed.
594 * Returns:
595 * 0 - success.
596 * -1 - error.
599 ndmpd_api_file_recovered_v3(void *cookie, char *name, int error)
601 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
602 ndmp_log_file_request_v3 request;
604 if (session == NULL)
605 return (-1);
607 request.name = name;
609 switch (error) {
610 case 0:
611 request.error = NDMP_NO_ERR;
612 break;
613 case ENOENT:
614 request.error = NDMP_FILE_NOT_FOUND_ERR;
615 break;
616 default:
617 request.error = NDMP_PERMISSION_ERR;
620 if (ndmp_send_request_lock(session->ns_connection, NDMP_LOG_FILE,
621 NDMP_NO_ERR, (void *)&request, 0) < 0) {
622 NDMP_LOG(LOG_DEBUG, "Error sending log file request");
623 return (-1);
626 return (0);
631 * ndmpd_api_seek_v3
633 * Seek to the specified position in the data stream and start a
634 * read for the specified amount of data.
636 * Parameters:
637 * cookie (input) - session pointer.
638 * offset (input) - stream position to seek to.
639 * length (input) - amount of data that will be read using ndmpd_api_read
641 * Returns:
642 * 0 - seek successful.
643 * 1 - seek needed DMA(client) intervention.
644 * -1 - error.
647 ndmpd_api_seek_v3(void *cookie, u_longlong_t offset, u_longlong_t length)
649 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
650 int err;
651 ndmp_notify_data_read_request request;
653 if (session == NULL)
654 return (-1);
656 session->ns_data.dd_read_offset = offset;
657 session->ns_data.dd_read_length = length;
660 * Send a notify_data_read request if the mover is remote.
662 if (session->ns_data.dd_data_addr.addr_type != NDMP_ADDR_LOCAL) {
663 session->ns_data.dd_discard_length =
664 session->ns_data.dd_bytes_left_to_read;
665 session->ns_data.dd_bytes_left_to_read = length;
666 session->ns_data.dd_position = offset;
668 request.offset = long_long_to_quad(offset);
669 request.length = long_long_to_quad(length);
671 if (ndmp_send_request_lock(session->ns_connection,
672 NDMP_NOTIFY_DATA_READ, NDMP_NO_ERR,
673 (void *)&request, 0) < 0) {
674 NDMP_LOG(LOG_DEBUG,
675 "Sending notify_data_read request");
676 return (-1);
679 return (0);
682 /* Mover is local. */
684 err = ndmpd_mover_seek(session, offset, length);
685 if (err < 0) {
686 ndmpd_mover_error(session, NDMP_MOVER_HALT_INTERNAL_ERROR);
687 return (-1);
690 if (err == 0)
691 return (0);
694 * NDMP client intervention is required to perform the seek.
695 * Wait for the client to either do the seek and send a continue
696 * request or send an abort request.
698 err = ndmp_wait_for_mover(session);
701 * If we needed a client intervention, then we should be able to
702 * detect this in DAR.
704 if (err == 0)
705 err = 1;
706 return (err);
711 * ************************************************************************
712 * NDMP V4 CALLBACKS
713 * ************************************************************************
717 * ndmpd_api_log_v4
719 * Sends a log request to the NDMP client.
720 * No message association is supported now, but can be added later on
721 * in this function.
723 * Parameters:
724 * cookie (input) - session pointer.
725 * format (input) - printf style format.
726 * ... (input) - format arguments.
728 * Returns:
729 * 0 - success.
730 * -1 - error.
732 /*ARGSUSED*/
734 ndmpd_api_log_v4(void *cookie, ndmp_log_type type, ulong_t msg_id,
735 char *format, ...)
737 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
738 ndmp_log_message_request_v4 request;
739 static char buf[1024];
740 va_list ap;
742 if (session == NULL)
743 return (-1);
745 va_start(ap, format);
747 /*LINTED variable format specifier */
748 (void) vsnprintf(buf, sizeof (buf), format, ap);
749 va_end(ap);
751 request.entry = buf;
752 request.log_type = type;
753 request.message_id = msg_id;
754 request.associated_message_valid = NDMP_NO_ASSOCIATED_MESSAGE;
755 request.associated_message_sequence = 0;
757 if (ndmp_send_request(session->ns_connection, NDMP_LOG_MESSAGE,
758 NDMP_NO_ERR, (void *)&request, 0) < 0) {
759 NDMP_LOG(LOG_DEBUG, "Error sending log message request.");
760 return (-1);
762 return (0);
767 * ndmpd_api_file_recovered_v4
769 * Notify the NDMP client that the specified file was recovered.
771 * Parameters:
772 * cookie (input) - session pointer.
773 * name (input) - name of recovered file.
774 * ssid (input) - selection set id.
775 * error (input) - 0 if file successfully recovered.
776 * otherwise, error code indicating why recovery failed.
778 * Returns:
779 * void.
782 ndmpd_api_file_recovered_v4(void *cookie, char *name, int error)
784 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
785 ndmp_log_file_request_v4 request;
787 if (session == NULL)
788 return (-1);
790 request.name = name;
792 switch (error) {
793 case 0:
794 request.recovery_status = NDMP_RECOVERY_SUCCESSFUL;
795 break;
796 case EPERM:
797 request.recovery_status = NDMP_RECOVERY_FAILED_PERMISSION;
798 break;
799 case ENOENT:
800 request.recovery_status = NDMP_RECOVERY_FAILED_NOT_FOUND;
801 break;
802 case ENOTDIR:
803 request.recovery_status = NDMP_RECOVERY_FAILED_NO_DIRECTORY;
804 break;
805 case ENOMEM:
806 request.recovery_status = NDMP_RECOVERY_FAILED_OUT_OF_MEMORY;
807 break;
808 case EIO:
809 request.recovery_status = NDMP_RECOVERY_FAILED_IO_ERROR;
810 break;
811 case EEXIST:
812 request.recovery_status = NDMP_RECOVERY_FAILED_FILE_PATH_EXISTS;
813 break;
814 default:
815 request.recovery_status = NDMP_RECOVERY_FAILED_UNDEFINED_ERROR;
816 break;
819 if (ndmp_send_request_lock(session->ns_connection, NDMP_LOG_FILE,
820 NDMP_NO_ERR, (void *)&request, 0) < 0) {
821 NDMP_LOG(LOG_DEBUG, "Error sending log file request");
822 return (-1);
825 return (0);
830 * ************************************************************************
831 * LOCALS
832 * ************************************************************************
836 * ndmpd_api_find_env
838 * Return the pointer of the environment variable from the variable
839 * array for the spcified environment variable.
841 * Parameters:
842 * cookie (input) - NDMP session pointer.
843 * name (input) - name of variable.
845 * Returns:
846 * Pointer to variable.
847 * NULL if variable not found.
850 ndmp_pval *
851 ndmpd_api_find_env(void *cookie, char *name)
853 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
854 ulong_t i;
855 ndmp_pval *envp;
857 if (session == NULL)
858 return (NULL);
860 envp = session->ns_data.dd_env;
861 for (i = 0; envp && i < session->ns_data.dd_env_len; envp++, i++)
862 if (strcmp(name, envp->name) == 0)
863 return (envp);
865 return (NULL);
870 * ndmpd_api_get_env
872 * Return the value of an environment variable from the variable array.
874 * Parameters:
875 * cookie (input) - NDMP session pointer.
876 * name (input) - name of variable.
878 * Returns:
879 * Pointer to variable value.
880 * 0 if variable not found.
883 char *
884 ndmpd_api_get_env(void *cookie, char *name)
886 ndmp_pval *envp;
888 envp = ndmpd_api_find_env(cookie, name);
889 if (envp)
890 return (envp->value);
892 return (NULL);
897 * ndmpd_api_add_env
899 * Adds an environment variable name/value pair to the environment
900 * variable list.
902 * Parameters:
903 * session (input) - session pointer.
904 * name (input) - variable name.
905 * val (input) - value.
907 * Returns:
908 * 0 - success.
909 * -1 - error.
912 ndmpd_api_add_env(void *cookie, char *name, char *value)
914 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
915 char *namebuf;
916 char *valbuf;
918 if (session == NULL)
919 return (-1);
921 session->ns_data.dd_env = realloc((void *)session->ns_data.dd_env,
922 sizeof (ndmp_pval) * (session->ns_data.dd_env_len + 1));
924 if (session->ns_data.dd_env == NULL) {
925 NDMP_LOG(LOG_ERR, "Out of memory.");
926 return (-1);
928 namebuf = strdup(name);
929 if (namebuf == NULL)
930 return (-1);
932 valbuf = strdup(value);
933 if (valbuf == NULL) {
934 free(namebuf);
935 return (-1);
938 (void) mutex_lock(&session->ns_lock);
939 session->ns_data.dd_env[session->ns_data.dd_env_len].name = namebuf;
940 session->ns_data.dd_env[session->ns_data.dd_env_len].value = valbuf;
941 session->ns_data.dd_env_len++;
942 (void) mutex_unlock(&session->ns_lock);
944 return (0);
949 * ndmpd_api_set_env
951 * Sets an environment variable name/value pair in the environment
952 * variable list. If the variable exists, it gets the new value,
953 * otherwise it's added as a new variable.
955 * Parameters:
956 * session (input) - session pointer.
957 * name (input) - variable name.
958 * val (input) - value.
960 * Returns:
961 * 0 - success.
962 * -1 - error.
965 ndmpd_api_set_env(void *cookie, char *name, char *value)
967 char *valbuf;
968 int rv;
969 ndmp_pval *envp;
971 envp = ndmpd_api_find_env(cookie, name);
972 if (!envp) {
973 rv = ndmpd_api_add_env(cookie, name, value);
974 } else if (!(valbuf = strdup(value))) {
975 rv = -1;
976 } else {
977 rv = 0;
978 free(envp->value);
979 envp->value = valbuf;
982 return (rv);
987 * ndmpd_api_get_name
989 * Return the name entry at the specified index from the
990 * recover file name list.
992 * Parameters:
993 * cookie (input) - NDMP session pointer.
994 * name_index (input) - index of entry to be returned.
996 * Returns:
997 * Pointer to name entry.
998 * 0 if requested entry does not exist.
1000 void *
1001 ndmpd_api_get_name(void *cookie, ulong_t name_index)
1003 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
1005 if (session == NULL)
1006 return (NULL);
1008 if (name_index >= session->ns_data.dd_nlist_len)
1009 return (NULL);
1011 return (&session->ns_data.dd_nlist[name_index]);
1016 * ndmpd_api_dispatch
1018 * Process pending NDMP client requests and check registered files for
1019 * data availability.
1021 * Parameters:
1022 * cookie (input) - session pointer.
1023 * block (input) -
1024 * TRUE block until a request has been processed or
1025 * until a file handler has been called.
1026 * FALSE don't block.
1028 * Returns:
1029 * -1 - abort request received or connection closed.
1030 * 0 - success.
1033 ndmpd_api_dispatch(void *cookie, boolean_t block)
1035 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
1036 int err;
1038 if (session == NULL)
1039 return (-1);
1041 for (; ; ) {
1042 err = ndmpd_select(session, block, HC_ALL);
1043 if (err < 0 || session->ns_data.dd_abort == TRUE ||
1044 session->ns_eof)
1045 return (-1);
1047 if (err == 0)
1048 return (0);
1051 * Something was processed.
1052 * Set the block flag to false so that we will return as
1053 * soon as everything available to be processed has been
1054 * processed.
1056 block = FALSE;
1062 * ndmpd_api_add_file_handler
1064 * Adds a file handler to the file handler list.
1065 * The file handler list is used by ndmpd_api_dispatch.
1067 * Parameters:
1068 * daemon_cookie (input) - session pointer.
1069 * cookie (input) - opaque data to be passed to file hander when called.
1070 * fd (input) - file descriptor.
1071 * mode (input) - bitmask of the following:
1072 * NDMP_SELECT_MODE_READ = watch file for ready for reading
1073 * NDMP_SELECT_MODE_WRITE = watch file for ready for writing
1074 * NDMP_SELECT_MODE_EXCEPTION = watch file for exception
1075 * func (input) - function to call when the file meets one of the
1076 * conditions specified by mode.
1078 * Returns:
1079 * 0 - success.
1080 * -1 - error.
1083 ndmpd_api_add_file_handler(void *daemon_cookie, void *cookie, int fd,
1084 ulong_t mode, ndmpd_file_handler_func_t *func)
1086 ndmpd_session_t *session = (ndmpd_session_t *)daemon_cookie;
1088 return (ndmpd_add_file_handler(session, cookie, fd, mode, HC_MODULE,
1089 func));
1094 * ndmpd_api_remove_file_handler
1096 * Removes a file handler from the file handler list.
1098 * Parameters:
1099 * cookie (input) - session pointer.
1100 * fd (input) - file descriptor.
1102 * Returns:
1103 * 0 - success.
1104 * -1 - error.
1107 ndmpd_api_remove_file_handler(void *cookie, int fd)
1109 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
1111 return (ndmpd_remove_file_handler(session, fd));