1*6ba597c5SAnurag S. Maskey /* 2*6ba597c5SAnurag S. Maskey * CDDL HEADER START 3*6ba597c5SAnurag S. Maskey * 4*6ba597c5SAnurag S. Maskey * The contents of this file are subject to the terms of the 5*6ba597c5SAnurag S. Maskey * Common Development and Distribution License (the "License"). 6*6ba597c5SAnurag S. Maskey * You may not use this file except in compliance with the License. 7*6ba597c5SAnurag S. Maskey * 8*6ba597c5SAnurag S. Maskey * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*6ba597c5SAnurag S. Maskey * or http://www.opensolaris.org/os/licensing. 10*6ba597c5SAnurag S. Maskey * See the License for the specific language governing permissions 11*6ba597c5SAnurag S. Maskey * and limitations under the License. 12*6ba597c5SAnurag S. Maskey * 13*6ba597c5SAnurag S. Maskey * When distributing Covered Code, include this CDDL HEADER in each 14*6ba597c5SAnurag S. Maskey * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*6ba597c5SAnurag S. Maskey * If applicable, add the following below this CDDL HEADER, with the 16*6ba597c5SAnurag S. Maskey * fields enclosed by brackets "[]" replaced with your own identifying 17*6ba597c5SAnurag S. Maskey * information: Portions Copyright [yyyy] [name of copyright owner] 18*6ba597c5SAnurag S. Maskey * 19*6ba597c5SAnurag S. Maskey * CDDL HEADER END 20*6ba597c5SAnurag S. Maskey */ 21*6ba597c5SAnurag S. Maskey 22*6ba597c5SAnurag S. Maskey /* 23*6ba597c5SAnurag S. Maskey * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24*6ba597c5SAnurag S. Maskey * Use is subject to license terms. 25*6ba597c5SAnurag S. Maskey */ 26*6ba597c5SAnurag S. Maskey 27*6ba597c5SAnurag S. Maskey /* 28*6ba597c5SAnurag S. Maskey * netcfgd - network configuration daemon. At present, this daemon implements 29*6ba597c5SAnurag S. Maskey * the configuration backend for libnwam (via calls to nwam_backend_init() 30*6ba597c5SAnurag S. Maskey * and nwam_backend_fini()). Initialization of the backend creates a door 31*6ba597c5SAnurag S. Maskey * that libnwam calls use to read, update and destroy persistent configuration. 32*6ba597c5SAnurag S. Maskey * 33*6ba597c5SAnurag S. Maskey * More long-term, netcfgd will be used to manage other sources of configuration 34*6ba597c5SAnurag S. Maskey * data and the backend functionality currently contained in libnwam will be 35*6ba597c5SAnurag S. Maskey * generalized. 36*6ba597c5SAnurag S. Maskey */ 37*6ba597c5SAnurag S. Maskey 38*6ba597c5SAnurag S. Maskey #include <errno.h> 39*6ba597c5SAnurag S. Maskey #include <signal.h> 40*6ba597c5SAnurag S. Maskey #include <stdio.h> 41*6ba597c5SAnurag S. Maskey #include <stdarg.h> 42*6ba597c5SAnurag S. Maskey #include <stdlib.h> 43*6ba597c5SAnurag S. Maskey #include <string.h> 44*6ba597c5SAnurag S. Maskey #include <syslog.h> 45*6ba597c5SAnurag S. Maskey #include <sys/types.h> 46*6ba597c5SAnurag S. Maskey #include <sys/stat.h> 47*6ba597c5SAnurag S. Maskey #include <unistd.h> 48*6ba597c5SAnurag S. Maskey #include <wait.h> 49*6ba597c5SAnurag S. Maskey #include <libnwam_priv.h> 50*6ba597c5SAnurag S. Maskey #include <libnwam.h> 51*6ba597c5SAnurag S. Maskey 52*6ba597c5SAnurag S. Maskey static const char *progname; 53*6ba597c5SAnurag S. Maskey static boolean_t fg = B_FALSE; 54*6ba597c5SAnurag S. Maskey 55*6ba597c5SAnurag S. Maskey /* 56*6ba597c5SAnurag S. Maskey * This function allows you to drop a dtrace probe here and trace 57*6ba597c5SAnurag S. Maskey * complete strings (not just those containing formatting). It's 58*6ba597c5SAnurag S. Maskey * important that we actually format the strings so we could trace them 59*6ba597c5SAnurag S. Maskey * even if we choose not to log them. 60*6ba597c5SAnurag S. Maskey */ 61*6ba597c5SAnurag S. Maskey static void 62*6ba597c5SAnurag S. Maskey log_out(int severity, const char *str) 63*6ba597c5SAnurag S. Maskey { 64*6ba597c5SAnurag S. Maskey if (fg) { 65*6ba597c5SAnurag S. Maskey (void) fprintf(stderr, "%s: %s\n", progname, str); 66*6ba597c5SAnurag S. Maskey } else { 67*6ba597c5SAnurag S. Maskey syslog(severity, str); 68*6ba597c5SAnurag S. Maskey } 69*6ba597c5SAnurag S. Maskey } 70*6ba597c5SAnurag S. Maskey 71*6ba597c5SAnurag S. Maskey /* PRINTFLIKE2 */ 72*6ba597c5SAnurag S. Maskey void 73*6ba597c5SAnurag S. Maskey nlog(int severity, const char *fmt, ...) 74*6ba597c5SAnurag S. Maskey { 75*6ba597c5SAnurag S. Maskey va_list ap; 76*6ba597c5SAnurag S. Maskey char *vbuf; 77*6ba597c5SAnurag S. Maskey 78*6ba597c5SAnurag S. Maskey va_start(ap, fmt); 79*6ba597c5SAnurag S. Maskey if (vasprintf(&vbuf, fmt, ap) != -1) { 80*6ba597c5SAnurag S. Maskey log_out(severity, vbuf); 81*6ba597c5SAnurag S. Maskey free(vbuf); 82*6ba597c5SAnurag S. Maskey } 83*6ba597c5SAnurag S. Maskey va_end(ap); 84*6ba597c5SAnurag S. Maskey } 85*6ba597c5SAnurag S. Maskey 86*6ba597c5SAnurag S. Maskey static void 87*6ba597c5SAnurag S. Maskey start_logging(void) 88*6ba597c5SAnurag S. Maskey { 89*6ba597c5SAnurag S. Maskey if (!fg) 90*6ba597c5SAnurag S. Maskey openlog(progname, LOG_PID, LOG_DAEMON); 91*6ba597c5SAnurag S. Maskey 92*6ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "%s started", progname); 93*6ba597c5SAnurag S. Maskey } 94*6ba597c5SAnurag S. Maskey 95*6ba597c5SAnurag S. Maskey static void 96*6ba597c5SAnurag S. Maskey daemonize(void) 97*6ba597c5SAnurag S. Maskey { 98*6ba597c5SAnurag S. Maskey pid_t pid; 99*6ba597c5SAnurag S. Maskey 100*6ba597c5SAnurag S. Maskey /* 101*6ba597c5SAnurag S. Maskey * A little bit of magic here. By the first fork+setsid, we 102*6ba597c5SAnurag S. Maskey * disconnect from our current controlling terminal and become 103*6ba597c5SAnurag S. Maskey * a session group leader. By forking again without calling 104*6ba597c5SAnurag S. Maskey * setsid again, we make certain that we are not the session 105*6ba597c5SAnurag S. Maskey * group leader and can never reacquire a controlling terminal. 106*6ba597c5SAnurag S. Maskey */ 107*6ba597c5SAnurag S. Maskey if ((pid = fork()) == -1) { 108*6ba597c5SAnurag S. Maskey nlog(LOG_ERR, "fork 1 failed"); 109*6ba597c5SAnurag S. Maskey exit(EXIT_FAILURE); 110*6ba597c5SAnurag S. Maskey } 111*6ba597c5SAnurag S. Maskey if (pid != 0) { 112*6ba597c5SAnurag S. Maskey (void) wait(NULL); 113*6ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "child %ld exited, daemonizing", pid); 114*6ba597c5SAnurag S. Maskey _exit(0); 115*6ba597c5SAnurag S. Maskey } 116*6ba597c5SAnurag S. Maskey if (setsid() == (pid_t)-1) { 117*6ba597c5SAnurag S. Maskey nlog(LOG_ERR, "setsid"); 118*6ba597c5SAnurag S. Maskey exit(EXIT_FAILURE); 119*6ba597c5SAnurag S. Maskey } 120*6ba597c5SAnurag S. Maskey if ((pid = fork()) == -1) { 121*6ba597c5SAnurag S. Maskey nlog(LOG_ERR, "fork 2 failed"); 122*6ba597c5SAnurag S. Maskey exit(EXIT_FAILURE); 123*6ba597c5SAnurag S. Maskey } 124*6ba597c5SAnurag S. Maskey if (pid != 0) { 125*6ba597c5SAnurag S. Maskey _exit(0); 126*6ba597c5SAnurag S. Maskey } 127*6ba597c5SAnurag S. Maskey (void) chdir("/"); 128*6ba597c5SAnurag S. Maskey (void) umask(022); 129*6ba597c5SAnurag S. Maskey } 130*6ba597c5SAnurag S. Maskey 131*6ba597c5SAnurag S. Maskey /* ARGSUSED */ 132*6ba597c5SAnurag S. Maskey static void 133*6ba597c5SAnurag S. Maskey graceful_shutdown(int signo) 134*6ba597c5SAnurag S. Maskey { 135*6ba597c5SAnurag S. Maskey nwam_backend_fini(); 136*6ba597c5SAnurag S. Maskey exit(EXIT_SUCCESS); 137*6ba597c5SAnurag S. Maskey } 138*6ba597c5SAnurag S. Maskey 139*6ba597c5SAnurag S. Maskey int 140*6ba597c5SAnurag S. Maskey main(int argc, char *argv[]) 141*6ba597c5SAnurag S. Maskey { 142*6ba597c5SAnurag S. Maskey int c; 143*6ba597c5SAnurag S. Maskey nwam_error_t err; 144*6ba597c5SAnurag S. Maskey 145*6ba597c5SAnurag S. Maskey if ((progname = strrchr(argv[0], '/')) == NULL) 146*6ba597c5SAnurag S. Maskey progname = argv[0]; 147*6ba597c5SAnurag S. Maskey else 148*6ba597c5SAnurag S. Maskey progname++; 149*6ba597c5SAnurag S. Maskey 150*6ba597c5SAnurag S. Maskey while ((c = getopt(argc, argv, "f")) != -1) { 151*6ba597c5SAnurag S. Maskey switch (c) { 152*6ba597c5SAnurag S. Maskey case 'f': 153*6ba597c5SAnurag S. Maskey fg = B_TRUE; 154*6ba597c5SAnurag S. Maskey break; 155*6ba597c5SAnurag S. Maskey default: 156*6ba597c5SAnurag S. Maskey (void) fprintf(stderr, "%s: unrecognized option %c\n", 157*6ba597c5SAnurag S. Maskey progname, optopt); 158*6ba597c5SAnurag S. Maskey exit(EXIT_FAILURE); 159*6ba597c5SAnurag S. Maskey } 160*6ba597c5SAnurag S. Maskey } 161*6ba597c5SAnurag S. Maskey start_logging(); 162*6ba597c5SAnurag S. Maskey 163*6ba597c5SAnurag S. Maskey if (!fg) 164*6ba597c5SAnurag S. Maskey daemonize(); 165*6ba597c5SAnurag S. Maskey 166*6ba597c5SAnurag S. Maskey (void) signal(SIGTERM, graceful_shutdown); 167*6ba597c5SAnurag S. Maskey (void) signal(SIGQUIT, graceful_shutdown); 168*6ba597c5SAnurag S. Maskey (void) signal(SIGPIPE, SIG_IGN); 169*6ba597c5SAnurag S. Maskey (void) signal(SIGCHLD, SIG_IGN); 170*6ba597c5SAnurag S. Maskey (void) atexit(nwam_backend_fini); 171*6ba597c5SAnurag S. Maskey 172*6ba597c5SAnurag S. Maskey if ((err = nwam_backend_init()) != NWAM_SUCCESS) { 173*6ba597c5SAnurag S. Maskey nlog(LOG_ERR, 174*6ba597c5SAnurag S. Maskey "couldn't initialize libnwam backend: %s", 175*6ba597c5SAnurag S. Maskey nwam_strerror(err)); 176*6ba597c5SAnurag S. Maskey exit(EXIT_FAILURE); 177*6ba597c5SAnurag S. Maskey } 178*6ba597c5SAnurag S. Maskey 179*6ba597c5SAnurag S. Maskey for (;;) 180*6ba597c5SAnurag S. Maskey (void) pause(); 181*6ba597c5SAnurag S. Maskey 182*6ba597c5SAnurag S. Maskey /* NOTREACHED */ 183*6ba597c5SAnurag S. Maskey return (EXIT_SUCCESS); 184*6ba597c5SAnurag S. Maskey } 185