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

📄 gping.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
			m->unreachable++;	}	m->seq++;}voidpingrcv(void *arg){	uchar buf[512];	Icmp *ip;	ushort x;	int i, n, fd;	vlong now;	Machine *m = arg;	ip = (Icmp*)buf;	fd = dup(m->pingfd, -1);	for(;;){		n = read(fd, buf, sizeof(buf));		now = nsec();		if(n <= 0)			continue;		if(n < MSGLEN){			print("bad len %d/%d\n", n, MSGLEN);			continue;		}		for(i = 32; i < MSGLEN; i++)			if(buf[i] != (i&0xff))				continue;		x = (ip->seq[1]<<8)|ip->seq[0];		if(ip->type != EchoReply || ip->code != 0)			continue;		lock(m);		pingclean(m, x, now, ip->ttl);		unlock(m);	}}voidinitmach(Machine *m, char *name){	char *p;	srand(time(0));	p = strchr(name, '!');	if(p){		p++;		m->name = estrdup(p+1);	}else		p = name;	m->name = estrdup(p);	m->nproc = 1;	m->pingfd = dial(netmkaddr(m->name, "icmp", "1"), 0, 0, 0);	if(m->pingfd < 0)		sysfatal("dialing %s: %r", m->name);	startproc(pingrcv, m);}ulongrttscale(ulong x){	if(x == 0)		return 0;	x = 10.0*log10(x) - 20.0;	if(x < 0)		x = 0;	return x;}ulongrttunscale(ulong x){	double dx;	x += 20;	dx = x;	return pow(10.0, dx/10.0);}voidrttval(Machine *m, long *v, long *vmax, long *mark){	ulong x;	if(m->rttmsgs == 0){		x = m->lastrtt;	} else {		x = m->rttsum/m->rttmsgs;		m->rttsum = m->rttmsgs = 0;		m->lastrtt = x;	}	*v = rttscale(x);	*vmax = Rttmax;	*mark = 0;}voidlostval(Machine *m, long *v, long *vmax, long *mark){	ulong x;	if(m->rcvdmsgs+m->lostmsgs > 0)		x = (m->lostavg>>1) + (((m->lostmsgs*100)/(m->lostmsgs + m->rcvdmsgs))>>1);	else		x = m->lostavg;	m->lostavg = x;	m->lostmsgs = m->rcvdmsgs = 0;	if(m->unreachable){		m->unreachable = 0;		*mark = 100;	} else		*mark = 0;	*v = x;	*vmax = 100;}jmp_buf catchalarm;voidalarmed(void *a, char *s){	if(strcmp(s, "alarm") == 0)		notejmp(a, catchalarm, 1);	noted(NDFLT);}voidusage(void){	fprint(2, "usage: %s machine [machine...]\n", argv0);	exits("usage");}voidaddgraph(int n){	Graph *g, *ograph;	int i, j;	static int nadd;	if(n > nelem(menu2str))		abort();	/* avoid two adjacent graphs of same color */	if(ngraph>0 && graph[ngraph-1].colindex==nadd%Ncolor)		nadd++;	ograph = graph;	graph = emalloc(nmach*(ngraph+1)*sizeof(Graph));	for(i=0; i<nmach; i++)		for(j=0; j<ngraph; j++)			graph[i*(ngraph+1)+j] = ograph[i*ngraph+j];	free(ograph);	ngraph++;	for(i=0; i<nmach; i++){		g = &graph[i*ngraph+(ngraph-1)];		memset(g, 0, sizeof(Graph));		g->label = menu2str[n]+Opwid;		g->newvalue = newvaluefn[n];		g->update = update1;	/* no other update functions yet */		g->mach = &mach[i];		g->colindex = nadd%Ncolor;	}	present[n] = 1;	nadd++;}intwhich2index(int which){	int i, n;	n = -1;	for(i=0; i<ngraph; i++){		if(strcmp(menu2str[which]+Opwid, graph[i].label) == 0){			n = i;			break;		}	}	if(n < 0){		fprint(2, "%s: internal error can't drop graph\n", argv0);		killall("error");	}	return n;}intindex2which(int index){	int i, n;	n = -1;	for(i=0; i<Nmenu2; i++){		if(strcmp(menu2str[i]+Opwid, graph[index].label) == 0){			n = i;			break;		}	}	if(n < 0){		fprint(2, "%s: internal error can't identify graph\n", argv0);		killall("error");	}	return n;}voiddropgraph(int which){	Graph *ograph;	int i, j, n;	if(which > nelem(menu2str))		abort();	/* convert n to index in graph table */	n = which2index(which);	ograph = graph;	graph = emalloc(nmach*(ngraph-1)*sizeof(Graph));	for(i=0; i<nmach; i++){		for(j=0; j<n; j++)			graph[i*(ngraph-1)+j] = ograph[i*ngraph+j];		free(ograph[i*ngraph+j].data);		freeimage(ograph[i*ngraph+j].overtmp);		for(j++; j<ngraph; j++)			graph[i*(ngraph-1)+j-1] = ograph[i*ngraph+j];	}	free(ograph);	ngraph--;	present[which] = 0;}voidaddmachine(char *name){	if(ngraph > 0){		fprint(2, "%s: internal error: ngraph>0 in addmachine()\n", argv0);		usage();	}	if(nmach == NMACH)		sysfatal("too many machines");	initmach(&mach[nmach++], name);}voidresize(void){	int i, j, n, startx, starty, x, y, dx, dy, hashdx, ondata;	Graph *g;	Rectangle machr, r;	long v, vmax, mark;	char buf[128];	draw(screen, screen->r, display->white, nil, ZP);	/* label left edge */	x = screen->r.min.x;	y = screen->r.min.y + Labspace+mediumfont->height+Labspace;	dy = (screen->r.max.y - y)/ngraph;	dx = Labspace+stringwidth(mediumfont, "0")+Labspace;	startx = x+dx+1;	starty = y;	for(i=0; i<ngraph; i++,y+=dy){		draw(screen, Rect(x, y-1, screen->r.max.x, y), display->black, nil, ZP);		draw(screen, Rect(x, y, x+dx, screen->r.max.y), cols[graph[i].colindex][0], nil, paritypt(x));		label(Pt(x, y), dy, graph[i].label);		draw(screen, Rect(x+dx, y, x+dx+1, screen->r.max.y), cols[graph[i].colindex][2], nil, ZP);	}	/* label right edge */	dx = Labspace+stringwidth(mediumfont, "0.001")+Labspace;	hashdx = dx;	x = screen->r.max.x - dx;	y = screen->r.min.y + Labspace+mediumfont->height+Labspace;	for(i=0; i<ngraph; i++,y+=dy){		draw(screen, Rect(x, y-1, screen->r.max.x, y), display->black, nil, ZP);		draw(screen, Rect(x, y, x+dx, screen->r.max.y), cols[graph[i].colindex][0], nil, paritypt(x));		hashmarks(Pt(x, y), dy, i);		draw(screen, Rect(x+dx, y, x+dx+1, screen->r.max.y), cols[graph[i].colindex][2], nil, ZP);	}	/* label top edge */	dx = (screen->r.max.x - dx - startx)/nmach;	for(x=startx, i=0; i<nmach; i++,x+=dx){		draw(screen, Rect(x-1, starty-1, x, screen->r.max.y), display->black, nil, ZP);		j = dx/stringwidth(mediumfont, "0");		n = mach[i].nproc;		if(n>1 && j>=1+3+(n>10)+(n>100)){	/* first char of name + (n) */			j -= 3+(n>10)+(n>100);			if(j <= 0)				j = 1;			snprint(buf, sizeof buf, "%.*s(%d)", j, mach[i].name, n);		}else			snprint(buf, sizeof buf, "%.*s", j, mach[i].name);		string(screen, Pt(x+Labspace, screen->r.min.y + Labspace), display->black, ZP,			mediumfont, buf);	}	/* draw last vertical line */	draw(screen,		Rect(screen->r.max.x-hashdx-1, starty-1, screen->r.max.x-hashdx, screen->r.max.y),		display->black, nil, ZP);	/* create graphs */	for(i=0; i<nmach; i++){		machr = Rect(startx+i*dx, starty, screen->r.max.x, screen->r.max.y);		if(i < nmach-1)			machr.max.x = startx+(i+1)*dx - 1;		else			machr.max.x = screen->r.max.x - hashdx - 1;		y = starty;		for(j=0; j<ngraph; j++, y+=dy){			g = &graph[i*ngraph+j];			/* allocate data */			ondata = g->ndata;			g->ndata = Dx(machr)+1;	/* may be too many if label will be drawn here; so what? */			g->data = erealloc(g->data, g->ndata*sizeof(long));			if(g->ndata > ondata)				memset(g->data+ondata, 0, (g->ndata-ondata)*sizeof(long));			/* set geometry */			g->r = machr;			g->r.min.y = y;			g->r.max.y = y+dy - 1;			if(j == ngraph-1)				g->r.max.y = screen->r.max.y;			draw(screen, g->r, cols[g->colindex][0], nil, paritypt(g->r.min.x));			g->overflow = 0;			*g->msg = 0;			freeimage(g->overtmp);			g->overtmp = nil;			g->overtmplen = 0;			r = g->r;			r.max.y = r.min.y+mediumfont->height;			n = (g->r.max.x - r.min.x)/stringwidth(mediumfont, "9");			if(n > 4){				if(n > Gmsglen)					n = Gmsglen;				r.max.x = r.min.x+stringwidth(mediumfont, "9")*n;				g->overtmplen = n;				g->overtmp = allocimage(display, r, screen->chan, 0, -1);			}			g->newvalue(g->mach, &v, &vmax, &mark);			redraw(g, vmax);		}	}	flushimage(display, 1);}voideresized(int new){	lockdisplay(display);	if(new && getwindow(display, Refnone) < 0) {		fprint(2, "%s: can't reattach to window\n", argv0);		killall("reattach");	}	resize();	unlockdisplay(display);}voiddobutton2(Mouse *m){	int i;	for(i=0; i<Nmenu2; i++)		if(present[i])			memmove(menu2str[i], "drop ", Opwid);		else			memmove(menu2str[i], "add  ", Opwid);	i = emenuhit(3, m, &menu2);	if(i >= 0){		if(!present[i])			addgraph(i);		else if(ngraph > 1)			dropgraph(i);		resize();	}}voiddobutton1(Mouse *m){	int i, n, dx, dt;	Graph *g;	char *e;	double f;	for(i = 0; i < ngraph*nmach; i++){		if(ptinrect(m->xy, graph[i].r))			break;	}	if(i == ngraph*nmach)		return;	g = &graph[i];	if(g->overtmp == nil)		return;	// clear any previous message and cursor	if(g->overflow || *g->msg){		clearmsg(g);		*g->msg = 0;		clearcursor(g);	}	dx = g->r.max.x - m->xy.x;	g->cursor = dx;	dt = dx*pinginterval;	e = &g->msg[sizeof(g->msg)];	seprint(g->msg, e, "%s", ctime(starttime-dt/1000)+11);	g->msg[8] = 0;	n = 8;	switch(index2which(i)){	case Mrtt:		f = rttunscale(g->data[dx]);		seprint(g->msg+n, e, " %3.3g", f/1000000);		break;	case Mlost:		seprint(g->msg+n, e, " %d%%", g->data[dx]);		break;	}	drawmsg(g, g->msg);	drawcursor(g, m->xy.x);}voidmouseproc(void*){	Mouse mouse;	for(;;){		mouse = emouse();		if(mouse.buttons == 4){			lockdisplay(display);			dobutton2(&mouse);			unlockdisplay(display);		} else if(mouse.buttons == 1){			lockdisplay(display);			dobutton1(&mouse);			unlockdisplay(display);		}	}}voidstartproc(void (*f)(void*), void *arg){	int pid;	switch(pid = rfork(RFPROC|RFMEM|RFNOWAIT)){	case -1:		fprint(2, "%s: fork failed: %r\n", argv0);		killall("fork failed");	case 0:		f(arg);		killall("process died");		exits(nil);	}	pids[npid++] = pid;}voidmain(int argc, char *argv[]){	int i, j;	long v, vmax, mark;	char flags[10], *f, *p;	fmtinstall('V', eipfmt);	f = flags;	pinginterval = 5000;		// 5 seconds	ARGBEGIN{	case 'i':		p = ARGF();		if(p == nil)			usage();		pinginterval = atoi(p);		break;	default:		if(f - flags >= sizeof(flags)-1)			usage();		*f++ = ARGC();		break;	}ARGEND	*f = 0;	for(i=0; i<argc; i++)		addmachine(argv[i]);	for(f = flags; *f; f++)		switch(*f){		case 'l':			addgraph(Mlost);			break;		case 'r':			addgraph(Mrtt);			break;		}	if(nmach == 0)		usage();	if(ngraph == 0)		addgraph(Mrtt);	for(i=0; i<nmach; i++)		for(j=0; j<ngraph; j++)			graph[i*ngraph+j].mach = &mach[i];	if(initdraw(nil, nil, argv0) < 0){		fprint(2, "%s: initdraw failed: %r\n", argv0);		exits("initdraw");	}	colinit();	einit(Emouse);	notify(nil);	startproc(mouseproc, 0);	display->locking = 1;	/* tell library we're using the display lock */	resize();	starttime = time(0);	unlockdisplay(display); /* display is still locked from initdraw() */	for(j = 0; ; j++){		lockdisplay(display);		if(j == nmach){			parity = 1-parity;			j = 0;			for(i=0; i<nmach*ngraph; i++){				graph[i].newvalue(graph[i].mach, &v, &vmax, &mark);				graph[i].update(&graph[i], v, vmax, mark);			}			starttime = time(0);		}		flushimage(display, 1);		unlockdisplay(display);		pingsend(&mach[j%nmach]);		sleep(pinginterval/nmach);	}}

⌨️ 快捷键说明

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