/************************************************************************
 * psig.c                                                               *
 *                                                                      *
 * Copyright (C) 2002 - 2020 Joshua Birnbaum <engineer@noorg.org>.      *
 * All Rights Reserved.                                                 *
 *                                                                      *
 * This program is free software; you can redistribute it and/or modify *
 * it under the terms of the GNU General Public License as published    *
 * by the Free Software Foundation; either version 2 of the License, or *
 * (at your option) any later version.                                  *
 *                                                                      *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS    *
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED    *
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE   *
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY      *
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL   *
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE    *
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS        *
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,         *
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING            *
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS   *
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.         *
 *                                                                      *
 * You should have received a copy of the GNU General Public License    *
 * along with this program; see the file COPYING. If not, write to the  *
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, *
 * MA 02111-1307, USA.                                                  *
 ************************************************************************/

/*****************************************************************
 * Project ifchk -- Host based network interface promiscuous     *
 *                  mode detection and handling.                 *
 *                                                               *
 * Version:         1.1.2                                        *
 *                                                               *
 * ------------------------------------------------------------- *
 *                                                               *
 * psig.c:          ifchk posix signal routines.                 *
 *                                                               *
 * Module                                                        *
 * Functions:     - Initializes our POSIX signal set to empty.   *
 *                - Adds specific signals to the new signal set. *
 *                - Blocks signals in the new signal set.        *
 *****************************************************************/

/**********************
 * include directives *
 **********************/

#include "psig.h"


/************************************************************
 * sigsetInit() - Create a POSIX signal set and then block. *
 *                                                          *
 * Parameters:    None.                                     *
 *                                                          *
 * Returns:       Initalized POSIX signal set.              *
 ************************************************************/

sigset_t sigsetInit()
{
    static sigset_t newMask;
    static int sig = 0;

    /*
     * Initialize our POSIX signal set, newMask, to the
     * empty set. Once initialized, we then add SIGINT,
     * SIGTERM, SIGUSR1, and SIGUSR2 to newMask.
     */
    if( sigemptyset( &newMask ) != 0 )
    {
        errHandler( "ERROR: sigemptyset(): could not clear signal set: %s\n",
                                                            strerror( errno ) );
        exit( EXIT_FAILURE );
     }

    /*
     * Add SIGHUP to newMask.
     */
    if( sigaddset( &newMask, SIGHUP ) != 0 )
    {
        errHandler( "ERROR: sigaddset(): could not add SIGHUP to signal set: %s\n",
                                                                  strerror( errno ) );
        exit( EXIT_FAILURE );
     }

    /*
     * Add SIGINT to newMask.
     */
    if( sigaddset( &newMask, SIGINT ) != 0 )
    {
        errHandler( "ERROR: sigaddset(): could not add SIGINT to signal set: %s\n",
                                                                  strerror( errno ) );
        exit( EXIT_FAILURE );
     }

    /*
     * Add SIGTERM to newMask.
     */
    if( sigaddset( &newMask, SIGTERM ) != 0 )
    {
        errHandler( "ERROR: sigaddset(): could not add SIGTERM to signal set: %s\n",
                                                                   strerror( errno ) );
        exit( EXIT_FAILURE );
     }

    /*
     * Add SIGUSR1 to newMask.
     */
    if( sigaddset( &newMask, SIGUSR1 ) != 0 )
    {
        errHandler( "ERROR: sigaddset(): could not add SIGUSR1 to signal set: %s\n",
                                                                   strerror( errno ) );
        exit( EXIT_FAILURE );
     }

    /*
     * Add SIGUSR2 to newMask.
     */
    if( sigaddset( &newMask, SIGUSR2 ) != 0 )
    {
        errHandler( "ERROR: sigaddset(): could not add SIGUSR2 to signal set: %s\n",
                                                                   strerror( errno ) );
        exit( EXIT_FAILURE );
     }

    /*
     * Block the four signals in newMask.
     */
    if( sigprocmask( SIG_BLOCK, &newMask, NULL ) != 0 )
    {
        errHandler( "ERROR: sigprocmask(): could not modify signal mask: %s\n",
                                                              strerror( errno ) );
        exit( EXIT_FAILURE );
     }

    return( newMask );
}
