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

📄 last.c

📁 sysvinit--linux系统下的init
💻 C
📖 第 1 页 / 共 2 页
字号:
		if (len >= sizeof(domain)) len = sizeof(domain) - 1;		domain[0] = 0;		strncat(domain, p->ut_host, len);	}	if (showhost) {#if CHOP_DOMAIN		/*		 *	See if this is in our domain.		 */		if (!usedns && (s = strchr(p->ut_host, '.')) != NULL &&		     strcmp(s + 1, domainname) == 0) *s = 0;#endif		if (!altlist) {			snprintf(final, sizeof(final),				"%-8.8s %-12.12s %-16.16s "				"%-16.16s %-7.7s %-12.12s\n",				p->ut_name, utline,				domain, logintime, logouttime, length);		} else {			snprintf(final, sizeof(final), 				"%-8.8s %-12.12s %-16.16s %-7.7s %-12.12s %s\n",				p->ut_name, utline,				logintime, logouttime, length, domain);		}	} else		snprintf(final, sizeof(final),			"%-8.8s %-12.12s %-16.16s %-7.7s %-12.12s\n",			p->ut_name, utline,			logintime, logouttime, length);	/*	 *	Print out "final" string safely.	 */	for (s = final; *s; s++) {		if (*s == '\n' || (*s >= 32 && (unsigned char)*s <= 126))			putchar(*s);		else			putchar('*');	}	recsdone++;	if (maxrecs && recsdone >= maxrecs)		return 1;	return 0;}/* *	show usage */void usage(char *s){	fprintf(stderr, "Usage: %s [-num | -n num] [-f file] "			"[-t YYYYMMDDHHMMSS] "			"[-R] [-x] [-o] [username..] [tty..]\n", s);	exit(1);}time_t parsetm(char *ts){	struct tm	u = {0}, origu;	time_t		tm;	if (sscanf(ts, "%4d%2d%2d%2d%2d%2d", &u.tm_year,	    &u.tm_mon, &u.tm_mday, &u.tm_hour, &u.tm_min,	    &u.tm_sec) != 6)		return (time_t)-1;	u.tm_year -= 1900;	u.tm_mon -= 1;	u.tm_isdst = -1;	origu = u;	if ((tm = mktime(&u)) == (time_t)-1)		return tm;	/*	 *	Unfortunately mktime() is much more forgiving than	 *	it should be.  For example, it'll gladly accept	 *	"30" as a valid month number.  This behavior is by	 *	design, but we don't like it, so we want to detect	 *	it and complain.	 */	if (u.tm_year != origu.tm_year ||	    u.tm_mon != origu.tm_mon ||	    u.tm_mday != origu.tm_mday ||	    u.tm_hour != origu.tm_hour ||	    u.tm_min != origu.tm_min ||	    u.tm_sec != origu.tm_sec)		return (time_t)-1;	return tm;}int main(int argc, char **argv){  FILE *fp;		/* Filepointer of wtmp file */  struct utmp ut;	/* Current utmp entry */  struct utmp oldut;	/* Old utmp entry to check for duplicates */  struct utmplist *p;	/* Pointer into utmplist */  struct utmplist *next;/* Pointer into utmplist */  time_t lastboot = 0;  /* Last boottime */  time_t lastrch = 0;	/* Last run level change */  time_t lastdown;	/* Last downtime */  time_t begintime;	/* When wtmp begins */  int whydown = 0;	/* Why we went down: crash or shutdown */  int c, x;		/* Scratch */  struct stat st;	/* To stat the [uw]tmp file */  int quit = 0;		/* Flag */  int down = 0;		/* Down flag */  int lastb = 0;	/* Is this 'lastb' ? */  int extended = 0;	/* Lots of info. */  char *altufile = NULL;/* Alternate wtmp */  time_t until = 0;	/* at what time to stop parsing the file */  progname = mybasename(argv[0]);  /* Process the arguments. */  while((c = getopt(argc, argv, "f:n:Rxadiot:0123456789")) != EOF)    switch(c) {	case 'R':		showhost = 0;		break;	case 'x':		extended = 1;		break;	case 'n':		maxrecs = atoi(optarg);		break;	case 'o':		oldfmt = 1;		break;	case 'f':		if((altufile = malloc(strlen(optarg)+1)) == NULL) {			fprintf(stderr, "%s: out of memory\n",				progname);			exit(1);		}		strcpy(altufile, optarg);		break;	case 'd':		usedns++;		break;	case 'i':		useip++;		break;	case 'a':		altlist++;		break;	case 't':		if ((until = parsetm(optarg)) == (time_t)-1) {			fprintf(stderr, "%s: Invalid time value \"%s\"\n",				progname, optarg);			usage(progname);		}		break;	case '0': case '1': case '2': case '3': case '4':	case '5': case '6': case '7': case '8': case '9':		maxrecs = 10*maxrecs + c - '0';		break;	default:		usage(progname);		break;    }  if (optind < argc) show = argv + optind;  /*   *	Which file do we want to read?   */  if (strcmp(progname, "lastb") == 0) {	ufile = BTMP_FILE;	lastb = 1;  } else	ufile = WTMP_FILE;  if (altufile)	ufile = altufile;  time(&lastdown);  lastrch = lastdown;  /*   *	Fill in 'lastdate'   */  lastdate = lastdown;#if CHOP_DOMAIN  /*   *	Find out domainname.   *   *	This doesn't work on modern systems, where only a DNS   *	lookup of the result from hostname() will get you the domainname.   *	Remember that domainname() is the NIS domainname, not DNS.   *	So basically this whole piece of code is bullshit.   */  hostname[0] = 0;  (void) gethostname(hostname, sizeof(hostname));  if ((domainname = strchr(hostname, '.')) != NULL) domainname++;  if (domainname == NULL || domainname[0] == 0) {	hostname[0] = 0;	(void) getdomainname(hostname, sizeof(hostname));	hostname[sizeof(hostname) - 1] = 0;	domainname = hostname;	if (strcmp(domainname, "(none)") == 0 || domainname[0] == 0)		domainname = NULL;  }#endif  /*   *	Install signal handlers   */  signal(SIGINT, int_handler);  signal(SIGQUIT, quit_handler);  /*   *	Open the utmp file   */  if ((fp = fopen(ufile, "r")) == NULL) {	x = errno;	fprintf(stderr, "%s: %s: %s\n", progname, ufile, strerror(errno));	if (altufile == NULL && x == ENOENT)		fprintf(stderr, "Perhaps this file was removed by the "			"operator to prevent logging %s info.\n", progname);	exit(1);  }  /*   *	Optimize the buffer size.   */  setvbuf(fp, NULL, _IOFBF, UCHUNKSIZE);  /*   *	Read first structure to capture the time field   */  if (uread(fp, &ut, NULL) == 1)	begintime = ut.ut_time;  else {  	fstat(fileno(fp), &st);	begintime = st.st_ctime;	quit = 1;  }  /*   *	Go to end of file minus one structure   *	and/or initialize utmp reading code.   */  uread(fp, NULL, NULL);  /*   *	Read struct after struct backwards from the file.   */  while(!quit) {	if (uread(fp, &ut, &quit) != 1)		break;	if (until && until < ut.ut_time)		continue;	if (memcmp(&ut, &oldut, sizeof(struct utmp)) == 0) continue;	memcpy(&oldut, &ut, sizeof(struct utmp));	lastdate = ut.ut_time;  	if (lastb) {  		quit = list(&ut, ut.ut_time, R_NORMAL);  		continue;  	}	/*	 *	Set ut_type to the correct type.	 */	if (strncmp(ut.ut_line, "~", 1) == 0) {		if (strncmp(ut.ut_user, "shutdown", 8) == 0)			ut.ut_type = SHUTDOWN_TIME;		else if (strncmp(ut.ut_user, "reboot", 6) == 0)			ut.ut_type = BOOT_TIME;		else if (strncmp(ut.ut_user, "runlevel", 7) == 0)			ut.ut_type = RUN_LVL;	}#if 1 /*def COMPAT*/	/*	 *	For stupid old applications that don't fill in	 *	ut_type correctly.	 */	else {		if (ut.ut_type != DEAD_PROCESS &&		    ut.ut_name[0] && ut.ut_line[0] &&		    strcmp(ut.ut_name, "LOGIN") != 0)			ut.ut_type = USER_PROCESS;		/*		 *	Even worse, applications that write ghost		 *	entries: ut_type set to USER_PROCESS but		 *	empty ut_name...		 */		if (ut.ut_name[0] == 0)			ut.ut_type = DEAD_PROCESS;		/*		 *	Clock changes.		 */		if (strcmp(ut.ut_name, "date") == 0) {			if (ut.ut_line[0] == '|') ut.ut_type = OLD_TIME;			if (ut.ut_line[0] == '{') ut.ut_type = NEW_TIME;		}	}#endif	switch (ut.ut_type) {		case SHUTDOWN_TIME:			if (extended) {				strcpy(ut.ut_line, "system down");				quit = list(&ut, lastdown, R_NORMAL);			}			lastdown = lastrch = ut.ut_time;			down = 1;			break;		case OLD_TIME:		case NEW_TIME:			if (extended) {				strcpy(ut.ut_line,				ut.ut_type == NEW_TIME ? "new time" :					"old time");				quit = list(&ut, lastdown, R_TIMECHANGE);			}			break;		case BOOT_TIME:			strcpy(ut.ut_line, "system boot");			quit = list(&ut, lastdown, R_REBOOT);			down = 1;			break;		case RUN_LVL:			x = ut.ut_pid & 255;			if (extended) {				sprintf(ut.ut_line, "(to lvl %c)", x);				quit = list(&ut, lastrch, R_NORMAL);			}			if (x == '0' || x == '6') {				lastdown = ut.ut_time;				down = 1;				ut.ut_type = SHUTDOWN_TIME;			}			lastrch = ut.ut_time;			break;		case USER_PROCESS:			/*			 *	This was a login - show the first matching			 *	logout record and delete all records with			 *	the same ut_line.			 */			c = 0;			for (p = utmplist; p; p = next) {				next = p->next;				if (strncmp(p->ut.ut_line, ut.ut_line,				    UT_LINESIZE) == 0) {					/* Show it */					if (c == 0) {						quit = list(&ut, p->ut.ut_time,							R_NORMAL);						c = 1;					}					if (p->next) p->next->prev = p->prev;					if (p->prev)						p->prev->next = p->next;					else						utmplist = p->next;					free(p);				}			}			/*			 *	Not found? Then crashed, down, still			 *	logged in, or missing logout record.			 */			if (c == 0) {				if (lastboot == 0) {					c = R_NOW;					/* Is process still alive? */					if (ut.ut_pid > 0 &&					    kill(ut.ut_pid, 0) != 0 &&					    errno == ESRCH)						c = R_PHANTOM;				} else					c = whydown;				quit = list(&ut, lastboot, c);			}			/* FALLTHRU */		case DEAD_PROCESS:			/*			 *	Just store the data if it is			 *	interesting enough.			 */			if (ut.ut_line[0] == 0)				break;			if ((p = malloc(sizeof(struct utmplist))) == NULL) {				fprintf(stderr, "%s: out of memory\n",					progname);				exit(1);			}			memcpy(&p->ut, &ut, sizeof(struct utmp));			p->next  = utmplist;			p->prev  = NULL;			if (utmplist) utmplist->prev = p;			utmplist = p;			break;	}	/*	 *	If we saw a shutdown/reboot record we can remove	 *	the entire current utmplist.	 */	if (down) {		lastboot = ut.ut_time;		whydown = (ut.ut_type == SHUTDOWN_TIME) ? R_DOWN : R_CRASH;		for (p = utmplist; p; p = next) {			next = p->next;			free(p);		}		utmplist = NULL;		down = 0;	}  }  printf("\n%s begins %s", mybasename(ufile), ctime(&begintime));  fclose(fp);  /*   *	Should we free memory here? Nah. This is not NT :)   */  return 0;}

⌨️ 快捷键说明

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