⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shutdown.c

📁 sysvinit--linux系统下的init
💻 C
📖 第 1 页 / 共 2 页
字号:
 */void shutdown(char *halttype){	char	*args[8];	int	argp = 0;	int	do_halt = (down_level[0] == '0');	/* Warn for the last time */	warn(0);	if (dontshut) {		hardsleep(1);		stopit(0);	}	openlog("shutdown", LOG_PID, LOG_USER);	if (do_halt)  		syslog(LOG_NOTICE, "shutting down for system halt");	else		syslog(LOG_NOTICE, "shutting down for system reboot");	closelog();	/* See if we have to do it ourself. */	if (doself) fastdown();	/* Create the arguments for init. */	args[argp++] = INIT;	if (sltime) {		args[argp++] = "-t";		args[argp++] = sltime;	}	args[argp++] = down_level;	args[argp]   = (char *)NULL;	unlink(SDPID);	unlink(NOLOGIN);	/* Now execute init to change runlevel. */	sync();	init_setenv("INIT_HALT", halttype);	execv(INIT, args);	/* Oops - failed. */	fprintf(stderr, "\rshutdown: cannot execute %s\r\n", INIT);	unlink(FASTBOOT);	unlink(FORCEFSCK);	init_setenv("INIT_HALT", NULL);	openlog("shutdown", LOG_PID, LOG_USER);	syslog(LOG_NOTICE, "shutdown failed");	closelog();	exit(1);}/* *	returns if a warning is to be sent for wt */static int needwarning(int wt){	int ret;	if (wt < 10)		ret = 1;	else if (wt < 60)		ret = (wt % 15 == 0);	else if (wt < 180)		ret = (wt % 30 == 0);	else		ret = (wt % 60 == 0);	return ret;}/* *	Main program. *	Process the options and do the final countdown. */int main(int argc, char **argv){	FILE			*fp;	extern int		getopt();	extern int		optind; 	struct sigaction	sa;	struct tm		*lt;	struct stat		st;	struct utmp		*ut;	time_t			t;	uid_t			realuid;	char			*halttype;	char			*downusers[32];	char			buf[128];	char			term[UT_LINESIZE + 6];	char			*sp;	char			*when = NULL;	int			c, i, wt;	int			hours, mins;	int			didnolog = 0;	int			cancel = 0;	int			useacl = 0;	int			pid = 0;	int			user_ok = 0;	/* We can be installed setuid root (executable for a special group) */	realuid = getuid();	setuid(geteuid());	if (getuid() != 0) {  		fprintf(stderr, "shutdown: you must be root to do that!\n");  		exit(1);	}	strcpy(down_level, "1");	halttype = NULL;	/* Process the options. */	while((c = getopt(argc, argv, "HPacqkrhnfFyt:g:i:")) != EOF) {  		switch(c) {			case 'H':				halttype = "HALT";				break;			case 'P':				halttype = "POWERDOWN";				break;			case 'a': /* Access control. */				useacl = 1;				break;			case 'c': /* Cancel an already running shutdown. */				cancel = 1;				break;  			case 'k': /* Don't really shutdown, only warn.*/  				dontshut = 1;  				break;  			case 'r': /* Automatic reboot */				down_level[0] = '6';  				break;  			case 'h': /* Halt after shutdown */				down_level[0] = '0';  				break;  			case 'f': /* Don't perform fsck after next boot */  				fastboot = 1;  				break;  			case 'F': /* Force fsck after next boot */  				forcefsck = 1;  				break;			case 'n': /* Don't switch runlevels. */				doself = 1;				break;			case 't': /* Delay between TERM and KILL */				sltime = optarg;				break;			case 'y': /* Ignored for sysV compatibility */				break;			case 'g': /* sysv style to specify time. */				when = optarg;				break;			case 'i': /* Level to go to. */				if (!strchr("0156aAbBcCsS", optarg[0])) {					fprintf(stderr,					"shutdown: `%s': bad runlevel\n",					optarg);					exit(1);				}				down_level[0] = optarg[0];				break;  			default:  				usage();  				break;	  		}	}	/* Do we need to use the shutdown.allow file ? */	if (useacl && (fp = fopen(SDALLOW, "r")) != NULL) {		/* Read /etc/shutdown.allow. */		i = 0;		while(fgets(buf, 128, fp)) {			if (buf[0] == '#' || buf[0] == '\n') continue;			if (i > 31) continue;			for(sp = buf; *sp; sp++) if (*sp == '\n') *sp = 0;			downusers[i++] = strdup(buf);		}		if (i < 32) downusers[i] = 0;		fclose(fp);		/* Now walk through /var/run/utmp to find logged in users. */		while(!user_ok && (ut = getutent()) != NULL) {			/* See if this is a user process on a VC. */			if (ut->ut_type != USER_PROCESS) continue;			sprintf(term, "/dev/%.*s", UT_LINESIZE, ut->ut_line);			if (stat(term, &st) < 0) continue;#ifdef major /* glibc */			if (major(st.st_rdev) != 4 ||			    minor(st.st_rdev) > 63) continue;#else			if ((st.st_rdev & 0xFFC0) != 0x0400) continue;#endif			/* Root is always OK. */			if (strcmp(ut->ut_user, "root") == 0) {				user_ok++;				break;			}			/* See if this is an allowed user. */			for(i = 0; i < 32 && downusers[i]; i++)				if (!strncmp(downusers[i], ut->ut_user,				    UT_NAMESIZE)) {					user_ok++;					break;				}		}		endutent();		/* See if user was allowed. */		if (!user_ok) {			if ((fp = fopen(CONSOLE, "w")) != NULL) {				fprintf(fp, "\rshutdown: no authorized users "						"logged in.\r\n");				fclose(fp);			}			exit(1);		}	}	/* Read pid of running shutdown from a file */	if ((fp = fopen(SDPID, "r")) != NULL) {		fscanf(fp, "%d", &pid);		fclose(fp);	}	/* Read remaining words, skip time if needed. */	message[0] = 0;	for(c = optind + (!cancel && !when); c < argc; c++) {		if (strlen(message) + strlen(argv[c]) + 4 > MESSAGELEN)			break;  		strcat(message, argv[c]);  		strcat(message, " ");	}	if (message[0]) strcat(message, "\r\n");	/* See if we want to run or cancel. */	if (cancel) {		if (pid <= 0) {			fprintf(stderr, "shutdown: cannot find pid "					"of running shutdown.\n");			exit(1);		}		init_setenv("INIT_HALT", NULL);		if (kill(pid, SIGINT) < 0) {			fprintf(stderr, "shutdown: not running.\n");			exit(1);		}		if (message[0]) wall(message, 1, 0);		exit(0);	}  	/* Check syntax. */	if (when == NULL) {		if (optind == argc) usage();		when = argv[optind++];	}	/* See if we are already running. */	if (pid > 0 && kill(pid, 0) == 0) {		fprintf(stderr, "\rshutdown: already running.\r\n");		exit(1);	}	/* Extra check. */	if (doself && down_level[0] != '0' && down_level[0] != '6') {		fprintf(stderr,		"shutdown: can use \"-n\" for halt or reboot only.\r\n");		exit(1);	}	/* Tell users what we're gonna do. */	switch(down_level[0]) {		case '0':			strcpy(newstate, "for system halt");			break;		case '6':			strcpy(newstate, "for reboot");			break;		case '1':			strcpy(newstate, "to maintenance mode");			break;		default:			sprintf(newstate, "to runlevel %s", down_level);			break;	}	/* Create a new PID file. */	unlink(SDPID);	umask(022);	if ((fp = fopen(SDPID, "w")) != NULL) {		fprintf(fp, "%d\n", getpid());		fclose(fp);	} else if (errno != EROFS)		fprintf(stderr, "shutdown: warning: cannot open %s\n", SDPID);	/*	 *	Catch some common signals.	 */	signal(SIGQUIT, SIG_IGN);	signal(SIGCHLD, SIG_IGN);	signal(SIGHUP,  SIG_IGN);	signal(SIGTSTP, SIG_IGN);	signal(SIGTTIN, SIG_IGN);	signal(SIGTTOU, SIG_IGN);	memset(&sa, 0, sizeof(sa));	sa.sa_handler = stopit;	sigaction(SIGINT, &sa, NULL);	/* Go to the root directory */	chdir("/");	if (fastboot)  close(open(FASTBOOT,  O_CREAT | O_RDWR, 0644));	if (forcefsck) close(open(FORCEFSCK, O_CREAT | O_RDWR, 0644));	/* Alias now and take care of old '+mins' notation. */	if (!strcmp(when, "now")) strcpy(when, "0");	if (when[0] == '+') when++;	/* Decode shutdown time. */	for (sp = when; *sp; sp++) {		if (*sp != ':' && (*sp < '0' || *sp > '9'))			usage();	}	if (strchr(when, ':') == NULL) {		/* Time in minutes. */		wt = atoi(when);		if (wt == 0 && when[0] != '0') usage();	} else {		/* Time in hh:mm format. */		if (sscanf(when, "%d:%2d", &hours, &mins) != 2) usage();		if (hours > 23 || mins > 59) usage();		time(&t);		lt = localtime(&t);		wt = (60*hours + mins) - (60*lt->tm_hour + lt->tm_min);		if (wt < 0) wt += 1440;	}	/* Shutdown NOW if time == 0 */	if (wt == 0) shutdown(halttype);	/* Give warnings on regular intervals and finally shutdown. */	if (wt < 15 && !needwarning(wt)) warn(wt);	while(wt) {		if (wt <= 5 && !didnolog) {			donologin(wt);			didnolog++;		}		if (needwarning(wt)) warn(wt);		hardsleep(60);		wt--;	}	shutdown(halttype);	return 0; /* Never happens */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -