main.c revision 9b38c94425adf01f8223f4710a89ca01d6be3386
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* nwamd - NetWork Auto-Magic Daemon
*/
#include <fcntl.h>
#include <priv.h>
#include <pthread.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <syslog.h>
#include <unistd.h>
#include <locale.h>
#include <libintl.h>
#include <errno.h>
#include "defines.h"
#include "structures.h"
#include "functions.h"
#include "variables.h"
const char *OUR_PG = "nwamd";
char zonename[ZONENAME_MAX];
/*
* nwamd
*
* This is the Network Auto-Magic daemon. For further high level information
* see the Network Auto-Magic project and the Approachability communities
* on opensolaris.org, and nwamd(1M).
*
* The general structure of the code is as a set of threads collecting
* system events which are fed into a state machine which alters system
* state based on configuration.
*
* signal management
* Due to being threaded, a simple set of signal handlers would not work
* very well for nwamd. Instead nwamd blocks signals at startup and
* then starts a thread which sits in sigwait(2) waiting for signals.
* When a signal is received the signal handling thread dispatches it.
* It handles:
* - shutting down, done by creating an event which is passed through the
* system allowing the various subsystems to do any necessary cleanup.
* - SIGALRM for timers.
* - SIGHUP for instance refresh, which tells us to look up various
* properties from SMF(5).
*
* subprocess management
* nwamd starts several different subprocesses to manage the system. Some
* of those start other processes (e.g. `ifconfig <if> dhcp` ends up starting
* dhcpagent if necessary). Due to the way we manage signals if we started
* those up without doing anything special their signal mask would mostly
* block signals. So we restore the signal mask when we start subprocesses.
* This is especially important with respect to DHCP as later when we exit
* we need to kill the dhcpagent process which we started; for details, see
* the block comment in state_machine.c in its cleanup() function.
*/
/*
* In this file there are several utility functions which might otherwise
* belong in util.c, but since they are only called from main(), they can
* live here as static functions:
* - syslog set-up
* - daemonizing
* - looking up SMF(5) properties
* - signal handling
* - managing privileges(5)
*/
static void
start_logging(void)
{
}
static void
daemonize(void)
{
/*
* A little bit of magic here. By the first fork+setsid, we
* disconnect from our current controlling terminal and become
* a session group leader. By forking again without calling
* setsid again, we make certain that we are not the session
* group leader and can never reacquire a controlling terminal.
*/
}
if (pid != 0) {
_exit(0);
}
}
}
if (pid != 0) {
_exit(0);
}
(void) chdir("/");
(void) umask(022);
}
/*
* Look up nwamd property values and set daemon variables appropriately.
* This function will be called on startup and via the signal handling
* thread on receiving a HUP (which occurs when the nwam service is
* refreshed).
*/
static void
lookup_daemon_properties(void)
{
dprintf("Read daemon configuration properties.");
}
/* ARGSUSED */
static void *
sighandler(void *arg)
{
int sig;
(void) sigfillset(&sigset);
for (;;) {
switch (sig) {
case SIGALRM:
/*
* We may have multiple interfaces with
* scheduled timers; walk the list and
* create a timer event for each one.
*/
break;
case SIGHUP:
/*
* Refresh action - reread configuration properties.
*/
break;
default:
dprintf("could not allocate shutdown event");
cleanup();
}
break;
}
/* if we're shutting down, exit this thread */
if (shutting_down)
return (NULL);
}
}
static void
init_signalhandling(void)
{
int err;
(void) sigfillset(&new);
(void) pthread_attr_init(&attr);
} else {
}
(void) pthread_attr_destroy(&attr);
}
static void
change_user_set_privs(void)
{
priv_set = priv_allocset();
} else {
char *p;
free(p);
}
/* always start with the basic set */
}
}
}
}
}
int
{
int c;
int scan_lev;
struct np_event *e;
(void) textdomain(TEXT_DOMAIN);
switch (c) {
case 'f':
break;
case 's':
if (scan_lev >= DLADM_WLAN_STRENGTH_VERY_WEAK &&
} else {
"strength: %s", optarg);
}
break;
default:
optopt);
break;
}
}
if (!fg)
daemonize();
init_mutexes();
(void) start_event_collection();
npe_type_str(e->npe_type));
switch (e->npe_type) {
case EV_ROUTING:
case EV_NEWADDR:
case EV_TIMER:
state_machine(e);
free_event(e);
break;
case EV_SYS:
free_event(e);
break;
case EV_SHUTDOWN:
state_machine(e);
(void) pthread_cancel(routing);
(void) pthread_cancel(scan);
/* NOTREACHED */
default:
free_event(e);
break;
}
}
return (0);
}