コード例 #1
0
ファイル: ifplugd.c プロジェクト: ArcSung/busybox-1.22.1
static int run_script(const char *action)
{
	char *env_PREVIOUS, *env_CURRENT;
	char *argv[5];
	int r;

	bb_error_msg("executing '%s %s %s'", G.script_name, G.iface, action);

	argv[0] = (char*) G.script_name;
	argv[1] = (char*) G.iface;
	argv[2] = (char*) action;
	argv[3] = (char*) G.extra_arg;
	argv[4] = NULL;

	env_PREVIOUS = xasprintf("%s=%s", IFPLUGD_ENV_PREVIOUS, strstatus(G.iface_prev_status));
	putenv(env_PREVIOUS);
	env_CURRENT = xasprintf("%s=%s", IFPLUGD_ENV_CURRENT, strstatus(G.iface_last_status));
	putenv(env_CURRENT);

	/* r < 0 - can't exec, 0 <= r < 0x180 - exited, >=0x180 - killed by sig (r-0x180) */
	r = spawn_and_wait(argv);

	unsetenv(IFPLUGD_ENV_PREVIOUS);
	unsetenv(IFPLUGD_ENV_CURRENT);
	free(env_PREVIOUS);
	free(env_CURRENT);

	bb_error_msg("exit code: %d", r & 0xff);
	return (option_mask32 & FLAG_IGNORE_RETVAL) ? 0 : r;
}
コード例 #2
0
ファイル: keyserv.c プロジェクト: AhmadTux/DragonFlyBSD
cryptkeyres *
key_decrypt_1_svc_prog(uid_t uid, cryptkeyarg *arg)
{
	static cryptkeyres res;

	if (debugging) {
		fprintf(stderr, "decrypt(%ld, %s, %08x%08x) = ", uid,
				arg->remotename, arg->deskey.key.high,
				arg->deskey.key.low);
	}
	res.cryptkeyres_u.deskey = arg->deskey;
	res.status = pk_decrypt(uid, arg->remotename, NULL,
				&res.cryptkeyres_u.deskey);
	if (debugging) {
		if (res.status == KEY_SUCCESS) {
			fprintf(stderr, "%08x%08x\n",
					res.cryptkeyres_u.deskey.key.high,
					res.cryptkeyres_u.deskey.key.low);
		} else {
			fprintf(stderr, "%s\n", strstatus(res.status));
		}
		fflush(stderr);
	}
	return (&res);
}
コード例 #3
0
ファイル: keyserv.c プロジェクト: AhmadTux/DragonFlyBSD
getcredres *
key_getcred_1_svc_prog(uid_t uid, netnamestr *name)
{
	static getcredres res;
	static u_int gids[NGROUPS];
	struct unixcred *cred;

	cred = &res.getcredres_u.cred;
	cred->gids.gids_val = gids;
	if (!netname2user(*name, (uid_t *) &cred->uid, (gid_t *) &cred->gid,
			(int *)&cred->gids.gids_len, (gid_t *)gids)) {
		res.status = KEY_UNKNOWN;
	} else {
		res.status = KEY_SUCCESS;
	}
	if (debugging) {
		fprintf(stderr, "getcred(%s) = ", *name);
		if (res.status == KEY_SUCCESS) {
			fprintf(stderr, "uid=%d, gid=%d, grouplen=%d\n",
				cred->uid, cred->gid, cred->gids.gids_len);
		} else {
			fprintf(stderr, "%s\n", strstatus(res.status));
		}
		fflush(stderr);
	}
	return (&res);
}
コード例 #4
0
ファイル: glom.c プロジェクト: muennich/rc3
static List *backq(Node *ifs, Node *n) {
	int p[2], sp;
	pid_t pid;
	List *bq;
	struct termios t;
	if (n == NULL)
		return NULL;
	if (pipe(p) < 0) {
		uerror("pipe");
		rc_error(NULL);
	}
	if (interactive)
		tcgetattr(0, &t);
	if ((pid = rc_fork()) == 0) {
		mvfd(p[1], 1);
		close(p[0]);
		redirq = NULL;
		walk(n, FALSE);
		exit(getstatus());
	}
	close(p[1]);
	bq = bqinput(glom(ifs), p[0]);
	close(p[0]);
	rc_wait4(pid, &sp, TRUE);
	if (interactive && WIFSIGNALED(sp))
		tcsetattr(0, TCSANOW, &t);
	statprint(-1, sp);
	varassign("bqstatus", word(strstatus(sp), NULL), FALSE);
	sigchk();
	return bq;
}
コード例 #5
0
interface_status_t detect_beat(int fd, char*iface) {
    interface_status_t status;
    static interface_status_t last_status = (interface_status_t) -1;

    if (disabled)
        return IFSTATUS_DOWN;
    
    if ((status = detect_beat_func(fd, iface)) == IFSTATUS_ERR)
        status = failure_status;

    if (status == IFSTATUS_ERR && detect_beat_func == detect_beat_auto)
        daemon_log(LOG_INFO, "Failed to detect plug status of %s", interface);
    
    if (status != last_status) {
        setenv(IFPLUGD_ENV_PREVIOUS, strstatus(last_status), 1);
        setenv(IFPLUGD_ENV_CURRENT, strstatus(status), 1);
        last_status = status;
    }
    
    return status;
}
コード例 #6
0
ファイル: status.c プロジェクト: Edwin-Edward/elks
extern List *sgetstatus() {
	List *r = NULL;
	int i;

	for (i = 0; i < pipelength; i++) {
		List *q = nnew(List);
		q->w = strstatus(statuses[i]);
		q->m = NULL;
		q->n = r;
		r = q;
	}

	return r;
}
コード例 #7
0
static smallint detect_link(void)
{
    smallint status;

    if (!G.iface_exists)
        return (option_mask32 & FLAG_MONITOR) ? IFSTATUS_DOWN : IFSTATUS_ERR;

    /* Some drivers can't detect link status when the interface is down.
     * I imagine detect_link_iff() is the most vulnerable.
     * That's why -a "noauto" in an option, not a hardwired behavior.
     */
    if (!(option_mask32 & FLAG_NO_AUTO))
        up_iface();

    status = G.detect_link_func();
    if (status == IFSTATUS_ERR) {
        if (option_mask32 & FLAG_IGNORE_FAIL)
            status = IFSTATUS_DOWN;
        if (option_mask32 & FLAG_IGNORE_FAIL_POSITIVE)
            status = IFSTATUS_UP;
    }

    if (status == IFSTATUS_ERR
            && G.detect_link_func == detect_link_auto
       ) {
        bb_error_msg("failed to detect link status");
    }

    if (status != G.iface_last_status) {
//TODO: is it safe to repeatedly do this?
        setenv(IFPLUGD_ENV_PREVIOUS, strstatus(G.iface_last_status), 1);
        setenv(IFPLUGD_ENV_CURRENT, strstatus(status), 1);
        G.iface_last_status = status;
    }

    return status;
}
コード例 #8
0
ファイル: keyserv.c プロジェクト: AhmadTux/DragonFlyBSD
keystatus *
key_set_1_svc_prog(uid_t uid, keybuf key)
{
	static keystatus status;

	if (debugging) {
		fprintf(stderr, "set(%ld, %.*s) = ", uid,
				(int) sizeof (keybuf), key);
	}
	status = pk_setkey(uid, key);
	if (debugging) {
		fprintf(stderr, "%s\n", strstatus(status));
		fflush(stderr);
	}
	return (&status);
}
コード例 #9
0
ファイル: keyserv.c プロジェクト: AhmadTux/DragonFlyBSD
keystatus *
key_net_put_2_svc_prog(uid_t uid, key_netstarg *arg)
{
	static keystatus status;

	if (debugging) {
		fprintf(stderr, "net_put(%s, %.*s, %.*s) = ",
			arg->st_netname, (int)sizeof (arg->st_pub_key),
			arg->st_pub_key, (int)sizeof (arg->st_priv_key),
			arg->st_priv_key);
	};

	status = pk_netput(uid, arg);

	if (debugging) {
		fprintf(stderr, "%s\n", strstatus(status));
		fflush(stderr);
	}

	return (&status);
}
コード例 #10
0
ファイル: write_reponse.hpp プロジェクト: rmokerone/avbot
	async_write_response_op(Stream & stream, int status, const response_opts & _opts,
							Handler handler)
		: m_stream(stream), m_handler(handler)
	{
		response_opts opts = _opts;
		m_headers = boost::make_shared<boost::asio::streambuf>();
		std::ostream out(m_headers.get());

		if (opts.find(avhttpd::http_options::http_version)=="HTTP/1.1")
			out << "HTTP/1.1 ";
		else out <<  "HTTP ";

		opts.remove(avhttpd::http_options::http_version);

		out <<  status <<  " " << strstatus(status)  << "\r\n";

		if (opts.size())
			out  <<  opts.header_string();
		out <<  "\r\n";

		boost::asio::async_write(m_stream, *m_headers, *this);
	};
コード例 #11
0
ファイル: keyserv.c プロジェクト: AhmadTux/DragonFlyBSD
cryptkeyres *
key_get_conv_2_svc_prog(uid_t uid, keybuf arg)
{
	static cryptkeyres  res;

	if (debugging)
		fprintf(stderr, "get_conv(%ld, %.*s) = ", uid,
			(int)sizeof (arg), arg);


	res.status = pk_get_conv_key(uid, arg, &res);

	if (debugging) {
		if (res.status == KEY_SUCCESS) {
			fprintf(stderr, "%08x%08x\n",
				res.cryptkeyres_u.deskey.key.high,
				res.cryptkeyres_u.deskey.key.low);
		} else {
			fprintf(stderr, "%s\n", strstatus(res.status));
		}
		fflush(stderr);
	}
	return (&res);
}
コード例 #12
0
ファイル: ifplugd.c プロジェクト: ArcSung/busybox-1.22.1
int ifplugd_main(int argc UNUSED_PARAM, char **argv)
{
	int iface_status;
	int delay_time;
	const char *iface_status_str;
	struct pollfd netlink_pollfd[1];
	unsigned opts;
	const char *api_mode_found;
#if ENABLE_FEATURE_PIDFILE
	char *pidfile_name;
	pid_t pid_from_pidfile;
#endif

	INIT_G();

	opt_complementary = "t+:u+:d+";
	opts = getopt32(argv, OPTION_STR,
		&G.iface, &G.script_name, &G.poll_time, &G.delay_up,
		&G.delay_down, &G.api_mode, &G.extra_arg);
	G.poll_time *= 1000;

	applet_name = xasprintf("ifplugd(%s)", G.iface);

#if ENABLE_FEATURE_PIDFILE
	pidfile_name = xasprintf(CONFIG_PID_FILE_PATH "/ifplugd.%s.pid", G.iface);
	pid_from_pidfile = read_pid(pidfile_name);

	if (opts & FLAG_KILL) {
		if (pid_from_pidfile > 0)
			/* Upstream tool use SIGINT for -k */
			kill(pid_from_pidfile, SIGINT);
		return EXIT_SUCCESS;
	}

	if (pid_from_pidfile > 0 && kill(pid_from_pidfile, 0) == 0)
		bb_error_msg_and_die("daemon already running");
#endif

	api_mode_found = strchr(api_modes, G.api_mode[0]);
	if (!api_mode_found)
		bb_error_msg_and_die("unknown API mode '%s'", G.api_mode);
	G.api_method_num = api_mode_found - api_modes;

	if (!(opts & FLAG_NO_DAEMON))
		bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv);

	xmove_fd(xsocket(AF_INET, SOCK_DGRAM, 0), ioctl_fd);
	if (opts & FLAG_MONITOR) {
		struct sockaddr_nl addr;
		int fd = xsocket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);

		memset(&addr, 0, sizeof(addr));
		addr.nl_family = AF_NETLINK;
		addr.nl_groups = RTMGRP_LINK;
		addr.nl_pid = getpid();

		xbind(fd, (struct sockaddr*)&addr, sizeof(addr));
		xmove_fd(fd, netlink_fd);
	}

	write_pidfile(pidfile_name);

	/* this can't be moved before socket creation */
	if (!(opts & FLAG_NO_SYSLOG)) {
		openlog(applet_name, 0, LOG_DAEMON);
		logmode |= LOGMODE_SYSLOG;
	}

	bb_signals(0
		| (1 << SIGINT )
		| (1 << SIGTERM)
		| (1 << SIGQUIT)
		| (1 << SIGHUP ) /* why we ignore it? */
		/* | (1 << SIGCHLD) - run_script does not use it anymore */
		, record_signo);

	bb_error_msg("started: %s", bb_banner);

	if (opts & FLAG_MONITOR) {
		struct ifreq ifrequest;
		set_ifreq_to_ifname(&ifrequest);
		G.iface_exists = (network_ioctl(SIOCGIFINDEX, &ifrequest, NULL) == 0);
	}

	if (G.iface_exists)
		maybe_up_new_iface();

	iface_status = detect_link();
	if (iface_status == IFSTATUS_ERR)
		goto exiting;
	iface_status_str = strstatus(iface_status);

	if (opts & FLAG_MONITOR) {
		bb_error_msg("interface %s",
			G.iface_exists ? "exists"
			: "doesn't exist, waiting");
	}
	/* else we assume it always exists, but don't mislead user
	 * by potentially lying that it really exists */

	if (G.iface_exists) {
		bb_error_msg("link is %s", iface_status_str);
	}

	if ((!(opts & FLAG_NO_STARTUP)
	     && iface_status == IFSTATUS_UP
	    )
	 || (opts & FLAG_INITIAL_DOWN)
	) {
		if (run_script(iface_status_str) != 0)
			goto exiting;
	}

	/* Main loop */
	netlink_pollfd[0].fd = netlink_fd;
	netlink_pollfd[0].events = POLLIN;
	delay_time = 0;
	while (1) {
		int iface_status_old;
		int iface_exists_old;

		switch (bb_got_signal) {
		case SIGINT:
		case SIGTERM:
			bb_got_signal = 0;
			goto cleanup;
		case SIGQUIT:
			bb_got_signal = 0;
			goto exiting;
		default:
			bb_got_signal = 0;
			break;
		}

		if (poll(netlink_pollfd,
				(opts & FLAG_MONITOR) ? 1 : 0,
				G.poll_time
			) < 0
		) {
			if (errno == EINTR)
				continue;
			bb_perror_msg("poll");
			goto exiting;
		}

		iface_status_old = iface_status;
		iface_exists_old = G.iface_exists;

		if ((opts & FLAG_MONITOR)
		 && (netlink_pollfd[0].revents & POLLIN)
		) {
			G.iface_exists = check_existence_through_netlink();
			if (G.iface_exists < 0) /* error */
				goto exiting;
			if (iface_exists_old != G.iface_exists) {
				bb_error_msg("interface %sappeared",
						G.iface_exists ? "" : "dis");
				if (G.iface_exists)
					maybe_up_new_iface();
			}
		}

		/* note: if !G.iface_exists, returns DOWN */
		iface_status = detect_link();
		if (iface_status == IFSTATUS_ERR) {
			if (!(opts & FLAG_MONITOR))
				goto exiting;
			iface_status = IFSTATUS_DOWN;
		}
		iface_status_str = strstatus(iface_status);

		if (iface_status_old != iface_status) {
			bb_error_msg("link is %s", iface_status_str);

			if (delay_time) {
				/* link restored its old status before
				 * we run script. don't run the script: */
				delay_time = 0;
			} else {
				delay_time = monotonic_sec();
				if (iface_status == IFSTATUS_UP)
					delay_time += G.delay_up;
				if (iface_status == IFSTATUS_DOWN)
					delay_time += G.delay_down;
				if (delay_time == 0)
					delay_time++;
			}
		}

		if (delay_time && (int)(monotonic_sec() - delay_time) >= 0) {
			delay_time = 0;
			if (run_script(iface_status_str) != 0)
				goto exiting;
		}
	} /* while (1) */

 cleanup:
	if (!(opts & FLAG_NO_SHUTDOWN)
	 && (iface_status == IFSTATUS_UP
	     || (iface_status == IFSTATUS_DOWN && delay_time)
	    )
	) {
		setenv(IFPLUGD_ENV_PREVIOUS, strstatus(iface_status), 1);
		setenv(IFPLUGD_ENV_CURRENT, strstatus(-1), 1);
		run_script("down\0up"); /* reusing string */
	}

 exiting:
	remove_pidfile(pidfile_name);
	bb_error_msg_and_die("exiting");
}
コード例 #13
0
ファイル: cdcontrol.c プロジェクト: 2asoft/freebsd
static int
pstatus(char *arg)
{
	struct ioc_vol v;
	struct ioc_read_subchannel ss;
	struct cd_sub_channel_info data;
	int rc, trk, m, s, f;
	int what = 0;
	char *p, vmcn[(4 * 15) + 1];

	while ((p = strtok(arg, " \t"))) {
	    arg = 0;
	    if (!strncasecmp(p, "audio", strlen(p)))
		what |= STATUS_AUDIO;
	    else if (!strncasecmp(p, "media", strlen(p)))
		what |= STATUS_MEDIA;
	    else if (!strncasecmp(p, "volume", strlen(p)))
		what |= STATUS_VOLUME;
	    else {
		warnx("invalid command arguments");
		return 0;
	    }
	}
	if (!what)
	    what = STATUS_AUDIO|STATUS_MEDIA|STATUS_VOLUME;
	if (what & STATUS_AUDIO) {
	    rc = status (&trk, &m, &s, &f);
	    if (rc >= 0)
		if (verbose)
		    printf ("Audio status = %d<%s>, current track = %d, current position = %d:%02d.%02d\n",
			    rc, strstatus (rc), trk, m, s, f);
		else
		    printf ("%d %d %d:%02d.%02d\n", rc, trk, m, s, f);
	    else
		printf ("No current status info available\n");
	}
	if (what & STATUS_MEDIA) {
	    bzero (&ss, sizeof (ss));
	    ss.data = &data;
	    ss.data_len = sizeof (data);
	    ss.address_format = msf ? CD_MSF_FORMAT : CD_LBA_FORMAT;
	    ss.data_format = CD_MEDIA_CATALOG;
	    rc = ioctl (fd, CDIOCREADSUBCHANNEL, (char *) &ss);
	    if (rc >= 0) {
		printf("Media catalog is %sactive",
		    ss.data->what.media_catalog.mc_valid ? "": "in");
		if (ss.data->what.media_catalog.mc_valid &&
		    ss.data->what.media_catalog.mc_number[0])
		{
		    strvisx (vmcn, ss.data->what.media_catalog.mc_number,
			    (sizeof (vmcn) - 1) / 4, VIS_OCTAL | VIS_NL);
		    printf(", number \"%.*s\"", (int)sizeof (vmcn), vmcn);
		}
		putchar('\n');
	    } else
		printf("No media catalog info available\n");
	}
	if (what & STATUS_VOLUME) {
	    rc = ioctl (fd, CDIOCGETVOL, &v);
	    if (rc >= 0)
		if (verbose)
		    printf ("Left volume = %d, right volume = %d\n",
			    v.vol[0], v.vol[1]);
		else
		    printf ("%d %d\n", v.vol[0], v.vol[1]);
	    else
		printf ("No volume level info available\n");
	}
	return(0);
}
コード例 #14
0
ファイル: ifplugd.c プロジェクト: realdesktop/ifplug-ng
char* iface_read_state(struct rbus_t *rbus, char* buf) {
    struct interface_state *iface = rbus->native;

    return strstatus(iface->status);
};
コード例 #15
0
void work(void) {
    interface_status_t status;
    int fd = -1;
    fd_set fds;
    int sigfd;
    time_t t = 0;
    int send_retval = 1;
    int paused = 0;
    static char log_ident[256];

    snprintf(log_ident, sizeof(log_ident), "ifplugd(%s)", interface);

    daemon_log_ident = log_ident;

    daemon_log(LOG_INFO, "ifplugd "VERSION" initializing%s.", use_ifmonitor ? ", using NETLINK device monitoring" : "");

    if (daemon_pid_file_create() < 0) {
        daemon_log(LOG_ERR, "Could not create PID file %s.", daemon_pid_file_proc());
        goto finish;
    }

    if (daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, SIGCHLD, SIGUSR1, SIGUSR2, -1) < 0) {
        daemon_log(LOG_ERR, "Could not register signal handler: %s", strerror(errno));
        goto finish;
    }

    switch (api_mode) {
        case API_ETHTOOL: detect_beat_func = interface_detect_beat_ethtool; break;
        case API_MII: detect_beat_func = interface_detect_beat_mii; break;
        case API_PRIVATE: detect_beat_func = interface_detect_beat_priv; break;
        case API_WLAN: detect_beat_func = interface_detect_beat_wlan; break;
        case API_IFF: detect_beat_func = interface_detect_beat_iff; break;
            
        default:
            detect_beat_func = detect_beat_auto; 
            interface_do_message = 0;
            break;
    }

    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        daemon_log(LOG_ERR, "socket(): %s", strerror(errno));
        goto finish;
    }

    if (use_ifmonitor) {
        int b;
        if ((b = is_iface_available(fd, interface)) < 0) {
            daemon_log(LOG_ERR, "Failed to check interface availabilty!");
            goto finish;
        }
        
        disabled = !b;

        if (nlapi_open(RTMGRP_LINK) < 0)
            goto finish;

        if (ifmonitor_init(ifmonitor_cb) < 0)
            goto finish;
    } else
        disabled = 0;

    if (!disabled) {
        if (welcome_iface(fd, interface) < 0)
            goto finish;
    }

    if ((status = detect_beat(fd, interface)) == IFSTATUS_ERR)
        goto finish;
    
    daemon_log(LOG_INFO, "Initialization complete, link beat %sdetected%s.", status == IFSTATUS_UP ? "" : "not ", use_ifmonitor ? (disabled ? ", interface disabled" : ", interface enabled") : "");
    beep(status == IFSTATUS_UP ? 0 : 1);

    if ((!no_startup_script && status == IFSTATUS_UP) || initial_down)
        if (action(status) < 0)
            goto finish;

    if (send_retval && daemonize && wait_on_fork) {
        char c = status == IFSTATUS_UP ? 2 : (status == IFSTATUS_DOWN ? 3 : 1);
        daemon_retval_send(c);
        send_retval = 0;
    }

    FD_ZERO(&fds);
    sigfd = daemon_signal_fd();
    FD_SET(sigfd, &fds);

    if (use_ifmonitor)
        FD_SET(nlapi_fd, &fds);

    for (;;) {
        interface_status_t s;
        fd_set qfds = fds;
        int d;
        struct timeval tv;

        tv.tv_sec = polltime;
        tv.tv_usec = 0;
        
        if (select(FD_SETSIZE, &qfds, NULL, NULL, &tv) < 0) {
            if (errno == EINTR)
                continue;

            daemon_log(LOG_ERR, "select(): %s", strerror(errno));
            goto finish;
        }

        //daemon_log(LOG_INFO, "select()");
        
        d = disabled;
        s = status;
        
        if (use_ifmonitor) {

            if (FD_ISSET(nlapi_fd, &qfds)) {
                if (nlapi_work(0) < 0)
                    goto finish;
            }

            if (d && !disabled) {
                daemon_log(LOG_INFO, "Interface enabled");
                welcome_iface(fd, interface);
                status = IFSTATUS_DOWN;
            }
            
            if (!d && disabled) {
                daemon_log(LOG_INFO, "Interface disabled");
                status = IFSTATUS_DOWN;
            }
        }
            

        if (!paused && !disabled) {
            //daemon_log(LOG_INFO, "detect");
            if ((status = detect_beat(fd, interface)) == IFSTATUS_ERR) {
                if (!use_ifmonitor)
                    goto finish;

                status = IFSTATUS_DOWN;
            }
        }

        if (status != s) {
            daemon_log(LOG_INFO, "Link beat %s.", status == IFSTATUS_DOWN ? "lost" : "detected");
            beep(status == IFSTATUS_UP ? 0 : 1);
            
            if (t)
                t = 0;
            else {
                t = time(NULL);
                
                if (status == IFSTATUS_UP)
                    t += delay_up;
                
                if (status == IFSTATUS_DOWN)
                    t += delay_down;
            }
        }

        if (FD_ISSET(sigfd, &qfds)) {
            int sig;

            if ((sig = daemon_signal_next()) < 0) {
                daemon_log(LOG_ERR, "daemon_signal_next(): %s", strerror(errno));
                goto finish;
            }

            switch (sig) {

                case SIGINT:
                case SIGTERM:
                    goto cleanup;
                    
                case SIGQUIT:
                    goto finish;
                    
                case SIGCHLD:
                    break;

                case SIGHUP:
                    daemon_log(LOG_INFO, "SIGHUP: %s, link detected on %s: %s", paused ? "Suspended" : "Running", interface, status == IFSTATUS_DOWN ? "no" : "yes");

                    if (use_ifmonitor)
                        daemon_log(LOG_INFO, "SIGHUP: Interface %s", disabled ? "disabled" : "enabled");
                    break;
                    
                case SIGUSR1:
                    daemon_log(LOG_INFO, "SIGUSR1: Daemon suspended (#%i)", ++paused);
                    break;

                case SIGUSR2:
                    if (paused > 0) {
                        daemon_log(LOG_INFO, "SIGUSR2: Daemon resumed (#%i)", paused);
                        paused --;
                    }
                    
                    break;
                    
                default:
                    daemon_log(LOG_INFO, "Ignoring unknown signal %s", strsignal(sig));
                    break;
            }
        }

        if (t && t < time(NULL)) {
            t = 0;

            if (action(status) < 0)
                goto finish;
        }
    }

cleanup:
    if (!no_shutdown_script && (status == IFSTATUS_UP || (status == IFSTATUS_DOWN && t))) {
        setenv(IFPLUGD_ENV_PREVIOUS, strstatus(status), 1);
        setenv(IFPLUGD_ENV_CURRENT, strstatus(-1), 1);
        action(IFSTATUS_DOWN);
        beep(1);
    }
    
finish:

    if (fd >= 0)
        close(fd);

    if (use_ifmonitor)
        nlapi_close();
    
    if (send_retval && daemonize && wait_on_fork)
        daemon_retval_send(255);

    daemon_pid_file_remove();
    daemon_signal_done();
    
    daemon_log(LOG_INFO, "Exiting.");
}