📄 main.c
字号:
/* -*- Mode: C -*- * main.c * * Description : NDMP daemon main(). * * usage: ndmpd [-d debug-level] [-p port-number] [-f] * * where: * debug-level - The least significant 4 bits of the * level specify the detail. 0 will * result in mimimal messages for enabled * components being output. 15 will * result in all messages for enabled * components being output. * The remaining bits in the level specify * the components for which messages are * to be output. Refer to ../common/log.h * for defined components. * Default is all messages disabled. * * port-number - TCP port number on which the NDMP server * is listening for connection requests. * Default is to lookup the port in the * services database. * * -f - Disables forking to handle a new connection. * Default is to fork a child process to handle * each connection. * * Copyright (c) 1996,1997 PDC, Network Appliance. All Rights Reserved. * * $Id: main.c,v 1.9 1998/05/26 03:52:18 tim Exp $ */#if !defined(lint) && !defined(SABER)static char rcsId[] __attribute__ ((unused)) = "@(#) $Id: main.c,v 1.9 1998/05/26 03:52:18 tim Exp $";#endif#include <unistd.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <signal.h>#include <sys/socket.h>#include <netdb.h>#include <netinet/in.h>#include <arpa/inet.h>#include <rpc/rpc.h>#include "ndmpd.h"extern NdmpMsgHandler ndmpdMsgHandlerTable[];static NdmpConHandlerFunc connectionHandler;static NdmpdFileHandlerFunc connectionFileHandler;intmain(int argc, char* argv[]){ int port = 0; bool_t doFork = TRUE; char c; pid_t childPid; int fd; extern char *optarg; extern int optind; extern int opterr; openlog("ndmpd", LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_DAEMON); opterr = 0; while ((c = getopt(argc, argv, "d:fp:")) != -1) { switch(c) { case 'd': { SetDebugLevel(strtol(optarg, 0, 0)); break; } case 'f': { doFork = FALSE; break; } case 'p': { port = strtol(optarg, 0, 0); break; } default: { fprintf(stderr, "usage: %s [-d debug-level] [-p port]\n", argv[0]); exit(1); } } } /* Ignore terminal stop signals. */ sigignore(SIGTTOU); sigignore(SIGTTIN); sigignore(SIGTSTP); /* * Only act as a real daemon if not in debug mode. */ if (doFork == TRUE) { /* * Fork and let the parent exit in case we weren't started * in the background. * This also guarantees the child is not the process group leader. */ if ((childPid = fork()) < 0) { Error(LOG_ERR, "fork error: %s\n", strerror(errno)); exit(1); } else if (childPid > 0) exit(0); /* * Disassociate from controlling terminal and process group. * Ensure the process can't reacquire a new controlling terminal. */ (void)setpgrp(); sigignore(SIGHUP); /* make self immune from pgrp leader death */ if ((childPid = fork()) < 0) { Error(LOG_ERR, "fork error: %s\n", strerror(errno)); exit(1); } else if (childPid > 0) exit(0); } /* * Close all open file descriptors. * stderr is left open since it is used for debugging. */ (void)close(0); (void)close(1); for (fd = 3; fd < NOFILE; fd++) (void)close(fd); errno = 0; (void)chdir("/"); /* Don't want to be on a mounted filesystem */ (void)umask(0); /* clear any inherited file mode creation mask */ sigignore(SIGCHLD); /* prevent zombies */ sigignore(SIGPIPE); /* ignore signals resulting from attempting to * write to a broken pipe. */ ndmpRun(port, doFork, ndmpdMsgHandlerTable, connectionHandler); exit(0);}/* * connectionHandler * * NDMP connection handler. * Waits for, reads, and processes NDMP requests on a connection. * * Parameters: * connection (input) - connection handle. * * Return: * void */static voidconnectionHandler(NdmpConnection connection){ static u_long sessionCounter = 1; NdmpdSession session; ndmp_notify_connected_request req; Debug(DBG_CAT_CONN|DBG_FOC_FLOW, "ndmpConnectionHandler: received connection.\n"); session.connection = connection; session.eof = FALSE; session.protocolVersion = NDMPVER; session.scsi.fd = -1; session.tape.fd = -1; session.fileHandlerList = 0; session.id = sessionCounter++; ndmpdDataInit(&session); ndmpdFileHistoryInit(&session); ndmpdMoverInit(&session); /* * Setup defaults here. The init functions can not set defaults * since the init functions are called by the stop request handlers * and client set variables need to persist across data operations. */ session.mover.recordSize = MAX_RECORD_SIZE; ndmpSetClientData(connection, (void *)&session); req.reason = NDMP_CONNECTED; req.protocol_version = NDMPVER; req.text_reason = ""; if (ndmpSendRequest(connection, NDMP_NOTIFY_CONNECTED, NDMP_NO_ERR, (void*) &req, 0) < 0) { Debug(DBG_CAT_CONN|DBG_FOC_FLOW, "ndmpConnectionHandler: connection terminated.\n"); return; } if (ndmpdAddFileHandler(&session, (void*)&session, ndmpGetFd(connection), NDMPD_SELECT_MODE_READ, HC_CLIENT, connectionFileHandler) != 0) return; while (session.eof == FALSE) ndmpdSelect(&session, TRUE, HC_ALL); Debug(DBG_CAT_CONN|DBG_FOC_FLOW, "ndmpConnectionHandler: connection terminated.\n"); (void)ndmpdRemoveFileHandler(&session, ndmpGetFd(connection)); if (session.scsi.fd != -1) (void)close(session.scsi.fd); if (session.tape.fd != -1) (void)close(session.tape.fd); ndmpdDataCleanup(&session); ndmpdFileHistoryCleanup(&session, FALSE); ndmpdMoverCleanup(&session); return;}/* * connectionFileHandler * Connection file handler function. * Called by ndmpdSelect when data is available to be read on the * NDMP connection. * * Parameters: * cookie (input) - session pointer. * fd (input) - connection file descriptor. * mode (input) - select mode. * * Returns: * void. */static voidconnectionFileHandler(void* cookie, int fd __attribute__ ((unused)), u_long mode __attribute__ ((unused))){ NdmpdSession* session = (NdmpdSession*)cookie; if (ndmpProcessRequests(session->connection) < 0) session->eof = TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -