📄 callbacks.c
字号:
/* -*- Mode: C -*- * callbacks.c * * Description : Callback functions called by the dump and restore * functions. * * Note: not all callback functions are here. * Some are in file_history.c. * * Copyright (c) 1996,1997 PDC, Network Appliance. All Rights Reserved. * * $Id: callbacks.c,v 1.11 1998/02/16 21:08:15 tim Exp $ */#if !defined(lint) && !defined(SABER)static char rcsId[] __attribute__ ((unused)) = "@(#) $Id: callbacks.c,v 1.11 1998/02/16 21:08:15 tim Exp $";#endif#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <sys/types.h>#include <string.h>#include "ndmpd.h"/* * ndmpdApiGetEnv * Return the value of an environment variable from the variable array. * * Parameters: * cookie (input) - NDMP session pointer. * name (input) - name of variable. * * Returns: * Pointer to variable value. * 0 if variable not found. * */char*ndmpdApiGetEnv(void* cookie, char* name){ NdmpdSession* session = (NdmpdSession*)cookie; u_long i; for (i = 0; i < session->data.envLen; i++) { if (strcmp(name, session->data.env[i].name) == 0) return(session->data.env[i].value); } return(0);}/* * ndmpdApiAddEnv * Adds an environment variable name/value pair to the environment * variable list. * * Parameters: * session (input) - session pointer. * name (input) - variable name. * val (input) - value. * * Returns: * 0 - success. * -1 - error. */intndmpdApiAddEnv(void* cookie, char* name, char* value){ NdmpdSession* session = (NdmpdSession*)cookie; char* namebuf; char* valbuf; session->data.env = (ndmp_pval*)realloc((void*)session->data.env, sizeof(ndmp_pval)* (session->data.envLen+1)); if (session->data.env == 0) { Error(LOG_ERR, "ndmpdApiAddEnv: malloc error: %s.\n", strerror(errno)); return(-1); } namebuf = (char*)malloc(strlen(name)+1); if (namebuf == 0) { Error(LOG_ERR, "ndmpdApiAddEnv: malloc error: %s.\n", strerror(errno)); return(-1); } valbuf = (char*)malloc(strlen(value)+1); if (valbuf == 0) { Error(LOG_ERR, "ndmpdApiAddEnv: malloc error: %s.\n", strerror(errno)); free(namebuf); return(-1); } strcpy(namebuf, name); strcpy(valbuf, value); session->data.env[session->data.envLen].name = namebuf; session->data.env[session->data.envLen].value = valbuf; session->data.envLen++; return(0);}/* * ndmpdApiGetName * Return the name entry at the specified index from the * recover file name list. * * Parameters: * cookie (input) - NDMP session pointer. * nameIndex (input) - index of entry to be returned. * * Returns: * Pointer to name entry. * 0 if requested entry does not exist. */ndmp_name*ndmpdApiGetName(void* cookie, u_long nameIndex){ NdmpdSession* session = (NdmpdSession*)cookie; if (nameIndex >= session->data.nlistLen) return(0); return(&session->data.nlist[nameIndex]);}/* * ndmpdApiDispatch * Process pending NDMP client requests and check registered files for * data availability. * * Parameters: * cookie (input) - session pointer. * block (input) - TRUE -> block until a request has been processed or * until a file handler has been called. * FALSE -> don't block. * * Returns: * -1 - abort request received or connection closed. * 0 - success. */intndmpdApiDispatch(void* cookie, bool_t block){ NdmpdSession* session = (NdmpdSession*)cookie; int err; if (session == 0) return(-1); for (;;) { err = ndmpdSelect(session, block, HC_ALL); if (err < 0 || session->data.abortFlag == TRUE || session->eof) return(-1); if (err == 0) return(0); /* * Something was processed. * Set the block flag to false so that we will return as * soon as everything available to be processed has been * processed. */ block = FALSE; }}/* * ndmpdApiDone * Called when the data module has completed. * Sends a notify_halt request to the NDMP client. * * Parameters: * session (input) - session pointer. * err (input) - UNIX error code. * * Returns: * void */voidndmpdApiDone(void* cookie, int err){ NdmpdSession* session = (NdmpdSession*)cookie; ndmp_data_halt_reason reason; switch (err) { case 0: reason = NDMP_DATA_HALT_SUCCESSFUL; break; case EINTR: reason = NDMP_DATA_HALT_ABORTED; break; case EIO: reason = NDMP_DATA_HALT_CONNECT_ERROR; break; default: reason = NDMP_DATA_HALT_INTERNAL_ERROR; break; } ndmpdDataError(session, reason);}/* * ndmpdApiLog * Sends a log request to the NDMP client. * * Parameters: * cookie (input) - session pointer. * format (input) - printf style format. * ... (input) - format arguments. * * Returns: * 0 - success. * -1 - error. */intndmpdApiLog(void* cookie, ndmp_log_type type, u_long msgId, char* format, ...){ NdmpdSession* session = (NdmpdSession*)cookie; ndmp_log_message_request request; static char buf[1024]; va_list ap; if (session == 0) return(-1); va_start(ap, format); vsprintf(buf, format, ap); va_end(ap); request.entry = buf; request.log_type = type; request.message_id = msgId; if (ndmpSendRequest(session->connection, NDMP_LOG_MESSAGE, NDMP_NO_ERR, (void *)&request, 0) < 0) { Error(LOG_ERR, "ndmpdApiLog: error sending log message request.\n"); return(-1); } return(0);}/* * ndmpdApiWrite * Callback function called by the backup/restore module. * Writes data to the mover. * If the mover is remote, the data is written to the data connection. * If the mover is local, the data is buffered and written to the * tape device after a full record has been buffered. * * Parameters: * clientData (input) - session pointer. * data (input) - data to be written. * length (input) - data length. * * Returns: * 0 - data successfully written. * -1 - error. */intndmpdApiWrite(void* clientData, char* data, u_long length){ NdmpdSession* session = (NdmpdSession*)clientData; Debug(DBG_CAT_DATA|DBG_FOC_FLOW, "ndmpdApiWrite: length:%u\n", length); /* * Write the data to the data connection if the mover is remote. */ if (session->data.moverAddr.addr_type == NDMP_ADDR_LOCAL) return(ndmpdLocalWrite(session, data, length)); else return(ndmpdRemoteWrite(session, data, length));}/* * ndmpdApiRead * Callback function called by the backup/recover module. * Reads data from the mover. * If the mover is remote, the data is read from the data connection. * If the mover is local, the data is read from the tape device. * * Parameters: * clientData (input) - session pointer. * data (input) - data to be written. * length (input) - data length. * * Returns: * 0 - data successfully read. * -1 - error. */intndmpdApiRead(void* clientData, char* data, u_long length){ NdmpdSession* session = (NdmpdSession*)clientData; Debug(DBG_CAT_DATA|DBG_FOC_FLOW, "ndmpdApiRead: length:%u\n", length); /* * Read the data from the data connection if the mover is remote. */ if (session->data.moverAddr.addr_type == NDMP_ADDR_LOCAL) return(ndmpdLocalRead(session, data, length)); else return(ndmpdRemoteRead(session, data, length));}/* * ndmpdApiSeek * Seek to the specified position in the data stream and start a * read for the specified amount of data. * * Parameters: * cookie (input) - session pointer. * offset (input) - stream position to seek to. * length (input) - amount of data that will be read using ndmpdApiRead * * Returns: * 0 - seek successful. * -1 - error. */intndmpdApiSeek(void* cookie, u_longlong_t offset, u_longlong_t length){ NdmpdSession* session = (NdmpdSession*)cookie; int err; Debug(DBG_CAT_DATA|DBG_FOC_FLOW, "ndmpdApiSeek: offset:%llu length:%llu\n", offset, length); session->data.readOffset = offset; session->data.readLength = length; /* * Send a notify_data_read request if the mover is remote. */ if (session->data.moverAddr.addr_type != NDMP_ADDR_LOCAL) { ndmp_notify_data_read_request request; session->data.discardLength = session->data.bytesLeftToRead; session->data.bytesLeftToRead = length; session->data.position = offset; request.offset = longLongToQuad(offset); request.length = longLongToQuad(length); if (ndmpSendRequest(session->connection, NDMP_NOTIFY_DATA_READ, NDMP_NO_ERR, (void *)&request, 0) < 0) { Error(LOG_ERR, "ndmpdApiSeek: error sending notify_data_read request.\n"); return(-1); } return(0); } /* Mover is local. */ err = ndmpdMoverSeek(session, offset, length); if (err < 0) { ndmpdMoverError(session, NDMP_MOVER_HALT_INTERNAL_ERROR); return(-1); } if (err == 0) return(0); /* * NDMP client intervention is required to perform the seek. * Wait for the client to either do the seek and send a continue * request or send an abort request. */ for (;;) { if (ndmpdSelect(session, TRUE, HC_CLIENT) < 0) return(-1); if (session->eof == TRUE) return(-1); switch (session->mover.state) { case NDMP_MOVER_STATE_ACTIVE: break; case NDMP_MOVER_STATE_PAUSED: continue; default: return(-1); } } return(0);}/* * ndmpdApiFileRecovered * Notify the NDMP client that the specified file was recovered. * * Parameters: * cookie (input) - session pointer. * name (input) - name of recovered file. * ssid (input) - selection set id. * error (input) - 0 if file successfully recovered. * otherwise, error code indicating why recovery failed. * * Returns: * void. */intndmpdApiFileRecovered(void* cookie, char* name, int error){ NdmpdSession* session = (NdmpdSession*)cookie; ndmp_log_file_request request; if (session == 0) return(-1); request.name = name; switch (error) { case 0: request.error = NDMP_NO_ERR; break; case ENOENT: request.error = NDMP_FILE_NOT_FOUND_ERR; break; default: request.error = NDMP_PERMISSION_ERR; break; } if (ndmpSendRequest(session->connection, NDMP_LOG_FILE, NDMP_NO_ERR, (void *)&request, 0) < 0) { Error(LOG_ERR, "ndmpdApiFileRecovered: error sending log file request.\n"); return(-1); } return(0);}/* * ndmpdApiAddFileHandler * Adds a file handler to the file handler list. * The file handler list is used by ndmpdApiDispatch. * * Parameters: * daemonCookie (input) - session pointer. * cookie (input) - opaque data to be passed to file hander when called. * fd (input) - file descriptor. * mode (input) - bitmask of the following: * 1 = watch file for ready for reading * 2 = watch file for ready for writing * 4 = watch file for exception * func (input) - function to call when the file meets one of the * conditions specified by mode. * * Returns: * 0 - success. * -1 - error. */intndmpdApiAddFileHandler(void* daemonCookie, void* cookie, int fd, u_long mode, NdmpdFileHandlerFunc* func){ NdmpdSession* session = (NdmpdSession*)daemonCookie; return(ndmpdAddFileHandler(session, cookie, fd, mode, HC_MODULE, func));}/* * ndmpdApiRemoveFileHandler * Removes a file handler from the file handler list. * * Parameters: * cookie (input) - session pointer. * fd (input) - file descriptor. * * Returns: * 0 - success. * -1 - error. */intndmpdApiRemoveFileHandler(void* cookie, int fd){ NdmpdSession* session = (NdmpdSession*)cookie; return(ndmpdRemoveFileHandler(session, fd));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -