• R/O
  • HTTP
  • SSH
  • HTTPS

Tags
Aucun tag

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

oga's tools


File Info

Révision d66ca5f0860741c4abc315dd1a4dbffc3b2dba14
Taille 13,468 octets
l'heure 2025-01-24 07:45:56
Auteur hyperoga
Message de Log

addimgdate: support prefix v2

Content

/*
 *  xpstat : デーモン起動状態監視ツール
 *
 *      defailt  : for Linux
 *      -DH3050R : for HI-UX/WE2 and HP-UX
 *
 *	V1.00  96/10/30  by oga.
 *	V1.01  96/10/30  -fn support and wait time adjust
 *	V1.02  96/10/31  -fs, -n support
 *	V1.03  96/11/06  .xpstat comment, -x, -y, -l  support
 *	V1.04  14/05/01  fix open argument
 *
 */
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <signal.h>
#include <fcntl.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdlib.h>
#include <string.h>

#define VER		"1.04"
#define MAXPRC		64
#define BARLEN		12
#define MAXBARLEN	30
#define LOADTITLE	"Load ave."
#define AVEKEY		"average: "

/* process info */
typedef struct pst {
	char procname[256];	/* process name		*/
	char name[256];		/* display process name */
	char active;		/* 0:inactive  1:active */
	char cnt;		/* bar length		*/
} ps_t;

/* globals */
Display *d;
Window  w;
GC      ggreen,gwhite,gblack,gred,gskblue,gyellow;
int	xx, yy;
int	refresh = 0;		/* -r spcify flag (black refresh option) */
int	kaif    = 0;		/* -k spcify flag (kainuma option)       */
int	vuef    = 0;		/* -vue spcify flag (for VUE option)     */
int	lf      = 0;		/* -l spcify flag (load average)         */
int	nf      = 0;		/* -n spcify flag (number of procs)      */
int	loadave = 0;		/* load average */
char	fontn[256];		/* font name	*/
char	tmpf[256];		/* tmp filename */

int	BX = 10;	/* mini : 8  */
int	BY = 15;	/* mini : 12 */

void usage()
{
    printf("\n");
    printf(" xpstat Ver %s\n",VER);
    printf("\n");
    printf("   usage : xpstat [{ -f <proc_file> | procname1 procname2 ...}]\n");
    printf("\n");
    printf("   # <proc_file> is following format.\n");
    printf("   procname1[:name1]\n");
    printf("   procname2[:name2]\n");
    printf("       :        :   \n\n");
    printf("   # null line is a separator\n");
    printf("   # default <proc_file> is $HOME/.xpstat\n");
    printf("       -n   : level meter is number of processes\n");
    printf("       -x   : level meter block width\n");
    printf("       -y   : level meter block height\n");
    printf("       -l   : display load average\n");
    printf("       -fn  : set font name<%s>\n",fontn);
    printf("       -fs  : set font size<7>\n");
#if 0
    printf("       -vue : string color blue\n");
    printf("       -k   : kainuma option (display only one block)\n");
    printf("       -r   : refresh/always fill black\n");
#endif
    printf("\n Copyright(C)1996, Moritaka Ogasawara. All Rights Reserved.\n\n");
}

/*
 *   監視するプロセス名ファイル(.xpstat)を読み込む
 */
void getprocs(prc,num,filen,maxlen)
ps_t *prc;
int  *num, *maxlen;
char *filen;
{
	FILE *fp;
	int  i,j;
	char buf[1024];

	if (!(fp = fopen(filen,"r"))) {
	    sprintf(buf,"read %s",filen);
	    perror(buf);
	    usage();
	    exit(1);
	}
	while (fgets(buf,sizeof(buf),fp)) {
	    if (buf[0] == '#') {
		/* skip comment line */
	    	continue;
	    }
	    if (buf[strlen(buf)-1] == 0xa) {
	    	buf[strlen(buf)-1] = '\0';
	    }
	    i=0;
	    while (buf[i] != ':' && buf[i] != '\0') {
	    	prc[*num].procname[i] = buf[i];
		i++;
	    }
	    j=0;
	    if (buf[i] == ':') {
	        i++;
	        while (buf[i] != ':' && buf[i] != '\0') {
	    	    prc[*num].name[j] = buf[i];
		    i++;
		    j++;
	        }
	    } else {
	    	strcpy(prc[*num].name, prc[*num].procname);
	    }
            if (*maxlen < strlen(prc[*num].name)) {
            	*maxlen = strlen(prc[*num].name);
            }
#ifdef DEBUG
	    fprintf(stderr,"procname=[%s]\t/ name=[%s]\n",
	    				prc[*num].procname,prc[*num].name);
#endif
	    ++(*num);
	}
	fclose(fp);
}

/*
 *   レベルメータを表示する。 
 */
void dispbar(x,y,len)
int x,y,len;
{
	int i, barlen;

	if (nf) {
	    barlen = MAXBARLEN;
	} else {
	    barlen = BARLEN;
	}

	for (i = 0; i<barlen; i++) {
	    if (i < len) {
	        if (i < 9) {
	            /* green level */
	            XFillRectangle(d,w,ggreen,x+i*BX, y, BX-2, BY-2);
		    if (kaif) break;	/* 1個だけ表示 */
	        } else {
	            /* red zone */
	            XFillRectangle(d,w,gred,x+i*BX, y, BX-2, BY-2);
	        }
	    } else {
	        XFillRectangle(d,w,gblack,x+i*BX, y, BX-2, BY-2);
		if (kaif) break;	/* 1個だけ表示 */
	    } 
	}
}

/*
 *    監視プロセス情報を表示する
 */
void dispall(prc,num,strarea)
ps_t *prc;
int  num,strarea;
{
	int i, nfbk;

	if (refresh) {
	    /* fill black for VUE */
	    XFillRectangle(d,w,gblack,0,0,xx,yy);
	}

	if (lf) {
	    /* display load average line */
	    XDrawString(d, w, gyellow, 3, BY, LOADTITLE, strlen(LOADTITLE));
	    nfbk = nf;
	    nf = 1;		/* MAXBARLEN 使用 */
	    dispbar(strarea,2,(loadave*3)/100 +1);
	    nf = nfbk;
	}
	for(i = 0; i<num; i++) {
	    if (strlen(prc[i].procname)) {
	        /* draw process name */
	        XDrawString(d, w, gwhite, 3, (i+lf)*BY+BY,
	        			prc[i].name,strlen(prc[i].name));
		if (nf) {
		    /* length is number of procs */
	            dispbar(strarea,(i+lf)*BY+2,prc[i].active);/* disp meter */
		} else {
	            dispbar(strarea,(i+lf)*BY+2,prc[i].cnt);   /* disp meter */
		}
	    } else {
	        /* draw separate line */
	        XFillRectangle(d, w, gskblue, 3, (i+lf)*BY+BY/2+2,
	        				strarea+BX*MAXBARLEN-6,1);
	    }
	}
	XFlush(d);
}

unsigned long MyColor(display,color)
Display *display;
char *color;
{
	Colormap cmap;
	XColor c0,c1;
	int code;

	cmap = DefaultColormap(display,0);

	code = XAllocNamedColor(display,cmap,color,&c1,&c0);
	if (code)
		return(c1.pixel);
	else
		return((unsigned long)-1);
}

/* 
 *    get load average
 *
 *    IN  : buf ... uptime output
 *    OUT : ret ... load average x 100
 */
int get_loadave(buf)
char *buf;
{
	char *pt;
	char wkbuf[16];
	int  i=0;

	pt = (char *)strstr(buf,AVEKEY);/* search "average: " */

	pt += strlen(AVEKEY);		/* move pointer to X.XX */
	while (*pt != ' ') {
	    if (*pt != '.') {		/* skip . */
	        wkbuf[i] = *pt;
		i++;
	    }
	    pt++;
	}
	wkbuf[i] = '\0';

#ifdef DEBUG
	fprintf(stderr,"load ave = %s\n",wkbuf);
#endif
	return(atoi(wkbuf));
}

void sigcatch()
{
	unlink(tmpf);
	exit(1);
}

/*
 *   MAIN routine
 */
void main(a,b)
int a;
char *b[];
{
        FILE *fp;
        int fd;
        int num= 0, i, j, strarea = 0;
        int ff = 0;			/* -f spcify flag */
        int fnsize = 7;			/* font width     */
        int x_home=0,y_home=0;
        char buf[1024], filen[256];
        char *pt;
        ps_t prc[MAXPRC];
        struct timeval  tv, tv2, tv3;
        struct timezone tz;

	/* for Window */
	Font	font;
        XSetWindowAttributes att;
        unsigned long green,red,skblue,yellow,white,black;

	memset(prc,0,sizeof(ps_t)*MAXPRC);
	gettimeofday(&tv2,&tz);		/* init */

	/* default font name */
#ifdef H3050R
	strcpy(fontn,"7x13bold");
#else  /* Linux */
	strcpy(fontn,"7x14bold");
#endif

	/* get args */
        for (i=1; i<a; i++) {
            if (!strncmp(b[i],"-h",2)) {
            	usage();
        	exit(1);
            }
            if (!strcmp(b[i],"-f")) {
            	ff = 1;
            	i++;
            	strcpy(filen,b[i]);
            	continue;
            }
	    if (!strncmp(b[i],"-g",2) && a > i) {
		strcpy(buf,b[++i]);
		if (pt =(char *) strtok(buf,"+"))  x_home = atoi(pt);
		if (pt =(char *) strtok(NULL,"+")) y_home = atoi(pt);
		/* printf("x=%d / y=%d\n",x_home,y_home); */
		continue;
	    }
            if (!strncmp(b[i],"-r",2)) {
		refresh = 1;	/* VUE用にいちいち黒く塗る(注)ちかちかする*/
		continue;
            }
            if (!strncmp(b[i],"-k",2)) {
		kaif = 1;	/* 1 個のみ表示 海沼の好み */
		continue;
            }
            if (!strncmp(b[i],"-v",2)) {
		vuef = 1;	/* 文字の色を青にする for VUE */
		continue;
            }
            if (!strcmp(b[i],"-fn")) {
		if (++i < a) {
		    strcpy(fontn,b[i]);
		} else {
		    printf("specify font name!\n");
		}
		continue;
            }
            if (!strcmp(b[i],"-fs")) {
		if (++i < a) {
		    fnsize = atoi(b[i]);
		} else {
		    printf("specify font size!\n");
		}
		continue;
            }
            if (!strcmp(b[i],"-l")) {
		lf = 1;		/* load average 表示 */
		continue;
            }
            if (!strcmp(b[i],"-n")) {
		nf = 1;		/* レベルメータはプロセス数 */
		continue;
            }
            if (!strcmp(b[i],"-x")) {
		if (++i < a) {
		    BX = atoi(b[i]);
		} else {
		    printf("specify block width!\n");
		}
		continue;
            }
            if (!strcmp(b[i],"-y")) {
		if (++i < a) {
		    BY = atoi(b[i]);
		} else {
		    printf("specify block height!\n");
		}
		continue;
            }
            strcpy(prc[num].procname,b[i]);
            strcpy(prc[num].name,b[i]);
            if (strarea < strlen(prc[num].name)) {
            	strarea = strlen(prc[num].name);
            }
            num++;
            /* clear arg area */
            memset(b[i],0,strlen(b[i]));
        }

	/* read proc name */
	if (!ff) {
	    sprintf(filen,"%s/.xpstat",getenv("HOME"));
	} 
	if (!num) {
	    getprocs(prc,&num,filen,&strarea);
	}
	if (lf) {
	    if (strarea < strlen(LOADTITLE)) {
		strarea = strlen(LOADTITLE);
	    }
	}
	strarea = strarea*fnsize+7;	/* proc name area length */

	d = XOpenDisplay(NULL);

	green  = MyColor(d,"green");
	red    = MyColor(d,"red");
	skblue = MyColor(d,"orange");
	yellow = MyColor(d,"yellow");

	if (vuef) {
	    white  = MyColor(d,"blue");
	} else {
	    white  = MyColor(d,"white");
	}
	black  = MyColor(d,"Black");

	xx = strarea+BX*BARLEN+3;
	yy = num*BY+5;

	w = XCreateSimpleWindow(d, RootWindow (d,0),
			x_home,y_home, 			   /* home x,y        */
			strarea+BX*BARLEN+3, (num+lf)*BY+5,/* window size x,y */
			1,              		   /* border_width    */
			1,              		   /* border          */
			0   );          		   /* background      */

	att.override_redirect = 0;         /* Window Manager 介入あり ... 0 */
                                           /*                    なし ... 1 */

	sprintf(buf,"xpstat %s",VER);
	XStoreName(d,w,buf);

	XChangeWindowAttributes(d,w,CWOverrideRedirect,&att);
	XMapWindow(d,w);

	ggreen   = XCreateGC(d,w,0,0);           /* create gc   */
	gred     = XCreateGC(d,w,0,0);           /* create gc   */
	gwhite   = XCreateGC(d,w,0,0);           /* create gc   */
	gblack   = XCreateGC(d,w,0,0);           /* create gc   */
	gskblue  = XCreateGC(d,w,0,0);           /* create gc   */
	gyellow  = XCreateGC(d,w,0,0);           /* create gc   */

	XSetForeground(d,ggreen  ,green);        /* set color to gc  */
	XSetForeground(d,gred    ,red);          /* set color to gc  */
	XSetForeground(d,gwhite  ,white);        /* set color to gc  */
	XSetBackground(d,gwhite  ,black);        /* set back color to gc  */
	XSetForeground(d,gblack  ,black);        /* set color to gc  */
	XSetForeground(d,gskblue ,skblue);       /* set color to gc  */
	XSetForeground(d,gyellow ,yellow);       /* set color to gc  */

	/* load font and set */
	font = XLoadFont(d, fontn);
	XSetFont(d,gwhite,font);
	XSetFont(d,gyellow,font);

	XSelectInput(d,w, ButtonPressMask|ExposureMask);

	/* set tmp filename */
	sprintf(tmpf,"/tmp/pstmp%d",tv2.tv_usec);

	/* set signal handler */
        signal(SIGINT, sigcatch);
        signal(SIGQUIT,sigcatch);
        signal(SIGTRAP,sigcatch);
        signal(SIGABRT,sigcatch);
        signal(SIGTERM,sigcatch);
        signal(SIGPIPE,sigcatch);	/* close button */

        while(1) {
            /* ブロセスデータ採取 */
	    if ((fd = open(tmpf,O_CREAT|O_RDWR|O_TRUNC, 0666)) < 0) {
		perror("open pstmp");
		exit(1);
	    }
	    close(1);		/* close stdout(1) */
	    dup(fd);		/* stdout(1) redirect to tmpfile */

	    if (lf) {
		/* get load average */
	        system("uptime");
	    }
#ifdef H3050R
	    system("ps -ef");
#else  /* linux */
	    system("ps ax");
#endif
	    fchmod(fd,0666);	/* mode set to rw-rw-rw- */
	    close(fd);		/* close tmpfile         */

	    /* プロセス起動状態チェック */
	    if (!(fp = fopen(tmpf,"r"))) {
	    	perror("fopen pstmp");
	    	exit(1);
	    }

	    for (i=0; i<num; i++) {
		prc[i].active = 0;
	    }
	    if (lf) {
		/* get load average */
	    	fgets(buf,sizeof(buf),fp);
		loadave = get_loadave(buf);
	    }
	    while (fgets(buf,sizeof(buf),fp)) {
	    	for (i=0; i<num; i++) {
		    if (strstr(buf,"xpstat")) {
			continue;	/* H3050R cannot clear args */
		    }
		    if (pt =(char *) strstr(buf,prc[i].procname)) {
		        int c1,c2;

			/* 前後が区切り文字であることのチェック */
		        c1 = pt[strlen(prc[i].procname)];
		        c2 = *(--pt);
		    	if ((c1 == ' ' || c1 == 0xa || c1 == '\0') &&
		    	    (c2 == '/' || c2 == ' ')) {
		    	    ++prc[i].active;	/* process is active */
		    	}
		    }
	    	}
	    }
	    fclose(fp);

	    /* 起動/停止状態によりBARの長さを変更 */
	    for (j=0; j<3; j++) {
	    	for (i=0; i<num; i++) {
	    	    if (prc[i].active) {
	    	    	(prc[i].cnt < BARLEN)? prc[i].cnt++ : 0 ;
	    	    } else {
	    	    	(prc[i].cnt > 0)? prc[i].cnt-- : 0 ;
	    	    }
		}

		/* ちょっと待ってみよう */
		gettimeofday(&tv3,&tz);
		tv.tv_sec  = 0;
		/* tv.tv_usec = 300000;		/* 0.3sec        */

		/* 待ち時間調整 */
		if (tv2.tv_usec < tv3.tv_usec) {
		    tv.tv_usec = 300000 - (tv3.tv_usec-tv2.tv_usec);
		} else {
		    tv.tv_usec = 300000 - (1000000+tv3.tv_usec-tv2.tv_usec);
		}
		if (tv.tv_usec < 0) {
		    tv.tv_usec = 1;
		}

		select(0,0,0,0,&tv);		/* wait a little */	
		gettimeofday(&tv2,&tz);

		/* BAR 表示 */
		dispall(prc,num,strarea);
	    }
	}
}

/* vim:ts=8:sw=8:
 */