File:  [ELWIX - Embedded LightWeight unIX -] / embedtools / src / wdog.c
Revision 1.1.2.6: download - view: text, annotated - select for diffs - revision graph
Mon Oct 18 11:20:37 2010 UTC (13 years, 8 months ago) by misho
Branches: tools1_0
add feature for infinit loop

    1: /*************************************************************************
    2:  * (C) 2010 AITNET - Sofia/Bulgaria - <office@aitbg.com>
    3:  *  by Michael Pounov <misho@aitbg.com>
    4:  *
    5:  * $Author: misho $
    6:  * $Id: wdog.c,v 1.1.2.6 2010/10/18 11:20:37 misho Exp $
    7:  *
    8:  *************************************************************************/
    9: #include "global.h"
   10: 
   11: 
   12: int Verbose, Kill;
   13: extern char compiled[], compiledby[], compilehost[];
   14: 
   15: 
   16: static void
   17: Usage()
   18: {
   19: 
   20: 	printf(	"WatchDog tool for risk process managment\n"
   21: 		"=== %s === %s@%s ===\n\n"
   22: 		"  Syntax: wdog [options] [exec_file]\n\n"
   23: 		"\t-v\t\tVerbose ...\n"
   24: 		"\t-c <dir>\tBefore execute chroot to dir [default=/]\n"
   25: 		"\t-u <user>\tBefore execute change user\n"
   26: 		"\t-P\t\tInfinit loop, bypass penalty timeout\n"
   27: 		"\n", compiled, compiledby, compilehost);
   28: }
   29: 
   30: static void
   31: sigHand(int sig)
   32: {
   33: 	int stat;
   34: 
   35: 	switch (sig) {
   36: 		case SIGTERM:
   37: 			Kill++;
   38: 			break;
   39: 		case SIGCHLD:
   40: 			while (waitpid(-1, &stat, WNOHANG) > 0);
   41: 			break;
   42: 	}
   43: }
   44: 
   45: 
   46: int
   47: main(int argc, char **argv)
   48: {
   49: 	char ch, bypass = 0, szChroot[MAXPATHLEN] = "/";
   50: 	int status = 0, ret = 1;
   51: 	struct sigaction sa;
   52: 	struct passwd *pass = NULL;
   53: 	uid_t uid = getuid();
   54: 	u_int penalty = 1;
   55: 
   56: 	while ((ch = getopt(argc, argv, "vhPc:u:")) != -1)
   57: 		switch (ch) {
   58: 			case 'v':
   59: 				Verbose++;
   60: 				break;
   61: 			case 'P':
   62: 				bypass = 1;
   63: 				break;
   64: 			case 'c':
   65: 				if (uid) {
   66: 					printf("Error:: can`t chroot, please run as root!\n");
   67: 					goto end;
   68: 				}
   69: 				if (access(optarg, R_OK)) {
   70: 					printf("Error:: can`t chroot to %s #%d - %s\n", optarg, 
   71: 							errno, strerror(errno));
   72: 					goto end;
   73: 				} else
   74: 					strlcpy(szChroot, optarg, MAXPATHLEN);
   75: 				status |= 1;
   76: 				break;
   77: 			case 'u':
   78: 				if (uid) {
   79: 					printf("Error:: can`t setuid, please run as root!\n");
   80: 					goto end;
   81: 				}
   82: 				pass = getpwnam(optarg);
   83: 				if (!pass) {
   84: 					printf("Error:: can`t find user %s\n", optarg);
   85: 					goto end;
   86: 				} else
   87: 					uid = pass->pw_uid;
   88: 				endpwent();
   89: 				status |= 2;
   90: 				break;
   91: 			case 'h':
   92: 			default:
   93: 				Usage();
   94: 				goto end;
   95: 		}
   96: 	argc -= optind;
   97: 	argv += optind;
   98: 	if (!argc || !argv || !*argv) {
   99: 		Usage();
  100: 		goto end;
  101: 	} else
  102: 		VERB(2) printf("Info:: Chroot=%s Run=%s\n", szChroot, *argv);
  103: 
  104: 	memset(&sa, 0, sizeof sa);
  105: 	sa.sa_handler = sigHand;
  106: 	sigemptyset(&sa.sa_mask);
  107: 	sigaction(SIGTERM, &sa, NULL);
  108: 	sigaction(SIGCHLD, &sa, NULL);
  109: 	sa.sa_handler = SIG_IGN;
  110: 	sigaction(SIGHUP, &sa, NULL);
  111: 	sigaction(SIGINT, &sa, NULL);
  112: 	sigaction(SIGQUIT, &sa, NULL);
  113: 	sigaction(SIGPIPE, &sa, NULL);
  114: 	sigaction(SIGTSTP, &sa, NULL);
  115: 	sigaction(SIGSTOP, &sa, NULL);
  116: 	VERB(5) printf("Info:: Catched signals ...\n");
  117: 
  118: 	if (status & 1 && (ret = chroot(szChroot)) == -1) {
  119: 		printf("Error:: error in chroot to %s #%d - %s\n", szChroot, errno, strerror(errno));
  120: 		ret = 3;
  121: 		goto end;
  122: 	} else
  123: 		VERB(1) printf("Info:: chrooted to %s\n", szChroot);
  124: 
  125: 	if (status & 2 && setuid(uid) == -1) {
  126: 		printf("Error:: error in setuid to %u #%d - %s\n", uid, errno, strerror(errno));
  127: 		ret = 4;
  128: 		goto end;
  129: 	} else
  130: 		VERB(1) printf("Info:: setuid to %u\n", uid);
  131: 
  132: 	status ^= status;
  133: 	while (!Kill && penalty) {
  134: 		switch ((ret = fork())) {
  135: 			case -1:
  136: 				printf("Error:: error in fork #%d - %s\n", errno, strerror(errno));
  137: 				ret = 5;
  138: 				goto end;
  139: 			case 0:
  140: 				VERB(3) printf("Info:: I`m child of shadows ...\n");
  141: 				if (execvp(*argv, argv) == -1) {
  142: 					printf("Error:: error in exec %s #%d - %s\n", 
  143: 							*argv, errno, strerror(errno));
  144: 					ret = 6;
  145: 					goto end;
  146: 				}
  147: 				/* never reached !!! */
  148: 				break;
  149: 			default:
  150: 				wait(&status);
  151: 				kill(ret, SIGTERM);
  152: 				ret = status;
  153: 		}
  154: 		/* penalty timeout retry */
  155: 		usleep(penalty);
  156: 		if (!bypass) {
  157: 			penalty <<= 1;
  158: 			VERB(2) printf("Info:: penalty timeout %u microseconds\n", penalty);
  159: 		}
  160: 	}
  161: 	if (!penalty)
  162: 		ret = 9;
  163: end:
  164: 	return ret;
  165: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>