• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

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

oga's tools


Commit MetaInfo

修訂aefa1f5106cfe7c5747dce12926e539983d9a56a (tree)
時間2013-12-31 10:56:32
作者oga <oga@mxg....>
Commiteroga

Log Message

add tools

Change Summary

差異

--- /dev/null
+++ b/class.c
@@ -0,0 +1,57 @@
1+/*
2+ * class : IP アドレスクラスチェック
3+ *
4+ * 97/09/09 by oga
5+ * 13/12/08 support private check
6+ */
7+#include <stdio.h>
8+#include <stdlib.h>
9+#include <string.h>
10+
11+#define CLASS_A 0x80
12+#define CHECK_A 0x00
13+
14+#define CLASS_B 0xc0
15+#define CHECK_B 0x80
16+
17+#define CLASS_C 0xe0
18+#define CHECK_C 0xc0
19+
20+#define PRIVATE "(private)"
21+
22+
23+main(a,b)
24+int a;
25+char *b[];
26+{
27+ int ad; /* 1st octet */
28+ int ad2 = 0; /* 2nd octet */
29+ int vf = 1;
30+ char *private = "";
31+ char *pt;
32+
33+ if (a < 2) {
34+ printf("usage: class <IP_address>\n");
35+ exit(1);
36+ }
37+ ad = atoi(b[1]);
38+ pt = strchr(b[1], '.');
39+ if (pt) {
40+ ++pt;
41+ ad2 = atoi(pt);
42+ if (vf) printf("1st.2nd = %d.%d\n", ad, ad2);
43+ }
44+ if ((ad & CLASS_A) == CHECK_A) {
45+ if (ad == 10) private = PRIVATE;
46+ printf("%s is class A address %s\n", b[1], private);
47+ }
48+ if ((ad & CLASS_B) == CHECK_B) {
49+ if (ad == 172 && (ad2 >= 16 && ad2 <= 31)) private = PRIVATE;
50+ printf("%s is class B address %s\n", b[1], private);
51+ }
52+ if ((ad & CLASS_C) == CHECK_C) {
53+ if (ad == 192 && ad2 == 168) private = PRIVATE;
54+ printf("%s is class C address %s\n", b[1], private);
55+ }
56+ return 0;
57+}
--- /dev/null
+++ b/cp2.c
@@ -0,0 +1,273 @@
1+/*
2+ * cp2.c : プログレスバー付きコピー
3+ *
4+ * 2003/01/24 V0.10 by oga.
5+ * 2009/10/28 V0.11 support -v and disp perf
6+ */
7+#include<stdio.h>
8+#include<stdlib.h>
9+#include<sys/stat.h>
10+#include<string.h>
11+#include<time.h>
12+#ifdef _WIN32
13+#include<windows.h>
14+#else /* !_WIN32 */
15+#include<unistd.h>
16+#include<sys/time.h>
17+#endif /* _WIN32 */
18+
19+
20+#ifdef _WIN32
21+#define PDELM "\\"
22+#define PDELMC '\\'
23+#define PDELM2 "/"
24+#define PDELM2C '/'
25+#define S_ISDIR(m) ((m) & S_IFDIR)
26+#else
27+#define PDELM "/"
28+#define PDELMC '/'
29+#endif
30+
31+#define ISKANJI(c) (((c) >= 0x80 && (c) < 0xa0) || ((c) >= 0xe0 && (c)<0xff))
32+
33+#ifdef _WIN32
34+/*
35+struct timeval {
36+ u_int tv_sec;
37+ u_int tv_usec;
38+};
39+*/
40+
41+struct timezone {
42+ int tz_minuteswest;
43+ int tz_dsttime;
44+};
45+
46+int gettimeofday(struct timeval *tv, struct timezone *tz);
47+#endif /* _WIN32 */
48+
49+/*
50+ * tv_diff(tv1, tv2, tv3)
51+ *
52+ * IN
53+ * tv1, tv2 : time value
54+ *
55+ * OUT
56+ * tv3 : tv1 - tv2
57+ *
58+ */
59+void tv_diff(tv1,tv2,tv3)
60+struct timeval *tv1,*tv2,*tv3;
61+{
62+ if (tv1->tv_usec < tv2->tv_usec) {
63+ tv3->tv_sec = tv1->tv_sec - tv2->tv_sec - 1;
64+ tv3->tv_usec = tv1->tv_usec + 1000000 - tv2->tv_usec;
65+ } else {
66+ tv3->tv_sec = tv1->tv_sec - tv2->tv_sec;
67+ tv3->tv_usec = tv1->tv_usec - tv2->tv_usec;
68+ }
69+}
70+
71+#ifdef _WIN32
72+int gettimeofday(struct timeval *tv, struct timezone *tz)
73+{
74+ SYSTEMTIME syst;
75+
76+ //GetSystemTime(&syst); // UTC
77+ GetLocalTime(&syst);
78+ tv->tv_sec = syst.wHour * 3600 +
79+ syst.wMinute *60 +
80+ syst.wSecond;
81+ tv->tv_usec = syst.wMilliseconds * 1000;
82+ return 0;
83+}
84+#endif /* _WIN32 */
85+
86+/*
87+ * ファイル名部分を取り出す
88+ *
89+ * IN path: (フルパスの)ファイル名
90+ * OUT ret : ファイル名の開始位置
91+ */
92+char *GetFileName(char *path)
93+{
94+ char *pt = path; /* 区切り文字がなければ先頭を返す */
95+ int i;
96+
97+ for (i = 0; i<(int)strlen(path); i++) {
98+ if (ISKANJI((unsigned char)path[i])) {
99+ ++i; // 全角の1バイト目なら次の文字までスキップ
100+ continue;
101+ }
102+ if (path[i] == PDELMC) {
103+ pt = &path[i+1]; // 最後の\の次の位置を保存
104+ }
105+ }
106+ return pt;
107+}
108+
109+void usage()
110+{
111+ printf("usage : cp2 <src_file> <dest_file>\n");
112+ exit(1);
113+}
114+
115+int main(int a, char *b[])
116+{
117+ FILE *fp1; /* for src_file */
118+ FILE *fp2; /* for dest_file */
119+ struct stat stbuf;
120+ int size; /* read size */
121+ int wsize; /* write size */
122+ int pcent; /* copy percent */
123+ int total; /* total copy size */
124+ unsigned int all_size = 0; /* file size */
125+ int i; /* V0.11-A */
126+ int vf = 0; /* -v: verbose V0.11-A */
127+ int msec = 0; /* millisec V0.11-A */
128+ int blksiz = 4096; /* block size V0.11-A */
129+ char buf[4096*16]; /* buffer V0.11-C */
130+ char strbar[100];
131+ char *bar = "################################################## ";
132+ char *pt;
133+ char src_file[1025];
134+ char dest_file[1025];
135+ char fname[1025]; /* file basename */
136+ struct timeval tvs, tve, tvd; /* V0.11-A */
137+
138+#ifdef _WIN32
139+ char *cur_up = "";
140+#else /* UNIX */
141+ char *cur_up = "\033M";
142+#endif /* _WIN32 */
143+
144+ strcpy(src_file, "");
145+ strcpy(dest_file, "");
146+
147+ for (i = 1; i < a; i++) {
148+ if (!strcmp(b[i], "-h")) {
149+ usage();
150+ }
151+ if (!strcmp(b[i], "-v")) {
152+ ++vf;
153+ continue;
154+ }
155+ if (src_file[0] == '\0') {
156+ strcpy(src_file, b[i]);
157+ continue;
158+ }
159+ if (dest_file[0] == '\0') {
160+ strcpy(dest_file, b[i]);
161+ continue;
162+ }
163+ }
164+
165+
166+ /* dest_file is directory? */
167+ if (stat(dest_file, &stbuf) == 0) {
168+ if (S_ISDIR(stbuf.st_mode)) {
169+ if (strchr(src_file, PDELMC)) {
170+ /* exist path delm */
171+ //pt = strrchr(src_file, PDELMC); /* ファイル名取得(仮) */
172+ //++pt;
173+ pt = GetFileName(src_file); /* ファイル名取得 */
174+ strcpy(fname, pt);
175+#ifdef _WIN32
176+ } else if (strchr(src_file, PDELM2C)) {
177+ /* UNIX形式も許す */
178+ pt = strrchr(src_file, PDELM2C);
179+ ++pt;
180+ strcpy(fname, pt);
181+#endif
182+ } else {
183+ /* filename only */
184+ strcpy(fname, src_file);
185+ }
186+ strcat(dest_file, PDELM);
187+ strcat(dest_file, fname);
188+ if (vf) printf("dest_file: %s\n", dest_file);
189+ }
190+ }
191+
192+ if (vf) printf("open %s ...\n", src_file);
193+ if ( (fp1 = fopen(src_file,"rb")) == 0) {
194+ perror(src_file);
195+ usage();
196+ exit(1);
197+ }
198+
199+ if (vf) printf("open %s ...\n", dest_file);
200+ if ( (fp2 = fopen(dest_file,"wb")) == 0) {
201+ perror(dest_file);
202+ usage();
203+ exit(1);
204+ }
205+
206+ if (vf) printf("stat %s ...\n", src_file);
207+ if (stat(src_file, &stbuf) == 0) {
208+ all_size = stbuf.st_size; /* src_file size */
209+
210+ /* V0.11-A start */
211+ if (all_size > sizeof(buf) * 4) {
212+ blksiz = sizeof(buf);
213+ } else {
214+ blksiz = all_size/4;
215+ if (blksiz < 4096) {
216+ blksiz = 4096;
217+ }
218+ }
219+ /* V0.11-A end */
220+ }
221+ if (vf) printf("blksiz = %d\n", blksiz);
222+
223+ total = 0;
224+
225+ gettimeofday(&tvs, NULL); /* V0.11-A */
226+ while (size = fread(buf, 1, blksiz, fp1)) { /* V0.11-C */
227+ wsize = fwrite(buf, 1, size, fp2);
228+ if (wsize != size) {
229+ fprintf(stderr, "Write Incomplete %d/%d\n", wsize, size);
230+ }
231+
232+ /* for disp progress bar */
233+ total += size;
234+ if (all_size > 1024*1024) {
235+ pcent = total/(all_size/100);
236+ } else {
237+ pcent = (total*100)/all_size;
238+ }
239+ strncpy(strbar, &bar[50-pcent/2], 50);
240+ strbar[0] = strbar[10] = strbar[20] = strbar[30]
241+ = strbar[40] = strbar[50] = '|';
242+ strbar[51] = '\0';
243+#ifdef _WIN32
244+ printf(" %3d%% %s %dKB/%dKB\r", pcent, strbar, total/1024, all_size/1024, cur_up);
245+#else
246+ printf(" %3d%% %s %dKB/%dKB\n%s", pcent, strbar, total/1024, all_size/1024, cur_up);
247+#endif
248+ fflush(stdout);
249+ }
250+ printf("\n");
251+
252+ if (!feof(fp1)) {
253+ fprintf(stderr, "Copy Incompleted.\n");
254+ }
255+ if (vf) printf("close %s ...\n", src_file);
256+ fclose(fp1);
257+ if (vf) printf("close %s ...\n", dest_file);
258+ fclose(fp2);
259+
260+ /* V0.11-A start */
261+ gettimeofday(&tve, NULL);
262+
263+ tv_diff(&tve, &tvs, &tvd);
264+ msec = tvd.tv_sec*1000 + tvd.tv_usec/1000;
265+ printf(" (Size:%dKB Time:%d.%03d sec %dKB/s)\n",
266+ stbuf.st_size/1024, tvd.tv_sec, tvd.tv_usec/1000,
267+ msec?(((stbuf.st_size/1024)*1000)/msec):0);
268+ /* V0.11-A end */
269+}
270+
271+/* vim:ts=8:sw=4:
272+ */
273+
--- /dev/null
+++ b/deltag.c
@@ -0,0 +1,124 @@
1+/*
2+ * deltag : HTMLのタグを除去するフィルタ
3+ *
4+ * 98/03/03 V1.00 by oga.
5+ * 10/11/21 V1.10 support -c option (convert <br><p><hr> &gt; &lt; &amp;)
6+ *
7+ */
8+#include <stdio.h>
9+#include <stdlib.h>
10+#include <string.h>
11+
12+main(a,b)
13+int a;
14+char *b[];
15+{
16+ int i, c;
17+ int tagin = 0; /* 1:タグ中 0:タグ外 */
18+ int vf = 0;
19+ int cf = 0; /* -c: convert some tag */
20+ int pos;
21+ int change;
22+ char *fname = NULL;
23+ FILE *fp;
24+ unsigned char buf[4096*4];
25+ unsigned char work[1024];
26+
27+ /* arg check */
28+ for (i = 1; i<a; i++) {
29+ if (!strncmp(b[i],"-c",2)) {
30+ cf = 1;
31+ continue;
32+ }
33+ if (!strncmp(b[i],"-v",2)) {
34+ vf = 1;
35+ continue;
36+ }
37+ if (!strncmp(b[i],"-h",2)) {
38+ printf("usage: deltag [-c] [filename]\n");
39+ exit(1);
40+ }
41+ fname = b[i];
42+ }
43+
44+ /* open file */
45+ if (fname == NULL) {
46+ fp = stdin;
47+ } else {
48+ if ((fp = fopen(fname,"r")) == 0) {
49+ perror(b[0]);
50+ exit(1);
51+ }
52+ }
53+
54+ while ((c = getc(fp)) != EOF) {
55+ if (c == '<') {
56+ // start of tag
57+ tagin = 1;
58+ pos = 0;
59+ buf[pos++] = c;
60+ continue;
61+ }
62+ if (tagin) {
63+ // store tag string
64+ buf[pos++] = c;
65+ }
66+ if (c == '>') {
67+ // end of tag
68+ tagin = 0;
69+ buf[pos] = '\0';
70+ pos = 0;
71+ if (vf) printf("buf=[%s]\n", buf);
72+ if (cf) {
73+ if (!strcasecmp(buf, "<br>")) {
74+ printf("\n");
75+ } else if (!strcasecmp(buf, "<p>")) {
76+ printf("\n");
77+ } else if (!strcasecmp(buf, "<hr>")) {
78+ printf("\n--------------------------------------------\n");
79+ }
80+ }
81+ continue;
82+ }
83+ if (!tagin) {
84+ if (c == '&') {
85+ change = 0;
86+ work[0] = getc(fp); /* g l a */
87+ work[1] = getc(fp); /* t t m */
88+ work[2] = getc(fp); /* ; ; p */
89+ work[3] = '\0';
90+ if (!strcmp(work, "gt;")) {
91+ printf(">");
92+ change = 1;
93+ } else if (!strcmp(work, "lt;")) {
94+ printf("<");
95+ change = 1;
96+ } else if (!strcmp(work, "amp")) {
97+ work[3] = getc(fp); /* ; */
98+ work[4] = '\0';
99+ if (!strcmp(work, "amp;")) {
100+ printf("&");
101+ change = 1;
102+ }
103+ }
104+ if (!change) {
105+ putchar(c); /* & */
106+ /* 変換対象外の場合はそのまま出力 */
107+ /* EOFは\0に変更 */
108+ for (i = 0; i<strlen(work); i++) {
109+ if (work[i] == 0xff) {
110+ work[i] = '\0';
111+ break;
112+ }
113+ }
114+ printf("%s", work);
115+ }
116+ } else {
117+ /* タグ以外で、&xxでもなければならそのまま出力 */
118+ putchar(c);
119+ }
120+ }
121+ }
122+ fclose(fp);
123+}
124+
--- /dev/null
+++ b/galaxian.c
@@ -0,0 +1,619 @@
1+/*
2+ * galaxian [speed<40/2500>] [-n] ..... Galaxianもどき
3+ *
4+ * by hyper halx.f oga.
5+ *
6+ * 1994.11.27 Ver 1.01
7+ * 1994.11.28 Ver 1.02 porting to H3050R
8+ * 1995.08.21 Ver 1.03 color support
9+ * 1995.08.21 Ver 1.04 high score support
10+ * 1995.08.23 Ver 1.05 star support
11+ * 2003.05.23 Ver 1.06 use usleep
12+ */
13+
14+#include <stdio.h>
15+#include <stdlib.h>
16+#include <math.h>
17+
18+#ifdef X3050RX
19+#include <curses.h>
20+#include <sys/ioctl.h>
21+#else /* X68000 */
22+#include "cur.h"
23+#include <unistd.h>
24+#endif /* X68000 */
25+
26+#define NUM_AL 10 /* エイリアンの数 */
27+#ifdef X3050RX
28+#define NUM_STAR 20 /* 星の数 */
29+#else /* X68000 */
30+#define NUM_STAR 10 /* 星の数 */
31+#endif /* X68000 */
32+#define STAR "." /* 星 */
33+#define DIE -1
34+#define TYP (typ/5)%2 /* エイリアンの形 0 or 1 */
35+#define RSPACE 8 /* 右の空き(SHIPサイズ分) */
36+#define A_MAX 14 /* エイリアンの振幅(MAX) */
37+
38+#ifdef X3050RX
39+#define NORMAL 0
40+#define BLUE 31
41+#define RED 32
42+#define MAGENTA 33
43+#define GREEN 34
44+#define CYAN 35
45+#define YELLOW 36
46+#define WHITE 37
47+#else /* X68000 */
48+#define NORMAL 0
49+#define BLUE 31
50+#define RED 32
51+#define MAGENTA 33
52+#define GREEN 31
53+#define CYAN 35
54+#define YELLOW 36
55+#define WHITE 37
56+#endif /* X68000 */
57+
58+struct mis_loc {
59+ short x;
60+ short y;
61+};
62+struct al_loc {
63+ short x; /* 位置 X */
64+ short y; /* 位置 Y */
65+ short dx; /* 移動ベクトル X成分 */
66+ short dy; /* 移動ベクトル Y成分 */
67+ short delay; /* 待機カウンタ */
68+ short a; /* 振幅 */
69+ short a_cnt; /* 振幅カウンタ */
70+};
71+struct st_loc {
72+ short x; /* 位置 X */
73+ short y; /* 位置 Y */
74+};
75+
76+#ifdef X3050RX
77+/* int wait = 2500; */ /* game speed */
78+int wait = 10; /* game speed 0.2 sec */
79+#else /* X68000 */
80+int wait = 40; /* game speed */
81+#endif /* X68000 */
82+
83+int xmin = 2, xmax, ymax;
84+int sc = 0, stage = 0, typ = 0; /* score, stage, alien_type */
85+int hisc = 0; /* high score */
86+char hinm[100]; /* high name */
87+int x, y, ships = 3, mf = 0; /* ship's locate , rest , missile flag */
88+int extend = 5000; /* extend ship over 5000pts. */
89+int starf = 1; /* star flag */
90+
91+char misle[]=" I ";
92+#ifdef X3050RX
93+char ship[]=" <H>  H H H  HHHHH  H H H \n";
94+#else /* X68000 */
95+char ship[]=" <H>  H H H  HHHHH  H H H \n";
96+#endif /* X68000 */
97+char space[]="  ";
98+char *alien[2];
99+
100+main(a,b)
101+int a;
102+char *b[];
103+{
104+ int i=0, c, mf = 0, rel=1;
105+ int al_rest;
106+ long size;
107+ char buf[30];
108+ FILE *fp;
109+
110+ struct mis_loc mi;
111+ struct al_loc al[NUM_AL];
112+ struct st_loc star[NUM_STAR];
113+
114+ /* INITIALIZE */
115+ for (i = 1; i<a ; i++) {
116+ if (!strcmp(b[i],"-h")) {
117+ printf("usage : galaxian [speed<%d>] [-n]\n",wait);
118+ exit(1);
119+ } else if (!strcmp(b[i],"-n")) {
120+ starf = 0;
121+ } else {
122+ wait = atoi(b[1]);
123+ printf("speed = %d\n",wait);
124+ }
125+ }
126+#ifdef X3050RX
127+ alien[0]="V vXooX\n";
128+ alien[1]="v VXOOX\n";
129+#else /* X68000 */
130+ alien[0]="V vXooX\n";
131+ alien[1]="v VXOOX\n";
132+#endif /* X68000 */
133+#ifdef X3050RX
134+ xmax = atoi(getenv("COLUMNS"))-RSPACE;
135+ ymax = atoi(getenv("LINES"))-1;
136+ if (xmax == 0)
137+ xmax = 80-RSPACE;
138+ if (ymax == 0)
139+ ymax = 24-1;
140+#else /* X68000 */
141+ xmax = 95-RSPACE;
142+ ymax = 31;
143+#endif /* X68000 */
144+
145+ if (fp = fopen("galax.hi","rb")) {
146+ fread(&hisc,4,1,fp);
147+ fread(&hinm,11,1,fp);
148+ hinm[10]='\0';
149+ fclose(fp);
150+ }
151+ /* initialize STAR position */
152+ for (i=0; i<NUM_STAR; i++) {
153+ star[i].x = rnd(xmax);
154+ star[i].y = rnd(ymax*2)+6;
155+ xprint(star[i].x, star[i].y/2,STAR,WHITE);
156+ }
157+
158+ /* STAGE LOOP */
159+ while (1) {
160+#ifdef X3050RX
161+ initscr();
162+ /* nonl(); */
163+ cbreak();
164+ noecho();
165+ clear();
166+ refresh();
167+#else /* X68000 */
168+ cls();
169+ CUR_OFF;
170+#endif /* X68000 */
171+ /* initialize ALIEN position */
172+ for (i=0; i<NUM_AL; i++) {
173+ al[i].x = ((xmax-(A_MAX+2)*2)/5)*(i%5) + A_MAX+2 ;
174+ al[i].y = (i/5)*4 + 3;
175+ al[i].dx = (rnd(2)*2-1)*(rnd(2)+1);
176+ /* printf("dx = %d /",al[i].dx); */
177+ al[i].dy = 1;
178+ al[i].delay = (stage > 13 ? 0 : rnd(500-stage*500/15));
179+ al[i].a = al[i].a_cnt = rnd(A_MAX/2)+A_MAX/2;
180+ xprint(al[i].x, al[i].y, alien[0],YELLOW);
181+
182+ }
183+ y = ymax - 3;
184+ x = (xmin + xmax) / 2;
185+ al_rest = NUM_AL;
186+
187+ xprint(x+1,y-1,misle,YELLOW);
188+ xprint(x,y,ship,CYAN);
189+
190+ sprintf(buf,"STAGE %02d",++stage);
191+ xprint(xmax-1,1,buf,MAGENTA);
192+ sc_disp(sc);
193+
194+ /* MAIN LOOP */
195+ while (1) {
196+
197+ /* if (starf) move_star(star); V1.05 */
198+ if (starf) {
199+ for (i=0; i<NUM_STAR; i++) {
200+ xprint(star[i].x, star[i].y/2," ",WHITE);
201+ if (++star[i].y >= ymax*2)
202+ star[i].y = 4;
203+ if (i >= NUM_STAR/2 && ++star[i].y >= ymax*2)
204+ star[i].y = 4;
205+ xprint(star[i].x, star[i].y/2,STAR,WHITE);
206+ }
207+ }
208+ #ifdef X3050RX
209+ /* c = getch(); */
210+ ioctl(fileno(stdin),FIONREAD,&size);
211+ if (size > 0)
212+ c = getch();
213+ else
214+ c = 0;
215+
216+ #else /* X68000 */
217+ c = inkey(0);
218+ #endif /* X68000 */
219+
220+ /* KEY SCAN */
221+ switch (c) {
222+ case 'j' :
223+ rel = 1;
224+ if (--x < xmin ) x = xmin ;
225+ break;
226+ case 'l' :
227+ rel = 1;
228+ if (++x > xmax) x = xmax;
229+ break;
230+ case 'i' :
231+ case ' ' :
232+ #ifdef REPEAT
233+ if (mf == 0) {
234+ #else
235+ if (rel && mf == 0) { /* } */
236+ #endif
237+ mf = 1;
238+ mi.x = x+1;
239+ mi.y = y-1;
240+ }
241+ rel = 0;
242+ break;
243+ case 12 : /* ^L */
244+ case 27 : /* ESC */
245+#ifdef X3050RX
246+ clear();
247+ refresh();
248+#else /* X68000 */
249+ cls();
250+#endif /* X68000 */
251+ xprint(x+1,y-1,misle,YELLOW);
252+ xprint(x,y,ship,CYAN);
253+ sprintf(buf,"STAGE %02d",++stage);
254+ xprint(xmax-1,1,buf,MAGENTA);
255+ sc_disp(sc);
256+ break;
257+ case 'q' :
258+#ifdef X3050RX
259+ nocbreak();
260+ endwin();
261+#else
262+ CUR_ON;
263+#endif
264+ exit(0);
265+ default :
266+ rel = 1;
267+ break;
268+
269+ }
270+
271+ /* MISSILE CHECK */
272+ if (mf) {
273+ switch (i = move_misle(&mi,al)) {
274+ case 0: /* nop */
275+ break;
276+ case 5: /* alien hit */
277+ case 4: /* alien hit */
278+ case 3: /* alien hit */
279+ case 2: /* alien hit */
280+ al_rest -= (i-1);
281+#if 0
282+ printf("i=%d/al_rest=%d\n",i,al_rest);
283+#endif
284+ case 1: /* missle go away */
285+ mf = 0;
286+ break;
287+ }
288+ if (al_rest == 0)
289+ break; /* next stage */
290+ } else {
291+ xprint(x+1,y-1,misle,YELLOW);
292+ }
293+
294+ /* DISPLAY SHIP */
295+ xprint(x,y,ship,CYAN);
296+ /* xwait(wait); */
297+ usleep(wait*10000); /* V1.06-C */
298+
299+ /* MOVE ALIEN */
300+ for (i=0; i<NUM_AL; i++) {
301+ if (al[i].delay == 0) {
302+ if (move_al(&al[i])) {
303+ bomb_ship(al,&mi,star);
304+ }
305+ } else {
306+ if (al[i].delay > 0) {
307+ xprint(al[i].x, al[i].y, alien[TYP],YELLOW);
308+ --al[i].delay;
309+ } else { /* alian die */
310+ xprint(al[i].x, al[i].y, space,YELLOW);
311+ }
312+ }
313+ }
314+
315+ if (stage < 10) {
316+
317+ /* MISSILE CHECK 2 */
318+ if (mf) {
319+ switch (i = move_misle(&mi,al)) {
320+ case 0: /* nop */
321+ break;
322+ case 5: /* alien hit */
323+ case 4: /* alien hit */
324+ case 3: /* alien hit */
325+ case 2: /* alien hit */
326+ al_rest -= (i-1);
327+#if 0
328+ printf("i=%d/al_rest=%d\n",i,al_rest);
329+#endif
330+ case 1: /* missle go away */
331+ mf = 0;
332+ break;
333+ }
334+ if (al_rest == 0)
335+ break; /* next stage */
336+ } else {
337+ xprint(x+1,y-1,misle,YELLOW);
338+ }
339+
340+ /* DISPLAY SHIP 2 */
341+ xprint(x,y,ship,CYAN);
342+ /* xwait(wait); */
343+ usleep(wait*10000); /* V1.06-C */
344+ }
345+ ++typ;
346+ }
347+ xprint(xmax/2-15, ymax/2, " << S T A G E C L E A R ! >> \n",CYAN);
348+#ifdef X3050RX
349+ sleep(2);
350+#else /* X68000 */
351+ xwait(10000);
352+#endif /* X68000 */
353+ }
354+}
355+
356+/* LOCATE PRINT */
357+/* x:x_location, y:y_location s:print_string c:color */
358+xprint(x,y,s,c)
359+int x, y, c;
360+char *s;
361+{
362+ printf("[%d;%dH[%dm%s",y,x,c,s);
363+}
364+
365+/* CHANGE COLOR */
366+color(c)
367+int c;
368+{
369+ printf("[%dm",c);
370+}
371+
372+#if 0
373+cls()
374+{
375+ printf("\n"); /* Clear Screen & HOME */
376+}
377+#endif
378+
379+#ifdef NO_USLEEP /* for 3050RX */
380+/* Select WAIT */
381+/*
382+ * usleep(usec)
383+ *
384+ * IN
385+ * usec : micro seconds
386+ *
387+ */
388+void usleep(int usec)
389+{
390+ struct timeval tv;
391+
392+ if (!usec) return;
393+ tv.tv_sec = 0; /* second */
394+ tv.tv_usec = usec; /* micro second */
395+
396+ select(0,0,0,0,&tv); /* wait a little */
397+}
398+#endif
399+
400+/* LOOP WAIT */
401+xwait(val)
402+int val;
403+{
404+ int i,x;
405+ for (i=0;i<val*100;i++)
406+ x=i*3; /* dummy instruction */
407+}
408+
409+#define ax al[i].x
410+#define ay al[i].y
411+#define mx (mip->x)+1
412+#define my mip->y
413+
414+/* MOVE MISSILE */
415+move_misle(mip,al)
416+struct mis_loc *mip;
417+struct al_loc *al;
418+{
419+ int i;
420+ int ret = 0;
421+
422+ xprint(mip->x,mip->y," ",WHITE);
423+ if (--mip->y <= 1) {
424+ ret = 1;
425+ } else {
426+ xprint(mip->x,mip->y,misle,YELLOW);
427+
428+ /* CHECK HIT ALIEN */
429+ for (i=0; i<NUM_AL; i++) {
430+ if (al[i].delay == DIE) continue;
431+ if (ax <= mx && mx <= ax+3 && ay <= my && my <= ay+1) {
432+ xprint(ax,ay,"☆☆☆☆",YELLOW);
433+ if (al[i].delay == 0)
434+ sc += 100 * stage; /* moving point */
435+ else
436+ sc += 50 * stage; /* stay point */
437+ sc_disp(sc);
438+ al[i].delay = DIE;
439+ if (ret)
440+ ret += 1;
441+ else
442+ ret = 2;
443+ }
444+ }
445+ }
446+ return ret;
447+}
448+
449+/* MOVE ALIEN */
450+move_al(alp)
451+struct al_loc *alp;
452+{
453+ xprint(alp->x, alp->y, space,WHITE);
454+ alp->x += alp->dx;
455+ alp->y += alp->dy;
456+
457+ /* 画面の下に行ったか? */
458+ if (alp->y > ymax-2) {
459+ if (alp->x < A_MAX+2) alp->x = A_MAX+2;
460+ if (alp->x > xmax-A_MAX-2) alp->x = xmax-A_MAX-2;
461+ alp->y = 2;
462+ alp->dx = (rnd(2)*2-1)*(rnd(2)+1);
463+ if (alp->dx < -1 && alp->x < A_MAX*2+2) alp->x = A_MAX*2+2;
464+ if (alp->dx > 1 && alp->x > xmax-A_MAX-2*2-2) alp->dx = xmax-A_MAX*2-2;
465+ alp->a = alp->a_cnt = rnd(A_MAX/2)+A_MAX/2;
466+#if 0
467+ alp->delay = rnd(3);
468+#endif
469+ }
470+
471+ /* 振幅カウンタ update */
472+ if (--alp->a_cnt == 0) {
473+ alp->dx *= -1;
474+ alp->a_cnt = alp->a;
475+ }
476+ xprint(alp->x, alp->y, alien[TYP],YELLOW);
477+
478+ /* SHIP HIT CHECK */
479+ if (alp->y > ymax-5 && alp->x <= x+3 && alp->x >= x) {
480+ return 1;
481+ }
482+ return 0;
483+
484+}
485+
486+/* GENERATE RANDOM VALUE */
487+rnd(n)
488+int n;
489+{
490+ return(rand()*n/RAND_MAX);
491+}
492+
493+/* DISPLAY SCORE */
494+sc_disp(sc)
495+int sc;
496+{
497+ char buf[40];
498+ char bufhi[50];
499+ int i;
500+
501+ if (sc >= extend) {
502+ printf("");
503+ ++ships;
504+ extend += 20000;
505+ }
506+ xprint(55,0,"SHIP:",YELLOW);
507+ for (i=1;i<ships ; i++) {
508+ printf("A");
509+ }
510+ sprintf(buf, "SCORE %08d\n",sc);
511+ sprintf(bufhi,"HI-SCORE %08d %s\n",hisc,hinm);
512+ xprint(0,0,buf,RED);
513+ xprint(18,0,bufhi,RED);
514+}
515+
516+bomb_ship(al, mi, star)
517+struct al_loc *al;
518+struct mis_loc *mi;
519+struct star_loc *star;
520+{
521+ int i, size;
522+ char buf[80];
523+ FILE *fp;
524+
525+ xprint(x,y," ☆☆ ☆☆☆ ☆☆☆ ☆☆☆\n",RED);
526+#ifdef X3050RX
527+ sleep(1);
528+#else /* X68000 */
529+ xwait(6000);
530+#endif /* X68000 */
531+ if (--ships < 1) {
532+ /* game is over */
533+#ifdef X3050RX
534+ nocbreak();
535+ endwin();
536+ xprint((xmin+xmax)/2-5,ymax/2," GAME OVER! \n",WHITE);
537+#else
538+ CUR_ON;
539+ xprint((xmin+xmax)/2-5,ymax/2," GAME OVER! \n",RED);
540+#endif
541+ if (hisc < sc) {
542+ xprint((xmin+xmax)/2-7,ymax/2+2," High Score! Your Name? ",CYAN);
543+ scanf("%s",buf);
544+ if (fp = fopen("galax.hi","wb")) {
545+ fwrite(&sc,4,1,fp);
546+ fwrite(buf,11,1,fp);
547+ fclose(fp);
548+ }
549+ } else {
550+ xprint((xmin+xmax)/2-7,ymax/2+2," Hit <RETURN> Key! \n",CYAN);
551+#ifdef X3050RX
552+ while(getch() != '\n') ;
553+#else /* X68000 */
554+ while(getch() != 13) ;
555+#endif /* X68000 */
556+ }
557+ color(NORMAL);
558+ printf("\n");
559+ exit(0);
560+ }
561+#ifdef X3050RX
562+ clear();
563+ refresh();
564+#else /* X68000 */
565+ cls();
566+ CUR_OFF;
567+#endif /* X68000 */
568+ if (starf) move_star(star);
569+ for (i=0; i<NUM_AL; i++) {
570+ al[i].x = ((xmax-(A_MAX+2)*2)/5)*(i%5) + A_MAX+2 ;
571+ al[i].y = (i/5)*4 + 3;
572+ al[i].dx = (rnd(2)*2-1)*(rnd(2)+1);
573+ al[i].dy = 1;
574+ if (al[i].delay != DIE) {
575+ al[i].delay = (stage > 13 ? 0 : rnd(500-stage*500/15));
576+ xprint(al[i].x, al[i].y, alien[0],YELLOW);
577+ }
578+ al[i].a = al[i].a_cnt = rnd(A_MAX/2)+A_MAX/2;
579+ }
580+ y = ymax - 3;
581+ x = (xmin + xmax) / 2;
582+ mf = 0;
583+ /* printf("mfはクリアしました\n"); */
584+ mi->x = x+1;
585+ mi->y = y-1;
586+ sc_disp(sc);
587+ sprintf(buf,"STAGE %02d",stage);
588+ xprint(xmax-1,1,buf,MAGENTA);
589+ xprint(x,y-8,"READY!",RED); /* READY */
590+ xprint(x+1,y-1,misle,YELLOW);
591+ xprint(x,y,ship,CYAN);
592+#ifdef X3050RX
593+ sleep(2);
594+ ioctl(fileno(stdin),FIONREAD,&size);
595+ while (size>0) {
596+ getch();
597+ ioctl(fileno(stdin),FIONREAD,&size);
598+ }
599+
600+#else /* X68000 */
601+ xwait(13000);
602+#endif /* X68000 */
603+ xprint(x,y-8," \n",WHITE);
604+}
605+move_star(star)
606+struct st_loc *star;
607+{
608+ int i;
609+
610+ if (starf == 0) return 0;
611+ for (i=0; i<NUM_STAR; i++) {
612+ xprint(star[i].x, star[i].y/2," ",WHITE);
613+ if (++star[i].y >= ymax*2)
614+ star[i].y = 4;
615+ if (i >= NUM_STAR/2 && ++star[i].y >= ymax*2)
616+ star[i].y = 4;
617+ xprint(star[i].x, star[i].y/2,STAR,WHITE);
618+ }
619+}
--- /dev/null
+++ b/gz.c
@@ -0,0 +1,84 @@
1+#include <stdio.h>
2+#include <stdlib.h>
3+#include <string.h>
4+#include <zlib.h>
5+
6+#if 0
7+/* ===========================================================================
8+ * Test read/write of .gz files
9+ */
10+void test_gzio(out, in, uncompr, uncomprLen)
11+ const char *out; /* output file */
12+ const char *in; /* input file */
13+ Byte *uncompr;
14+ int uncomprLen;
15+{
16+ int err;
17+ int len = strlen(hello)+1;
18+ gzFile file;
19+
20+ file = gzopen(out, "wb");
21+ if (file == NULL) {
22+ fprintf(stderr, "gzopen error\n");
23+ exit(1);
24+ }
25+
26+ if (gzwrite(file, (const voidp)hello, (unsigned)len) != len) {
27+ fprintf(stderr, "gzwrite err: %s\n", gzerror(file, &err));
28+ }
29+ gzclose(file);
30+
31+ file = gzopen(in, "rb");
32+ if (file == NULL) {
33+ fprintf(stderr, "gzopen error\n");
34+ }
35+ strcpy((char*)uncompr, "garbage");
36+
37+ uncomprLen = gzread(file, uncompr, (unsigned)uncomprLen);
38+ if (uncomprLen != len) {
39+ fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
40+ }
41+ gzclose(file);
42+
43+ if (strcmp((char*)uncompr, hello)) {
44+ fprintf(stderr, "bad gzread\n");
45+ } else {
46+ printf("gzread(): %s\n", uncompr);
47+ }
48+}
49+#endif /* 0 */
50+
51+int gzip(char *inf, char *outf)
52+{
53+ FILE *infp;
54+ gzFile ozfp;
55+ char buf[4096];
56+ int sz;
57+
58+ if ((infp = fopen(inf,"rb")) == NULL) {
59+ printf("fopen %s error\n",inf);
60+ exit(1);
61+ }
62+ if ((ozfp = gzopen(outf,"wb")) == NULL) {
63+ printf("gzopen %s error\n",outf);
64+ exit(1);
65+ }
66+ while (sz = fread(buf,1,4096,infp)) {
67+ gzwrite(ozfp, buf, sz);
68+ }
69+
70+ gzclose(ozfp);
71+ fclose(infp);
72+}
73+
74+int main(int a, char *b[])
75+{
76+
77+ if (a < 3) {
78+ printf("usage: gz <infile> <file.gz>\n");
79+ exit(1);
80+ }
81+
82+ gzip(b[1],b[2]);
83+
84+}
--- /dev/null
+++ b/hex2bin.c
@@ -0,0 +1,107 @@
1+/*
2+ * hex2bin
3+ * hex文字列をascii文字列に変換
4+ * "48656c6c6f" => "Hello"
5+ *
6+ * 2002/04/16 V0.10 by oga.
7+ * 2010/09/26 V0.20 support wire shark hex dump
8+ *
9+ */
10+#include <stdio.h>
11+#include <stdlib.h>
12+#include <string.h>
13+#include <fcntl.h>
14+
15+
16+/* Wireshark packet dump format */
17+/* -----+----1----+----2----+----3----+----4----+----5----+----6----+----7--- */
18+/* 0060 4f 4e 54 52 4f 4c 3a 20 6d 61 78 2d 61 67 65 3d ONTROL: max-age= */
19+int wsf = 0; /* Wireshark hex dump format switch */
20+
21+/*
22+ * hex文字列をascii文字列に変換
23+ *
24+ * "48656c6c6f" => "Hello"
25+ *
26+ * ret : length
27+ */
28+int hex2str(char *in, char *out)
29+{
30+ int i = 0;
31+ int j = 0;
32+ char wk[16];
33+ char cc;
34+
35+ while (isdigit(in[i]) || (tolower(in[i]) >= 'a' && tolower(in[i]) <= 'f') || isspace(in[i])) { /* V0.20-C */
36+ /* V0.20-A start */
37+ if (wsf && (i < 6 || i > 53)) {
38+ ++i;
39+ continue; /* skip addr and ascii char */
40+ }
41+ if (isspace(in[i])) {
42+ ++i;
43+ continue; /* skip space */
44+ }
45+ /* V0.20-A end */
46+ strcpy(wk, "0x");
47+ memcpy(&wk[2], &in[i], 2);
48+ wk[4] = '\0';
49+ out[j] = (char)strtoul(wk, (char **)NULL, 0);
50+ i += 2;
51+ ++j;
52+ }
53+ out[j] = '\0';
54+ return j; // 変換結果がバイナリの場合のために長さを返す
55+}
56+
57+int main(int a, char *b[])
58+{
59+ FILE *fp;
60+ char *fname = NULL;
61+ char buf[4096];
62+ char work[4096];
63+ int i;
64+ int len;
65+
66+ for (i = 1; i<a; i++) {
67+ if (!strcmp(b[i], "-h")) {
68+ printf("usage: hex2bin [-ws] [<file>]\n");
69+ exit(1);
70+ }
71+ if (!strcmp(b[i], "-ws")) {
72+ wsf = 1;
73+ continue;
74+ }
75+ fname = b[i];
76+ }
77+
78+#ifdef _WIN32
79+ // 改行とかが勝手に変換されないようにstdoutをバイナリモードにする
80+ setmode(fileno(stdout),O_BINARY);
81+#endif
82+
83+ if (fname == NULL) {
84+ fp = stdin;
85+ } else
86+ if ((fp = fopen(fname, "r")) == NULL) {
87+ perror(fname);
88+ exit(1);
89+ }
90+
91+ while (fgets(buf, sizeof(buf), fp)) {
92+ if (buf[strlen(buf)-1] == 0x0a) {
93+ buf[strlen(buf)-1] = '\0';
94+ }
95+ if (buf[strlen(buf)-1] == 0x0d) {
96+ buf[strlen(buf)-1] = '\0';
97+ }
98+ len = hex2str(buf, work);
99+ fwrite(work, 1, len, stdout);
100+ }
101+
102+ if (fp != stdin) {
103+ fclose(fp);
104+ }
105+ return 0;
106+}
107+
--- /dev/null
+++ b/hexbin.c
@@ -0,0 +1,181 @@
1+/*
2+ * hexbin : テキストのHEXデータ(0x00, 0x11, ...)をバイナリファイルに変換する
3+ * またその逆を行う
4+ *
5+ * 2003/09/04 V1.00 by oga.
6+ * 2003/12/22 V1.01 support 2byte data
7+ *
8+ */
9+#include <stdio.h>
10+#include <string.h>
11+#include <sys/types.h>
12+#include <sys/stat.h>
13+#include <unistd.h>
14+
15+#define DATA_PER_LINE 10
16+
17+/*
18+ * HexStrlen
19+ * 0xNNNN, 0xNNNNN, ... 形式のHEXデータの長さを返す
20+ *
21+ * IN : str : "0x"で始まる文字列
22+ * OUT : ret : "0x"を含むHEX文字列の長さ
23+ * "0x"で始まらない場合は0を返す
24+ *
25+ */
26+int HexStrlen(char *str)
27+{
28+ int len = 0;
29+
30+ if (strncmp(str, "0x", 2)) {
31+ return len; /* return 0 */
32+ }
33+ str += 2;
34+ len += 2;
35+ while (isdigit(*str) ||
36+ ('a' <= *str && *str <= 'f') ||
37+ ('A' <= *str && *str <= 'F')) {
38+ ++len;
39+ ++str;
40+ }
41+ /* fprintf(stderr, "len = %d\n", len); */
42+ return len;
43+}
44+
45+/*
46+ * hex2bin
47+ * テキストのHEXデータをバイナリファイルに変換
48+ *
49+ * IN : fp : テキストのHEXデータファイルのファイルポインタ
50+ * 0x00,0x11,0x22,....形式
51+ * 0x0NNNN, 0xNNNN (2バイトの値まで対応 (03/12/22))
52+ *
53+ */
54+void hex2bin(FILE *fp)
55+{
56+ char buf[4096*10];
57+ char work[16];
58+ char *pt;
59+ int c;
60+ int len;
61+
62+ while (fgets(buf, sizeof(buf), fp)) {
63+ pt = &buf[0];
64+ while (pt = strstr(pt, "0x")) {
65+ len = HexStrlen(pt);
66+ strncpy(work, pt, len);
67+ work[len] = '\0';
68+ c = strtoul(work,(char **)NULL,0);
69+ if (len > 4) {
70+ /* 0xNNNNN... => 2バイト文字として扱う */
71+ if (c > 0xffff) {
72+ fprintf(stderr, "Warning: %s is over 0xffff\n", work);
73+ } else {
74+ /* 2バイト以内 */
75+ unsigned short short_val = c;
76+ unsigned char *uc_val = (unsigned char *)&short_val;
77+ putchar((int)(short_val / 256));
78+ putchar((int)(short_val & 0xff));
79+ }
80+ } else {
81+ /* 0xNN */
82+ putchar(c);
83+ }
84+ ++pt;
85+ }
86+ }
87+}
88+
89+/*
90+ * bin2hex
91+ * バイナリファイルをテキストのHEXデータに変換
92+ *
93+ * IN : fp : バイナリファイルのファイルポインタ
94+ *
95+ */
96+void bin2hex(FILE *fp)
97+{
98+ int c;
99+ int i = 0;
100+ int linefirst = 1;
101+
102+ while ((c = getc(fp)) != EOF) {
103+ if (i > 0 && i % DATA_PER_LINE == 0) {
104+ printf(",\n");
105+ linefirst = 1;
106+ }
107+ if (!linefirst) printf(",");
108+ printf("0x%02x", c);
109+ linefirst = 0;
110+ i++;
111+ }
112+ printf("\n");
113+ if (fp == stdin) {
114+ printf("/* size:%d */\n", i);
115+ }
116+}
117+
118+int main(int a, char *b[])
119+{
120+ char *fname = NULL;
121+ FILE *fp;
122+ int vf = 0;
123+ int rf = 0;
124+ int i;
125+
126+ /* arg check */
127+ for (i = 1; i<a; i++) {
128+ if (!strncmp(b[i],"-v",2)) {
129+ vf = 1;
130+ continue;
131+ }
132+ if (!strcmp(b[i],"-r")) {
133+ rf = 1;
134+ continue;
135+ }
136+ if (!strncmp(b[i],"-h",2)) {
137+ printf("usage: hexbin [-r] [filename]\n");
138+ printf(" -r : bin to hex\n");
139+ exit(1);
140+ }
141+ fname = b[i];
142+ }
143+
144+ /* open file */
145+ if (fname == NULL) {
146+ fp = stdin;
147+ } else {
148+ if ((fp = fopen(fname,"rb")) == 0) {
149+ perror(fname);
150+ exit(1);
151+ }
152+ }
153+
154+ /* 処理 */
155+ if (rf) {
156+ /* binary => 0xnn, 0xnn, ... */
157+ if (fp != stdin) {
158+ struct stat stbuf;
159+ char work[1024];
160+ char *pt;
161+
162+ stat(fname, &stbuf);
163+ strcpy(work, fname);
164+ if (pt = strrchr(fname, '/')) {
165+ strcpy(work, ++pt);
166+ } else {
167+ strcpy(work, fname);
168+ }
169+ printf("/* file:%s size:%d */\n", work, stbuf.st_size);
170+ }
171+ bin2hex(fp);
172+ } else {
173+ /* 0xnn, 0xnn, ... => binary */
174+ hex2bin(fp);
175+ }
176+
177+ if (fp != stdin) fclose(fp);
178+}
179+
180+/* vim:ts=8:sw=8:
181+ */
--- /dev/null
+++ b/hscp.c
@@ -0,0 +1,144 @@
1+/*
2+ * hscp.c : 同一デバイス高速コピー
3+ *
4+ * 2004/10/20 V0.10 by oga.
5+ */
6+#include<stdio.h>
7+#include<stdlib.h>
8+#include<sys/stat.h>
9+#include<string.h>
10+#ifndef _WIN32
11+#include<unistd.h>
12+#endif /* _WIN32 */
13+
14+
15+#ifdef _WIN32
16+#define PDELM "\\"
17+#define PDELMC '\\'
18+#define S_ISDIR(m) ((m) & S_IFDIR)
19+#else
20+#define PDELM "/"
21+#define PDELMC '/'
22+#endif
23+
24+#define MEM_SIZE (20*1024*1024)
25+
26+
27+int main(int a, char *b[])
28+{
29+ FILE *fp1; /* for src_file */
30+ FILE *fp2; /* for dest_file */
31+ struct stat stbuf;
32+ int size; /* read size */
33+ int wsize; /* write size */
34+ int pcent; /* copy percent */
35+ int total; /* total copy size */
36+ int all_size = 0; /* file size */
37+ char *buf;
38+ char strbar[100];
39+ char *bar = "################################################## ";
40+ char *pt;
41+ char src_file[1025];
42+ char dest_file[1025];
43+ char fname[1025]; /* file basename */
44+ int mem_size = MEM_SIZE;
45+
46+#ifdef _WIN32
47+ char *cur_up = "";
48+#else /* UNIX */
49+ char *cur_up = "\033M";
50+#endif /* _WIN32 */
51+
52+ if (a != 3) {
53+ //printf("usage : hscp [-b <buff_size(20MB)>] <src_file> <dest_file>\n");
54+ printf("usage : hscp <src_file> <dest_file>\n");
55+ exit(1);
56+ }
57+
58+ strcpy(src_file, b[1]);
59+ strcpy(dest_file, b[2]);
60+
61+ /* dest_file is directory? */
62+ if (stat(dest_file, &stbuf) == 0) {
63+ if (S_ISDIR(stbuf.st_mode)) {
64+ if (strchr(src_file, PDELMC)) {
65+ /* exist path delm */
66+ pt = strrchr(&src_file[strlen(src_file)-1], PDELMC);
67+ ++pt;
68+ strcpy(fname, pt);
69+ } else {
70+ /* filename only */
71+ strcpy(fname, src_file);
72+ }
73+ strcat(dest_file, PDELM);
74+ strcat(dest_file, fname);
75+ }
76+ }
77+
78+ if ( (fp1 = fopen(src_file,"rb")) == 0) {
79+ perror(src_file);
80+ exit(1);
81+ }
82+ if ( (fp2 = fopen(dest_file,"wb")) == 0) {
83+ perror(dest_file);
84+ exit(1);
85+ }
86+
87+ if (stat(src_file, &stbuf) == 0) {
88+ all_size = stbuf.st_size; /* src_file size */
89+ }
90+
91+ if (all_size < mem_size) {
92+ mem_size = all_size;
93+ }
94+
95+ buf = (char *)malloc(mem_size);
96+ if (buf == NULL) {
97+ perror("hscp: malloc");
98+ exit(1);
99+ }
100+
101+ total = 0;
102+ while (size = fread(buf, 1, mem_size, fp1)) {
103+ wsize = fwrite(buf, 1, size, fp2);
104+ if (wsize != size) {
105+ fprintf(stderr, "Write Incomplete %d/%d\n", wsize, size);
106+ }
107+
108+ /* for disp progress bar */
109+ total += size;
110+ if (all_size > 1024*1024) {
111+ pcent = total/(all_size/100);
112+ } else {
113+ pcent = (total*100)/all_size;
114+ }
115+ strncpy(strbar, &bar[50-pcent/2], 50);
116+ strbar[0] = strbar[10] = strbar[20] = strbar[30]
117+ = strbar[40] = strbar[50] = '|';
118+ strbar[51] = '\0';
119+#if 0
120+#ifdef _WIN32
121+ printf(" %3d%% %s %dKB/%dKB\r", pcent, strbar, total/1024, all_size/1024, cur_up);
122+#else /* !_WIN32 */
123+ printf(" %3d%% %s %dKB/%dKB\n%s", pcent, strbar, total/1024, all_size/1024, cur_up);
124+#endif /* !_WIN32 */
125+#endif /* 0 */
126+ fflush(stdout);
127+ }
128+
129+#if 0
130+ printf("\n");
131+#endif
132+
133+ if (!feof(fp1)) {
134+ fprintf(stderr, "Copy Incompleted.\n");
135+ }
136+ if (all_size != total) {
137+ fprintf(stderr, "Copy Incompleted. size=%d write=%d\n", all_size, total);
138+ }
139+ fclose(fp1);
140+ fclose(fp2);
141+}
142+
143+/* vim:ts=8:sw=8
144+ */
--- /dev/null
+++ b/htlink.c
@@ -0,0 +1,117 @@
1+/*
2+ * テキスト文書中のURLをリンク形式に変換する
3+ *
4+ * Copyright (C)1997 Moritaka Ogasawara.
5+ *
6+ * usage : htlink [filename]
7+ * filename指定がない場合、標準入力から読み取る
8+ *
9+ * 97/04/29 Ver1.00 by oga.
10+ * 99/12/03 Ver1.01 support "ftp://"
11+ * 11/08/20 Ver1.02 support DOS path "C:\xxx"
12+ */
13+#include <stdio.h>
14+#include <stdlib.h>
15+#include <string.h>
16+
17+int vf = 0;
18+
19+main(a,b)
20+int a;
21+char *b[];
22+{
23+ FILE *fp;
24+ char buf[4096],outbuf[4096];
25+ char wk[4096], wk2[4096];
26+ char url[4096];
27+ unsigned char *pt,*pt2,*pto,*pte, *pt3;
28+ unsigned char *pt4;
29+ int len;
30+
31+
32+ if (a < 2) {
33+ fp = stdin;
34+ } else {
35+ if (!strncmp(b[1],"-h",2)) {
36+ printf("usage : htlink [filename]\n");
37+ exit(1);
38+ }
39+ if ((fp = fopen(b[1],"r")) == 0) {
40+ perror(b[0]);
41+ exit(1);
42+ }
43+ }
44+
45+ while (fgets(buf,sizeof(buf),fp)) {
46+ pt = buf; /* pt : inbuf */
47+ pto = outbuf; /* pto: outbuf */
48+ outbuf[0] = '\0';
49+ while ((pt2 = (char *)strstr(pt,"http://"))|| /*pt2: "http:" ptr */
50+ (pt3 = (char *)strstr(pt,"ftp://")) || /*pt3: "ftp:" ptr */
51+ (pt4 = (char *)strstr(pt,":\\")) /*pt4: "X:\" ptr */
52+ ) { /*pt2: "ftp:" ptr */
53+ /* http: or ftp:の前までコピー */
54+ if (pt2) {
55+ len = (unsigned int)pt2 - (unsigned int)pt;
56+ } else if(pt3) {
57+ len = (unsigned int)pt3 - (unsigned int)pt;
58+ } else if (pt4) {
59+ --pt4;
60+ len = (unsigned int)pt4 - (unsigned int)pt;
61+ }
62+ /* "http:" の手前までコピー */
63+ strncpy(pto,pt,len); /* pto: outbuf */
64+ pto[len] = '\0';
65+
66+ /* pt を "http:"の先頭へ */
67+ pt += len;
68+ /* pto をコピーした文字列の末尾へ */
69+ pto += len;
70+
71+ /* "http://.../"の終わりをサーチ */
72+ pte = pt; /* pte: "http://.../ " last pointer */
73+ /* while (!isspace(*pte) */
74+ while (*pte != ' ' && *pte != '\r' && *pte != '\n'
75+ && *pte != '\0' /* && *pte < 128 */
76+ && *pte != '"' && *pte != '(' && *pte != ')'
77+ && *pte != '\t' && *pte != ','
78+ && !(*pte >= ';' && *pte <= '>' && *pte != '=')
79+ && !(*pte >= '[' && *pte <= '^' && *pte != '\\')
80+ && *pte != '}' && *pte != '{' ) {
81+ ++pte;
82+ }
83+ if (vf) printf("end char = [%c]\n", *pte);
84+ len = (unsigned int)pte - (unsigned int)pt;
85+ strncpy(wk,pt,len); /* copy "http://.../" */
86+ wk[len] = '\0';
87+
88+ if (vf) printf("wk: [%s]\n", wk);
89+
90+ if (pt4) {
91+ /* C:\xxx */
92+ sprintf(url, "file://%s", wk);
93+ } else {
94+ /* http://xxx, ftp://xxx */
95+ strcpy(url, wk);
96+ }
97+ sprintf(wk2,"<a href=\"%s\">%s</a>",url,wk);
98+ strcat(pto,wk2);
99+ pt += len;
100+ pto += strlen(wk2);
101+ if (*pt == '\0') {
102+ break;
103+ }
104+ }
105+ strcat(pto,pt);
106+
107+ if (outbuf[strlen(outbuf)-1] != 0x0a) {
108+ strcat(outbuf,"\n");
109+ }
110+ printf("%s",outbuf);
111+ }
112+}
113+
114+/* vim:ts=8:sw=8:
115+ */
116+
117+
--- /dev/null
+++ b/irctrl.c
@@ -0,0 +1,377 @@
1+/*
2+ * irctrl.c
3+ * パラレルインタフェースを利用した赤外線データR/W
4+ *
5+ * (注)PCのプリンタのI/OアドレスとPORT_PRT_BASEを合わせること
6+ * PCのプリンタのBIOS設定では双方向通信可に設定すること
7+ *
8+ * 04/01/04 V0.10 by oga.
9+ * 04/06/14 V0.20 by oga.
10+ */
11+
12+#ifdef _WIN32
13+#include <windows.h>
14+#include <conio.h>
15+#endif
16+#include <stdio.h>
17+#include <stdlib.h>
18+#include <string.h>
19+#include <sys/io.h>
20+#include <sys/stat.h>
21+#include <sys/time.h>
22+#include <unistd.h>
23+
24+/* I/O Ports */
25+#define PORT_PRT_BASE 0x378 /* lp0:0x3bc lp1:0x378 lp2:0x278 */
26+#define PORT_PRT_DATA (PORT_PRT_BASE+0) /* Data R/W */
27+#define BIT_DATA_IRREAD 0x01 /* Bit0: Input IR Data */
28+#define BIT_DATA_IRWRITE 0x02 /* Bit1: Output IR Data */
29+#define PORT_PRT_STAT (PORT_PRT_BASE+1) /* Status (Read Only) */
30+#define BIT_STAT_SLCT 0x10 /* Bit4: SLCT(Not Use) */
31+#define PORT_PRT_CTRL (PORT_PRT_BASE+2) /* Control(Write Only) */
32+#define BIT_CTRL_DIRECT 0x20 /* Bit5: Direction 0:OUT 1:IN */
33+
34+#define WAIT_TIME 00000 /* 20ms */
35+/* #define WAIT_TIME 200000 /* 200ms */
36+/* #define WAIT_SPIN 1000000 /* 6.5ms(loop(K6-2/366MHz)) */
37+#define WAIT_SPIN 5000 /* 5ms */
38+
39+/* とりあえず 格納データは可視データで */
40+#define IR_DATA_OFF '0'
41+#define IR_DATA_ON '1'
42+
43+/* globals */
44+int vf = 0; /* verbose */
45+
46+/*
47+ * tv_diff(tv1, tv2, tv3)
48+ *
49+ * IN
50+ * tv1, tv2 : time value
51+ *
52+ * OUT
53+ * tv3 : tv1 - tv2
54+ *
55+ */
56+void tv_diff(tv1, tv2, tv3)
57+struct timeval *tv1,*tv2,*tv3;
58+{
59+ if (tv1->tv_usec < tv2->tv_usec) {
60+ tv3->tv_sec = tv1->tv_sec - tv2->tv_sec - 1;
61+ tv3->tv_usec = tv1->tv_usec + 1000000 - tv2->tv_usec;
62+ } else {
63+ tv3->tv_sec = tv1->tv_sec - tv2->tv_sec;
64+ tv3->tv_usec = tv1->tv_usec - tv2->tv_usec;
65+ }
66+}
67+
68+/*
69+ * SpinSleep
70+ * 指定μsだけスピンして待つ(1/100秒よりも小さい解像度で待ちたい場合)
71+ *
72+ * usec : micro seconds
73+ */
74+void SpinSleep(int usec)
75+{
76+ int i;
77+ struct timeval tv, tv2, tv3;
78+ struct timezone tz;
79+
80+ gettimeofday(&tv, &tz);
81+ while (1) {
82+ gettimeofday(&tv2, &tz);
83+ tv_diff(&tv2, &tv, &tv3);
84+ if (tv3.tv_sec*1000000+tv3.tv_usec >= usec) {
85+ break;
86+ }
87+ }
88+}
89+
90+/*
91+ * IrRead
92+ *
93+ * OUT data : Infrared Read Data
94+ * IN size : data buffer size
95+ * OUT ret : Read Data Size
96+ */
97+int IrRead(char *data, int size)
98+{
99+ int i = 0;
100+ int val;
101+ int off_len = 0; /* IR_DATA_OFF length */
102+ int last_point = 0;
103+
104+ outb(BIT_CTRL_DIRECT, PORT_PRT_CTRL); /* Bit5:1 ... Input */
105+
106+ /* Wait IR Data */
107+ printf("Waiting IR Data...\n");
108+ fflush(stdout);
109+ while (1) {
110+ usleep(WAIT_TIME); /* DEBUG */
111+ val = inb(PORT_PRT_DATA);
112+ if (vf) printf("IrRead1: INB[%d] : %d\n", i++, val); /* DEBUG */
113+ if (!(val & BIT_DATA_IRREAD)) {
114+ data[0] = IR_DATA_ON;
115+ break;
116+ }
117+ }
118+ SpinSleep(WAIT_TIME);
119+
120+ printf("Reading ...\n");
121+ fflush(stdout);
122+
123+ for (i=1; i<size; i++) {
124+ //if (off_len > 500000/WAIT_TIME) {
125+ if (off_len > 50000) {
126+ /* 500ms以上データがない場合終了 */
127+ break;
128+ }
129+ val = inb(PORT_PRT_DATA);
130+ if (vf) printf("IrRead2: val=%d\n", val);
131+ if (!(val & BIT_DATA_IRREAD)) { /* Bit0(D0)で入力 */
132+ data[i] = IR_DATA_ON;
133+ off_len = 0;
134+ last_point = i; /* 最後に1になった場所 */
135+ } else {
136+ data[i] = IR_DATA_OFF;
137+ ++off_len;
138+ }
139+ SpinSleep(WAIT_TIME);
140+ }
141+ return (last_point+1);
142+}
143+
144+/*
145+ * IrWrite
146+ *
147+ * IN data : Infrared Output Data
148+ * IN size : Data Size
149+ */
150+void IrWrite(char *data, int size)
151+{
152+ int i;
153+
154+ outb(0x00, PORT_PRT_CTRL); /* Bit5:0 ... Output */
155+
156+ for (i=0; i<size; i++) {
157+ if (data[i] == IR_DATA_ON) {
158+ outb( 0x00, PORT_PRT_DATA);
159+ } else {
160+ outb(BIT_DATA_IRWRITE, PORT_PRT_DATA); /* Bit1(D1)で出力 */
161+ }
162+ SpinSleep(WAIT_TIME);
163+ }
164+
165+ /* Ir Off */
166+ outb(BIT_DATA_IRWRITE, PORT_PRT_DATA); /* Bit1(D1)で出力 */
167+}
168+
169+/*
170+ * ReadIRData
171+ * ファイルからIRデータを取得
172+ *
173+ * IN fname : filename
174+ * IN data : read data buffer
175+ * IN size : data buffer size
176+ * OUT data : read data buffer
177+ * OUT ret : read data size
178+ *
179+ */
180+int ReadIRData(char *fname, char *data, int size)
181+{
182+ FILE *fp;
183+ struct stat stbuf;
184+ int size2 = size;
185+ int ret = 0;
186+
187+ if (stat(fname, &stbuf) < 0) {
188+ perror(fname);
189+ exit(1);
190+ }
191+ if (stbuf.st_size < size) {
192+ size2 = stbuf.st_size;
193+ }
194+
195+ if ((fp = fopen(fname,"rb")) == 0) {
196+ perror(fname);
197+ exit(1);
198+ }
199+ ret = fread(data, 1, size2, fp);
200+ fclose(fp);
201+
202+ return ret;
203+}
204+
205+/*
206+ * WriteIRData
207+ * ファイルにIRデータを格納
208+ *
209+ * IN fname : filename
210+ * OUT data : read data buffer
211+ * OUT size : data buffer size
212+ *
213+ */
214+void WriteIRData(char *fname, char *data, int size)
215+{
216+ FILE *fp;
217+ struct stat stbuf;
218+
219+ if ((fp = fopen(fname,"wb")) == 0) {
220+ perror(fname);
221+ exit(1);
222+ }
223+ fwrite(data, 1, size, fp);
224+ fclose(fp);
225+
226+ printf("Write %s completed.\n", fname);
227+}
228+
229+int main(int a, char* b[])
230+{
231+ int val = 0;
232+ //char data[200]; /* 0.02x200 = 4sec */
233+ char data[2000000]; /* 0.02x200 = 4sec */
234+ int size;
235+ char buf[4096]; /* dummy buf */
236+
237+ char *fname = NULL;
238+ int i;
239+
240+ /* arg check */
241+ for (i = 1; i<a; i++) {
242+ if (!strncmp(b[i],"-v",2)) {
243+ vf = 1;
244+ continue;
245+ }
246+ if (!strncmp(b[i],"-h",2)) {
247+ printf("usage: irctrl [in_ir_data_file]\n");
248+ exit(1);
249+ }
250+ fname = b[i];
251+ }
252+
253+ /* 書式 ioperm(from, num, turn_on)
254+ * from : アクセスを許すポートの最初のアドレス (0x000〜0x3ff)
255+ * num : fromからいくつの連続アドレスのアクセスを許すかを指定
256+ * turn_on : true:1 = アクセスを許可, false:0 = アクセスを禁止
257+ *
258+ * <例>
259+ * ioperm(0x300, 5, 1) は、0x300 から 0x304 (合計で 5 つのポート)
260+ * に対する許可を指定し、最後のパラメータでは、そのポートに対する
261+ * アクセス許可を与えるのか禁止するのかを論理値
262+ * (true:1 = アクセスを許可する, false:0 = アクセスを禁止する)で指定
263+ */
264+ if (ioperm(PORT_PRT_BASE, 3, 1) < 0) {
265+ perror("ioperm");
266+ exit(1);
267+ }
268+
269+ memset(data, 0, sizeof(data));
270+
271+ outb(0x00, PORT_PRT_CTRL); /* Bit5:0 ... Output */
272+ outb(0x00, PORT_PRT_DATA);
273+
274+
275+ /* debug 04/06/13 */
276+ strcpy(buf, "0101010");
277+ IrWrite(buf, strlen(buf));
278+
279+ if (fname != NULL) {
280+ /* ファイル指定がある場合はファイルからデータ取得 */
281+ if ((size = ReadIRData(fname, data, sizeof(data))) < 0) {
282+ printf("IR Data Read Error\n");
283+ exit(1);
284+ }
285+ } else {
286+ /* ファイル指定がない場合はデバイスからデータ取得 */
287+ printf("IR Read start.\n");
288+ fflush(stdout);
289+
290+ size = IrRead(data, sizeof(data)-1); /* 赤外線入力 */
291+
292+ printf("IR Read end. size:%d\n", size);
293+ fflush(stdout);
294+ }
295+
296+
297+ while (1) {
298+ printf("IR Out start. hit any key! [q:quit]\n");
299+ fflush(stdout);
300+
301+ scanf("%s", buf);
302+ if (buf[0] == 'q' || buf[0] == 'e') {
303+ /* "quit" or "exit" */
304+ break;
305+ }
306+ if (buf[0] == 'd') {
307+ /* "dump" : dump data */
308+ printf("## dump Ir Data...\n");
309+ for (i = 0; i<size; i++) {
310+ printf("%c", data[i]);
311+ }
312+ printf("\n");
313+ continue;
314+ }
315+ printf("PiPiPi...\n");
316+ fflush(stdout);
317+
318+ IrWrite(data, size); /* 赤外線出力 */
319+
320+ printf("IR Out end. size:%d\n", size);
321+ fflush(stdout);
322+ }
323+
324+ printf("data=%s\n", data);
325+
326+ WriteIRData("/tmp/irdata.ir", data, size);
327+
328+ /* 後始末 */
329+ if (ioperm(PORT_PRT_BASE, 3, 0) < 0) {
330+ perror("ioperm");
331+ exit(1);
332+ }
333+ return 0;
334+}
335+
336+
337+#if 0
338+// 参考 Linux HOWTO IO-Port-Programming/useful-ports.html
339+//
340+// ■BASE+0のポート(データポート)は、ポートのデータ信号を制御します。
341+// D0 〜 D7 はビット 0 〜 7 に対応します。
342+// 状態 : 0 = low (0V)、1 = high (5V))。
343+// このポートに対するライトはデータをラッチして外部のピンに出力します。
344+// 標準または拡張ライトモードの場合には、リードすると、最後にライト
345+// されたデータが読み出されます。
346+// 拡張リードモードの場合には、外部デバイスからのデータが読み出されます。
347+//
348+// ■BASE+1のポート(ステータスポート) はリードオンリーで、以下のような入力信号のステータスを返します:
349+// Bit 0 と 1 は予約済
350+// Bit 2 IRQ ステータス (外部ピンの値ではない。どういうふうに動作するか知らない)
351+// Bit 3 ERROR (1=high)
352+// Bit 4 SLCT (1=high)
353+// Bit 5 PE (1=high)
354+// Bit 6 ACK (1=high)
355+// Bit 7 -BUSY (0=high)
356+//
357+// ■BASE+2のポート(制御ポート)はライトオンリー (リードした場合、最後にライトしたデータを返す。)で、以下のステータス信号を制御します:
358+// Bit 0 -STROBE (0=high)
359+// Bit 1 -AUTO_FD_XT (0=high)
360+// Bit 2 INIT (1=high)
361+// Bit 3 -SLCT_IN (0=high)
362+// Bit 4 '1' にすると、パラレルポートの割り込みを許可する(ACK の low -> high の遷移で割り込み発生。)
363+// Bit 5 拡張モードでの方向(0 = 出力, 1 = 入力) を制御する。 ★
364+// このビットは完全にライトオンリーで、リード時には不定の値が返る。
365+// Bit 6 と 7 は予約済
366+//
367+// ■ピン接続 (25 ピンの D-sub メスコネクタ) (i=input, o=output):
368+// 1io -STROBE,
369+// ★2io D0, 3io D1, 4io D2, 5io D3, 6io D4, 7io D5, 8io D6, 9io D7,
370+// 10i ACK, 11i -BUSY, 12i PE, 13i SLCT, 14o -AUTO_FD_XT,
371+// 15i ERROR, 16o INIT, 17o -SLCT_IN,
372+// ★18-25 Ground
373+#endif /* 0 */
374+
375+/* vim:ts=8:sw=8:
376+ */
377+
--- /dev/null
+++ b/iso2022.c
@@ -0,0 +1,275 @@
1+#include <stdio.h>
2+#include <stdlib.h>
3+#include <string.h>
4+
5+#define ISO2022 "=?ISO-2022-JP?B?"
6+#define iso2022 "=?iso-2022-jp?B?"
7+
8+char kin[] ={0x1b,0x24,0x42,0}; /* kanji mode in ^[(B */
9+char kout[] ={0x1b,0x28,0x42,0}; /* kanji mode out ^{)B */
10+char kout2[] ={0x1b,0x28,0x4a,0}; /* kanji mode out2 ^[)J */
11+
12+unsigned char tr[256]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
13+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
14+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,62, 0, 0, 0,63,
15+ 52,53,54,55,56,57,58,59,60,61, 0, 0, 0, 0, 0, 0,
16+ 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,
17+ 15,16,17,18,19,20,21,22,23,24,25, 0, 0, 0, 0, 0,
18+ 0,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
19+ 41,42,43,44,45,46,47,48,49,50,51, 0, 0, 0, 0, 0,
20+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
21+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
23+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
24+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
25+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
26+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
27+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
28+
29+
30+int vf = 0;
31+
32+int IsBigEndian()
33+{
34+ int n = 1;
35+ char *pn = (char *)&n;
36+
37+ if (pn[3] == 1) return 1; /* big endian */
38+ return 0; /* little endian (eg. INTEL) */
39+}
40+
41+/*
42+ * delcrlf(str)
43+ *
44+ * Delete CR/LF
45+ *
46+ * IN str : string with CR/LF
47+ * OUT str : string with no CR/LF
48+ */
49+void delcrlf(char *str)
50+{
51+ int i;
52+
53+ for (i = 0; i<strlen(str); i++) {
54+ if (str[i] == 0x0a || str[i] == 0x0d) {
55+ str[i] = ' ';
56+ }
57+ }
58+}
59+
60+/*
61+ * j2s(in,out);
62+ *
63+ * IN : in JISコード(2バイト)
64+ * OUT : out SJISコード(2バイト)
65+ *
66+ */
67+void j2s(unsigned char *in, unsigned char *out)
68+{
69+ if (in[0] % 2) {
70+ out[0] = in[0]/2 + 0x71;
71+ out[1] = in[1] + 0x1f;
72+ if (out[1] > 0x7f) { /* or >= */
73+ out[1]++;
74+ }
75+ } else {
76+ out[0] = in[0]/2 + 0x70;
77+ out[1] = in[1] + 0x7e;
78+ }
79+#if 0
80+ printf("IN 0x%04x / OUT 0x%04x\n",htons(*(unsigned short *)in),
81+ htons(*(unsigned short *)out));
82+#endif
83+}
84+
85+
86+/*
87+ * unsigned char *jis2sjis((u_char *)buf, (u_char *)obuf, int* sisof)
88+ *
89+ * kanji IN/OUT付き
90+ *
91+ * IN : buf 変換元文字列(SJIS)
92+ * siso 現在のSI/SOの状態 1:SI 0:SO
93+ * OUT : obuf 変換後文字列(JIS)
94+ * ret obufのアドレス
95+ */
96+
97+unsigned char *jis2sjis(buf,obuf,siso)
98+unsigned char *buf, *obuf;
99+int *siso;
100+{
101+ int ip=0, op=0;
102+ for (ip = 0; ip<strlen(buf); ) {
103+ if (*siso) {
104+ /* Under Shift In */
105+ if (!memcmp(&buf[ip],kin,3)) {
106+ ip += 3;
107+ continue;
108+ }
109+ if (!memcmp(&buf[ip],kout,3) || !memcmp(&buf[ip],kout2,3)) {
110+ /* Shift Out */
111+ if (vf == vf) printf("Shift OUT!!\n");
112+ *siso = 0;
113+ ip += 3;
114+ } else {
115+ j2s(&buf[ip],&obuf[op]);
116+ ip += 2;
117+ op += 2;
118+ }
119+ } else {
120+ /* Under Shift Out */
121+ if (!memcmp(&buf[ip],kout,3 || !memcmp(&buf[ip],kout2,3))) {
122+ ip += 3;
123+ continue;
124+ }
125+ if (!memcmp(&buf[ip],kin,3)) {
126+ /* Shift In */
127+ if (vf == vf) printf("Shift IN!!\n");
128+ *siso = 1;
129+ ip += 3;
130+ } else {
131+ obuf[op] = buf[ip];
132+ ++ip;
133+ ++op;
134+ }
135+ }
136+ }
137+ obuf[op] = '\0';
138+ return obuf;
139+}
140+
141+/*
142+ * Base64のデコード
143+ *
144+ * IN istr : base64 string
145+ * OUT ostr : decoded string
146+ * ret : decoded string
147+ */
148+
149+unsigned char *DecodeBase64(istr,ostr)
150+unsigned char *istr, *ostr;
151+{
152+ int wk4;
153+ int i;
154+ unsigned char *wk4s = (unsigned char *)&wk4;
155+
156+ while (*istr != '\0' && *istr != '\n' ) {
157+ wk4 = 0;
158+ for (i = 0; i<4; i++) {
159+ wk4 <<= 6;
160+ if (*istr == '\0' || *istr == '\n') {
161+ break;
162+ }
163+ wk4 |= tr[*istr];
164+ ++istr;
165+ }
166+
167+ if (IsBigEndian()) {
168+ memcpy(ostr,&wk4s[1],3);
169+ } else {
170+ ostr[0] = wk4s[2];
171+ ostr[1] = wk4s[1];
172+ ostr[2] = wk4s[0];
173+ }
174+
175+ ostr += 3;
176+ printf("[%c]",*istr);
177+ if (*istr == '?' && *(istr+1) == '=') {
178+ /* "?=" is terminate */
179+ istr += 2; /* skip "?=" */
180+ break;
181+ }
182+ }
183+ *ostr = '\0';
184+
185+ return istr;
186+}
187+
188+/*
189+ * すでにJISのShift IN ESCシーケンスが存在するか?
190+ */
191+int IsEscExist(buf)
192+char *buf;
193+{
194+ char SIN[16];
195+ sprintf(SIN, "%c%c%c",27,'$','B');
196+ return strstr(buf,SIN)?1:0 ;
197+}
198+
199+/*
200+ * ISO2022...が含まれていたら、JISコードに変換する
201+ *
202+ * IN in : "...=?ISO-2022-JP?B?<str>?="
203+ * OUT out: <SI>JISコード<SO>
204+ * ret: char *outを返す
205+ *
206+ */
207+char *chg_iso2022(in, out)
208+char *in,*out;
209+{
210+ char wk[4096];
211+ char *pp;
212+ int pt = 0;
213+ int i;
214+
215+ if (vf != vf) printf("BEFORE:[%s]\n",in);
216+
217+ if (strstr(in,ISO2022) || strstr(in,iso2022)) {
218+ i = 0;
219+ while (strncasecmp(&in[i],ISO2022,strlen(ISO2022))) {
220+ out[pt++] = in[i++];
221+ }
222+ i += strlen(ISO2022);
223+ /* printf("decode start = [%s]\n",&in[i]); */
224+ pp = DecodeBase64(&in[i],wk);
225+ if (IsEscExist(wk)) {
226+ sprintf(&out[pt],"%s\n",wk);
227+ } else {
228+ sprintf(&out[pt],"%c%c%c%s%c%c%c\n",27,'$','B',wk,27,'(','B');
229+ }
230+ if (pp) strcat(out, pp); /* 残りをコピー */
231+ } else {
232+ strcpy(out,in);
233+ }
234+ if (vf != vf) printf("AFTER :[%s]\n",out);
235+ return out;
236+}
237+
238+int main(int a, char *b[])
239+{
240+
241+ char buf[4096];
242+ char rbuf[4096];
243+ char wk[4096];
244+ int siso = 0;
245+ int i;
246+ int ff = 0;
247+
248+ for (i = 1; i<a; i++) {
249+ if (!strcmp(b[i],"-f")) {
250+ ff = 1;
251+ continue;
252+ }
253+ }
254+
255+ if (ff) {
256+ FILE *fp;
257+
258+ if (!(fp = fopen(b[2],"r"))) {
259+ perror("fopen");
260+ exit(1);
261+ }
262+ while (fgets(rbuf,sizeof(rbuf),fp)) {
263+ printf("%s\n=>%s\n",rbuf,chg_iso2022(rbuf, buf));
264+ }
265+ fclose(fp);
266+ } else {
267+ printf("%s\n=>%s\n",b[1],chg_iso2022(b[1], buf));
268+ printf("[%s]\n", jis2sjis(buf,wk,&siso));
269+ for (i = 0; i<strlen(wk); i++) {
270+ printf("%02x ",(unsigned char)wk[i]);
271+ }
272+ printf("\n");
273+ }
274+ return 0;
275+}
--- /dev/null
+++ b/joytest.c
@@ -0,0 +1,155 @@
1+/*
2+ * joytest.c
3+ *
4+ * 2003/12/07 V0.10 by oga.
5+ *
6+ */
7+
8+#define USE_JOYSTICK
9+
10+#include <stdio.h>
11+#include <unistd.h>
12+#include <stdlib.h>
13+#include <string.h>
14+#include <pwd.h>
15+#include <sys/types.h>
16+#include <sys/time.h>
17+#include <sys/stat.h>
18+#include <fcntl.h>
19+#include <errno.h>
20+
21+#ifdef USE_JOYSTICK
22+#include <linux/joystick.h>
23+#endif /* USE_JOYSTICK */
24+
25+int joyf = 0; /* 1: Use Joystick V1.02 */
26+int joyinit = 0; /* get_joystick init flg V1.02 */
27+int joy_x_max= 0; /* joy maxvalue x V1.02 */
28+int joy_y_max= 0; /* joy maxvalue y V1.02 */
29+char joydev[256] = "/dev/js0"; /* joystick device name V1.02 */
30+
31+/*
32+ * charcter vector define / keycode
33+*/
34+#define JOY_NOMOVE 0x00
35+#define JOY_UP 0x01
36+#define JOY_DOWN 0x02
37+#define JOY_LEFT 0x04
38+#define JOY_RIGHT 0x08
39+
40+#define JOY_TRIG1 0x10
41+#define JOY_TRIG2 0x20
42+#define JOY_TRIG3 0x40
43+#define JOY_TRIG4 0x80
44+
45+/*
46+ * JOYSTICK取り込み V1.02
47+ *
48+ * IN : なし
49+ * IN : global : joydev : joystickデバイス名
50+ * OUT : ret
51+ * JOY_NOMOVE : 入力なし
52+ * UP,DOWN,LEFT,RIGHT,TRIG1,TRIG2 : 各キーが押された。
53+ *
54+ */
55+int get_joystick()
56+{
57+ int status = JOY_NOMOVE;
58+ int st;
59+#ifdef USE_JOYSTICK
60+ struct JS_DATA_TYPE js;
61+ int fd;
62+
63+ /* open device file */
64+ if ((fd = open(joydev, O_RDONLY)) < 0) {
65+ printf("%s : open error(%d)\n", joydev, errno);
66+ return JOY_NOMOVE;
67+ }
68+
69+ st = read(fd, &js, JS_RETURN);
70+ if (st != JS_RETURN) {
71+ printf("%s : open error(%d)\n", joydev, errno);
72+ return JOY_NOMOVE;
73+ }
74+
75+ if (joyinit == 0) {
76+ joy_x_max = js.x*2;
77+ joy_y_max = js.y*2;
78+ joyinit = 1;
79+ }
80+
81+ if (joy_x_max < js.x) joy_x_max = js.x;
82+ if (joy_y_max < js.y) joy_y_max = js.y;
83+
84+ if (js.x < joy_x_max/3) status |= JOY_LEFT; /* move left */
85+ if (js.x > joy_x_max*2/3) status |= JOY_RIGHT; /* move right */
86+ if (js.y < joy_y_max/3) status |= JOY_UP; /* move up */
87+ if (js.y > joy_y_max*2/3) status |= JOY_DOWN; /* move down */
88+
89+ /* ボタンの方が優先 */
90+ if (js.buttons & 1) status |= JOY_TRIG1; /* left button */
91+ if (js.buttons & 2) status |= JOY_TRIG2; /* right button */
92+ if (js.buttons & 4) status |= JOY_TRIG3; /* right button */
93+ if (js.buttons & 8) status |= JOY_TRIG4; /* right button */
94+
95+ close(fd);
96+#endif /* USE_JOYSTICK */
97+
98+ return status;
99+}
100+
101+void print_joystat(int val)
102+{
103+ /* 0 3 8 13 20 23 26 29 */
104+ char *str = "UP DOWN LEFT RIGHT T1 T2 T3 T4";
105+ char sts[] = "□ □ □ □ □ □ □ □";
106+
107+ if (val & JOY_UP) memcpy(&sts[ 0], "■", 2);
108+ if (val & JOY_DOWN) memcpy(&sts[ 3], "■", 2);
109+ if (val & JOY_LEFT) memcpy(&sts[ 8], "■", 2);
110+ if (val & JOY_RIGHT) memcpy(&sts[13], "■", 2);
111+ if (val & JOY_TRIG1) memcpy(&sts[20], "■", 2);
112+ if (val & JOY_TRIG2) memcpy(&sts[23], "■", 2);
113+ if (val & JOY_TRIG3) memcpy(&sts[26], "■", 2);
114+ if (val & JOY_TRIG4) memcpy(&sts[29], "■", 2);
115+
116+ printf("%s (0x%02x)\n", str, val);
117+ printf("%s\n", sts);
118+ fflush(stdout);
119+}
120+
121+int main(int a, char *b[])
122+{
123+ int val;
124+ int prev_val = 999;
125+ int i;
126+
127+ /* get args */
128+ for (i = 1; i < a; i++) {
129+ if (!strncmp(b[i],"-h",2)) {
130+ printf("usage : joytest [-joy {<0>|1}]\n");
131+ exit(1);
132+ }
133+ if (!strncmp(b[i],"-joy",4)) {
134+ /* use joystick */
135+ sprintf(joydev, "/dev/js%s", b[++i]);
136+ joyf = 1;
137+ continue;
138+ }
139+ }
140+ printf("joy device = %s\n", joydev);
141+ printf("\n\n");
142+ while (1) {
143+ val = get_joystick();
144+ if (prev_val != val) {
145+ //printf("joy = %d\n", val);
146+ printf("%cM%cM", 27, 27);
147+ print_joystat(val);
148+ prev_val = val;
149+ }
150+ usleep(100000);
151+ }
152+ return 0;
153+}
154+
155+
--- /dev/null
+++ b/kita2.c
@@ -0,0 +1,43 @@
1+/*
2+ * kita2.c
3+ * 2ch kitaaaaaa...
4+ *
5+ * 2002/03/03 by oga.
6+ * 2005/02/11 for http://pc5.2ch.net/test/read.cgi/unix/1019380983/ #138 by oga.
7+ */
8+#include <stdio.h>
9+
10+int main(int a, char *b[])
11+{
12+ int i;
13+ char *kita[7] = {
14+ "(゚∀゚)",
15+ "( ゚∀)",
16+ "(  ゚)",
17+ "(  )",
18+ "(  )",
19+ "(゚  )",
20+ "(∀゚ )"
21+ };
22+
23+ printf("\n");
24+ printf("      *  ※ ☆   ※ ※   ☆ ※  *\n");
25+ printf("     *  ※ ☆  ※   ※   ※  ☆ ※  *\n");
26+ printf("    * ※ ☆ ※   ※ ☆ ※  ※ ☆ ※ *\n");
27+ printf("   * ※ ☆ ※  ※ ☆  .☆ ※  ※ ☆ ※ *\n");
28+ printf("  * ※ ☆ ※ ※☆     ☆※ ※ ☆ ※ *\n");
29+ printf("\n\n\n\n\n\n");
30+
31+ while (1) {
32+ for (i = 0; i < 7; i++) {
33+ printf("%cM%cM%cM%cM%cM%cM", 27, 27, 27, 27, 27, 27);
34+ printf("  * ※キタ━━━━━%s━━━━━ !!!※ *\n", kita[i]);
35+ printf("  * ※ ☆ ※ ※☆     ☆※ ※ ☆ ※ *\n");
36+ printf("   * ※ ☆ ※  ※ ☆  .☆ ※  ※ ☆ ※ *\n");
37+ printf("    * ※ ☆ ※   ※ ☆ ※  ※ ☆ ※ *\n");
38+ printf("     *  ※ ☆  ※   ※   ※  ☆ ※  *\n");
39+ printf("      *  ※ ☆   ※ ※   ☆ ※  *\n");
40+ usleep(200000);
41+ }
42+ }
43+}
--- /dev/null
+++ b/midic.c
@@ -0,0 +1,506 @@
1+/*
2+ * midic: midi compiler
3+ *
4+ * 11/10/01 V0.10 by oga.
5+ */
6+#include <stdio.h>
7+#include <stdlib.h>
8+#include <string.h>
9+
10+/* script format */
11+/*
12+-------------------------
13+# comment
14+SmfFormat=1 (省略可)
15+# 480: 1/4
16+# 240: 1/8
17+# 120: 1/16
18+DeltaTime=480 (省略可)
19+
20+[Track1]
21+TrackName=Track1 (省略可: "")
22+# 00ff03lldddddd...
23+Copyright=Copyright (C)2011 oga. Labo. (省略可: なし)
24+# 00ff02lldddddd...
25+Tempo=120 (省略可: 120)
26+# 00ff5103tttttt
27+Beat=4/4 (省略可: 4/4) {4/4|3/4|6/8|2/2}
28+# 00ff5804 0402 1808
29+
30+[Track2]
31+TrackName=Track2
32+ChannelPrefix=0
33+# 00ff2101nn
34+<Delta>:9xnnvv 904364 (Note On ) G5
35+<Delta>:8xnn00 804300 (Note Off)
36+MML=t120o4l4cdef#gabc+d+e+f#+
37+-------------------------
38+ */
39+
40+/* globals */
41+int vf = 0; /* verbose */
42+
43+/* for header */
44+int HeadLen = 6;
45+short SmfFormat = 1;
46+short NumOfTrack = 0;
47+short DeltaTime = 480; /* 1/4 time */
48+
49+/* for track */
50+int Tempo = 120; /* MM=120 : 500000us */
51+int ChannelPrefix = 0; /* Channel Prefix */
52+int Beat1 = 4; /* Beat1/Beat2 */
53+int Beat2 = 4; /* Beat1/Beat2 */
54+
55+#define MAX_TRACK 16
56+#define ALLOC_SIZE (500*1024) /* 500KB/track */
57+
58+char *TrackData[MAX_TRACK];
59+int TrackLen[MAX_TRACK];
60+
61+/* for Midi Header */
62+#define ID_HEAD "MThd"
63+
64+/* for Midi Track */
65+#define ID_TRACK "MTrk"
66+
67+#define KEY_SMFFMT "SmfFormat="
68+#define KEY_DELTA "DeltaTime="
69+
70+#define SECT_TRACK "[Track"
71+#define KEY_TRACKN "TrackName="
72+#define KEY_COPYR "Copyright="
73+#define KEY_TEMPO "Tempo="
74+#define KEY_BEAT "Beat="
75+#define KEY_CHPREFIX "ChannelPrefix="
76+
77+/* for Midi Command */
78+#define CMD_EndOfTrack "ff2f00"
79+
80+/*
81+ * output syntax error & msg
82+ *
83+ * IN : buf : error script line data
84+ * msg : error message
85+ */
86+void SyntaxErr(char *buf, char *msg)
87+{
88+ printf("Syntax Error: [%s]\n", buf);
89+ if (msg != NULL && strlen(msg)) {
90+ printf("%s\n", msg);
91+ }
92+}
93+
94+/*
95+ * read script file
96+ *
97+ * IN : fp : script file pointer
98+ */
99+int ReadMidiScript(FILE *fp)
100+{
101+ char buf[2048];
102+ char msg[256];
103+ char Copyright[4096];
104+ char TrackName[4096];
105+ char CmdStr[4096];
106+ char *cmd;
107+ int CurTrack = -1; /* current track number */
108+ int PrevTrack = -1; /* previous track number */
109+
110+ while (fgets(buf, sizeof(buf), fp)) {
111+ /* delete CR/LF */
112+ if (buf[strlen(buf)-1] == 0x0a) {
113+ buf[strlen(buf)-1] = '\0';
114+ }
115+ if (buf[strlen(buf)-1] == 0x0d) {
116+ buf[strlen(buf)-1] = '\0';
117+ }
118+ if (vf > 1) printf("DEBUG: ReadMidiScript2: buf=[%s]\n", buf);
119+ if (strlen(buf) == 0) continue; /* blank line */
120+ if (buf[0] == '#') continue; /* comment */
121+
122+ /* Common Info */
123+ if (!strncmp(buf, KEY_SMFFMT, strlen(KEY_SMFFMT))) {
124+ SmfFormat = atoi(&buf[strlen(KEY_SMFFMT)]);
125+ if (vf) printf("SmfFormat=%d\n", SmfFormat);
126+ continue;
127+ }
128+ if (!strncmp(buf, KEY_DELTA, strlen(KEY_DELTA))) {
129+ DeltaTime = atoi(&buf[strlen(KEY_DELTA)]);
130+ if (vf) printf("DeltaTime=%d\n", DeltaTime);
131+ continue;
132+ }
133+
134+ /* Track */
135+ if (!strncmp(buf, SECT_TRACK, strlen(SECT_TRACK))) {
136+ PrevTrack = CurTrack;
137+ CurTrack = atoi(&buf[strlen(SECT_TRACK)]) - 1;
138+ if (CurTrack < 0 || CurTrack >= MAX_TRACK) {
139+ sprintf(msg, "The track number must be %d or less.", MAX_TRACK);
140+ SyntaxErr(buf, msg);
141+ return -1;
142+ }
143+
144+ if (TrackData[CurTrack]) {
145+ SyntaxErr(buf, "Duplicate Track");
146+ return -1;
147+ }
148+ TrackData[CurTrack] = (char *)malloc(ALLOC_SIZE);
149+ memset(TrackData[CurTrack], 0, ALLOC_SIZE);
150+ ++NumOfTrack;
151+ if (PrevTrack >= 0) {
152+ // add EOT
153+ AddMidiCommand(TrackData[PrevTrack], &TrackLen[PrevTrack], 0, CMD_EndOfTrack);
154+ }
155+ if (vf) printf("## Track : %d\n", CurTrack);
156+ continue;
157+ }
158+
159+ if (CurTrack >= 0) {
160+ /* Track Name (str) */
161+ if (!strncmp(buf, KEY_TRACKN, strlen(KEY_TRACKN))) {
162+ strcpy(TrackName, &buf[strlen(KEY_TRACKN)]);
163+ if (vf) printf("TrackName=[%s]\n", TrackName);
164+ if (strlen(TrackName) > 255) {
165+ SyntaxErr(buf, "Track name too long.");
166+ TrackName[256] = '\0';
167+ }
168+ AddMidiCmdStr(TrackData[CurTrack], &TrackLen[CurTrack], "ff03", TrackName);
169+ continue;
170+ }
171+
172+ /* Copyright (str) */
173+ if (!strncmp(buf, KEY_COPYR, strlen(KEY_COPYR))) {
174+ strcpy(Copyright, &buf[strlen(KEY_COPYR)]);
175+ if (vf) printf("Copyright=[%s]\n", Copyright);
176+ if (strlen(Copyright) > 255) {
177+ SyntaxErr(buf, "Copyright too long.");
178+ Copyright[256] = '\0';
179+ }
180+ AddMidiCmdStr(TrackData[CurTrack], &TrackLen[CurTrack], "ff02", Copyright);
181+ continue;
182+ }
183+
184+ /* Tempo */
185+ if (!strncmp(buf, KEY_TEMPO, strlen(KEY_TEMPO))) {
186+ Tempo = atoi(&buf[strlen(KEY_TEMPO)]);
187+ if (vf) printf("Tempo=%d\n", Tempo);
188+ sprintf(CmdStr, "ff5103%06x", 60000000/Tempo); /* ff5103<ms> */
189+ AddMidiCommand(TrackData[CurTrack], &TrackLen[CurTrack], 0, CmdStr);
190+ continue;
191+ }
192+
193+ /* Channel Prefix */
194+ if (!strncmp(buf, KEY_CHPREFIX, strlen(KEY_CHPREFIX))) {
195+ ChannelPrefix = atoi(&buf[strlen(KEY_CHPREFIX)]);
196+ if (vf) printf("ChannelPrefix=%d\n", ChannelPrefix);
197+ sprintf(CmdStr, "ff2101%02x", ChannelPrefix); /* ff2101<chprefix> */
198+ AddMidiCommand(TrackData[CurTrack], &TrackLen[CurTrack], 0, CmdStr);
199+ continue;
200+ }
201+
202+ /* Beat */
203+ if (!strncmp(buf, KEY_BEAT, strlen(KEY_BEAT))) {
204+ char *pt = strchr(&buf[strlen(KEY_BEAT)], '/');
205+ if (pt == NULL) {
206+ sprintf(msg, "ex.)%s4/4\n", KEY_BEAT);
207+ SyntaxErr(buf, msg);
208+ } else {
209+ int k, Beat2val = 0;
210+
211+ Beat1 = atoi(&buf[strlen(KEY_BEAT)]);
212+ ++pt; /* skip '/' */
213+ Beat2 = atoi(pt);
214+ if (vf) printf("Beat=%d/%d\n", Beat1, Beat2);
215+ for (k = 0; k < 30; k++) {
216+ if ((Beat2 >> k) & 1) {
217+ Beat2val = k;
218+ break;
219+ }
220+ }
221+ sprintf(CmdStr, "ff5804%02x%02x1808", Beat1, Beat2val); /*ff5804xxyy1808*/
222+ AddMidiCommand(TrackData[CurTrack], &TrackLen[CurTrack], 0, CmdStr);
223+ }
224+ continue;
225+ }
226+
227+ /* midi command */
228+ /* <delta>:9xnnvv */
229+ if (cmd = strchr(buf, ':')) {
230+ char *delta_pt = &buf[0];
231+ int delta;
232+
233+ while(isspace(delta_pt[0])) ++delta_pt;
234+ if (isdigit(delta_pt[0])) {
235+ ++cmd; /* skip ":" */
236+ delta = atoi(delta_pt);
237+ AddMidiCommand(TrackData[CurTrack], &TrackLen[CurTrack], delta, cmd);
238+ } else {
239+ SyntaxErr(buf, "no delta len");
240+ }
241+ continue;
242+ }
243+ }
244+ if (CurTrack < 0) {
245+ SyntaxErr(buf, "No Track Section.");
246+ } else {
247+ SyntaxErr(buf, "unknown command");
248+ }
249+ }
250+ if (CurTrack >= 0) {
251+ AddMidiCommand(TrackData[CurTrack], &TrackLen[CurTrack], 0, CMD_EndOfTrack);
252+ }
253+}
254+
255+/*
256+ * AddDelta()
257+ *
258+ * IN : delta : delta value
259+ * IN/OUT: trackdat : track data
260+ * len : tracklen
261+ *
262+ * DeltaTime bytes: MSB is continuation flag
263+ * 7bit time data
264+ */
265+int AddDelta(unsigned char *trackdat, int *len, int delta)
266+{
267+ char work_delta[4];
268+ int i;
269+ int cnt = 0;
270+
271+ /* delta to bytes */
272+ if (delta == 0) {
273+ work_delta[0] = delta;
274+ ++cnt;
275+ } else {
276+ while (delta) {
277+ work_delta[cnt] = delta & 0x7f;
278+ if (vf > 1) printf("AddDelta: work_delta[%d] = 0x%02x\n", cnt, work_delta[cnt]);
279+ delta = delta >> 7;
280+ ++cnt;
281+ }
282+ }
283+
284+ for (i = 0; i<cnt; i++) {
285+ trackdat[*len + i] = work_delta[(cnt-1)-i];
286+ if (i < cnt-1) {
287+ trackdat[*len + i] |= 0x80; /* set continuation flag */
288+ }
289+ if (vf > 1) printf("AddDelta: trackdat[%d] = 0x%02x\n", *len+i, trackdat[*len+i]);
290+ }
291+ *len += cnt;
292+}
293+
294+/*
295+ * AddMidiCommand()
296+ *
297+ * IN : delta : delta time
298+ * : cmd : midi command (hexadecimal ascii string)
299+ * IN/OUT: trackdat : track data
300+ * len : tracklen
301+ *
302+ */
303+int AddMidiCommand(unsigned char *trackdat, int *len, int delta, char *cmd)
304+{
305+ char work[128];
306+
307+ if (vf > 1) printf("AddMidiCommand: cmd=%s [%c] %d\n", cmd, *cmd, !isspace(*cmd));
308+ /* add delta */
309+ AddDelta(trackdat, len, delta);
310+
311+ /* add midi command */
312+ strcpy(work, "0x");
313+ while ((*cmd != '\0') && (!isspace(*cmd)) && (*cmd != '#')) {
314+ strncpy(&work[2], cmd, 2);
315+ work[4] = '\0';
316+ trackdat[*len] = (unsigned char)strtoul(work,(char **)NULL,0);
317+ if (vf > 1) printf("AddMidiCommand: %s\n", work);
318+ ++(*len);
319+ ++cmd;
320+ ++cmd;
321+ }
322+ if (vf > 1) printf("AddMidiCommand: len = %d\n", *len);
323+}
324+
325+/*
326+ * AddMidiCmdStr()
327+ * add MIDI command & string
328+ *
329+ * IN : delta : always zero
330+ * : cmd : midi command (hexadecimal ascii string)
331+ * : str : string
332+ * IN/OUT: trackdat : track data
333+ * len : tracklen
334+ *
335+ */
336+int AddMidiCmdStr(unsigned char *trackdat, int *len, char *cmd, char *str)
337+{
338+ char CmdStr[4096];
339+
340+ if (strlen(str) > 255) {
341+ return -1;
342+ }
343+
344+ /* add command */
345+ sprintf(CmdStr, "%s%02x", cmd, strlen(str));
346+ AddMidiCommand(trackdat, len, 0, CmdStr);
347+
348+ /* add string */
349+ strcpy(&trackdat[*len], str);
350+ *len += strlen(str);
351+}
352+
353+/*
354+ * write midi data
355+ *
356+ * IN : fp : output file pointer
357+ */
358+int WriteMidi(FILE *fp)
359+{
360+ int i;
361+ int worki;
362+ short works;
363+ int pos = 0;
364+ int size = 0;
365+
366+ /* header */
367+ fwrite(ID_HEAD, 1, strlen(ID_HEAD), fp);
368+
369+ /* convert to big endian and write*/
370+ worki = htonl(HeadLen);
371+ fwrite(&worki, 1, sizeof(worki), fp);
372+ works = htons(SmfFormat);
373+ fwrite(&works, 1, sizeof(works), fp);
374+ works = htons(NumOfTrack);
375+ fwrite(&works, 1, sizeof(works), fp);
376+ works = htons(DeltaTime);
377+ fwrite(&works, 1, sizeof(works), fp);
378+
379+ /* track */
380+ for (i = 0; i < MAX_TRACK; i++) {
381+ if (TrackData[i]) {
382+ fwrite(ID_TRACK, 1, strlen(ID_TRACK), fp);
383+ worki = htonl(TrackLen[i]);
384+ fwrite(&worki, 1, sizeof(worki), fp);
385+ if (vf) printf("Write Track%d len=%d\n", i+1, TrackLen[i]);
386+ pos = 0;
387+ while (pos < TrackLen[i]) {
388+ size = TrackLen[i] - pos;
389+ if (size > 4096) size = 4096;
390+ size = fwrite(&TrackData[i][pos], 1, size, fp);
391+ if (size < 0) {
392+ perror("fwrite");
393+ return -1;
394+ }
395+ pos += size;
396+ }
397+ }
398+ }
399+ return 0;
400+}
401+
402+/*
403+ * Disp Script Sample
404+ */
405+void DispScriptSample()
406+{
407+ printf("#SmfFormat=1\n");
408+ printf("#DeltaTime=480 # 480 = 1/4\n");
409+
410+ printf("[Track1]\n");
411+ printf("#TrackName=Track1\n");
412+ printf("#Copyright=Copyright (C)2011 xxx.\n");
413+ printf("#Beat=4/4 # {4/4 | 3/4 | 6/8 | 2/2}\n");
414+ printf("#Tempo=120\n");
415+
416+ printf("#[Track2]\n");
417+ printf("#TrackName=Track2\n");
418+ printf("#ChannelPrefix=0\n");
419+ printf("<DeltaLen>:9xnnvv #904364 (Note On ) G5\n");
420+ printf("<DeltaLen>:9xnn00 #904300 (Note Off)\n");
421+ printf("<DeltaLen>:8xnnvv #804300 (Note Off)\n");
422+ printf("<DeltaLen>:Cxnn #c072 Program Change (SteelDrum)\n");
423+ printf("# DeltaLen ... 1920:1/1 960:1/2 480:1/4 240:1/8 120:1/16\n");
424+}
425+
426+void usage()
427+{
428+ printf("usage: midic <script> [-o <output.mid>]\n");
429+ printf("usage: midic [-sample]\n");
430+ printf(" -sample: output sample script\n");
431+ exit(1);
432+}
433+
434+int main(int a, char *b[])
435+{
436+ int i;
437+ char *filename = NULL;
438+ char ofname[2048];
439+ FILE *ifp;
440+ FILE *ofp;
441+
442+
443+ strcpy(ofname, "");
444+ for (i = 1; i<a; i++) {
445+ if (!strcmp(b[i],"-h")) {
446+ usage();
447+ }
448+ if (!strcmp(b[i],"-v")) {
449+ ++vf;
450+ continue;
451+ }
452+ if (!strcmp(b[i],"-sample")) {
453+ DispScriptSample();
454+ exit(0);
455+ }
456+ if (i+1 < a && !strcmp(b[i],"-o")) {
457+ strcpy(ofname, b[++i]);
458+ continue;
459+ }
460+ filename = b[i];
461+ }
462+
463+ if (filename) {
464+ if (!(ifp = fopen(filename, "r"))) {
465+ perror(filename);
466+ exit(1);
467+ }
468+ } else {
469+ ifp = stdin;
470+ }
471+
472+ if (filename == NULL && strlen(ofname) == 0) {
473+ usage();
474+ }
475+ if (strlen(ofname) == 0) {
476+ strcpy(ofname, filename);
477+ strcat(ofname, ".mid");
478+ }
479+ printf("output to %s\n", ofname);
480+
481+ memset(TrackData, 0, sizeof(TrackData));
482+ memset(TrackLen, 0, sizeof(TrackLen));
483+
484+ // read script
485+ ReadMidiScript(ifp);
486+ fclose(ifp);
487+
488+ // ouput midi
489+ if (NumOfTrack == 0) {
490+ printf("Error: no track.\n");
491+ exit(1);
492+ }
493+ if (!(ofp = fopen(ofname, "w"))) {
494+ perror(ofname);
495+ exit(1);
496+ }
497+ WriteMidi(ofp);
498+ fclose(ofp);
499+
500+ return 0;
501+}
502+
503+
504+/* vim:ts=4:sw=4:
505+ */
506+
--- /dev/null
+++ b/netmonitor.c
@@ -0,0 +1,445 @@
1+/*
2+ * netmonitor : monitoring network packet and logging
3+ *
4+ * 2001/01/30 V1.00 by oga.
5+ * 2001/02/05 V1.01 fix sum bug
6+ * 2001/06/27 V1.02 support Linux 2.2.x
7+ * 2003/05/12 V1.03 fix ibyte, obyte overflow
8+ * 2003/06/17 V1.04 fix obyte always 0
9+ * 2005/10/02 V1.05 atoi => strtoul
10+ *
11+ */
12+#include <stdio.h>
13+#include <stdlib.h>
14+#include <string.h>
15+#include <time.h>
16+#include <sys/stat.h>
17+#include <unistd.h>
18+
19+enum pkt_id {IPKT, /* 0: Input packets */
20+ IERRS, /* 1: Input errors */
21+ IDROP, /* 2: Input dorp */
22+ IFIFO, /* 3: Input fifo */
23+ IFRAME, /* 4: Input frame */
24+ OPKT, /* 5: Output packets */
25+ OERRS, /* 6: Output errors */
26+ ODROP, /* 7: Output drop */
27+ OFIFO, /* 8: Output fifo */
28+ OCOLLS, /* 9: Output collision */
29+ OCARRIER, /*10: Output carrier */
30+ NUMENT}; /*11: Num of data */
31+
32+typedef struct _if_t {
33+ char name[32]; /* Interface name */
34+ int active; /* active flag */
35+ int mtu; /* MTU size */
36+ unsigned int pktdata[NUMENT]; /* packet data */
37+} if_t;
38+
39+#define NDAT 20 /* max num of interfaces */
40+#define dprintf if (vf) printf
41+
42+/* globals */
43+if_t pktdat[NDAT];
44+if_t pktold[NDAT];
45+
46+int vf = 0;
47+
48+void get_datetime(char *ymd, char *hms)
49+{
50+ time_t tt;
51+
52+ tt = time(0);
53+ strftime(ymd, 16, "%Y/%m/%d", localtime(&tt));
54+ strftime(hms, 10, "%H:%M:%S", localtime(&tt));
55+}
56+
57+/*
58+ * char *get_item(buf,sep,pos,outbuf)
59+ *
60+ * buf内のsepで区切られたpos番目の項目をoutbufにコピーして返します。
61+ * 項目中の前後のスペース文字は削除されます
62+ * bufは1024文字までです
63+ * sepに","を指定すると、",,"は一つの区切り文字として認識されます
64+ *
65+ * IN buf : 切り出し元の文字列(項目がsepで区切られている)
66+ * pos : 1以上の値 (1が最初の項目)
67+ * sep : 項目の区切り文字です " ", ","など
68+ * OUT outbuf : 指定項目の文字列(項目中の後のスペース/改行は削除)
69+ * ret : 成功時 outbuf
70+ * 失敗時 (char *)0
71+ */
72+char *get_item(char *buf, char *sep, int pos, char *outbuf)
73+{
74+ int i;
75+ char *pt = NULL;
76+ char *p;
77+ char wk[1024];
78+
79+ strcpy(wk,buf); /* strtok()はbufを破壊するためコピーして利用する */
80+
81+ for (i = 0; i<pos; i++) {
82+ if (i == 0) {
83+ pt = (char *)strtok(wk,sep);
84+ } else {
85+ pt = (char *)strtok(NULL,sep);
86+ }
87+ if (pt == NULL) break;
88+ }
89+ if (pt == NULL) {
90+ printf("Out of item(%s) pos(%d).",buf,pos);
91+ /* 結果領域クリア */
92+ strcpy(outbuf,"");
93+ return (char *)0;
94+ }
95+
96+ strcpy(outbuf, pt);
97+
98+ /* cut tail space */
99+ p = &outbuf[strlen(outbuf)-1]; /* last char */
100+ while (*p == ' ' || *p == 0x0a) --p;
101+ *(p+1) = '\0';
102+
103+ return outbuf;
104+} /* get_item */
105+
106+
107+/*
108+ * 10桁以上の場合下9桁のみに変更する
109+ *
110+ */
111+void to9digit(char *strnum)
112+{
113+ char buf[64];
114+
115+ if (strlen(strnum) < 10) return;
116+ strcpy(buf, &strnum[strlen(strnum)-9]);
117+ strcpy(strnum, buf);
118+}
119+
120+/*
121+ * get packet information from /proc/net/route,dev for Linux
122+ *
123+ * IN if_t *pkt : if_t *pkt[n]
124+ * OUT ret : 見つかったインタフェーステーブル数を格納する。
125+ */
126+int get_pktdata(if_t pkt[])
127+{
128+ FILE *fp;
129+ char buf[1024],wk[1024];
130+ char *pt;
131+ int i,j,found;
132+
133+ dprintf("---- get_pktdata start ----\n");
134+
135+ /* memset(pkt, 0, sizeof(if_t)*NDAT); */
136+ for (i = 0; i<NDAT; i++) { /* V1.01 */
137+ pkt[i].active = 0;
138+ }
139+
140+ /* get MTU,Ifname */
141+ if (!(fp = fopen("/proc/net/route","r"))) {
142+ perror("fopen /proc/net/route");
143+ exit(1);
144+ }
145+ fgets(buf,sizeof(buf),fp); /* skip header */
146+
147+ /* get Interface MTU */
148+ while (fgets(buf,sizeof(buf),fp)) {
149+ if (get_item(buf,"\t",1,wk)) {
150+ /* strcat(wk,":"); /* "eth0:" */
151+ i = 0;
152+ found = 0;
153+ while(pkt[i].mtu) {
154+ if (!strcmp(pkt[i].name, wk)) {
155+ found = 1;
156+ pkt[i].active = 1; /* V1.01 */
157+ break;
158+ }
159+ i++;
160+ }
161+ if (!found) {
162+ /* まだ未登録なら登録 */
163+ strcpy(pkt[i].name, wk);
164+ if (get_item(buf,"\t",9,wk)) pkt[i].mtu = atoi(wk);
165+
166+ /* V1.02-A start */
167+ if (pkt[i].mtu == 0 || pkt[i].mtu == 40) { /* V1.04-C */
168+ pkt[i].mtu = -1;
169+ }
170+#if 0
171+ if (pkt[i].mtu == 0) {
172+ dprintf("NAME[%s] MTU[%d]\n", pkt[i].name, pkt[i].mtu);
173+ get_mtu(pkt[i].name, &pkt[i].mtu);
174+ }
175+ dprintf("NAME[%s] MTU[%d]\n", pkt[i].name, pkt[i].mtu);
176+#endif
177+ /* V1.02-A end */
178+
179+ pkt[i].active = 1; /* V1.01 */
180+ }
181+ }
182+ }
183+ fclose(fp);
184+
185+ /* get Packet data */
186+ if (!(fp = fopen("/proc/net/dev","r"))) {
187+ perror("fopen /proc/net/dev");
188+ exit(1);
189+ }
190+ fgets(buf,sizeof(buf),fp); /* skip header1 */
191+ fgets(buf,sizeof(buf),fp); /* skip header2 */
192+
193+ while (fgets(buf,sizeof(buf),fp)) {
194+ if (get_item(buf," ",1,wk)) {
195+ i = 0;
196+ while (pkt[i].mtu && i < NDAT) {
197+ /* /proc/net/routeにあるifのみ設定 */
198+ if (strstr(wk,pkt[i].name)) {
199+ pt = (char *)strchr(buf, ':');
200+ if (pt) *pt = ' ';
201+ if (pkt[i].mtu > 0) { /* V1.02-A */
202+ /* Linux -2.0.x (IPKT,OPKT:packets) */
203+ for (j = 0; j<NUMENT; j++) {
204+ if (get_item(buf," ",j+2,wk)) {
205+ pkt[i].pktdata[j] = strtoul(wk,(char **)NULL,0);
206+ }
207+ }
208+ } else { /* V1.02-A */
209+ /* Linux 2.2.x- (IPKT,OPKT:bytes) V1.02-A */
210+ if (get_item(buf," ",2,wk)) pkt[i].pktdata[IPKT] = strtoul(wk,(char **)NULL,0);
211+ //if (get_item(buf," ",2,wk)) {
212+ // to9digit(wk);
213+ // pkt[i].pktdata[IPKT] = strtoul(wk,(char **)NULL,0);
214+ //}
215+ if (get_item(buf," ",4,wk)) pkt[i].pktdata[IERRS] = strtoul(wk,(char **)NULL,0);
216+ if (get_item(buf," ",5,wk)) pkt[i].pktdata[IDROP] = strtoul(wk,(char **)NULL,0);
217+ if (get_item(buf," ",6,wk)) pkt[i].pktdata[IFIFO] = strtoul(wk,(char **)NULL,0);
218+ if (get_item(buf," ",7,wk)) pkt[i].pktdata[IFRAME] = strtoul(wk,(char **)NULL,0);
219+
220+ if (get_item(buf," ",10,wk)) pkt[i].pktdata[OPKT] = strtoul(wk,(char **)NULL,0);
221+ //if (get_item(buf," ",10,wk)) {
222+ // to9digit(wk);
223+ // pkt[i].pktdata[OPKT] = strtoul(wk,(char **)NULL,0);
224+ //}
225+ if (get_item(buf," ",12,wk)) pkt[i].pktdata[OERRS] = strtoul(wk,(char **)NULL,0);
226+ if (get_item(buf," ",13,wk)) pkt[i].pktdata[ODROP] = strtoul(wk,(char **)NULL,0);
227+ if (get_item(buf," ",14,wk)) pkt[i].pktdata[OFIFO] = strtoul(wk,(char **)NULL,0);
228+ if (get_item(buf," ",15,wk)) pkt[i].pktdata[OCOLLS] = strtoul(wk,(char **)NULL,0);
229+ if (get_item(buf," ",16,wk)) pkt[i].pktdata[OCARRIER] = strtoul(wk,(char **)NULL,0);
230+ } /* V1.02-A */
231+ break;
232+ }
233+ i++;
234+ }
235+ }
236+ }
237+ fclose(fp);
238+
239+ /* count num of interfaces */
240+ i = 0;
241+ while (pkt[i].mtu && i < NDAT) {
242+ if (vf) {
243+ printf("IF:[%4s] active[%d] MTU[%d] IN[%u] OUT[%u]\n",
244+ pkt[i].name,
245+ pkt[i].active, /* V1.01 */
246+ pkt[i].mtu,
247+ pkt[i].pktdata[IPKT],
248+ pkt[i].pktdata[OPKT]);
249+ }
250+ i++;
251+ }
252+ dprintf("---- get_pktdata end ----\n");
253+ return i;
254+}
255+
256+/* wait next 00 minutes */
257+void wait_next_00min()
258+{
259+ char ymd[32];
260+ char hms[32];
261+ int i = 0;
262+
263+ while (1) {
264+ get_datetime(ymd, hms);
265+ if (!strncmp(&hms[3], "00", 2)) {
266+ /* if HH:00:SS then break */
267+ break;
268+ }
269+ /* for temporary interface (ig. ppp0) */
270+ if ((++i % 18) == 0) { /* V1.01-A */
271+ /* if check every 3 min */
272+ get_pktdata(pktdat); /* V1.01-A */
273+ } /* V1.01-A */
274+ sleep(10);
275+ }
276+}
277+
278+void usage()
279+{
280+ printf("usage: netmonitor [-up <interval_sec>] [-if <if_name>] [-csv] [<outfile.csv>]\n");
281+ exit(1);
282+}
283+
284+int main(int a, char *b[])
285+{
286+ FILE *fp = NULL;
287+ char *fname = NULL;
288+ char ymd[32];
289+ char hms[32];
290+
291+ int i, j;
292+ int ifnum;
293+ int af = 0; /* -a output lo: interface */
294+ int csvf = 0; /* -csv output csv format */
295+ int interval = 60; /* -up interval sec */
296+ char *ifname = NULL; /* -if interface name */
297+ int existfile = 0;
298+
299+ struct stat stbuf;
300+
301+ /* arg check */
302+ for (i = 1; i<a; i++) {
303+ if (!strcmp(b[i],"-a")) {
304+ af = 1; /* display lo: */
305+ continue;
306+ }
307+ if (!strcmp(b[i],"-up")) {
308+ if (i+1 >= a) {
309+ usage();
310+ }
311+ interval = atoi(b[++i]);
312+ if (interval <= 0) {
313+ printf("Warning: invalid interval. 60 sec assumed.\n");
314+ interval = 60;
315+ }
316+ continue;
317+ }
318+ if (!strcmp(b[i],"-if")) {
319+ if (i+1 >= a) {
320+ usage();
321+ }
322+ ifname = b[++i];
323+ continue;
324+ }
325+ if (!strcmp(b[i],"-csv")) {
326+ csvf = 1;
327+ continue;
328+ }
329+ if (!strcmp(b[i],"-v")) {
330+ vf = 1;
331+ continue;
332+ }
333+ if (!strncmp(b[i],"-h",2)) {
334+ usage();
335+ }
336+ fname = b[i];
337+ }
338+
339+ memset(pktdat, 0, sizeof(pktdat));
340+ memset(pktold, 0, sizeof(pktold));
341+
342+ /* open file */
343+ if (fname == NULL) {
344+ fp = stdout;
345+ } else {
346+ if (!stat(fname, &stbuf)) {
347+ if (stbuf.st_size != 0) {
348+ existfile = 1;
349+ }
350+ }
351+ if ((fp = fopen(fname,"a")) == 0) {
352+ perror(b[0]);
353+ exit(1);
354+ }
355+ }
356+
357+ get_pktdata(pktold);
358+
359+ if (fp == stdout && !csvf) {
360+ fprintf(fp," Time IfName MTU Ipkt Ierrs Idrop Opkt Oerrs Odrop Ocolls\n");
361+ } else {
362+ if (!existfile) {
363+ fprintf(fp,"Date,Time,IfName,MTU,Ipkt,In(KB),Ierrs,Idrop,Opkt,Out(KB),Oerrs,Odrop,Ocolls\n");
364+ fflush(fp);
365+ }
366+ }
367+
368+ while(1) {
369+ ifnum = get_pktdata(pktdat);
370+ for (i = 0; i<ifnum; i++) {
371+ if (pktdat[i].pktdata[IPKT] < pktold[i].pktdata[IPKT]) { /*V1.01-A*/
372+ /* interface restart or wraparound */
373+ for (j = 0; j<NUMENT; j++) { /*V1.01-A*/
374+ pktold[i].pktdata[j] = 0; /*V1.01-A*/
375+ } /*V1.01-A*/
376+ } /*V1.01-A*/
377+ if (!af && !strcmp(pktdat[i].name, "lo")) {
378+ /* if not -a, skip "lo" interface */
379+ continue;
380+ }
381+ if (ifname) {
382+ /* -if option specified */
383+ if (!strstr(pktdat[i].name, ifname)) {
384+ /* not target interface */
385+ continue;
386+ }
387+ }
388+ get_datetime(ymd, hms);
389+ if (fp == stdout && !csvf) {
390+ fprintf(fp, "%8s %6s %4d %10u %5u %5u %10u %5u %5u %7u\n",
391+ hms,
392+ pktdat[i].name,
393+ pktdat[i].mtu,
394+ pktdat[i].pktdata[IPKT] -pktold[i].pktdata[IPKT],
395+ pktdat[i].pktdata[IERRS] -pktold[i].pktdata[IERRS],
396+ pktdat[i].pktdata[IDROP] -pktold[i].pktdata[IDROP],
397+ pktdat[i].pktdata[OPKT] -pktold[i].pktdata[OPKT],
398+ pktdat[i].pktdata[OERRS] -pktold[i].pktdata[OERRS],
399+ pktdat[i].pktdata[ODROP] -pktold[i].pktdata[ODROP],
400+ pktdat[i].pktdata[OCOLLS]-pktold[i].pktdata[OCOLLS]);
401+ } else {
402+ /* spcify file or -csv specify */
403+ if (!existfile) {
404+ /* V1.02-A start */
405+ int ikb, okb;
406+ if (pktdat[i].mtu > 0) { /* Linux -2.0.x (packets) */
407+ ikb = (pktdat[i].pktdata[IPKT] -pktold[i].pktdata[IPKT])*pktdat[i].mtu/1024;
408+ okb = (pktdat[i].pktdata[OPKT] -pktold[i].pktdata[OPKT])*pktdat[i].mtu/1024;
409+ } else { /* Linux 2.2.x- (pktdata:bytes) */
410+ ikb = (pktdat[i].pktdata[IPKT] - pktold[i].pktdata[IPKT])/1024;
411+ okb = (pktdat[i].pktdata[OPKT] -pktold[i].pktdata[OPKT])/1024;
412+ }
413+ /* V1.02-A end */
414+
415+ /*Dt,Tm,Ifnm,MTU,Ipkt,I(KB),Ier,Idr,Opkt,O(KB),Oer,Odr,Ocol*/
416+ fprintf(fp, "%s,%s,%s,%d,%u,%u,%u,%u,%u,%u,%u,%u,%u\n",
417+ ymd, hms,
418+ pktdat[i].name,
419+ pktdat[i].mtu,
420+ pktdat[i].pktdata[IPKT] -pktold[i].pktdata[IPKT],
421+ ikb, /* V1.02-C */
422+ pktdat[i].pktdata[IERRS] -pktold[i].pktdata[IERRS],
423+ pktdat[i].pktdata[IDROP] -pktold[i].pktdata[IDROP],
424+ pktdat[i].pktdata[OPKT] -pktold[i].pktdata[OPKT],
425+ okb, /* V1.02-C */
426+ pktdat[i].pktdata[OERRS] -pktold[i].pktdata[OERRS],
427+ pktdat[i].pktdata[ODROP] -pktold[i].pktdata[ODROP],
428+ pktdat[i].pktdata[OCOLLS]-pktold[i].pktdata[OCOLLS]);
429+ fflush(fp);
430+ }
431+ existfile = 0;
432+ }
433+ }
434+ memcpy(pktold, pktdat, sizeof(pktold));
435+ if (interval == 3600) {
436+ sleep(61);
437+ wait_next_00min();
438+ } else {
439+ sleep(interval);
440+ }
441+ }
442+
443+ if (fp != stdout) fclose(fp);
444+}
445+
--- /dev/null
+++ b/othello2.c
@@ -0,0 +1,57 @@
1+/*
2+ * 7 line program : Othello by 2ch
3+ * http://piza2.2ch.net/test/read.cgi?bbs=tech&key=984182993
4+ */
5+#include <stdio.h>
6+#define R(x,v,w,y,z) r(i,c,x,(v>w?w:v))|r(i,c,-x,(y>z?z:y))
7+char n[]=" \\MD[REJQZBCIUY:<;A@^XP5]=`8cdkVbmFNWelGO9?_gf32>4on0H1i67jha";
8+int i,c,p,s[8],m[64],y,z;
9+
10+d()
11+{
12+ for(c=0;c<64;c++){
13+ printf("%s%s","┼\0●\0○"+m[c]*3,(2-(c%8==7)-(c==63))+"\n\n");
14+ }
15+ printf("%cM%cM%cM%cM%cM%cM%cM%cM%cM%cM\n",27,27,27,27,27,27,27,27,27,27);
16+ usleep(500000);
17+}
18+
19+r(int i,int c,int d,int e)
20+{
21+ p=0;
22+ while(e-->0&&(c+=d,m[c])) {
23+ if(m[c]-i) {
24+ s[p++]=c;
25+ } else{
26+ d=p;
27+ while(p) {
28+ m[s[--p]]=i;
29+ }
30+ return d;
31+ }
32+ }
33+ return 0;
34+}
35+q(int i,int c)
36+{
37+ y=c%8,z=c/8;
38+ if(R(1,7-y,7,y,7)|R(7,y,7-z,7-y,z)|R(8,7,7-z,7,z)|R(9,7-y,7-z,y,z))
39+ {
40+ m[c]=i;
41+ d();
42+ } else {
43+ q(3-i,c);
44+ }
45+}
46+
47+main()
48+{
49+ m[28]=m[35]=1;
50+ m[27]=m[36]=2;
51+ d();
52+ while(i++<60){
53+ q(2-i%2,n[i]-48);
54+ }
55+ printf("\n\n\n\n\n\n\n\n");
56+}
57+
--- /dev/null
+++ b/peke.c
@@ -0,0 +1,463 @@
1+/*
2+ * peke.c : ○×ゲーム for WWW
3+ *
4+ * 96/06/23 V1.00 by oga.
5+ * 96/06/27 V1.10 VS computer support.
6+ * 96/07/05 V1.11 add ALT= for lynx
7+ * 96/07/05 V1.12 ○が勝ったのに2を返す不良を修正
8+ *
9+ * ret : -1...勝敗未決
10+ * ret : 0...勝敗未決
11+ * 1...○の勝ち
12+ * 2...×の勝ち
13+ * 3...引き分け
14+ */
15+#include <stdio.h>
16+#include <stdlib.h>
17+#include <string.h>
18+#include <sys/stat.h>
19+
20+int check_ban();
21+void disp_boad();
22+int check_win();
23+void com_think();
24+int ck_num();
25+int check_mate();
26+void put_rnd();
27+
28+int vf=0;
29+
30+main(a,b)
31+int a;
32+char *b[];
33+{
34+ FILE *fp;
35+ struct stat st;
36+ char buf[1024];
37+ int koma;
38+ int i, x, y;
39+ int endf=0;
40+ int sf = 0;
41+
42+ if (a < 3) {
43+ printf("usage : peke <filename> <locate> [-s] [-v]\n");
44+ printf(" locate : [0-2][0-2]>\n");
45+ printf(" 90 is reset.\n");
46+ printf(" 91 is display current status.\n");
47+ printf(" -s : single player mode\n");
48+ printf(" -v : cancel URL output\n");
49+ exit(-1);
50+ }
51+ if (a > 3) {
52+ for (i = 3; i< a; i++) {
53+ if (!strcmp(b[i],"-v")) {
54+ vf = 1;
55+ }
56+ if (!strcmp(b[i],"-s")) {
57+ sf = 1;
58+ }
59+ }
60+ }
61+ if (stat(b[1],&st) || !strcmp(b[2],"90")) {
62+ if (!(fp = fopen(b[1],"w"))) {
63+ perror("fopen1");
64+ exit(-1);
65+ }
66+ if (sf) {
67+ /* for single player */
68+ fprintf(fp,"000010000");
69+ } else {
70+ fprintf(fp,"000000000");
71+ }
72+ fclose(fp);
73+ if (!strcmp(b[2],"90")) {
74+ exit(0);
75+ }
76+ }
77+
78+ if ((fp = fopen(b[1],"r")) == 0) {
79+ perror("fopen2");
80+ exit(-1);
81+ }
82+ fgets(buf,sizeof(buf),fp);
83+ fclose(fp);
84+
85+ if (!strcmp(b[2],"91")) {
86+ /* display current board */
87+ disp_boad(buf,endf);
88+ exit(0);
89+ }
90+
91+ if (strlen(buf) != 9) {
92+ printf("Invalid file type for peke!\n");
93+ fclose(fp);
94+ exit(-1);
95+ }
96+ x = b[2][0] - '0';
97+ y = b[2][1] - '0';
98+ if (buf[x+y*3] != '0') {
99+ if (vf) {
100+ printf("そこには置けません!!\n");
101+ } else {
102+ printf("そこには置けません!!\n");
103+ }
104+ fclose(fp);
105+ disp_boad(buf,endf);
106+ exit(-1);
107+ }
108+
109+ /* どちらの番かチェックし、コマを置く */
110+ buf[x+y*3] = check_ban(buf);
111+
112+ if (endf = check_win(buf)) {
113+ /* game is over */
114+ unlink(b[1]);
115+ }
116+
117+ /* コンピュータ対戦モードの場合 */
118+ if (!endf && sf && strcmp(b[2],"91")) {
119+ /* コンピュータの番 (status mode(91) でない場合) */
120+ com_think(buf);
121+
122+ if (endf = check_win(buf)) {
123+ /* game is over */
124+ unlink(b[1]);
125+ }
126+ }
127+ disp_boad(buf,endf);
128+
129+ if (!(fp = fopen(b[1],"w"))) {
130+ perror("fopen3");
131+ exit(-1);
132+ }
133+ fprintf(fp,"%s",buf);
134+ fclose(fp);
135+
136+ if (endf) {
137+ if (endf < 0) endf = 3; /* 引き分け */
138+ /* game over */
139+ if (endf == '1') endf = 1;
140+ if (endf == '2') endf = 2;
141+ return endf;
142+ }
143+ return 0; /* 勝敗未決 */
144+}
145+
146+/* check_ban() : どちらの番かチェックする
147+ *
148+ * ret : '1' ○の番
149+ * '2' ×の番
150+ */
151+int check_ban(buf)
152+char *buf;
153+{
154+ int i,maru=0,peke=0;
155+
156+ for (i = 0; i<9; i++) {
157+ if (buf[i] == '1') {
158+ maru++;
159+ }
160+ if (buf[i] == '2') {
161+ peke++;
162+ }
163+ }
164+ if (maru == peke) {
165+ return '1'; /* ○の番 */
166+ } else {
167+ return '2'; /* ×の番 */
168+ }
169+}
170+
171+/* disp_boad() : 板の表示
172+ *
173+ * endf : 0以外の場合、空白地帯のリンクを行なわない
174+ */
175+void disp_boad(buf,endf)
176+char *buf;
177+int endf;
178+{
179+ int i;
180+
181+ printf("<html>\n");
182+ for (i=0; i<9; i++) {
183+ switch(buf[i]) {
184+ case '0':
185+ if (vf) {
186+ printf("□");
187+ } else {
188+ if (endf) {
189+ printf("<img src=%c/gif/waku.gif%c",'"','"');
190+ printf(" alt=%c□%c>",'"','"');
191+ } else {
192+ printf("<a href=%c/cgi-bin/%d%d.cgi%c>",'"',i % 3, i/3,'"');
193+ printf("<img src=%c/gif/waku.gif%c",'"','"');
194+ printf(" border=%c0%c",'"','"');
195+ printf(" alt=%c□%c>",'"','"');
196+ printf("</a>");
197+ }
198+ }
199+ break;
200+ case '1':
201+ if (vf)
202+ printf("○");
203+ else
204+ printf("<img src=%c/gif/maru.gif%c",'"','"');
205+ printf(" alt=%c○%c>",'"','"');
206+ break;
207+ case '2':
208+ if (vf)
209+ printf("×");
210+ else
211+ printf("<img src=%c/gif/batsu.gif%c",'"','"');
212+ printf(" alt=%c×%c>",'"','"');
213+ break;
214+ }
215+ if ((i % 3) == 2) {
216+ if (vf)
217+ printf("\n");
218+ else
219+ printf("<br>\n");
220+ }
221+ }
222+ printf("</html>\n");
223+
224+}
225+
226+/* check_win() : 勝ったかどうかのチェック
227+ *
228+ * ret '1' or '2' : ○ or × の勝ち
229+ * -1 : 引分け
230+ * 0 : 勝敗未決
231+ *
232+ */
233+int check_win(buf)
234+char *buf;
235+{
236+ int x,y;
237+ /* 縦チェック */
238+ for (x=0;x<3;x++) {
239+ if (buf[x] != '0' && buf[x] == buf[x+3] && buf[x] == buf[x+6]) {
240+ if (vf)
241+ printf("%s の勝ちです。\n",(buf[x]=='1')? "○" : "×");
242+ else
243+ printf("<h1>%s の勝ちです。</h1>",(buf[x]=='1')? "○" : "×");
244+ return buf[x];
245+ }
246+ }
247+ /* 横チェック */
248+ for (y=0;y<3;y++) {
249+ if (buf[y*3] != '0' && buf[y*3] == buf[y*3+1] && buf[y*3] == buf[y*3+2]) {
250+ if (vf)
251+ printf("%s の勝ちです。\n",(buf[y*3]=='1')? "○" : "×");
252+ else
253+ printf("<h1>%s の勝ちです。</h1>\n",(buf[y*3]=='1')? "○" : "×");
254+ return buf[y*3]; /* V1.12 */
255+ }
256+ }
257+ /* 斜めチェック */
258+ if (buf[0] != '0' && buf[0] == buf[4] && buf[0] == buf[8]) {
259+ if (vf)
260+ printf("%s の勝ちです。\n",(buf[0]=='1')? "○" : "×");
261+ else
262+ printf("<h1>%s の勝ちです。</h1>\n",(buf[0]=='1')? "○" : "×");
263+ return buf[0];
264+ }
265+ if (buf[2] != '0' && buf[2] == buf[4] && buf[2] == buf[6]) {
266+ if (vf)
267+ printf("%s の勝ちです。\n",(buf[2]=='1')? "○" : "×");
268+ else
269+ printf("<h1>%s の勝ちです。</h1>\n",(buf[2]=='1')? "○" : "×");
270+ return buf[2];
271+ }
272+ if (!strchr(buf,'0')) {
273+ if (vf)
274+ printf("引分けです。\n");
275+ else
276+ printf("<h1>引分けです。</h1>\n");
277+ return -1;
278+ }
279+ return 0;
280+}
281+
282+/*
283+ * com_think() : コンピュータ(○)側思考ルーチン (C) oga.
284+ *
285+ */
286+void com_think(buf)
287+char *buf;
288+{
289+ int i,num;
290+
291+ /* ○が勝てる場合、そこに置く */
292+ if (check_mate(buf,'1')) {
293+ /* 勝った! */
294+ return;
295+ }
296+
297+ /* ×が勝ちそうな場合、阻止する */
298+ if (check_mate(buf,'2')) {
299+ /* 阻止した! */
300+ return;
301+ }
302+
303+ num = ck_num(buf);
304+ switch (num) {
305+ case 2:
306+ if (buf[1]=='2') {
307+ buf[3] = '1';
308+ } else if (buf[3]=='2') {
309+ buf[7] = '1';
310+ } else if (buf[5]=='2') {
311+ buf[1] = '1';
312+ } else if (buf[7]=='2') {
313+ buf[5] = '1';
314+ } else {
315+ put_rnd(buf);
316+ }
317+ break;
318+ case 4:
319+ if (buf[1]=='1' && buf[2]=='0') {
320+ buf[2] = '1';
321+ } else if (buf[3]=='1' && buf[0]=='0') {
322+ buf[0] = '1';
323+ } else if (buf[5]=='1' && buf[8]=='0') {
324+ buf[8] = '1';
325+ } else if (buf[7]=='1' && buf[6]=='0') {
326+ buf[6] = '1';
327+ } else {
328+ put_rnd(buf);
329+ }
330+ break;
331+ default :
332+ put_rnd(buf);
333+ }
334+}
335+
336+int ck_num(buf)
337+char *buf;
338+{
339+ int i,num=0;
340+ for (i = 0; i<9; i++) {
341+ if (buf[i] != '0') num++;
342+ }
343+ return num;
344+}
345+
346+/*
347+ * check_mate() : 勝てる場合、そこにコマをおいてリターン
348+ * 相手の勝ちを阻止する場合にも使う
349+ *
350+ * koma : ここに指定したコマが勝てる場合、そこに○コマをおいてリターン
351+ * ret : 0 no put
352+ * 1 put (win!)
353+ */
354+int check_mate(buf,koma)
355+char *buf;
356+char koma;
357+{
358+ int code = 0;
359+ int i,num=0;
360+ char rev;
361+
362+ if ( koma == '1' ) {
363+ rev = '2';
364+ } else {
365+ rev = '1';
366+ }
367+
368+ for (i = 0; i<3; i++) {
369+ /* ×がなくて空白が1個? */
370+ /* 横チェック */
371+ if ((buf[i*3+0] != rev && buf[i*3+1] != rev && buf[i*3+2] != rev) &&
372+ (buf[i*3+0]+buf[i*3+1]+buf[i*3+2] == koma* 2 + '0')) {
373+ if (buf[i*3+0] == '0') {
374+ buf[i*3+0] = '1'; /* put chip for win! */
375+ return 1;
376+ }
377+ if (buf[i*3+1] == '0') {
378+ buf[i*3+1] = '1'; /* put chip for win! */
379+ return 1;
380+ }
381+ if (buf[i*3+2] == '0') {
382+ buf[i*3+2] = '1'; /* put chip for win! */
383+ return 1;
384+ }
385+ }
386+ /* 縦チェック */
387+ if ((buf[i+0] != rev && buf[i+3] != rev && buf[i+6] != rev) &&
388+ (buf[i+0]+buf[i+3]+buf[i+6] == koma * 2 + '0')) {
389+ if (buf[i+0] == '0') {
390+ buf[i+0] = '1'; /* put chip for win! */
391+ return 1;
392+ }
393+ if (buf[i+3] == '0') {
394+ buf[i+3] = '1'; /* put chip for win! */
395+ return 1;
396+ }
397+ if (buf[i+6] == '0') {
398+ buf[i+6] = '1'; /* put chip for win! */
399+ return 1;
400+ }
401+ }
402+ }
403+ /* 斜めチェック1 */
404+ if ((buf[0] != rev && buf[4] != rev && buf[8] != rev) &&
405+ (buf[0]+buf[4]+buf[8] == koma * 2 + '0')) {
406+ if (buf[0] == '0') {
407+ buf[0] = '1'; /* put chip for win! */
408+ return 1;
409+ }
410+ if (buf[4] == '0') {
411+ buf[4] = '1'; /* put chip for win! */
412+ return 1;
413+ }
414+ if (buf[8] == '0') {
415+ buf[8] = '1'; /* put chip for win! */
416+ return 1;
417+ }
418+ }
419+ /* 斜めチェック2 */
420+ if ((buf[2] != rev && buf[4] != rev && buf[6] != rev) &&
421+ (buf[2]+buf[4]+buf[6] == koma * 2 + '0')) {
422+ if (buf[2] == '0') {
423+ buf[2] = '1'; /* put chip for win! */
424+ return 1;
425+ }
426+ if (buf[4] == '0') {
427+ buf[4] = '1'; /* put chip for win! */
428+ return 1;
429+ }
430+ if (buf[6] == '0') {
431+ buf[6] = '1'; /* put chip for win! */
432+ return 1;
433+ }
434+ }
435+
436+ /* no put */
437+ return 0;
438+}
439+
440+/*
441+ * put_rnd() : ランダムに"○"コマを置く
442+ *
443+ */
444+void put_rnd(buf)
445+char *buf;
446+{
447+ int rnd;
448+ int i;
449+
450+ srand(time(0)); /* 乱数系列初期化 */
451+ rnd = rand();
452+ rnd = (int)((float)rnd/RAND_MAX*10)+1;
453+ while(1) {
454+ for (i = 0; i<9; i++) {
455+ if (buf[i] == '0') {
456+ if (--rnd < 1) {
457+ buf[i] = '1';
458+ return;
459+ }
460+ }
461+ }
462+ }
463+}
--- /dev/null
+++ b/peke2.c
@@ -0,0 +1,422 @@
1+/*
2+ * peke.c : ○×ゲーム for WWW
3+ *
4+ * 96/06/23 V1.00 by oga.
5+ * 96/06/26 V1.10 VS computer support.
6+ *
7+ * ret : 2...game is over
8+ */
9+#include <stdio.h>
10+#include <stdlib.h>
11+#include <string.h>
12+#include <sys/stat.h>
13+
14+int check_ban();
15+void disp_boad();
16+int check_win();
17+void com_think();
18+int ck_num();
19+int check_mate();
20+void put_rnd();
21+
22+int vf=0;
23+
24+main(a,b)
25+int a;
26+char *b[];
27+{
28+ FILE *fp;
29+ struct stat st;
30+ char buf[1024];
31+ int koma;
32+ int i, x, y;
33+ int endf=0;
34+ int sf = 0;
35+
36+ if (a < 3) {
37+ printf("usage : peke <filename> <locate> [-s] [-v]\n");
38+ printf(" locate : [0-2][0-2]>\n");
39+ printf(" 90 is reset.\n");
40+ printf(" 91 is display current status.\n");
41+ printf(" -s : single player mode\n");
42+ printf(" -v : cancel URL output\n");
43+ exit(1);
44+ }
45+ if (a > 3) {
46+ for (i = 3; i< a; i++) {
47+ if (!strcmp(b[i],"-v")) {
48+ vf = 1;
49+ }
50+ if (!strcmp(b[i],"-s")) {
51+ sf = 1;
52+ }
53+ }
54+ }
55+ if (stat(b[1],&st) || !strcmp(b[2],"90")) {
56+ if (!(fp = fopen(b[1],"w"))) {
57+ perror("fopen1");
58+ exit(1);
59+ }
60+ if (sf) {
61+ /* for single player */
62+ fprintf(fp,"000010000");
63+ } else {
64+ fprintf(fp,"000000000");
65+ }
66+ fclose(fp);
67+ if (!strcmp(b[2],"90")) {
68+ exit(1);
69+ }
70+ }
71+
72+ if ((fp = fopen(b[1],"r")) == 0) {
73+ perror("fopen2");
74+ exit(1);
75+ }
76+ fgets(buf,sizeof(buf),fp);
77+ fclose(fp);
78+
79+ if (!strcmp(b[2],"91")) {
80+ /* display current board */
81+ disp_boad(buf,endf);
82+ exit(0);
83+ }
84+
85+ if (strlen(buf) != 9) {
86+ printf("Invalid file type for peke!\n");
87+ fclose(fp);
88+ exit(1);
89+ }
90+ x = b[2][0] - '0';
91+ y = b[2][1] - '0';
92+ if (buf[x+y*3] != '0') {
93+ if (vf) {
94+ printf("そこには置けません!!\n");
95+ } else {
96+ printf("そこには置けません!!\n");
97+ }
98+ fclose(fp);
99+ disp_boad(buf,endf);
100+ exit(1);
101+ }
102+
103+ /* どちらの番かチェックし、コマを置く */
104+ buf[x+y*3] = check_ban(buf);
105+
106+ if (check_win(buf)) {
107+ /* game is over */
108+ unlink(b[1]);
109+ endf = 1;
110+ }
111+
112+ if (!endf && sf && strcmp(b[2],"91")) {
113+ /* コンピュータの番 (status mode(91) でない場合) */
114+ com_think(buf);
115+
116+ if (check_win(buf)) {
117+ /* game is over */
118+ unlink(b[1]);
119+ endf = 1;
120+ }
121+ }
122+ disp_boad(buf,endf);
123+
124+ if (!(fp = fopen(b[1],"w"))) {
125+ perror("fopen3");
126+ exit(1);
127+ }
128+ fprintf(fp,"%s",buf);
129+ fclose(fp);
130+
131+ if (endf) {
132+ /* game over */
133+ return 2;
134+ }
135+ return 0;
136+}
137+
138+/* check_ban() : どちらの番かチェックする
139+ *
140+ * ret : '1' ○の番
141+ * '2' ×の番
142+ */
143+int check_ban(buf)
144+char *buf;
145+{
146+ int i,maru=0,peke=0;
147+
148+ for (i = 0; i<9; i++) {
149+ if (buf[i] == '1') {
150+ maru++;
151+ }
152+ if (buf[i] == '2') {
153+ peke++;
154+ }
155+ }
156+ if (maru == peke) {
157+ return '1'; /* ○の番 */
158+ } else {
159+ return '2'; /* ×の番 */
160+ }
161+}
162+
163+/* disp_boad() : 板の表示
164+ *
165+ * endf : 空白地帯のリンクを行なわない
166+ */
167+void disp_boad(buf,endf)
168+char *buf;
169+int endf;
170+{
171+ int i;
172+ for (i=0; i<9; i++) {
173+ switch(buf[i]) {
174+ case '0':
175+ if (vf) {
176+ printf("□");
177+ } else {
178+ if (endf) {
179+ printf("<img src=%c/gif/waku.gif%c>",'"','"');
180+ } else {
181+ printf("<a href=%c/cgi-bin/%d%d.cgi%c>",'"',i % 3, i/3,'"');
182+ printf("<img src=%c/gif/waku.gif%c",'"','"');
183+ printf(" border=%c0%c>",'"','"');
184+ printf("</a>");
185+ }
186+ }
187+ break;
188+ case '1':
189+ if (vf)
190+ printf("○");
191+ else
192+ printf("<img src=%c/gif/maru.gif%c>",'"','"');
193+ break;
194+ case '2':
195+ if (vf)
196+ printf("×");
197+ else
198+ printf("<img src=%c/gif/batsu.gif%c>",'"','"');
199+ break;
200+ }
201+ if ((i % 3) == 2) {
202+ if (vf)
203+ printf("\n");
204+ else
205+ printf("<br>\n");
206+ }
207+ }
208+
209+}
210+
211+/* check_win() : 勝ったかどうかのチェック
212+ *
213+ * ret '1' or '2' : ○ or × の勝ち
214+ * -1 : 引分け
215+ * 0 : 勝敗未決
216+ *
217+ */
218+int check_win(buf)
219+char *buf;
220+{
221+ int x,y;
222+ for (x=0;x<3;x++) {
223+ if (buf[x] != '0' && buf[x] == buf[x+3] && buf[x] == buf[x+6]) {
224+ if (vf)
225+ printf("%s の勝ちです。\n",(buf[x]=='1')? "○" : "×");
226+ else
227+ printf("<h1>%s の勝ちです。</h1>",(buf[x]=='1')? "○" : "×");
228+ return buf[x];
229+ }
230+ }
231+ for (y=0;y<3;y++) {
232+ if (buf[y*3] != '0' && buf[y*3] == buf[y*3+1] && buf[y*3] == buf[y*3+2]) {
233+ if (vf)
234+ printf("%s の勝ちです。\n",(buf[y*3]=='1')? "○" : "×");
235+ else
236+ printf("<h1>%s の勝ちです。</h1>\n",(buf[y*3]=='1')? "○" : "×");
237+ return buf[y];
238+ }
239+ }
240+ if (buf[0] != '0' && buf[0] == buf[4] && buf[0] == buf[8]) {
241+ if (vf)
242+ printf("%s の勝ちです。\n",(buf[0]=='1')? "○" : "×");
243+ else
244+ printf("<h1>%s の勝ちです。</h1>\n",(buf[0]=='1')? "○" : "×");
245+ return buf[0];
246+ }
247+ if (buf[2] != '0' && buf[2] == buf[4] && buf[2] == buf[6]) {
248+ if (vf)
249+ printf("%s の勝ちです。\n",(buf[2]=='1')? "○" : "×");
250+ else
251+ printf("<h1>%s の勝ちです。</h1>\n",(buf[2]=='1')? "○" : "×");
252+ return buf[2];
253+ }
254+ if (!strchr(buf,'0')) {
255+ if (vf)
256+ printf("引分けです。\n");
257+ else
258+ printf("<h1>引分けです。</h1>\n");
259+ return -1;
260+ }
261+ return 0;
262+}
263+
264+void com_think(buf)
265+char *buf;
266+{
267+ int i,num;
268+
269+ if (check_mate(buf)) {
270+ return;
271+ }
272+ num = ck_num(buf);
273+ switch (num) {
274+ case 2:
275+ if (buf[1]=='0') {
276+ buf[3] = '1';
277+ } else if (buf[3]=='0') {
278+ buf[7] = '1';
279+ } else if (buf[5]=='0') {
280+ buf[1] = '1';
281+ } else if (buf[7]=='0') {
282+ buf[5] = '1';
283+ } else {
284+ put_rnd(buf);
285+ }
286+ break;
287+ case 4:
288+ if (buf[1]=='1') {
289+ buf[2] = '1';
290+ } else if (buf[3]=='1') {
291+ buf[0] = '1';
292+ } else if (buf[5]=='1') {
293+ buf[7] = '1';
294+ } else if (buf[7]=='1') {
295+ buf[6] = '1';
296+ } else {
297+ put_rnd(buf);
298+ }
299+ break;
300+ default :
301+ put_rnd(buf);
302+ }
303+}
304+
305+int ck_num(buf)
306+char *buf;
307+{
308+ int i,num=0;
309+ for (i = 0; i<9; i++) {
310+ if (buf[i] != '0') num++;
311+ }
312+ return num;
313+}
314+
315+/*
316+ * check_mate() : 勝てる場合、そこにコマをおいてリターン
317+ *
318+ * ret : 0 no put
319+ * 1 put (win!)
320+ */
321+int check_mate(buf)
322+char *buf;
323+{
324+ int code = 0;
325+ int i,num=0;
326+
327+ for (i = 0; i<3; i++) {
328+ /* ×がなくて空白が1個? */
329+ /* 横チェック */
330+ if ((buf[i*3+0] != '2' && buf[i*3+1] != '2' && buf[i*3+2] != '2') &&
331+ (buf[i*3+0]+buf[i*3+1]+buf[i*3+2] == '1' * 2 + '0')) {
332+ if (buf[i*3+0] == '0') {
333+ buf[i*3+0] = '1'; /* put chip for win! */
334+ return 1;
335+ }
336+ if (buf[i*3+1] == '0') {
337+ buf[i*3+1] = '1'; /* put chip for win! */
338+ return 1;
339+ }
340+ if (buf[i*3+2] == '0') {
341+ buf[i*3+2] = '1'; /* put chip for win! */
342+ return 1;
343+ }
344+ }
345+ /* 縦チェック */
346+ if ((buf[i+0] != '2' && buf[i+3] != '2' && buf[i+6] != '2') &&
347+ (buf[i+0]+buf[i+3]+buf[i+6] == '1' * 2 + '0')) {
348+ if (buf[i+0] == '0') {
349+ buf[i+0] = '1'; /* put chip for win! */
350+ return 1;
351+ }
352+ if (buf[i+3] == '0') {
353+ buf[i+3] = '1'; /* put chip for win! */
354+ return 1;
355+ }
356+ if (buf[i+6] == '0') {
357+ buf[i+6] = '1'; /* put chip for win! */
358+ return 1;
359+ }
360+ }
361+ }
362+ /* 斜めチェック1 */
363+ if ((buf[0] != '2' && buf[4] != '2' && buf[8] != '2') &&
364+ (buf[0]+buf[4]+buf[8] == '1' * 2 + '0')) {
365+ if (buf[0] == '0') {
366+ buf[0] = '1'; /* put chip for win! */
367+ return 1;
368+ }
369+ if (buf[4] == '0') {
370+ buf[4] = '1'; /* put chip for win! */
371+ return 1;
372+ }
373+ if (buf[8] == '0') {
374+ buf[8] = '1'; /* put chip for win! */
375+ return 1;
376+ }
377+ }
378+ /* 斜めチェック2 */
379+ if ((buf[2] != '2' && buf[4] != '2' && buf[6] != '2') &&
380+ (buf[0]+buf[4]+buf[8] == '1' * 2 + '0')) {
381+ if (buf[2] == '0') {
382+ buf[2] = '1'; /* put chip for win! */
383+ return 1;
384+ }
385+ if (buf[4] == '0') {
386+ buf[4] = '1'; /* put chip for win! */
387+ return 1;
388+ }
389+ if (buf[6] == '0') {
390+ buf[6] = '1'; /* put chip for win! */
391+ return 1;
392+ }
393+ }
394+
395+ /* no put */
396+ return 0;
397+}
398+
399+/*
400+ * put_rnd() : ランダムにコマを置く
401+ *
402+ */
403+void put_rnd(buf)
404+char *buf;
405+{
406+ int rnd;
407+ int i;
408+
409+ srand(time(0)); /* 乱数系列初期化 */
410+ rnd = rand();
411+ rnd = (int)((float)rnd/RAND_MAX*10)+1;
412+ while(1) {
413+ for (i = 0; i<9; i++) {
414+ if (buf[i] == '0') {
415+ if (--rnd < 1) {
416+ buf[i] = '1';
417+ return;
418+ }
419+ }
420+ }
421+ }
422+}
--- /dev/null
+++ b/perfan.c
@@ -0,0 +1,770 @@
1+/*
2+ * perfan
3+ *
4+ * ログ(hh:mm:ss.mmm形式の時刻を持つログ)から
5+ * 経過時刻を表示する。
6+ *
7+ * 99/11/30 V1.00 by oga
8+ * 99/11/30 V1.01 -sql support
9+ * 99/12/04 V1.02 -wco support
10+ * 99/12/09 V1.03 WinNT support
11+ * 00/06/08 V1.04 start/end diff support
12+ * 00/07/10 V1.05 support DbaConnectionImpl::commit() for TraceLevel10
13+ * 00/07/11 V1.06 support initialize(=CreateParamStatement),
14+ * DBPreparedStatment::GetResultSet(=execute) for TraceLevel10
15+ * 00/09/12 V1.07 -osql support
16+ * 00/10/04 V1.08 ave 1/10000 sec
17+ * 00/11/20 V1.09 add DBStatement::GetResultSet(=execute),
18+ * -ex(for Level-1)support
19+ * -max
20+ * 00/03/29 V1.10 uname support (not available)
21+ */
22+#include <stdio.h>
23+#include <stdlib.h>
24+#include <string.h>
25+
26+#ifndef _WIN32
27+#include <strings.h>
28+#include <sys/utsname.h>
29+#endif
30+
31+#define VER "V1.09"
32+
33+/*
34+ * Type Definition
35+ */
36+typedef struct hmsm {
37+ int hh; /* hour */
38+ int mm; /* minute */
39+ int ss; /* sec */
40+ int ms; /* mili second */
41+} hmsm_t;
42+
43+char *executeKey1 = "DBPreparedStatment::GetResultSet()";/* for TraceLevel=10 */
44+char *executeKey2 = "DBStatement::GetResultSet()"; /* for TraceLevel=10 */
45+
46+/*
47+ * MACROS
48+ */
49+/* execute : maybe SELECT */
50+/* #define IS_EXECUTE(buf) strstr(buf,"::execute()") */
51+#define IS_EXECUTE(buf) strstr(buf,executeKey1) /* V1.09 */
52+#define IS_EXECUTE2(buf) strstr(buf,executeKey2) /* V1.09 */
53+
54+/* next : maybe Fetch */
55+#define IS_NEXT(buf) strstr(buf,"::next()")
56+
57+/* execUpdate : maybe UPDATE/INSERT */
58+#define IS_EXECUPDATE(buf) strstr(buf,"::execUpdate()")
59+
60+/* commit : COMMIT */
61+/* #define IS_COMMIT(buf) strstr(buf,"DbaTransactionImpl::commit()") */
62+#define IS_COMMIT(buf) strstr(buf,"DbaConnectionImpl::commit()")
63+
64+/* initialize : createParamStatement*/
65+/*#define IS_INIT(buf) strstr(buf,"DbaConnectionImpl::createParamStatement()")*/
66+#define IS_INIT(buf) strstr(buf,"DbaParamStatementImpl::initialize()")
67+
68+/* initialize : createStatement(TraceLeve=-1) V1.09 */
69+#define IS_CREATES(buf) strstr(buf,"DbaConnectionImpl::createStatement()")
70+
71+
72+/* SQL ID */
73+#define ID_EXECUTE 0
74+#define ID_EXECUTE2 1
75+#define ID_NEXT 2
76+#define ID_EXECUPDATE 3
77+#define ID_COMMIT 4
78+#define ID_INITIALIZE 5
79+#define ID_CREATES 6
80+#define ID_MAX 7 /* array size */
81+
82+/*
83+ * globals
84+ */
85+hmsm_t start_tms[ID_MAX]; /* enter time */
86+int ms_total[ID_MAX]; /* Total millisec */
87+int cnt[ID_MAX]; /* Total SQL */
88+int u_max[ID_MAX]; /* unit max V1.09 */
89+int u_min[ID_MAX]; /* unit min V1.09 */
90+int vf = 0; /* verbose */
91+int maxf = 0; /* -max : display max/min V1.09 */
92+int first = 1; /* first line of one command execute */
93+int com_cnt = 0; /* command execute counter */
94+int cscnt = 0; /* for Duplicate createStatement V1.09 */
95+int msec = 0; /* diff msec V1.09 */
96+
97+hmsm_t com_start, com_end; /* for command time */
98+hmsm_t head_tms; /* for header change */
99+hmsm_t oldtms; /* previous time */
100+
101+#ifdef _WIN32
102+char *head_key = "Microsoft"; /* -hk: header kerword */
103+#else /* !_WIN32 */
104+char *head_key = "HP-UX"; /* -hk: header kerword */
105+#endif /* !_WIN32 */
106+
107+void usage()
108+{
109+ printf("usage: perfan filename {-k <key_word> [-k <keyword> ...] | -a [-t] }\n");
110+ printf(" [-p <print_pos(90/25)>]\n");
111+ printf(" [-hk <header_keyword(HP-UX/*SQL*)>]\n");
112+ printf(" [-sql]\n");
113+ printf(" [-osql]\n");
114+ printf(" [-wco [-max] [-ex]]\n");
115+ printf(" -k : search keyword\n");
116+ printf(" -a : search all line\n");
117+ printf(" -t : add time only for '(HH:MM:SS.mm)'\n");
118+ printf(" -p : print position(90:WCO log/25:SQL trace\n");
119+ printf(" -hk : header keyword(HP-UX:WCO log/*SQL*:SQL trace\n");
120+ printf(" -sql : for HiRDB SQL trace\n");
121+ printf(" -osql: for Oracle SQL trace\n");
122+ printf(" -wco : for WCO perf analyze (unnecessary -k, -a)\n");
123+ printf(" -ex : for TraceLevel=-1 log (execute time accuracy up)\n");
124+ printf(" -max : display max/min\n");
125+}
126+
127+/*
128+ * get_diff_times(hmsm_t *old, hmsm_t *new, hmsm_t *diff)
129+ *
130+ * FUNC : get difference of two hmsm_t (old-new)
131+ *
132+ * IN old : old hmsm_t
133+ * new : new hmsm_t
134+ * diff : diff hmsm_t (old - new)
135+ * OUT ret : 0 success
136+ */
137+int get_diff_times(hmsm_t *old, hmsm_t *new, hmsm_t *diff)
138+{
139+ int new1, old1, diff1;
140+
141+ new1 = new->hh*3600000 + new->mm*60000 + new->ss*1000 + new->ms;
142+ old1 = old->hh*3600000 + old->mm*60000 + old->ss*1000 + old->ms;
143+
144+ if (new1 - old1 < 0) {
145+ new1 += 3600000;
146+ }
147+ diff1 = new1 - old1;
148+
149+ diff->hh = diff1/3600000;
150+ diff1 -= (3600000 * diff->hh);
151+ diff->mm = diff1/60000;
152+ diff1 -= (60000 * diff->mm);
153+ diff->ss = diff1/1000;
154+ diff1 -= (1000 * diff->ss);
155+ diff->ms = diff1 % 1000;
156+
157+ return 0;
158+}
159+
160+/*
161+ * add_times(hmsm_t *t1, hmsm_t *t2, hmsm_t *addt)
162+ *
163+ * FUNC : add two hmsm_t (t1+t2) to addt
164+ *
165+ * IN t1 : hmsm_t
166+ * t2 : hmsm_t
167+ * addt : add result
168+ * OUT ret : 0 success
169+ */
170+int add_times(hmsm_t *t1, hmsm_t *t2, hmsm_t *addt)
171+{
172+ int tt1, tt2, add1;
173+
174+ tt1 = t1->hh*3600000 + t1->mm*60000 + t1->ss*1000 + t1->ms;
175+ tt2 = t2->hh*3600000 + t2->mm*60000 + t2->ss*1000 + t2->ms;
176+
177+ add1 = tt1 + tt2;
178+
179+ addt->hh = add1/3600000;
180+ add1 -= (3600000 * addt->hh);
181+ addt->mm = add1/60000;
182+ add1 -= (60000 * addt->mm);
183+ addt->ss = add1/1000;
184+ add1 -= (1000 * addt->ss);
185+ addt->ms = add1 % 1000;
186+
187+ return 0;
188+}
189+
190+/*
191+ * IN : buf : include "HH:MM:SS.mmm" str
192+ * OUT : tms : store tms to HH,MM,SS,mmm
193+ * str : "HH:MM:SS.mmm"
194+ * ret : !=0 : success (return "HH:MM:SS.mmm" pos ptr on buf)
195+ * NULL : false (not include "HH:MM:SS.mmm" str)
196+ */
197+char *get_times(char *buf, hmsm_t *tms, char *str)
198+{
199+ char *pt = NULL;
200+
201+ if (vf >= 2)printf("get_times : buf=[%s]\n", buf);
202+
203+ memset(tms, 0, sizeof(hmsm_t));
204+ strcpy(str, ""); /* HH:MM:SS.mmm */
205+
206+ if ((pt = strchr(buf,':')) && *(pt+3) == ':' && *(pt+6) == '.') {
207+ pt -= 2; /* point to top of "HH:..." */
208+ strncpy(str, pt, 12); /* copy "HH:MM:SS.mmm" to str */
209+ str[12] = '\0'; /* terminator */
210+ if (!isdigit(str[0])) {
211+ /* skip header's hh:mm:ss.sss */
212+ if (vf >= 2) printf("get_time() return NULL [%s]\n", str);
213+ return NULL;
214+ }
215+ tms->hh = atoi(&str[0]);
216+ tms->mm = atoi(&str[3]);
217+ tms->ss = atoi(&str[6]);
218+ tms->ms = atoi(&str[9]);
219+ if (vf >= 2) {
220+ printf("time = [%s] %02d:%02d:%02d.%03d\n",str,
221+ tms->hh,tms->mm,tms->ss,tms->ms);
222+ }
223+ return pt; /* success */
224+ }
225+ if (vf >= 2) printf("get_time() return NULL\n");
226+ return NULL; /* false */
227+}
228+
229+/*
230+ * Oracle SQL Trace用
231+ * "tim=xxxxxx" がある場合、先頭に、"HH:MM:SS.mmm "を付加する。
232+ * (print_times()に渡すための前処理)
233+ *
234+ * IN : buf : .... tim=xxxxxxxxxx ...
235+ * (xxxxxは1/100秒単位)
236+ * OUT : obuf : HH:MM:SS.mm0 <buf> HH:MM:SSは本当の時刻ではないので注意
237+ * ret : 0 : 無変換("tim="なし)
238+ */
239+int tim2hms(char *buf, char *obuf)
240+{
241+ int tim;
242+ int hh,mm,ss,mmm;
243+ char *pt;
244+
245+ if (pt = strstr(buf, "tim=")) {
246+ tim = atoi(&pt[5]); /* "tim=xyyyyyyyy" のyyyy部分を数値に */
247+ /* printf("DEBUG: tim=%d\n",tim); */
248+ hh = tim/100/3600;
249+ mm = (tim - hh*100*3600)/100/60;
250+ ss = (tim - hh*100*3600 - mm*100*60)/100;
251+ mmm= (tim % 100) * 10;
252+ sprintf(obuf,"%02d:%02d:%02d.%03d %s", hh%24, mm, ss, mmm, buf);
253+ /* printf("DEBUG: %s\n",obuf); */
254+ return 1;
255+ }
256+
257+ strcpy(obuf, buf); /* そのまま返す */
258+ return 0;
259+}
260+
261+/*
262+ * bufから時刻部分を取出し、前回との差分時刻を出力する。 for WCO log or other
263+ *
264+ * IN : buf : ....19:11:08.536 ....
265+ * OUT : stdout : 19:11:08.536 (00:00:00.000) 文字列
266+ */
267+int print_times(char *buf, int pos)
268+{
269+ hmsm_t tms, diff;
270+ char timstr[1024];
271+
272+ if (get_times(buf, &tms, timstr) == NULL) {
273+ return -1;
274+ }
275+
276+ get_diff_times(&oldtms, &tms, &diff);
277+
278+ if (first) {
279+ printf("%s (00:00:00.000) ", timstr);
280+ first = 0;
281+ } else {
282+ printf("%s (%02d:%02d:%02d.%03d) ", timstr,
283+ diff.hh, diff.mm, diff.ss, diff.ms);
284+ }
285+ memcpy(&oldtms, &tms, sizeof(hmsm_t));
286+ printf("%s\n", &buf[pos]);
287+
288+ return 0;
289+}
290+
291+/* V1.01 */
292+/*
293+ * bufから時刻部分2個を取出し、差分時刻を出力する。 for SQL trace
294+ *
295+ * IN : buf : ....19:11:08.536 .. 19:11:08.630 ....
296+ * OUT : stdout : 19:11:08.536 (00:00:00.000) 文字列
297+ */
298+int print_times2(char *buf, int pos)
299+{
300+ hmsm_t tms, diff;
301+ char timstr[1024], timstr_end[1024];
302+ char *pt = NULL;
303+
304+ if ((pt = get_times(buf, &oldtms, timstr)) == NULL) {
305+ return -1;
306+ }
307+
308+ if (get_times(pt+12, &tms, timstr_end) == NULL) {
309+ return -1;
310+ }
311+
312+ get_diff_times(&oldtms, &tms, &diff);
313+
314+ printf("(%02d:%02d:%02d.%03d) ",
315+ diff.hh, diff.mm, diff.ss, diff.ms);
316+ printf("%s\n", &buf[pos]);
317+
318+ return 0;
319+}
320+
321+/*
322+ * PrintResult(char *str, int id, int total)
323+ *
324+ * FUNC : print one result
325+ * IN str : print prefix string
326+ * id : SQL ID
327+ * total : command total sec for percent display
328+ */
329+void PrintResult(char *str, int id, int total)
330+{
331+ /* printf("DEBUG : ms_total[%d]=%d\n",id,ms_total[id]); */
332+ printf("%s %9.3f(sec)/%7d(times) ave:%6.4f(sec) %5.1f%%\n", str,
333+ ((float)ms_total[id])/1000 , cnt[id],
334+ cnt[id]?((float)(ms_total[id]))/1000/cnt[id]:0,
335+ ((float)ms_total[id]*100)/total);
336+ if (maxf && cnt[id]) {
337+ printf(" max:%4.3f min:%4.3f\n",
338+ ((float)(u_max[id]))/1000,
339+ ((float)(u_min[id]))/1000);
340+ }
341+}
342+
343+/*
344+ * PutAllResult()
345+ *
346+ * FUNC : print(flush) all result
347+ */
348+void PutAllResult()
349+{
350+ int sql_total = 0, com_total;
351+ int id;
352+ hmsm_t com_diff;
353+
354+ /* get SQL Total time */
355+ for (id = 0; id < ID_MAX; id++) {
356+ sql_total += ms_total[id];
357+ }
358+
359+ /* get Command Total time */
360+ get_diff_times(&com_start, &com_end, &com_diff);
361+ com_total = GetMilliSec(&com_diff);
362+
363+ /* print result */
364+ printf("\n############ WCO Perf Analyze %s Result[%d] #########\n", VER, com_cnt);
365+ PrintResult("execute(SELECT1) ", ID_EXECUTE, com_total);
366+ PrintResult("execute(SELECT2) ", ID_EXECUTE2, com_total);
367+ PrintResult("next(FETCH) ", ID_NEXT, com_total);
368+ PrintResult("execUpdate(INST/DEL)", ID_EXECUPDATE, com_total);
369+ PrintResult("commit(COMMIT) ", ID_COMMIT, com_total);
370+ PrintResult("createParamStatement", ID_INITIALIZE, com_total);
371+ PrintResult("createStatement ", ID_CREATES, com_total);
372+ printf("---------------------------------------------------\n");
373+ printf("SQL TOTAL %12.3f(sec) %5.1f%%\n",
374+ ((float)sql_total)/1000, ((float)sql_total*100)/com_total);
375+
376+ printf("No SQL TOTAL %12.3f(sec) %5.1f%%\n",
377+ ((float)com_total-sql_total)/1000,
378+ ((float)(com_total-sql_total)*100)/com_total);
379+ printf("---------------------------------------------------\n");
380+ printf("Command TOTAL %12.3f(sec) %5.1f%%\n",
381+ ((float)com_total)/1000, ((float)com_total*100)/com_total);
382+ printf("\n");
383+
384+ /* reset counters */
385+ memset(&head_tms, 0, sizeof(head_tms));
386+ memset(&start_tms[0], 0, sizeof(start_tms));
387+ memset(&ms_total[0], 0, sizeof(ms_total));
388+ memset(&cnt[0], 0, sizeof(cnt));
389+ memset(&com_start, 0, sizeof(com_start));
390+ memset(&com_end, 0, sizeof(com_end));
391+
392+ first = 1; /* reset first line */
393+ cscnt = 0;
394+ ++com_cnt; /* command execute count */
395+}
396+
397+/*
398+ * GetMilliSec(hmsm_t *tms)
399+ *
400+ * FUNC : convert hmsm_t to millisecond
401+ * IN tms : hmsm_t
402+ * OUT ret : millisecond
403+ */
404+int GetMilliSec(hmsm_t *tms)
405+{
406+ return(tms->hh*3600*1000 + tms->mm*60*1000 + tms->ss*1000 + tms->ms);
407+}
408+
409+/* V1.02 */
410+/*
411+ * AnalyzeWcoLog(char *buf)
412+ *
413+ * IN buf : WCO Log 1 line
414+ * OUT ret : 0 success
415+ * -n failed
416+ */
417+int AnalyzeWcoLog(char *buf)
418+{
419+ char *ex = NULL, *up = NULL, *cm = NULL, *nx = NULL;
420+ char *in = NULL, *ex2 = NULL, *cs = NULL; /* V1.06,V1.09 */
421+ char *pt;
422+ char wkstr[2048];
423+ int id = -1;
424+ hmsm_t wktms, diff;
425+
426+ /* get time */
427+ if (!(pt = get_times(buf, &wktms, wkstr))) {
428+ return -2;
429+ }
430+
431+ /* skip header */
432+ if (strstr(buf, head_key)) {
433+ if (GetMilliSec(&head_tms) && memcmp(&head_tms, &wktms, sizeof(wktms))) {
434+ /* if head_tms != 0 && change header time then flush results */
435+ PutAllResult();
436+ }
437+ printf("%s\n", buf);
438+ memcpy(&head_tms, &wktms, sizeof(hmsm_t));
439+ return -1;
440+ }
441+
442+ /* get command start time */
443+ if (first) {
444+ memcpy(&com_start, &wktms, sizeof(hmsm_t));
445+ first = 0;
446+ }
447+ /* get command end time */
448+ memcpy(&com_end, &wktms, sizeof(hmsm_t));
449+
450+ if (!(nx = IS_NEXT(buf)) && !(ex = IS_EXECUTE(buf)) &&
451+ !(ex2= IS_EXECUTE2(buf)) && !(cs = IS_CREATES(buf)) &&
452+ !(up = IS_EXECUPDATE(buf)) && !(cm = IS_COMMIT(buf)) &&
453+ !(in = IS_INIT(buf))
454+ ) {
455+ return -1;
456+ }
457+
458+ if (nx) {
459+ id = ID_NEXT;
460+ } else if (ex) {
461+ /* execute(1) */
462+ id = ID_EXECUTE;
463+ } else if (ex2) {
464+ /* execute(2) */
465+ id = ID_EXECUTE2;
466+ } else if (up) {
467+ /* execUpdate() */
468+ id = ID_EXECUPDATE;
469+ } else if (cm) {
470+ /* commit() */
471+ id = ID_COMMIT;
472+ } else if (in) {
473+ /* initialize(createParamStatement) */
474+ id = ID_INITIALIZE;
475+ } else if (cs) { /* V1.09 */
476+ /* createStatement(createStatement) Level=-1 only */
477+ id = ID_CREATES;
478+ } else {
479+ printf("Error : Invalid Line [%s]\n",buf);
480+ return -3;
481+ }
482+
483+ if (strstr(buf,"enter ") || strstr(buf,"call ")) {
484+ /* enter or call */
485+ if (cs) {
486+ /* for duplicate enter (createStatement) */
487+ if (cscnt == 0) {
488+ memcpy(&start_tms[id], &wktms, sizeof(hmsm_t));
489+ }
490+ ++cscnt;
491+ } else {
492+ memcpy(&start_tms[id], &wktms, sizeof(hmsm_t));
493+ }
494+ if (vf) {
495+ printf("## %s\n", buf);
496+ }
497+ } else if (strstr(buf,"exit ") || strstr(buf,"return ")) {
498+ if (cs) {
499+ --cscnt;
500+ if (cscnt > 0) {
501+ return 0;
502+ } else if (cscnt < 0) {
503+ cscnt = 0;
504+ printf("Error : exit with no enter createStatement [%s]\n",buf);
505+ return -6;
506+ }
507+ }
508+ /* exit or return */
509+ if (!GetMilliSec(&start_tms[id])) {
510+ printf("Error : exit with no enter [%s]\n",buf);
511+ return -4;
512+ }
513+ get_diff_times(&start_tms[id], &wktms, &diff);
514+ msec = GetMilliSec(&diff);
515+ ms_total[id] += msec;
516+ if (u_max[id] < msec) {
517+ u_max[id] = msec;
518+ }
519+ if (u_min[id] > msec) {
520+ u_min[id] = msec;
521+ }
522+ ++cnt[id];
523+ if (vf) {
524+ printf("## %02d:%02d:%02d:%03d (%d) %s\n",
525+ diff.hh, diff.mm, diff.ss, diff.ms, cnt[id], buf);
526+ }
527+ memset(&start_tms[id], 0, sizeof(hmsm_t)); /* clear enter time */
528+ } else {
529+ printf("Error : no exit or enter [%s]\n",buf);
530+ return -5;
531+ }
532+
533+ return 0;
534+}
535+
536+
537+int main(a,b)
538+int a;
539+char *b[];
540+{
541+ char *fname = NULL;
542+ FILE *fp;
543+ int i;
544+ int pos = 90; /* -p : 表示開始位置 */
545+ int af = 0; /* -a : 全表示 */
546+ int wcf = 0; /* -wco : WCO性能解析 V1.02 */
547+ int sqlf = 0; /* -sql : HiRDB SQLトレース用 V1.01 */
548+ int osqlf = 0; /* -osql: Oracle SQLトレース用 V1.07 */
549+ int tf = 0; /* -t : (時刻)合計 V1.04 */
550+ int exf = 0; /* -ex : for TraceLevel=10 V1.09 */
551+ int keycnt = 0;
552+ int rtn;
553+ char *keyword[200]; /* -k : キーワード格納 */
554+ char buf[4096];
555+ char newbuf[4096];
556+ hmsm_t totaltms; /* total time for -t V1.04 */
557+ hmsm_t ttms; /* wk tms for -t V1.04 */
558+
559+#if 0
560+#ifndef _WIN32
561+ struct utsname unbuf;
562+
563+ uname(&unbuf);
564+ head_key = unbuf.sysname;
565+#endif
566+#endif /* 0 */
567+
568+ memset(keyword, 0, sizeof(keyword));
569+ memset(&oldtms, 0, sizeof(oldtms));
570+ /* V1.02 start */
571+ memset(&start_tms[0], 0, sizeof(start_tms));
572+ memset(&ms_total[0], 0, sizeof(ms_total));
573+ memset(&u_max[0], 0, sizeof(u_max));
574+ memset(&cnt[0], 0, sizeof(cnt));
575+ memset(&head_tms, 0, sizeof(head_tms));
576+ memset(&com_start, 0, sizeof(com_start));
577+ memset(&com_end, 0, sizeof(com_end));
578+ /* V1.02 end */
579+ memset(&totaltms, 0, sizeof(oldtms)); /* V1.04 */
580+
581+ for (i = 0; i < ID_MAX; i++) {
582+ u_min[i] = 99999;
583+ }
584+
585+ /* arg check */
586+ for (i = 1; i<a; i++) {
587+ if (!strcmp(b[i],"-v")) {
588+ vf++;
589+ continue;
590+ }
591+ if (!strcmp(b[i],"-a")) {
592+ af = 1;
593+ continue;
594+ }
595+ if (!strcmp(b[i],"-t")) {
596+ tf = 1;
597+ continue;
598+ }
599+ if (!strcmp(b[i],"-wco")) {
600+ wcf = 1;
601+ continue;
602+ }
603+ if (!strcmp(b[i],"-sql")) {
604+ sqlf = 1;
605+ pos = 25;
606+ head_key = "*SQL*";
607+ continue;
608+ }
609+ if (!strcmp(b[i],"-osql")) {
610+ osqlf = 1;
611+ pos = 13;
612+ head_key = "*** SESSION ID:(";
613+ continue;
614+ }
615+ if (!strcmp(b[i],"-p")) {
616+ i++;
617+ pos = atoi(b[i]);
618+ continue;
619+ }
620+ if (!strcmp(b[i],"-hk")) {
621+ i++;
622+ head_key = (char *)strdup(b[i]);
623+ continue;
624+ }
625+ if (!strcmp(b[i],"-k")) {
626+ i++;
627+ keyword[keycnt] = (char *)strdup(b[i]);
628+ keycnt++;
629+ continue;
630+ }
631+ if (!strcmp(b[i],"-ex")) { /* V1.09 */
632+ /* for TraceLevel=-1 */
633+ exf = 1;
634+ executeKey1 = "DbaParamStatementImpl::execute()";
635+ executeKey2 = "DbaStatementImpl::execute()";
636+ continue;
637+ }
638+ if (!strcmp(b[i],"-max")) { /* V1.09 */
639+ /* disp max/min */
640+ maxf = 1;
641+ continue;
642+ }
643+ if (!strcmp(b[i],"-h")) {
644+ usage();
645+ exit(1);
646+ }
647+ fname = b[i];
648+ }
649+
650+ /* open file */
651+ if (!wcf && (af == 0 && keyword[0] == NULL) ) {
652+ usage();
653+ exit(1);
654+ }
655+
656+ if (fname == NULL || !strcmp(fname, "-")) {
657+ fprintf(stderr, "input from stdin!!\n");
658+ fp = stdin;
659+ } else {
660+ if ((fp = fopen(fname,"r")) == 0) {
661+ perror("fopen");
662+ exit(1);
663+ }
664+ }
665+ while (fgets(buf,sizeof(buf),fp)) {
666+ if (buf[strlen(buf)-1] == 0x0a) {
667+ buf[strlen(buf)-1] = '\0';
668+ }
669+ if (buf[strlen(buf)-1] == 0x0d) {
670+ buf[strlen(buf)-1] = '\0';
671+ }
672+
673+ if (wcf) { /* V1.02 */
674+ /* for WCO Log analyze for perf */
675+ AnalyzeWcoLog(buf);
676+ continue;
677+ }
678+
679+ /* ヘッダキーワードチェック */
680+ if (strstr(buf, head_key)) {
681+ hmsm_t wktms;
682+ char wkstr[2048];
683+
684+ if (!(get_times(buf, &wktms, wkstr))) {
685+ first = 1; /* reset */
686+ printf("%s\n", buf);
687+ continue;
688+ }
689+ if (GetMilliSec(&head_tms) && memcmp(&head_tms, &wktms, sizeof(wktms))) {
690+ /* if head_tms != 0 && change header time then reset first */
691+ first = 1; /* reset */
692+ }
693+ printf("%s\n", buf);
694+ memcpy(&head_tms, &wktms, sizeof(hmsm_t));
695+ if (tf) {
696+ memset(&totaltms, 0, sizeof(hmsm_t)); /* V1.04 */
697+ }
698+ continue;
699+ }
700+
701+ if (tf) { /* V1.04 */
702+ char *pt;
703+ char wkstr2[2048];
704+ hmsm_t addtms;
705+
706+ if (pt = strchr(buf,'(')) {
707+ if (get_times(pt, &ttms, wkstr2)) {
708+ add_times(&ttms, &totaltms, &addtms);
709+ printf("%s\n", buf);
710+ memcpy(&totaltms, &addtms, sizeof(hmsm_t));
711+ }
712+ }
713+ /* 時刻を合計するだけ */
714+ continue;
715+ }
716+
717+ /* 時刻表示キーワードチェック */
718+ if (af) {
719+ /* 全行表示対象 */
720+ if (sqlf) {
721+ /* HiRDB SQL trace */
722+ print_times2(buf,pos);
723+ } else if (osqlf) {
724+ /* Oracle SQL trace */
725+ tim2hms(buf,newbuf);
726+ print_times(newbuf,pos);
727+ } else {
728+ /* WCO log */
729+ print_times(buf,pos);
730+ }
731+ } else {
732+ for (i = 0; keyword[i]; i++) {
733+ if (vf > 2) printf("key=[%s]\n",keyword[i]);
734+ if (strstr(buf,keyword[i])) {
735+ if (sqlf) {
736+ /* HiRDB SQL trace */
737+ rtn = print_times2(buf,pos);
738+ } else if (osqlf) {
739+ /* Oracle SQL trace */
740+ tim2hms(buf,newbuf);
741+ rtn = print_times(newbuf,pos);
742+ } else {
743+ /* WCO log */
744+ rtn = print_times(buf,pos);
745+ }
746+ /* V1.07 start */
747+ if (rtn < 0) { /* print_times*()で表示されなかった */
748+ /* -k 指定のものは、時刻がなくても表示されるようにする) */
749+ printf("%s\n", buf);
750+ }
751+ /* V1.07 end */
752+ break;
753+ }
754+ }
755+ }
756+ }
757+
758+ if (fp != stdin) fclose(fp);
759+ if (tf) {
760+ printf("### Total (%02d:%02d:%02d.%03d)\n",
761+ totaltms.hh, totaltms.mm, totaltms.ss, totaltms.ms);
762+ }
763+
764+ if (wcf) {
765+ PutAllResult();
766+ }
767+
768+ return 0;
769+}
770+
--- /dev/null
+++ b/qix.c
@@ -0,0 +1,282 @@
1+/*
2+ *
3+ * qix.c V1.00 93.10.14 by Hyper Halx.f oga.
4+ * V1.01 95.09.13 speed change option.
5+ * V1.10 96.01.09 resize support.
6+ * V1.20 98.11.03 wait by usleep
7+ * V1.21 99.12.27 -y2k,-geometry support
8+ *
9+ * cc qix.c -o qix -I/usr/include/X11R5 -L/usr/lib/X11R5 -lX11 -lm -DX3050R
10+ *
11+ */
12+
13+#include <X11/Xlib.h>
14+#include <X11/Xutil.h>
15+#include <stdio.h>
16+#include <math.h>
17+#include <time.h>
18+#include <stdlib.h>
19+
20+
21+#define VER "Ver 1.21"
22+#define DELAY 30
23+#define STEP 2
24+#define WAIT 10000
25+
26+extern unsigned long MyColor();
27+
28+int X_SIZE = 250;
29+int Y_SIZE = 200;
30+
31+/*
32+union {
33+ XEvent report;
34+ XKeyEvent key;
35+} report;
36+*/
37+XEvent report;
38+
39+/* V1.21
40+ *
41+ * get y2k delta second
42+ */
43+int y2k_delta()
44+{
45+ struct tm tm2k;
46+ time_t cur_time;
47+ time_t wktime;
48+
49+ memset(&tm2k, 0, sizeof(tm2k));
50+ tm2k.tm_mday = 1; /* day : 1 */
51+ tm2k.tm_mon = 0; /* month : 1 */
52+ tm2k.tm_year = 100; /* year : 2000 */
53+
54+ cur_time = time(&wktime);
55+ /* printf("%d : %d\n", cur_time, mktime(&tm2k)); */
56+
57+ return (abs(mktime(&tm2k)-cur_time));
58+}
59+
60+main(a,b)
61+int a;
62+char *b[];
63+{
64+ Display *d;
65+ Window w;
66+ GC gc, gc2, gwhite, gyellow;
67+ XSetWindowAttributes att;
68+ unsigned long red, green, white, black, yellow;
69+ float i = 0;
70+ int loopwait = 0, vf = 0;
71+ int j, c, rnd_fl = 0;
72+ int sw = 0;
73+ int x1, x2, x3, x4;
74+ int y1, y2, y3, y4;
75+ int wait = WAIT;
76+ int y2k = 0; /* -y2k V1.21 */
77+ int geof = 0; /* -geometry V1.21 */
78+ int delta, deltax = 0;
79+ int hh;
80+ int x_home=0, y_home=0;
81+ char name[256];
82+ char y2kstr[256];
83+ char *fontn = "7x14bold";
84+ Font font;
85+
86+ /* for XGetGeometry() */
87+ Window root;
88+ int x,y;
89+ unsigned int width,height, border, depth;
90+
91+
92+ d = XOpenDisplay(NULL);
93+
94+ green = MyColor(d,"green");
95+
96+ for (j = 1; j<a; j++) {
97+ if (!strncmp(b[j],"-h",2)) {
98+ printf("usage : qix [<colorname>] [-w <wait(1)>] [-loopwait] [-y2k] [-geometry <geometry>]\n");
99+ printf(" colorname : ex. red blue purple ...\n");
100+ printf(" -w : wait time\n");
101+ printf(" -loopwat : wait with loop\n");
102+ printf(" -y2k : countdown y2k\n");
103+ printf(" -geometry : window position (<X>x<Y>+<x>+<y>)\n");
104+ exit(1);
105+ }
106+ if (!strncmp(b[j],"-w",2)) {
107+ wait = atoi(b[++j]) * 10000; /* 1/100 sec */
108+ continue;
109+ }
110+ if (!strncmp(b[j],"-v",2)) {
111+ vf = 1;
112+ continue;
113+ }
114+ if (!strcmp(b[j],"-loopwait")) {
115+ loopwait = 1;
116+ continue;
117+ }
118+ if (!strcmp(b[j],"-y2k")) { /* V1.21 */
119+ y2k = 1;
120+ continue;
121+ }
122+ if (!strcmp(b[j],"-geometry")) { /* V1.21 */
123+ XParseGeometry(b[++j], &x_home, &y_home, &X_SIZE, &Y_SIZE);
124+ geof = 1;
125+ continue;
126+ }
127+ green = MyColor(d,b[j]);
128+#ifdef DEBUG
129+ printf("color = %d(0x%x)\n",green,green);
130+#endif
131+ if (green == 0xffffffff) {
132+ rnd_fl = 1;
133+ }
134+ }
135+ red = MyColor(d,"red");
136+ white = MyColor(d,"white");
137+ black = MyColor(d,"Black");
138+ yellow= MyColor(d,"yellow");
139+
140+#ifdef DEBUG
141+ printf("green = %d, red = %d, white = %d, black = %d\n",green,red,white,black);
142+#endif
143+ w = XCreateSimpleWindow(d, RootWindow (d,0),
144+ x_home,y_home, /* home x,y */
145+ X_SIZE,Y_SIZE, /* window size x,y */
146+ 5, /* border_width */
147+ 1, /* border */
148+ 0 ); /* background */
149+
150+ att.override_redirect = 0; /* Window Manager 介入あり ... 0 */
151+ /* なし ... 1 */
152+
153+ XChangeWindowAttributes(d,w,CWOverrideRedirect,&att);
154+ XMapWindow(d,w);
155+
156+ /* V1.21 start */
157+ XGetGeometry(d,RootWindow(d,0),&root,&x,&y,&width,&height,&border,&depth);
158+ if (x_home < 0) {
159+ x_home = width - X_SIZE - 5;
160+ } else {
161+ x_home += 5;
162+ }
163+ if (y_home < 0) {
164+ y_home = height - Y_SIZE - 5 - 25;
165+ } else {
166+ y_home += 22;
167+ }
168+ if (geof) {
169+ XMoveWindow(d,w,x_home,y_home); /* V1.21 */
170+ }
171+ if (vf) {
172+ printf("%dx%d %d %d\n",
173+ X_SIZE, Y_SIZE, x_home, y_home);
174+ }
175+ /* V1.21 end */
176+
177+ gc = XCreateGC(d,w,0,0); /* create gc(green) */
178+ gc2 = XCreateGC(d,w,0,0); /* create gc2(black)*/
179+ gwhite = XCreateGC(d,w,0,0); /* create gwhite */
180+ gyellow= XCreateGC(d,w,0,0); /* create gyellow */
181+
182+ XSetForeground(d,gc ,green); /* set color to gc */
183+ XSetForeground(d,gc2,black); /* set color to gc2 */
184+ XSetForeground(d,gwhite,white); /* set color to gwhite */
185+ XSetForeground(d,gyellow,yellow); /* set color to gyellow*/
186+
187+ /* load font and set */
188+ font = XLoadFont(d, fontn);
189+ XSetFont(d,gc2,font); /* black */
190+ XSetFont(d,gwhite,font); /* white */
191+ XSetFont(d,gyellow,font); /* yellow */
192+
193+ /* V1.10 */
194+ sprintf(name,"QIX %s",VER);
195+ XStoreName(d,w,name);
196+ XSelectInput(d,w, ButtonPressMask|ExposureMask);
197+
198+ sprintf(name, "QIX %s by Moritaka Ogasawara.",VER);
199+
200+ while (1){
201+ x1 = cos(i/50)*X_SIZE/2+X_SIZE/2;
202+ y1 = sin(i/35)*Y_SIZE/2+Y_SIZE/2;
203+ x2 = cos(i/20)*X_SIZE/2+X_SIZE/2;
204+ y2 = sin(i/45)*Y_SIZE/2+Y_SIZE/2;
205+
206+ x3 = cos((i-DELAY)/50)*X_SIZE/2+X_SIZE/2;
207+ y3 = sin((i-DELAY)/35)*Y_SIZE/2+Y_SIZE/2;
208+ x4 = cos((i-DELAY)/20)*X_SIZE/2+X_SIZE/2;
209+ y4 = sin((i-DELAY)/45)*Y_SIZE/2+Y_SIZE/2;
210+
211+ if (rnd_fl)
212+ /* set random? color to gc */
213+ XSetForeground(d,gc ,(unsigned long)(c % 4095)+1);
214+ XDrawLine(d,w,gc2,x3,y3,x4,y4); /* erase */
215+ XDrawLine(d,w,gc,x1,y1,x2,y2); /* draw */
216+
217+ if (y2k) {
218+ delta = y2k_delta();
219+ hh = delta/3600;
220+ if (delta != deltax) {
221+ XDrawString(d,w,gc2,20,28,y2kstr,strlen(y2kstr)); /* erase */
222+ sprintf(y2kstr, "%02d:%02d:%02d (%d sec) ",
223+ hh, (delta-hh*3600)/60, delta % 60, delta);
224+ deltax = delta;
225+ }
226+ XDrawString(d,w,gyellow,20,28,y2kstr,strlen(y2kstr));
227+ }
228+
229+ XFlush(d);
230+
231+ if (loopwait) {
232+ for (j=0; j<wait; j++);
233+ } else {
234+ usleep(wait); /* V1.20 */
235+ }
236+
237+ i += STEP;
238+ c++;
239+
240+ if (sw) {
241+ XDrawString(d,w,gwhite,0,16,name,strlen(name));
242+ }
243+
244+ /* V1.10 */
245+ if (XCheckMaskEvent(d,ButtonPressMask,&report) == True) {
246+ sw = 1-sw;
247+ if (sw) {
248+ XDrawString(d,w,gwhite,0,16,name,strlen(name));
249+ } else {
250+ XDrawString(d,w,gc2,0,16,name,strlen(name));
251+ }
252+ }
253+
254+ /* resize event */
255+ if (XCheckMaskEvent(d,ExposureMask,&report) == True) {
256+
257+ XGetGeometry(d,w,&root,&x,&y,&width,&height,&border,&depth);
258+ if (X_SIZE != width || Y_SIZE != height) {
259+ X_SIZE = width;
260+ Y_SIZE = height;
261+ XClearWindow(d,w);
262+ }
263+ }
264+ }
265+}
266+
267+unsigned long MyColor(display,color)
268+Display *display;
269+char *color;
270+{
271+ Colormap cmap;
272+ XColor c0,c1;
273+ int code;
274+
275+ cmap = DefaultColormap(display,0);
276+
277+ code = XAllocNamedColor(display,cmap,color,&c1,&c0);
278+ if (code)
279+ return(c1.pixel);
280+ else
281+ return(-1);
282+}
--- /dev/null
+++ b/strings2.c
@@ -0,0 +1,75 @@
1+/*
2+ * strings2 : 漢字対応strings
3+ *
4+ */
5+#include <stdio.h>
6+#include <stdlib.h>
7+#include <string.h>
8+
9+#define ISKANJI(c) ((c >= 0x80 && c < 0xa0) || (c >= 0xe0 && c<0xff))
10+#define ISKANJI2(c) ((c >= 0x40 && c <= 0xfc))
11+#define ISHANKANA(c) ((c >= 0xa0 && c <= 0xdf))
12+
13+main(a,b)
14+int a;
15+char *b[];
16+{
17+ char *fname = NULL;
18+ FILE *fp;
19+ int i,c;
20+ unsigned char buf[4096];
21+ int kf = 0;
22+ int num = 4;
23+ int hk = 0;
24+
25+ /* arg check */
26+ for (i = 1; i<a; i++) {
27+ if (!strncmp(b[i],"-n",2)) {
28+ num = atoi(b[++i]);
29+ continue;
30+ }
31+ if (!strncmp(b[i],"-hk",3)) {
32+ hk = 1;
33+ continue;
34+ }
35+ if (!strncmp(b[i],"-h",2)) {
36+ printf("usage: strings2 [filename] [-n <num(4)>] [-hk]\n");
37+ printf(" -n : 文字列として判断するための連続文字数\n");
38+ printf(" -hk: 半角カナも対象とする\n");
39+ exit(1);
40+ }
41+ fname = b[i];
42+ }
43+
44+ /* open file */
45+ if (fname == NULL) {
46+ fp = stdin;
47+ } else {
48+ if ((fp = fopen(fname,"r")) == 0) {
49+ perror(b[0]);
50+ exit(1);
51+ }
52+ }
53+ i = 0;
54+ while((c = getc(fp)) != EOF) {
55+ if (isprint(c)) {
56+ kf = 0;
57+ buf[i++] = c;
58+ } else if (!kf && ISKANJI(c)) {
59+ kf = 1;
60+ buf[i++] = c;
61+ } else if (kf && ISKANJI2(c)) {
62+ kf = 0;
63+ buf[i++] = c;
64+ } else if (hk && ISHANKANA(c)) {
65+ kf = 0;
66+ buf[i++] = c;
67+ } else {
68+ buf[i] = '\0';
69+ if (i >= num) {
70+ printf("[%s]\n",buf);
71+ }
72+ i = 0;
73+ }
74+ }
75+}
--- /dev/null
+++ b/t64an.c
@@ -0,0 +1,249 @@
1+/*
2+ * VIC-1001 t64 file analyzer
3+ *
4+ * 11/05/05 V0.10 by oga.
5+ */
6+#include <stdio.h>
7+#include <stdlib.h>
8+#include <string.h>
9+
10+#define T64_HEADER "C64S tape image file"
11+
12+typedef unsigned int uint;
13+typedef unsigned short ushort;
14+typedef struct _fname_t {
15+ char fname[20];
16+} fname_t;
17+
18+/* basic operation code (0x80-0xff) */
19+char *op[128] = {
20+ /* 80 */ "end", "for", "next", "data", "input#", "input", "dim", "read",
21+ /* 88 */ "let", "goto", "run", "if", "restore", "gosub", "return", "rem",
22+ /* 90 */ "stop", "on", "wait", "load", "save", "verify", "def ", "poke",
23+ /* 98 */ "print#", "print", "cont", "list", "clr", "cmd ", "sys ", "open",
24+ /* a0 */ "close", "get ", "new", "tab(", "to", "fn", "spc(", " then",
25+ /* a8 */ "not", "step", "+", "-", "*", "/", "^", "and",
26+ /* b0 */ "or", ">", "=", "<", "sgn", "int", "abs", "usr",
27+ /* b8 */ "fre", "pos", "sqr", "rnd", "log", "exp", "cos", "sin",
28+ /* c0 */ "tan", "atn", "peek", "len", "str$", "val", "asc", "chr$",
29+ /* 0xcc-0xfe : Ver2.0 Super Expander */
30+ /* c8 */ "left$", "right$", "mid$", "go", "key", "graphic", "xxx", "xxx",
31+ /* d0 */ "draw", "region", "color", "point", "sound", "char", "paint", "rpot",
32+ /* d8 */ "rpen", "rsnd", "rcolr", "rgr", "rjoy", "rdot", "", "",
33+ /* e0 */ "", "", "", "", "", "", "", "",
34+ /* e8 */ "", "", "", "", "", "", "", "",
35+ /* f0 */ "", "", "", "", "", "", "", "",
36+ /* f8 */ "", "", "", "", "", "", "", "pi",
37+};
38+
39+
40+int vf = 0; /* -v : verbose */
41+int lff = 0; /* -lf: line format */
42+
43+void usage()
44+{
45+ printf("usage: t64an [-lf] <xxx.t64>\n");
46+ printf(" -lf: line format\n");
47+ exit(1);
48+}
49+
50+/* dump hex code */
51+void dump(FILE *fp, int size)
52+{
53+ uint c;
54+ int i;
55+ for (i = 0; i < size; i++) {
56+ if (i != 0 && (i % 4) == 0) {
57+ printf(" ");
58+ }
59+ c = getc(fp);
60+ if (c == EOF) break;
61+ printf("%02x", c);
62+ }
63+ printf("\n");
64+}
65+
66+/* BASIC 行番号 表示
67+ * nnnnmmmm nnnn:source addr mmmm:line number
68+ * nnnn:source addr
69+ * mmmm:line number
70+ *
71+ * IN : fp
72+ * OUT: ret : line no (0: EOS)
73+ */
74+int disp_lineno(FILE *fp)
75+{
76+ ushort val;
77+ int size;
78+
79+ fread(&val, 1, 2, fp);
80+ if (vf) printf("0x%4x ", val);
81+
82+ if (val == 0) {
83+ /* End of 1 Program Source */
84+ /* source addr値(nnnn)が(0000)の場合はEOSのため行番号表示しない */
85+ printf("--------------------\n");
86+ return 0;
87+ }
88+
89+ size = fread(&val, 1, 2, fp);
90+ if (size == 2) {
91+ if (lff) {
92+ printf("%5d ", val);
93+ } else {
94+ printf("%d ", val);
95+ }
96+ return val;
97+ }
98+ return 0;
99+}
100+
101+
102+/*
103+ * BASIC 中間コードを文字列に変換する
104+ *
105+ * IN : c 変換対象コード
106+ * OUT : buf 変換結果
107+ * IN/OUT : strf 文字列中かどうかのフラグ 1:文字列中
108+ */
109+
110+void cbm_bas_trans(uint c, char *obuf, int *strfp)
111+{
112+ if (*strfp == 0 && (c >= 0x80 && c <= 0xff) && strlen(op[c-0x80])) {
113+ sprintf(obuf, "%s", op[c-0x80]);
114+ } else {
115+ sprintf(obuf, "%c", c);
116+ if (c == '"') {
117+ *strfp = 1 - *strfp;
118+ }
119+ }
120+}
121+
122+/*
123+ * analyze t64
124+ *
125+ * <format>
126+ * +00-13(0x14) "C64S tape image file"
127+ * +14-27(0x14) ???1 (00000000 00000000 00000000 01000100 01000000)
128+ * == == num of entry
129+ * +28-3f(0x18) tape name (space filled)
130+ * -----------------------------------------+
131+ * +40-4f(0x10) file header | 1 entry 〜 n entry
132+ * +50-5f(0x10) file name (space filled) |
133+ * -----------------------------------------+
134+ * +60-63(0x04) <src_addr(2byte)><basic_line(2byte)> (little endian)
135+ * +64- Source (null terminate)
136+ * +nn "0x000000" End Of Source
137+ *
138+ */
139+void t64an(FILE *fp)
140+{
141+ char buf[4096];
142+ char wk[4096];
143+ int strf = 0; /* 1:文字列中 */
144+ int nent = 0;
145+ int size;
146+ int i;
147+ int ret;
148+ uint c;
149+ fname_t *fnames = NULL;
150+
151+ /* header */
152+ size = fread(buf, 1, 20, fp);
153+ buf[20] = '\0';
154+ if (strcmp(buf, T64_HEADER)) {
155+ printf("Error: This is not t64 file!!\n");
156+ exit(1);
157+ }
158+
159+ /* TapeHeader */
160+ size = fread(buf, 1, 20, fp);
161+ nent = buf[14]; /* num of tape entry */
162+
163+ /* file name */
164+ size = fread(buf, 1, 24, fp);
165+ buf[24] = '\0';
166+ //printf("Tape Name: [%s]\n", buf);
167+ printf("Tape Name: %s\n", buf);
168+ printf("Num Entry: %d\n", nent);
169+ fnames = (fname_t *)malloc(nent*sizeof(fname_t));
170+
171+ for (i = 0; i < nent; i++) {
172+ /* File Header */
173+ size = fread(buf, 1, 16, fp);
174+
175+ /* File Name */
176+ size = fread(buf, 1, 16, fp);
177+ buf[16] = '\0';
178+ strcpy(fnames[i].fname, buf);
179+ //printf("File %03d : [%s]\n", i, buf);
180+ printf("File %03d : %s\n", i+1, fnames[i].fname);
181+ }
182+
183+
184+ for (i = 0; i < nent; i++) {
185+ printf("\n");
186+ printf("###### File %03d : %s\n", i+1, fnames[i].fname);
187+ printf("--------------------\n");
188+
189+ /* source area */
190+ c = 0;
191+ while (c != EOF) {
192+ /* dump(fp, 4); */ /* line data */
193+ ret = disp_lineno(fp); /* disp line */
194+ if (ret == 0) break; /* EOS */
195+ strf = 0;
196+ while (1) {
197+ c = getc(fp);
198+ if (c == 0 || c == EOF) {
199+ printf("\n");
200+ break;
201+ }
202+ cbm_bas_trans(c, wk, &strf);
203+ printf("%s", wk);
204+ }
205+ }
206+
207+ }
208+}
209+
210+int main(int a, char *b[])
211+{
212+ int i;
213+ char *filename = NULL;
214+ FILE *fp;
215+
216+ for (i = 1; i<a; i++) {
217+ if (!strcmp(b[i],"-h")) {
218+ usage();
219+ }
220+ if (!strcmp(b[i],"-lf")) {
221+ lff = 1; /* line format */
222+ continue;
223+ }
224+ if (!strcmp(b[i],"-v")) {
225+ vf = 1;
226+ continue;
227+ }
228+ filename = b[i];
229+ }
230+
231+ if (filename) {
232+ if (!(fp = fopen(filename,"r"))) {
233+ perror("fopen");
234+ exit(1);
235+ }
236+ } else {
237+ fp = stdin;
238+ }
239+
240+ t64an(fp);
241+
242+ fclose(fp);
243+}
244+
245+/* vim:ts=4:sw=4:
246+ */
247+
248+
249+
--- /dev/null
+++ b/tolower.c
@@ -0,0 +1,66 @@
1+/*
2+ * tolower : change filename to lower case
3+ *
4+ * 2001/07/03 V1.00 by oga.
5+ * 2001/12/16 V1.01 -win support
6+ */
7+
8+#include <stdio.h>
9+#include <stdlib.h>
10+#include <string.h>
11+#include <ctype.h>
12+
13+void ToLower(char *istr, char *ostr)
14+{
15+ int i = 0;
16+ while (istr[i] != '\0') {
17+ ostr[i] = tolower(istr[i]);
18+ ++i;
19+ }
20+ ostr[i] = '\0';
21+}
22+
23+int main(int a, char *b[])
24+{
25+ int i;
26+ int winf = 0; /* -win */
27+ char lowname[4096];
28+ char tmpname[4096];
29+
30+ /* arg check */
31+ for (i = 1; i<a; i++) {
32+ if (!strcmp(b[i], "-h")) {
33+ printf("usage: tolower [-win] [filename ...]\n");
34+ exit(1);
35+ }
36+ if (!strcmp(b[i], "-win")) {
37+ winf = 1;
38+ }
39+ ToLower(b[i], lowname);
40+ if (strcmp(b[i], lowname)) {
41+ printf("rename %s => %s\n", b[i], lowname);
42+ if (winf) {
43+ strcpy(tmpname, lowname);
44+ strcat(tmpname, ".tolower.tmp");
45+ /* FILENAME => filename.lowercase.tmp */
46+ if (rename(b[i], tmpname) < 0) {
47+ /* error */
48+ printf("Error1: nochange %s\n", b[i]);
49+ } else {
50+ /* filename.lowercase.tmp => filename */
51+ if (rename(tmpname, lowname) < 0) {
52+ /* error */
53+ printf("Error2: nochange %s\n", b[i]);
54+ /* filename.lowercase.tmp => FILENAME */
55+ rename(tmpname, b[i]);
56+ }
57+ }
58+ } else {
59+ /* FILENAME => filename */
60+ rename(b[i], lowname);
61+ }
62+ } else {
63+ printf("nochange %s\n", b[i]);
64+ }
65+ }
66+}
--- /dev/null
+++ b/txt2vnt.c
@@ -0,0 +1,99 @@
1+/*
2+ * txt2vnt
3+ *
4+ * 09/06/02 V0.10 by oga.
5+ * 09/06/21 V0.11 fix bug
6+ *
7+ */
8+#include <stdio.h>
9+#include <stdlib.h>
10+#include <string.h>
11+#include <time.h>
12+
13+void disp_header()
14+{
15+ char work_date[256]; // Date
16+ char work_dt[256]; // Date Time yyyymmddTOnnnnnZ
17+ time_t tt;
18+ struct tm *tmp;
19+
20+ tt = time(0);
21+ tmp = localtime(&tt);
22+
23+ printf("BEGIN:VNOTE\r\n");
24+ printf("VERSION:1.1\r\n");
25+ // DCREATED:20090507T031900Z
26+ // LAST-MODIFIED:20090507T031900Z
27+ strftime(work_date, sizeof(work_date), "%Y%m%d", tmp);
28+ sprintf(work_dt, "%sTO%dZ", work_date, tmp->tm_hour*3600 + tmp->tm_min*60 + tmp->tm_sec);
29+ printf("DCREATED:%s\r\n", work_dt);
30+ printf("LAST-MODIFIED:%s\r\n", work_dt);
31+ printf("BODY;CHARSET=SHIFT_JIS;ENCODING=QUOTED-PRINTABLE:");
32+}
33+
34+void disp_footer()
35+{
36+ printf("CATEGORIES:%s\r\n", "");
37+ printf("END:VNOTE\r\n");
38+}
39+
40+void usage()
41+{
42+ printf("usage: txt2vnt [txt_file]\n");
43+}
44+
45+int main(int a, char *b[])
46+{
47+ int i;
48+ int vf = 0; /* verbose */
49+ int cnt = 0;
50+ unsigned int c;
51+ char *filename = NULL;
52+ FILE *fp;
53+
54+ for (i = 1; i<a; i++) {
55+ if (!strcmp(b[i],"-h")) {
56+ usage();
57+ }
58+ if (!strcmp(b[i],"-v")) {
59+ vf = 1;
60+ continue;
61+ }
62+ //if (i+1 < a && !strcmp(b[i],"-x")) {
63+ // xx = atoi(b[++i]);
64+ // continue;
65+ //}
66+ filename = b[i];
67+ }
68+
69+ if (filename) {
70+ if (!(fp = fopen(filename,"r"))) {
71+ perror("fopen");
72+ exit(1);
73+ }
74+ } else {
75+ fp = stdin;
76+ }
77+
78+ disp_header();
79+ cnt = 0;
80+ while ((c = getc(fp)) != EOF) {
81+ ++cnt;
82+ if (cnt >= 20) { // 20行で改行
83+ //printf("\r\n\t");
84+ printf("=\r\n");
85+ cnt = 0;
86+ }
87+
88+ if (isprint(c)) {
89+ putchar(c);
90+ } else {
91+ printf("=%02x", c);
92+ }
93+ }
94+ if (cnt) printf("\r\n");
95+ disp_footer();
96+
97+ fclose(fp);
98+
99+}
--- /dev/null
+++ b/upload.c
@@ -0,0 +1,191 @@
1+/*
2+ * upload.c
3+ *
4+ * ファイルアップロードのサンプルCGI
5+ *
6+ * <使用例>
7+ * upload.html
8+ * ------------------
9+ * <form enctype="multipart/form-data" method="POST" action="http://galaga/cgi-bin/upload">
10+ * <input type="file" NAME="file_name">
11+ * <input type="submit" value="OK">
12+ * </form>
13+ * ------------------
14+ *
15+ */
16+#include <stdio.h>
17+#include <string.h>
18+
19+/* アップロード先のパス */
20+#define UPLOAD_PATH "/tmp/oga/upload"
21+/* #define UPLOAD_PATH "." */
22+
23+int vf = 0; /* verbose */
24+
25+void DelKai(char *buf)
26+{
27+ if (buf[strlen(buf)-1] == 0x0a) {
28+ buf[strlen(buf)-1] = '\0';
29+ }
30+ if (buf[strlen(buf)-1] == 0x0d) {
31+ buf[strlen(buf)-1] = '\0';
32+ }
33+}
34+
35+/*
36+ * パスのファイル名部分を取り出す
37+ * IN : ibuf ディレクトリ名付きファイルパス
38+ * OUT: obuf ファイル名
39+ *
40+ */
41+void Basename(char *ibuf, char *obuf)
42+{
43+ char *pt;
44+
45+ // 仮
46+ pt = strrchr(ibuf, '/');
47+ if (pt) {
48+ strcpy(obuf, ++pt);
49+ } else {
50+ pt = strrchr(ibuf, '\\');
51+ if (pt) {
52+ strcpy(obuf, ++pt);
53+ } else {
54+ strcpy(obuf, ibuf);
55+ }
56+ }
57+}
58+
59+/*
60+ * GetFileBlock
61+ *
62+ * ファイルを取り出し出力する
63+ *
64+ * IN : filen 出力ファイル名
65+ * IN : sep ブロック完了セパレータ
66+ * OUT : ret : 0 success
67+ * : -1 error
68+ */
69+int GetFileBlock(char *filen, char *sep)
70+{
71+ FILE *fp;
72+ char path[1025];
73+ char buf[1025];
74+ int c, c2, c3;
75+
76+ if (filen[strlen(filen)-1] == '"') {
77+ filen[strlen(filen)-1] = '\0';
78+ }
79+
80+ if (strlen(UPLOAD_PATH)) {
81+ sprintf(path, "%s/%s", UPLOAD_PATH, filen);
82+ }
83+
84+ if ((fp = fopen(path, "wb")) == NULL) {
85+ return -1;
86+ }
87+
88+ if (vf) printf("output file %s ...\n", filen);
89+
90+ while (1) {
91+ c = getchar();
92+ if (c == EOF) break;
93+ if (c == 0x0d) {
94+ c2 = getchar();
95+ if (c2 == EOF) break;
96+ if (c2 == 0x0a) {
97+ if (vf) printf("expect 0d0a\n", filen);
98+ c3 = getchar();
99+ if (c3 == EOF) break;
100+ if (c3 == '-') {
101+ fgets(buf, sizeof(buf), stdin);
102+ if (vf) printf("expect 0d0a-[%s]\n", buf);
103+ if (vf) printf(" [%s]\n", &sep[1]);
104+ if (!strncmp(buf, &sep[1], strlen(&sep[1]))) {
105+ /* "[0d][0a]----------xxxxxx" ならばブロック終了 */
106+ if (vf) printf("expect separator.\n", filen, buf);
107+ break;
108+ }
109+ } else {
110+ putc(c, fp);
111+ putc(c2, fp);
112+ putc(c3, fp);
113+ continue;
114+ }
115+ } else {
116+ putc(c, fp);
117+ putc(c2, fp);
118+ continue;
119+ }
120+ }
121+ putc(c, fp);
122+ }
123+
124+ fclose(fp);
125+ return 0;
126+}
127+
128+int main(int a, char *b[])
129+{
130+
131+ char buf[4096];
132+ char separator[4096];
133+ char *pt;
134+ char filen[1025];
135+ int filef = 0;
136+
137+ printf("Content-type: text/html\n");
138+ printf("\n");
139+ printf("<html>\n");
140+ printf("<head><title>upload</title></head>\n");
141+ printf("<body>\n");
142+
143+ printf("<pre>\n"); /* for DEBUG */
144+
145+ /* get separator */
146+ fgets(separator, sizeof(separator), stdin);
147+ DelKai(separator);
148+
149+ while (1) {
150+ /* get Content Info 1 */
151+ if (!fgets(buf, sizeof(buf), stdin)) {
152+ break;
153+ }
154+ DelKai(buf);
155+ filef = 0;
156+ if (!strncasecmp(buf, "Content-Disposition:", strlen("Content-Disposition:"))
157+ /* ファイル名指定 */
158+ && (pt = strstr(buf, "filename="))) {
159+ /* filename */
160+ pt += (strlen("filename=") + 1);
161+ Basename(pt, filen); /* ファイル名部分を取得 */
162+ filef = 1;
163+ }
164+
165+ /* get Content info Info (other) */
166+ /* 改行のみの行がくるまで空読み */
167+ while (1) {
168+ if (strlen(buf) == 0) {
169+ break;
170+ }
171+ fgets(buf, sizeof(buf), stdin);
172+ DelKai(buf);
173+ }
174+
175+ if (filef && strlen(filen)) {
176+ /* ファイル取り出し & 出力 */
177+ GetFileBlock(filen, separator);
178+ } else {
179+ /* テキスト取り出し & 出力 */
180+ }
181+
182+ }
183+
184+ printf("</pre>\n"); /* for DEBUG */
185+
186+ printf("<h1><font color=\"ff0000\">アップロード完了</font></h1>\n");
187+ printf("<p><a href=\"javascript:history.back()\">戻る</a>\n");
188+ printf("</body>\n");
189+ printf("</html>\n");
190+}
191+
--- /dev/null
+++ b/wavana.c
@@ -0,0 +1,370 @@
1+/*
2+ * .WAV file analyzeer
3+ *
4+ * 2001/01/14 V0.10 by oga
5+ * 2005/10/16 V0.11 support max level, and -d option
6+ * 2005/12/06 V0.21 perfup
7+ *
8+ */
9+#include <stdio.h>
10+#include <errno.h>
11+#include <stdlib.h>
12+#include <string.h>
13+
14+int vf = 0; /* -v verbose */
15+int df = 0; /* -d disp all data value */
16+
17+/* data formats */
18+struct riff_hdr {
19+ char id[4]; /* RIFF id ("RIFF") */
20+ unsigned long len; /* length */
21+ char wave_id[4]; /* data type ("WAVE") */
22+};
23+
24+struct chunk_hdr {
25+ char id[4]; /* chunk id ("fmt "|"data"...) */
26+ unsigned long len; /* chunk length */
27+};
28+
29+/* chunk type fmt 1 */
30+struct ck_fmt {
31+ unsigned short wFormatTag; /* Format category */
32+#define WAVE_FORMAT_PCM 0x0001 /* Microsoft PCM */
33+#define FORMAT_MULAW 0x0101 /* IBM mu-law format */
34+#define IBM_FORMAT_ALAW 0x0102 /* IBM a-law format */
35+#define IBM_FORMAT_ADPCM 0x0103 /* IBM AVC Adaptive Diff PCM format */
36+ unsigned short wChannels; /* Number of channels */
37+ unsigned long dwSamplesPerSec; /* Sampling rate */
38+ unsigned long dwAvgBytesPerSec; /* For buffer estimation */
39+ unsigned short wBlockAlign; /* Data block size */
40+ unsigned short wBitsPerSample; /* Sample size (for WAVE_FORMAT_PCM */
41+ unsigned short unknown; /* Unknown data */
42+ char dummy[256]; /* dummy area for over run */
43+};
44+
45+/* chunk type fact 2 */
46+struct ck_fact {
47+ int unknown; /* unknown */
48+};
49+
50+/* chunk type data 3 */
51+/* any length data */
52+
53+/*
54+ * Dump Data
55+ *
56+ * IN buf : dump buffer
57+ * len : dump length
58+ */
59+void DumpData(unsigned char *buf, int len)
60+{
61+ int i;
62+
63+ for (i=0; i<len; i++){
64+ printf(" %02x",buf[i]);
65+ }
66+ printf("\n");
67+}
68+
69+/*
70+ * Read fmt chunk header block
71+ *
72+ * IN fp
73+ * IN cklen : chunk data len
74+ * OUT ckfmt : fmt chunk data
75+ * OUT ret : 0 success
76+ * -1 error
77+ */
78+int ReadChunkFmt(FILE *fp, int len, struct ck_fmt *ckfmt)
79+{
80+ if (len > sizeof(struct ck_fmt)) {
81+ printf("Error: ReadChunkFmt: Length Too long. (%d)\n",len);
82+ return -1;
83+ }
84+
85+ /* read wav format chunk */
86+ if (vf) printf("ck_fmt size = %d\n", sizeof(struct ck_fmt));
87+ fread(ckfmt, 1, len, fp); /* get fmt data */
88+ printf("---- fmt chunk (len=%d) ----\n", len);
89+ printf("FormatTag : 0x%04x (%d) %s\n",ckfmt->wFormatTag, ckfmt->wFormatTag,
90+ (ckfmt->wFormatTag == WAVE_FORMAT_PCM)?"MS PCM":"Other PCM");
91+ printf("Channels : 0x%04x (%d) %s\n",ckfmt->wChannels, ckfmt->wChannels,
92+ (ckfmt->wChannels == 1)?"Mono":"Stereo");
93+ printf("SamplesPerSec : 0x%08x (%d)\n",ckfmt->dwSamplesPerSec, ckfmt->dwSamplesPerSec);
94+ printf("AvgBytesPerSec : 0x%08x (%d)\n",ckfmt->dwAvgBytesPerSec, ckfmt->dwAvgBytesPerSec);
95+ printf("BlockAlign : 0x%04x (%d)\n",ckfmt->wBlockAlign, ckfmt->wBlockAlign);
96+ printf("BitsPerSample : 0x%04x (%d bits)\n",ckfmt->wBitsPerSample, ckfmt->wBitsPerSample);
97+ if (len > 16) {
98+ printf("unknown : 0x%04x (%d)\n",ckfmt->unknown, ckfmt->unknown);
99+ }
100+ return 0;
101+}
102+
103+/*
104+ * Read fact chunk header block
105+ *
106+ * IN fp
107+ * IN cklen : chunk data len
108+ * OUT ckfact : fact chunk data
109+ * OUT ret : 0 success
110+ * -1 error
111+ */
112+int ReadChunkFact(FILE *fp, int len, struct ck_fact *ckfact)
113+{
114+ if (len > sizeof(struct ck_fact)) {
115+ printf("Error: ReadChunkFact: Length Too long. (%d)\n",len);
116+ return -1;
117+ }
118+
119+ /* read wav format chunk */
120+ if (vf) printf("ck_fact size = %d\n", sizeof(struct ck_fact));
121+ fread(ckfact, 1, len, fp); /* get fact data */
122+ printf("---- fact chunk (len=%d) ----\n", len);
123+ printf("unknown : 0x%08x (%d)\n",ckfact->unknown,
124+ ckfact->unknown);
125+ return 0;
126+}
127+
128+/*
129+ * Analyze chunk header block
130+ *
131+ * IN fp
132+ * OUT ckid : chunk id
133+ * OUT cklen : chunk data len
134+ * OUT ret : 0 success
135+ * -1 EOF or error
136+ */
137+int ReadChunkHeader(FILE *fp, char *ckid, int *cklen)
138+{
139+ struct chunk_hdr chunkhdr;
140+
141+ if (vf) printf("chunk_hdr size = %d\n", sizeof(struct chunk_hdr));
142+ if (fread(&chunkhdr, 1, sizeof(struct chunk_hdr), fp) < sizeof(struct chunk_hdr)) {
143+ /* EOF or Error or Format Error */
144+ return -1;
145+ }
146+ printf("---- Chunk Header ----\n");
147+ strncpy(ckid, chunkhdr.id, 4);
148+ ckid[4] = '\0';
149+ *cklen = chunkhdr.len;
150+ printf("chunk_id : [%s]\n", ckid);
151+ printf("chunk_len : 0x%08x (%d)\n", *cklen, *cklen);
152+
153+ return 0;
154+}
155+
156+/*
157+ * Analyze WAV header block
158+ *
159+ * IN fp
160+ * OUT ret : 0 success
161+ * -1 error
162+ */
163+int ReadWavHeader(FILE *fp)
164+{
165+ char wk[4096];
166+ int len;
167+
168+ struct riff_hdr riffhdr;
169+
170+ /* read riff header */
171+ if (vf) printf("riffhdr size = %d\n", sizeof(riffhdr));
172+ fread(&riffhdr, sizeof(riffhdr), 1, fp); /* get header */
173+ strncpy(wk, riffhdr.id, 4);
174+ wk[4] = '\0';
175+ if (strcmp(wk, "RIFF")) {
176+ /* not WAV file */
177+ printf("Error : Not RIFF [%s]\n",wk);
178+ return -1;
179+ }
180+
181+ printf("---- RIFF Header ----\n");
182+ printf("riff_id : [%s]\n", wk);
183+ printf("riff_len : 0x%08x (%d)\n", riffhdr.len, riffhdr.len);
184+
185+ return 0;
186+}
187+
188+/*
189+ * Analyze WAV header block
190+ *
191+ * IN fp
192+ * OUT ret : 0 success
193+ * -1 error
194+ */
195+int ReadWavData(FILE *fp)
196+{
197+ char wk[4096];
198+ int len;
199+ int i, c;
200+
201+ for (i=0; i<10; i++) {
202+ len = fread(wk, 1, 16, fp);
203+ DumpData(wk, len);
204+ }
205+ return 0;
206+}
207+
208+/*
209+ * Wav Analyze
210+ *
211+ * IN fp : input file pointer
212+ *
213+ */
214+
215+int WavAnalyze(FILE *fp)
216+{
217+ int i;
218+ int j; /* V0.21-A */
219+ int cklen = 0; /* chunk len */
220+ char ckid[256]; /* chunk id */
221+ unsigned char rbuf[4096]; /* buf for fread() V0.21-A */
222+ unsigned char *buf = rbuf; /* dummy buffer V0.21-C */
223+ char buf_fmt[4096];
224+ char buf_fact[4096];
225+ int maxval[16]; /* Max Power 16ch */
226+ int maxvalcnt[16]; /* Max Power count 16ch */
227+
228+ struct ck_fmt *ckfmt = (struct ck_fmt *)buf_fmt;
229+ struct ck_fact *ckfact = (struct ck_fact *)buf_fact;
230+
231+ /* initialize */
232+ for (i = 0; i<16; i++) {
233+ maxval[i] = 0;
234+ maxvalcnt[i] = 0;
235+ }
236+
237+ printf("\n# Analyze WAV file. by oga.\n");
238+
239+ if (ReadWavHeader(fp)) {
240+ printf("This is not WAV(RIFF) format file.\n");
241+ exit(1);
242+ }
243+
244+ while (!ReadChunkHeader(fp, ckid, &cklen)) {
245+ if (!strncmp(ckid, "fmt", 3)) {
246+ ReadChunkFmt(fp, cklen, (struct ck_fmt *)buf_fmt);
247+ } else if (!strncmp(ckid, "fact", 4)) {
248+ ReadChunkFact(fp, cklen, (struct ck_fact *)buf_fact);
249+ } else if (!strncmp(ckid, "LIST", 4)) {
250+ printf("---- LIST chunk (len=%d) ----\n", cklen);
251+ printf("LIST:[");
252+ for (i = 0; i<cklen; i++) {
253+ if (fread(buf, 1, 1, fp) <= 0) {
254+ break;
255+ }
256+ if (buf[0] < 0x20) {
257+ //printf("<0x%02x>", buf[0]);
258+ printf("<%02x>", buf[0]);
259+ } else {
260+ printf("%c", buf[0]);
261+ }
262+ }
263+ printf("]\n");
264+ } else if (!strncmp(ckid, "data", 4)) {
265+ /* PCM Data */
266+ int total = 0;
267+ int rlen = 0; /* read len V0.21-A */
268+ int len = 0; /* dummy read len V0.21-C */
269+ int unit = (ckfmt->wBitsPerSample/8) * ckfmt->wChannels;
270+ int val;
271+ short *buf16 = (short *)buf;
272+
273+ while ((rlen = fread(rbuf, 1, unit*50, fp)) > 0) { /* V0.21-C */
274+ for (j = 0; j < rlen; j+=unit) { /* V0.21-A */
275+ len = unit; /* V0.21-A */
276+ buf = &rbuf[j]; /* V0.21-A */
277+ buf16 = (short *)buf; /* V0.21-A */
278+ if (df) {
279+ printf("%08x: ", total);
280+ DumpData(buf, len);
281+ }
282+
283+ for (i = 0; i < ckfmt->wChannels; i++) {
284+ if (ckfmt->wBitsPerSample == 8) {
285+ /* 1 byte */
286+ val = buf[i*(ckfmt->wBitsPerSample/8)] - 0x80;
287+ } else {
288+ /* 2 byte wBitsPerSample == 16 */
289+ /* val = buf16[i*(ckfmt->wBitsPerSample/8)]; */
290+ val = buf16[i];
291+ }
292+ if (df) printf("ch%d:%6d ", i+1, val);
293+
294+ if (maxval[i] < abs(val)) {
295+ maxval[i] = abs(val); /* new max */
296+ maxvalcnt[i] = 1; /* reset */
297+ } else if (maxval[i] == abs(val)) {
298+ ++maxvalcnt[i]; /* count up */
299+ }
300+ }
301+ if (df) printf("\n");
302+ total += len;
303+
304+ if (total >= cklen) {
305+ break;
306+ }
307+ } /* 1 bufferd data loop V0.21-A */
308+ } /* data chunk loop */
309+ printf("---- Other Info ----\n");
310+ /* ch0:Left ch1:Right */
311+ printf("Max Power : ");
312+ for (i = 0; i < ckfmt->wChannels; i++) {
313+ printf("ch%d:%d/%d (%d times) ", i+1,
314+ maxval[i], 1 << (ckfmt->wBitsPerSample - 1),
315+ maxvalcnt[i]);
316+ }
317+ printf("\n");
318+ printf("Time : %d:%04.2f\n", cklen/ckfmt->dwAvgBytesPerSec/60,
319+ ((float)(cklen-(cklen/ckfmt->dwAvgBytesPerSec/60)*ckfmt->dwAvgBytesPerSec*60)/ckfmt->dwAvgBytesPerSec));
320+ } else {
321+ /* unknown chank */
322+ fseek(fp, cklen, SEEK_CUR);
323+ }
324+ }
325+
326+ printf("WAV file Analyze end.\n");
327+ return 0;
328+}
329+
330+void usage()
331+{
332+ printf("usage: wavana [-d] [<wav_file>]\n");
333+ printf(" -d : display data\n");
334+ exit(1);
335+}
336+
337+int main(int a, char *b[])
338+{
339+ int i;
340+ char *filename = NULL;
341+ char buf[4096];
342+ FILE *fp;
343+
344+ for (i = 1; i<a; i++) {
345+ if (!strncmp(b[i],"-v",2)) {
346+ vf = 1;
347+ continue;
348+ }
349+ if (!strncmp(b[i],"-d",2)) {
350+ df = 1;
351+ continue;
352+ }
353+ if (!strncmp(b[i],"-h",2)) {
354+ usage();
355+ }
356+ filename = b[i];
357+ }
358+ if (filename) {
359+ if (!(fp = fopen(filename,"rb"))) {
360+ perror("fopen");
361+ exit(1);
362+ }
363+ } else {
364+ fp = stdin;
365+ }
366+
367+ WavAnalyze(fp);
368+
369+ fclose(fp);
370+}
--- /dev/null
+++ b/wavcut.c
@@ -0,0 +1,1530 @@
1+/*
2+ * .WAV cutter
3+ *
4+ * 05/10/18 V0.10 support blank cut by oga.
5+ * 05/10/28 V0.11 support -ex
6+ * 05/11/05 V0.20 support -no (normalize)
7+ * 05/11/13 V0.21 perf up 29.51sec=>7.93sec (41.9MB wav, K6/175MHz)
8+ * 05/12/25 V0.22 normalize 110% (test)
9+ * 06/02/01 V0.23 support -noX normalize 1X0%
10+ * 07/03/11 V0.24 support -rv reduce voice part
11+ * 07/10/07 V0.25 support -vol volume
12+ * 07/11/18 V0.26 fix riff_len bug
13+ * 07/12/02 V0.27 support -m (merge wavs)
14+ * 11/01/29 V0.28 fix display bug
15+ * 12/03/19 V0.29 fix -ex degrade (調査中 ex. -ex 00:05-21:50)
16+ *
17+ *
18+ * お勧め: wavcut -s -lv 20 -ln 15
19+ */
20+
21+#if 0
22+ typical wav format
23+ ---- RIFF Header ----
24+ riff_id : [RIFF]
25+ riff_len : 0x0017d93c (1562940)
26+ ---- Chunk Header ----
27+ chunk_id : [fmt ]
28+ chunk_len : 0x00000010 (16)
29+ ---- fmt chunk (len=16) ----
30+ FormatTag : 0x0001 (1) MS PCM
31+ Channels : 0x0002 (2) Stereo
32+ SamplesPerSec : 0x0000ac44 (44100)
33+ AvgBytesPerSec : 0x0002b110 (176400)
34+ BlockAlign : 0x0004 (4)
35+ BitsPerSample : 0x0010 (16 bits)
36+ ---- Chunk Header ----
37+ chunk_id : [data]
38+ chunk_len : 0x0017d918 (1562904)
39+#endif
40+
41+#include <stdio.h>
42+#include <errno.h>
43+#include <stdlib.h>
44+#include <string.h>
45+
46+#ifdef _WIN32
47+#define strcasecmp stricmp
48+#define strncasecmp strnicmp
49+#endif /* _WIN32 */
50+
51+#define VER "0.28"
52+#define dprintf if (vf) printf
53+#define dprintf2 if (vf >= 2) printf
54+#define sgn(x) (x==0)?0:((x>0)?1:-1)
55+
56+int vf = 0; /* -v verbose */
57+int df = 0; /* -d disp all data value */
58+int sf = 0; /* -s split wav data */
59+int th_val = 60; /* -lv threshold value (blank level) default:6.0% */
60+int bl_sec = 10; /* -ln time to recognize blank default:1.0s */
61+char in_fname[1024]; /* in wav filename (without suffix) */
62+int *start_dsec; /* start dsecs */
63+int *end_dsec; /* end dsecs */
64+int ntment = 0; /* -ex num of time data */
65+int nf = 0; /* -no normalize */
66+int volf = 0; /* -vol volume V0.25-A */
67+int rvf = 0; /* -rv reduce voice V0.24-A */
68+int mf = 0; /* -m merge wavfiles V0.27-A */
69+int peak_level = 0; /* peak level for -no */
70+int max_level = 0; /* max level for -no */
71+long pre_datlen = 0; /* heders total length to wav data */
72+
73+int gBytePerSample = 0; /* Byte / Sample */
74+int gChannels = 0; /* Num of Channel */
75+int gUnit = 0; /* Byte / Sample * nChannel */
76+
77+
78+/* data formats */
79+struct riff_hdr {
80+ char id[4]; /* RIFF id ("RIFF") */
81+ unsigned long len; /* length */
82+ char wave_id[4]; /* data type ("WAVE") */
83+};
84+
85+struct chunk_hdr {
86+ char id[4]; /* chunk id ("fmt "|"data"...) */
87+ unsigned long len; /* chunk length */
88+};
89+
90+/* chunk type fmt 1 */
91+struct ck_fmt {
92+ unsigned short wFormatTag; /* Format category */
93+#define WAVE_FORMAT_UNKNOWN 0x0000 /* unknown */
94+#define WAVE_FORMAT_PCM 0x0001 /* Microsoft PCM */
95+#define WAVE_FORMAT_ADPCM 0x0002 /* Microsoft ADPCM */
96+#define WAVE_FORMAT_ALAW 0x0006 /* A-Law */
97+#define WAVE_FORMAT_MULAW 0x0007 /* mu-Law */
98+#define WAVE_FORMAT_IDADPCM 0x0011 /* IMA/DVI ADPCM */
99+#define WAVE_FORMAT_TRUESPEECH 0x0022 /* TrueSpeech */
100+#define WAVE_FORMAT_GSM 0x0031 /* TrueSpeech */
101+#define IBM_FORMAT_MULAW 0x0101 /* IBM mu-law format */
102+#define IBM_FORMAT_ALAW 0x0102 /* IBM a-law format */
103+#define IBM_FORMAT_ADPCM 0x0103 /* IBM AVC Adaptive Diff PCM format */
104+ unsigned short wChannels; /* Number of channels */
105+ unsigned long dwSamplesPerSec; /* Sampling rate */
106+ unsigned long dwAvgBytesPerSec; /* For buffer estimation */
107+ unsigned short wBlockAlign; /* Data block size */
108+ unsigned short wBitsPerSample; /* Sample size (for WAVE_FORMAT_PCM */
109+ unsigned short unknown; /* Unknown data */
110+ char dummy[256]; /* dummy area for over run */
111+};
112+
113+/* chunk type fact 2 */
114+struct ck_fact {
115+ int unknown; /* unknown */
116+};
117+
118+/* chunk type data 3 */
119+/* any length data */
120+
121+/*
122+ * Dump Data
123+ *
124+ * IN buf : dump buffer
125+ * len : dump length
126+ */
127+void DumpData(unsigned char *buf, int len)
128+{
129+ int i;
130+
131+ for (i=0; i<len; i++){
132+ printf(" %02x",buf[i]);
133+ }
134+ printf("\n");
135+}
136+
137+/*
138+ * Read fmt chunk header block
139+ *
140+ * IN fp
141+ * IN cklen : chunk data len
142+ * OUT ckfmt : fmt chunk data
143+ * OUT ret : 0 success
144+ * -1 error
145+ */
146+int ReadChunkFmt(FILE *fp, int len, struct ck_fmt *ckfmt)
147+{
148+ if (len > sizeof(struct ck_fmt)) {
149+ printf("Error: ReadChunkFmt: Length Too long. (%d)\n",len);
150+ return -1;
151+ }
152+
153+ /* read wav format chunk */
154+ if (vf) printf("ck_fmt size = %d\n", sizeof(struct ck_fmt));
155+ fread(ckfmt, 1, len, fp); /* get fmt data */
156+ printf("---- fmt chunk (len=%d) ----\n", len);
157+ printf("FormatTag : 0x%04x (%d) %s\n",ckfmt->wFormatTag, ckfmt->wFormatTag,
158+ (ckfmt->wFormatTag == WAVE_FORMAT_PCM)?"MS PCM":"Other PCM");
159+ printf("Channels : 0x%04x (%d) %s\n",ckfmt->wChannels, ckfmt->wChannels,
160+ (ckfmt->wChannels == 1)?"Mono":"Stereo");
161+ printf("SamplesPerSec : 0x%08x (%d)\n",ckfmt->dwSamplesPerSec, ckfmt->dwSamplesPerSec);
162+ printf("AvgBytesPerSec : 0x%08x (%d)\n",ckfmt->dwAvgBytesPerSec, ckfmt->dwAvgBytesPerSec);
163+ printf("BlockAlign : 0x%04x (%d)\n",ckfmt->wBlockAlign, ckfmt->wBlockAlign);
164+ printf("BitsPerSample : 0x%04x (%d bits)\n",ckfmt->wBitsPerSample, ckfmt->wBitsPerSample);
165+ if (len > 16) {
166+ printf("unknown : 0x%04x (%d)\n",ckfmt->unknown, ckfmt->unknown);
167+ }
168+ return 0;
169+}
170+
171+/*
172+ * Read fact chunk header block
173+ *
174+ * IN fp
175+ * IN cklen : chunk data len
176+ * OUT ckfact : fact chunk data
177+ * OUT ret : 0 success
178+ * -1 error
179+ */
180+int ReadChunkFact(FILE *fp, int len, struct ck_fact *ckfact)
181+{
182+ if (len > sizeof(struct ck_fact)) {
183+ printf("Error: ReadChunkFact: Length Too long. (%d)\n",len);
184+ return -1;
185+ }
186+
187+ /* read wav format chunk */
188+ if (vf) printf("ck_fact size = %d\n", sizeof(struct ck_fact));
189+ fread(ckfact, 1, len, fp); /* get fact data */
190+ printf("---- fact chunk (len=%d) ----\n", len);
191+ printf("unknown : 0x%08x (%d)\n",ckfact->unknown,
192+ ckfact->unknown);
193+ return 0;
194+}
195+
196+/*
197+ * Analyze chunk header block
198+ *
199+ * IN fp
200+ * OUT ckid : chunk id
201+ * OUT cklen : chunk data len
202+ * OUT ret : 0 success
203+ * -1 EOF or error
204+ */
205+int ReadChunkHeader(FILE *fp, char *ckid, int *cklen, struct chunk_hdr *chunkhdr)
206+{
207+ if (vf) printf("chunk_hdr size = %d\n", sizeof(struct chunk_hdr));
208+ if (fread(chunkhdr, 1, sizeof(struct chunk_hdr), fp) < sizeof(struct chunk_hdr)) {
209+ /* EOF or Error or Format Error */
210+ return -1;
211+ }
212+ printf("---- Chunk Header ----\n");
213+ strncpy(ckid, chunkhdr->id, 4);
214+ ckid[4] = '\0';
215+ *cklen = chunkhdr->len;
216+ printf("chunk_id : [%s]\n", ckid);
217+ printf("chunk_len : 0x%08x (%d)\n", *cklen, *cklen);
218+
219+ return 0;
220+}
221+
222+/*
223+ * Analyze WAV(RIFF) header block
224+ *
225+ * IN fp
226+ * OUT ret : 0 success
227+ * -1 error
228+ */
229+int ReadWavHeader(FILE *fp, struct riff_hdr *riffhdr)
230+{
231+ char wk[4096];
232+ int len;
233+
234+ /* read riff header */
235+ if (vf) printf("riffhdr size = %d\n", sizeof(struct riff_hdr));
236+ fread(riffhdr, sizeof(struct riff_hdr), 1, fp); /* get header */
237+ strncpy(wk, riffhdr->id, 4);
238+ wk[4] = '\0';
239+ if (strcmp(wk, "RIFF")) {
240+ /* not WAV file */
241+ printf("Error : Not RIFF [%s]\n",wk);
242+ return -1;
243+ }
244+
245+ printf("---- RIFF Header ----\n");
246+ printf("riff_id : [%s]\n", wk);
247+ printf("riff_len : 0x%08x (%d)\n", riffhdr->len, riffhdr->len);
248+
249+ return 0;
250+}
251+
252+/*
253+ * Analyze WAV header block
254+ *
255+ * IN fp
256+ * OUT ret : 0 success
257+ * -1 error
258+ */
259+int ReadWavData(FILE *fp)
260+{
261+ char wk[4096];
262+ int len;
263+ int i, c;
264+
265+ for (i=0; i<10; i++) {
266+ len = fread(wk, 1, 16, fp);
267+ DumpData(wk, len);
268+ }
269+ return 0;
270+}
271+
272+/*
273+ * Write wav headers
274+ *
275+ */
276+int WriteWavHeaders(FILE *wfp,
277+ struct riff_hdr *rhdr,
278+ struct chunk_hdr *cnkhdr, int cnkcnt,
279+ struct ck_fmt *cnkfmt,
280+ struct ck_fact *cnkfct)
281+{
282+ int i;
283+ char buf[16];
284+
285+ dprintf("## write RIFF header ...\n");
286+
287+ fwrite(rhdr, sizeof(struct riff_hdr), 1, wfp);
288+
289+ for (i = 0; i<cnkcnt; i++) {
290+ if (strncmp(cnkhdr[i].id, "fact", 4)) {
291+ /* excpt fact chunk (fmt, data...) */
292+ fwrite(&cnkhdr[i], sizeof(struct chunk_hdr), 1, wfp); /* chunk header */
293+ if (!strncmp(cnkhdr[i].id, "fmt ", 4)) {
294+ fwrite(cnkfmt, cnkhdr[i].len, 1, wfp); /* fmt body */
295+ }
296+
297+ /* verbose log */
298+ strncpy(buf, cnkhdr[i].id, 4);
299+ buf[4] = '\0';
300+ dprintf("## write %s header ...\n", buf);
301+ }
302+ }
303+ return 0;
304+}
305+
306+/*
307+ * Change wav headers
308+ *
309+ */
310+int ChangeWavHeaders(FILE *wfp,
311+ struct riff_hdr *rhdr,
312+ struct chunk_hdr *cnkhdr, int cnkcnt,
313+ struct ck_fmt *cnkfmt,
314+ struct ck_fact *cnkfct, /* no write */
315+ int data_size)
316+{
317+ int i;
318+ int fmt_len = 0;
319+ char buf[16];
320+
321+ printf("## change RIFF header ...\n");
322+
323+ /* Seek to head */
324+ fseek(wfp, 0, SEEK_SET);
325+
326+ /* get fmt length & set data size */
327+ for (i = 0; i<cnkcnt; i++) {
328+ if (!strncmp(cnkhdr[i].id, "fmt ", 4)) {
329+ fmt_len = cnkhdr[i].len;
330+ } else if (!strncmp(cnkhdr[i].id, "data", 4)) {
331+ cnkhdr[i].len = data_size;
332+ }
333+ }
334+
335+ /* set riffhdr length */
336+ rhdr->len = data_size /* data size */
337+ + sizeof(struct chunk_hdr) /* data chunk header */
338+ + fmt_len /* fmt size */
339+ + sizeof(struct chunk_hdr) /* fmt chunk header */
340+ + 4; /* riff_hdr."WAVE" size V0.26-A */
341+
342+ WriteWavHeaders(wfp, rhdr, cnkhdr, cnkcnt, cnkfmt, cnkfct);
343+
344+ return 0;
345+}
346+
347+/*
348+ * Wav Analyze
349+ *
350+ * IN fp : input file pointer
351+ *
352+ * [global]
353+ * OUT in_fname : input file name (without ".wav")
354+ * OUT pre_datlen : Header Length
355+ *
356+ */
357+
358+int WavAnalyze(FILE *fp)
359+{
360+ int i, j;
361+ int cklen = 0; /* chunk len */
362+ char ckid[256]; /* chunk id */
363+ unsigned char rbuf[4096]; /* buf for fread() V0.21-A */
364+ unsigned char *buf = rbuf; /* dummy buffer V0.21-C */
365+ char buf_fmt[4096];
366+ char buf_fact[4096];
367+ char fname[1024];
368+ int maxval[16]; /* Max Power 16ch */
369+ int maxvalcnt[16]; /* Max Power count 16ch */
370+ int lowcont = 0; /* low level continue count */
371+ int contf = 0; /* blank continue flag */
372+ int outf = 0; /* output flag for -ex */
373+ int reopen = 0; /* reopen flag for -ex (end=next start) */
374+ int curdsec = 0; /* current dsec */
375+
376+ struct riff_hdr riffhdr; /* 01 */
377+ struct chunk_hdr chunkhdr[10]; /* 02 */
378+ int chunk_cnt = 0;
379+ struct ck_fmt *ckfmt = (struct ck_fmt *)buf_fmt; /* 03 */
380+ struct ck_fact *ckfact = (struct ck_fact *)buf_fact; /* 04 */
381+
382+ /* initialize */
383+ for (i = 0; i<16; i++) {
384+ maxval[i] = 0;
385+ maxvalcnt[i] = 0;
386+ }
387+
388+ printf("\n# Analyze WAV file. by oga.\n");
389+
390+ if (ReadWavHeader(fp, &riffhdr)) {
391+ printf("This is not WAV(RIFF) format file.\n");
392+ exit(1);
393+ }
394+
395+ while (!ReadChunkHeader(fp, ckid, &cklen, &chunkhdr[chunk_cnt++])) {
396+ if (!strncmp(ckid, "fmt", 3)) {
397+ ReadChunkFmt(fp, cklen, (struct ck_fmt *)buf_fmt);
398+ } else if (!strncmp(ckid, "fact", 4)) {
399+ ReadChunkFact(fp, cklen, (struct ck_fact *)buf_fact);
400+ } else if (!strncmp(ckid, "LIST", 4)) {
401+ printf("---- LIST chunk (len=%d) ----\n", cklen);
402+ printf("LIST:[");
403+ for (i = 0; i<cklen; i++) {
404+ if (fread(buf, 1, 1, fp) <= 0) {
405+ break;
406+ }
407+ if (buf[0] < 0x20) {
408+ printf("<0x%02x>", buf[0]);
409+ } else {
410+ printf("%c", buf[0]);
411+ }
412+ }
413+ printf("]\n");
414+ } else if (!strncmp(ckid, "data", 4)) {
415+ /* PCM Data */
416+ int total = 0; /* total data chunk size */
417+ int rlen = 0; /* read len V0.21-A */
418+ int len = 0; /* dummy read len V0.21-C */
419+ int val;
420+ short *buf16 = (short *)buf;
421+
422+ int file_cnt = 0; /* split file counter */
423+ int data_size = 0; /* data chank size */
424+ FILE *wfp = NULL; /* write wav fp */
425+
426+ gBytePerSample = ckfmt->wBitsPerSample/8;
427+ gChannels = ckfmt->wChannels;
428+ gUnit = gBytePerSample * gChannels;
429+
430+ pre_datlen = ftell(fp); /* get current file pointer */
431+ printf("Headers Len: %d\n", pre_datlen);
432+
433+ printf("---- Cut Info ----\n");
434+ printf("CutLevel: %d (%.1f%%)\n",
435+ ((1 << (ckfmt->wBitsPerSample - 1)) * th_val/1000),
436+ ((float)th_val)/10);
437+ printf("BlankSec: %.1fsec\n", ((float)bl_sec)/10);
438+
439+ outf = 0;
440+ curdsec = total/(ckfmt->dwAvgBytesPerSec/10);
441+ for (i = 0; i<ntment; i++) {
442+ if (start_dsec[i] <= curdsec && curdsec < end_dsec[i]){
443+ outf = 1;
444+ }
445+ }
446+
447+ if (sf || (ntment && outf)) {
448+ /* ### Open Output File */
449+ sprintf(fname, "%s_%03d.wav", in_fname, file_cnt++);
450+ printf("## Writing %s ...\n", fname);
451+ wfp = fopen(fname, "wb");
452+ if (wfp == NULL) {
453+ perror(fname);
454+ exit(1);
455+ }
456+ /* ### WriteWavHeaders */
457+ WriteWavHeaders(wfp,
458+ &riffhdr, /* 01 riff header */
459+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
460+ ckfmt, /* 03 fmt data */
461+ ckfact); /* 04: no write */
462+ }
463+
464+ data_size = 0;
465+
466+ while ((rlen = fread(rbuf, 1, gUnit*50, fp)) > 0) { /* V0.21-C */
467+ for (j = 0; j < rlen; j+=gUnit) { /* V0.21-A */
468+ len = gUnit; /* V0.21-A */
469+ buf = &rbuf[j]; /* V0.21-A */
470+ buf16 = (short *)buf; /* V0.21-A */
471+
472+ if (wfp) {
473+ fwrite(buf, 1, gUnit, wfp);
474+ data_size += len; /* data chunk size for write */
475+ }
476+
477+ if (df) {
478+ printf("%08x: ", total);
479+ DumpData(buf, len);
480+ }
481+
482+ /* current time */
483+ if (df) {
484+ printf("%02d:%05.2f ", total/ckfmt->dwAvgBytesPerSec/60,
485+ ((float)(total-(total/ckfmt->dwAvgBytesPerSec/60)*ckfmt->dwAvgBytesPerSec*60)/ckfmt->dwAvgBytesPerSec));
486+ }
487+
488+ for (i = 0; i < gChannels; i++) {
489+ if (gBytePerSample == 1) {
490+ /* 1 byte */
491+ val = buf[i * gBytePerSample] - 0x80;
492+ } else {
493+ /* 2 byte gBytePerSample == 2 */
494+ /* val = buf16[i * gBytePerSample]; */
495+ val = buf16[i];
496+ }
497+ if (df) printf("ch%d:%6d ", i+1, val);
498+
499+ if (maxval[i] < abs(val)) {
500+ maxval[i] = abs(val); /* new max */
501+ maxvalcnt[i] = 1; /* reset */
502+ } else if (maxval[i] == abs(val)) {
503+ ++maxvalcnt[i]; /* count up */
504+ }
505+ }
506+ if (df) printf("\n");
507+
508+ /* sound blank check for -s */
509+ if (abs(val) <
510+ ((1 << (ckfmt->wBitsPerSample - 1)) * th_val/1000)) {
511+ /* blank level */
512+ //printf("%8d: th_val...%d\n", total,
513+ // ((1 << (ckfmt->wBitsPerSample - 1)) * th_val/1000));
514+ ++lowcont;
515+ if (contf == 0 && lowcont > (ckfmt->dwSamplesPerSec*bl_sec)/10) {
516+ /* 1sec continue... maybe blank area */
517+ printf("Blank Time Start: %02d:%05.2f\n",
518+ total/ckfmt->dwAvgBytesPerSec/60,
519+ ((float)(total-
520+ (total/ckfmt->dwAvgBytesPerSec/60)
521+ *ckfmt->dwAvgBytesPerSec*60)
522+ /ckfmt->dwAvgBytesPerSec));
523+ contf = 1;
524+
525+ if (sf && wfp) {
526+ /* ### Change Each Header Size */
527+ ChangeWavHeaders(wfp,
528+ &riffhdr, /* 01 riff header */
529+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
530+ ckfmt, /* 03 fmt data */
531+ ckfact, /* 04: no write */
532+ data_size); /* "data" block size */
533+ printf("##1 %s (%02d:%05.2f)\n", fname,
534+ data_size/ckfmt->dwAvgBytesPerSec/60,
535+ ((float)(data_size-
536+ (data_size/ckfmt->dwAvgBytesPerSec/60)
537+ *ckfmt->dwAvgBytesPerSec*60)
538+ /ckfmt->dwAvgBytesPerSec));
539+ /* ### Close Wav File */
540+ if (wfp) fclose(wfp);
541+ wfp = NULL;
542+ }
543+ }
544+
545+ } else {
546+ /* no blank level */
547+ lowcont = 0;
548+ if (contf) {
549+ contf = 0;
550+ printf("Blank Time End : %02d:%05.2f\n",
551+ total/ckfmt->dwAvgBytesPerSec/60,
552+ ((float)(total-
553+ (total/ckfmt->dwAvgBytesPerSec/60)
554+ *ckfmt->dwAvgBytesPerSec*60)
555+ /ckfmt->dwAvgBytesPerSec));
556+
557+ data_size = 0; /* reset data chunk size */
558+ if (sf) {
559+ sprintf(fname, "%s_%03d.wav", in_fname, file_cnt++);
560+ printf("## Writing %s ...\n", fname);
561+ /* ### Open Next Wav File */
562+ wfp = fopen(fname, "wb");
563+ if (wfp == NULL) {
564+ perror(fname);
565+ exit(1);
566+ }
567+ /* ### WriteWavHeaders */
568+ WriteWavHeaders(wfp,
569+ &riffhdr, /* 01 riff header */
570+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
571+ ckfmt, /* 03 fmt data */
572+ ckfact); /* 04: no write */
573+ }
574+ }
575+ }
576+
577+ /* for -ex */
578+ if (ntment) {
579+ outf = 0;
580+ reopen = 0;
581+ curdsec = total/(ckfmt->dwAvgBytesPerSec/10);
582+ for (i = 0; i<ntment; i++) {
583+ if (start_dsec[i] <= curdsec && curdsec < end_dsec[i]){
584+ outf = 1;
585+ if (curdsec == end_dsec[i]) {
586+ reopen = 1;
587+ }
588+ }
589+ }
590+ if (outf == 0 || reopen == 1) {
591+ if (wfp) {
592+ /* ### Change Each Header Size */
593+ ChangeWavHeaders(wfp,
594+ &riffhdr, /* 01 riff header */
595+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
596+ ckfmt, /* 03 fmt data */
597+ ckfact, /* 04: no write */
598+ data_size); /* "data" block size */
599+ printf("##2 %s (%02d:%05.2f)\n", fname,
600+ data_size/ckfmt->dwAvgBytesPerSec/60,
601+ ((float)(data_size-
602+ (data_size/ckfmt->dwAvgBytesPerSec/60)
603+ *ckfmt->dwAvgBytesPerSec*60)
604+ /ckfmt->dwAvgBytesPerSec));
605+ /* ### Close Wav File */
606+ if (wfp) fclose(wfp);
607+ wfp = NULL;
608+ data_size = 0; /* reset data chunk size */
609+ }
610+ }
611+ if (outf) {
612+ if (wfp == NULL) {
613+ data_size = 0; /* reset data chunk size */
614+ sprintf(fname, "%s_%03d.wav", in_fname, file_cnt++);
615+ printf("## Writing %s ...\n", fname);
616+ /* ### Open Wav File */
617+ wfp = fopen(fname, "wb");
618+ if (wfp == NULL) {
619+ perror(fname);
620+ exit(1);
621+ }
622+ /* ### WriteWavHeaders */
623+ WriteWavHeaders(wfp,
624+ &riffhdr, /* 01 riff header */
625+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
626+ ckfmt, /* 03 fmt data */
627+ ckfact); /* 04: no write */
628+ }
629+ }
630+ }
631+
632+ total += len; /* total read size */
633+
634+ if (total >= cklen) {
635+ break;
636+ }
637+ } /* 1 bufferd data loop V0.21-A */
638+ } /* data chunk loop */
639+
640+ if (contf) {
641+ contf = 0;
642+ printf("Blank Time End : %02d:%05.2f\n",
643+ total/ckfmt->dwAvgBytesPerSec/60,
644+ ((float)(total-
645+ (total/ckfmt->dwAvgBytesPerSec/60)
646+ *ckfmt->dwAvgBytesPerSec*60)
647+ /ckfmt->dwAvgBytesPerSec));
648+ }
649+
650+ if (wfp) {
651+ /* ### Change Each Header Size */
652+ ChangeWavHeaders(wfp,
653+ &riffhdr, /* 01 riff header */
654+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
655+ ckfmt, /* 03 fmt data */
656+ ckfact, /* 04: no write */
657+ data_size); /* "data" block size */
658+ printf("##3 %s (%02d:%05.2f)\n", fname,
659+ data_size/ckfmt->dwAvgBytesPerSec/60,
660+ ((float)(data_size-
661+ (data_size/ckfmt->dwAvgBytesPerSec/60)
662+ *ckfmt->dwAvgBytesPerSec*60)
663+ /ckfmt->dwAvgBytesPerSec));
664+ /* ### Close Wav File */
665+ if (wfp) fclose(wfp);
666+ wfp = NULL;
667+ }
668+
669+ printf("---- Other Info ----\n");
670+ /* ch0:Left ch1:Right */
671+ printf("Max Power : ");
672+ for (i = 0; i < gChannels; i++) {
673+ printf("ch%d:%d/%d (%d times) ", i+1,
674+ maxval[i], 1 << (ckfmt->wBitsPerSample - 1),
675+ maxvalcnt[i]);
676+ if (peak_level < maxval[i]) {
677+ peak_level = maxval[i];
678+ }
679+ }
680+ max_level = 1 << (ckfmt->wBitsPerSample - 1);
681+ printf("\n");
682+ //printf("Time : %.2f sec\n",
683+ // ((float)cklen)/ckfmt->dwAvgBytesPerSec);
684+ printf("Time : %02d:%05.2f\n", cklen/ckfmt->dwAvgBytesPerSec/60,
685+ ((float)(cklen-(cklen/ckfmt->dwAvgBytesPerSec/60)*ckfmt->dwAvgBytesPerSec*60)/ckfmt->dwAvgBytesPerSec));
686+ }
687+ }
688+
689+ printf("WAV file Analyze end.\n");
690+ return 0;
691+}
692+
693+
694+/*
695+ * WavNormalize
696+ *
697+ * IN infp : input wav file fp
698+ * IN peek_lv : peek level
699+ * IN max_lv : max level
700+ *
701+ * [global]
702+ * IN in_fname : input file name (without ".wav")
703+ * IN pre_datlen : headers length
704+ *
705+ * OUT "<in_fname>.normalize.wav"
706+ *
707+ */
708+void WavNormalize(FILE *infp, int peak_lv, int max_lv)
709+{
710+ char ofname[1024];
711+ char buf[1024];
712+ short *buf16 = (short *)buf;
713+ FILE *ofp;
714+ int size, rsize;
715+ int rtotal = 0;
716+ int val, newval;
717+ int len;
718+ int i;
719+
720+ printf("Normalize: Level x %.2f (%d%%)\n", ((float)max_lv)/peak_lv, 100+10*(nf-1));
721+ if (volf) {
722+ /* change volume */
723+ sprintf(ofname, "%s.%d%%.wav", in_fname, volf);
724+ } else {
725+ /* normalize */
726+ sprintf(ofname, "%s.normalize.wav", in_fname);
727+ }
728+
729+ if (pre_datlen > sizeof(buf)) {
730+ printf("Error: WavNormalize: headers size too big!\n");
731+ exit(1);
732+ }
733+
734+ ofp = fopen(ofname, "wb");
735+ if (ofp == NULL) {
736+ perror(ofname);
737+ return;
738+ }
739+
740+ /* copy headers */
741+ size = fread(buf, 1, pre_datlen, infp);
742+ if (pre_datlen != size) {
743+ printf("Error: WavNormalize: read size too short!\n");
744+ exit(1);
745+ }
746+ fwrite(buf, 1, size, ofp);
747+
748+ /* normalize */
749+ while ((len = fread(buf, 1, gUnit, infp)) > 0) {
750+
751+ for (i = 0; i < gChannels; i++) {
752+ if (gBytePerSample == 1) {
753+ /* 1 byte */
754+ /*val = buf[i * gBytePerSample] - 0x80; */
755+ val = buf[i * gBytePerSample];
756+ newval = (val * max_lv) / peak_lv;
757+
758+ /* check overflow V0.23 */
759+ if (nf > 1 && abs(newval) >= max_lv) {
760+ buf[i * gBytePerSample] = sgn(newval) * (max_lv-1); /* V0.23 */
761+ } else {
762+ buf[i * gBytePerSample] = newval;
763+ }
764+ if (vf) printf("%d => %d\n", val, buf[i * gBytePerSample]);
765+ } else {
766+ /* 2 byte gBytePerSample == 2 */
767+ /* val = buf16[i * gBytePerSample]; */
768+ val = buf16[i];
769+ newval = (val * max_lv) / peak_lv;
770+
771+ /* check overflow V0.23 */
772+ if (nf > 1 && abs(newval) >= max_lv) {
773+ buf16[i] = sgn(newval) * (max_lv-1); /* V0.23 */
774+ } else {
775+ buf16[i] = newval;
776+ }
777+ if (vf) printf("%d => %d\n", val, buf16[i]);
778+ }
779+ }
780+
781+ if (ofp) {
782+ fwrite(buf, 1, gUnit, ofp);
783+ }
784+ } /* data chunk loop */
785+
786+ fclose(ofp);
787+}
788+
789+/* V0.24-A start */
790+/*
791+ * ReduceVoice
792+ *
793+ * IN infp : input wav file fp
794+ *
795+ * [global]
796+ * IN in_fname : input file name (without ".wav")
797+ * IN pre_datlen : headers length
798+ *
799+ * OUT "<in_fname>.novoice.wav"
800+ *
801+ */
802+void ReduceVoice(FILE *infp)
803+{
804+ char ofname[1024];
805+ char buf[1024];
806+ short *buf16 = (short *)buf;
807+ FILE *ofp;
808+ int size, rsize;
809+ int rtotal = 0;
810+ int val, newval;
811+ int len;
812+ int i;
813+
814+ sprintf(ofname, "%s.novoice.wav", in_fname);
815+
816+ printf("reduce voice data output to %s ...\n", ofname);
817+
818+ if (pre_datlen > sizeof(buf)) {
819+ printf("Error: ReduceVoice: headers size too big!\n");
820+ exit(1);
821+ }
822+ if (gChannels < 2) {
823+ printf("Error: ReduceVoice: not support mono data\n");
824+ exit(1);
825+ }
826+
827+ ofp = fopen(ofname, "wb");
828+ if (ofp == NULL) {
829+ perror(ofname);
830+ return;
831+ }
832+
833+ /* copy headers */
834+ size = fread(buf, 1, pre_datlen, infp);
835+ if (pre_datlen != size) {
836+ printf("Error: ReduceVoice: read size too short!\n");
837+ exit(1);
838+ }
839+ fwrite(buf, 1, size, ofp);
840+
841+ /* reduce voice */
842+ while ((len = fread(buf, 1, gUnit, infp)) > 0) {
843+ if (gBytePerSample == 1) {
844+ /* 1 byte */
845+ /*val = buf[i * gBytePerSample] - 0x80; */
846+ printf("unsupport reduce voice for 1byte/sample.\n");
847+#if 0
848+ val = buf[i * gBytePerSample];
849+
850+ /* check overflow V0.23 */
851+ if (nf > 1 && abs(newval) >= max_lv) {
852+ buf[i * gBytePerSample] = sgn(newval) * (max_lv-1); /* V0.23 */
853+ } else {
854+ buf[i * gBytePerSample] = newval;
855+ }
856+ if (vf) printf("%d => %d\n", val, buf[i * gBytePerSample]);
857+#endif
858+ } else {
859+ /* 2 byte gBytePerSample == 2 */
860+ /* val = buf16[i * gBytePerSample]; */
861+ if (buf16[0] * buf16[1] > 0) {
862+ if (buf16[0] > 0) {
863+ /* plus */
864+ if (buf16[0] > buf16[1]) {
865+ buf16[0] = buf16[0] - buf16[1];
866+ buf16[1] = 0;
867+ } else {
868+ buf16[0] = 0;
869+ buf16[1] = buf16[1] - buf16[0];
870+ }
871+ } else {
872+ /* minus */
873+ if (buf16[0] > buf16[1]) {
874+ buf16[1] = buf16[1] - buf16[0];
875+ buf16[0] = 0;
876+ } else {
877+ buf16[1] = 0;
878+ buf16[0] = buf16[0] - buf16[1];
879+ }
880+ }
881+ }
882+ }
883+
884+ if (ofp) {
885+ fwrite(buf, 1, gUnit, ofp);
886+ }
887+ } /* data chunk loop */
888+
889+ fclose(ofp);
890+}
891+/* V0.24-A start */
892+
893+/* V0.27-A start */
894+/*
895+ * MergeWavs
896+ *
897+ * IN files : input wav files
898+ *
899+ * OUT "<in_file1>.merge.wav"
900+ *
901+ */
902+void MergeWavs(char **files)
903+{
904+ char ofname[1024];
905+ FILE *ofp, *fp;
906+#if 0
907+ char buf[1024];
908+ short *buf16 = (short *)buf;
909+ int size, rsize;
910+ int rtotal = 0;
911+ int val, newval;
912+ int len;
913+#endif
914+ int i;
915+ int first = 1;
916+ int fcnt = 0;
917+ char *pt;
918+
919+ int cklen = 0; /* chunk len */
920+ char ckid[256]; /* chunk id */
921+ char buf_fmt[4096];
922+ char buf_fact[4096];
923+ struct riff_hdr riffhdr; /* 01 */
924+ struct chunk_hdr chunkhdr[10]; /* 02 */
925+ int chunk_cnt = 0;
926+ struct ck_fmt *ckfmt = (struct ck_fmt *)buf_fmt; /* 03 */
927+ struct ck_fact *ckfact = (struct ck_fact *)buf_fact; /* 04 */
928+
929+#if 0 /* 作成中 */
930+ strcpy(ofname, files[0]);
931+ pt = strrchr(ofname, '.');
932+ if (pt) {
933+ *pt = '\0'; /* delete suffix */
934+ }
935+
936+ strcat(ofname, ".merge.wav");
937+ if (!(ofp = fopen(ofname, "wb"))) {
938+ perror(ofname);
939+ exit(1);
940+ }
941+
942+ while (files[fcnt]) {
943+ if (!(fp = fopen(files[fcnt], "rb"))) {
944+ perror(files[fcnt]);
945+ exit(1);
946+ }
947+
948+ if (ReadWavHeader(fp, &riffhdr)) {
949+ printf("This is not WAV(RIFF) format file.\n");
950+ exit(1);
951+ }
952+
953+ while (!ReadChunkHeader(fp, ckid, &cklen, &chunkhdr[chunk_cnt++])) {
954+ if (!strncmp(ckid, "fmt", 3)) {
955+ ReadChunkFmt(fp, cklen, (struct ck_fmt *)buf_fmt);
956+ } else if (!strncmp(ckid, "fact", 4)) {
957+ ReadChunkFact(fp, cklen, (struct ck_fact *)buf_fact);
958+ } else if (!strncmp(ckid, "LIST", 4)) {
959+ printf("---- LIST chunk (len=%d) ----\n", cklen);
960+ printf("LIST:[");
961+ for (i = 0; i<cklen; i++) {
962+ if (fread(buf, 1, 1, fp) <= 0) {
963+ break;
964+ }
965+ if (buf[0] < 0x20) {
966+ printf("<0x%02x>", buf[0]);
967+ } else {
968+ printf("%c", buf[0]);
969+ }
970+ }
971+ printf("]\n");
972+ } else if (!strncmp(ckid, "data", 4)) {
973+ /* PCM Data */
974+ int total = 0; /* total data chunk size */
975+ int rlen = 0; /* read len V0.21-A */
976+ int len = 0; /* dummy read len V0.21-C */
977+ int val;
978+ short *buf16 = (short *)buf;
979+
980+ int file_cnt = 0; /* split file counter */
981+ int data_size = 0; /* data chank size */
982+ FILE *wfp = NULL; /* write wav fp */
983+
984+ gBytePerSample = ckfmt->wBitsPerSample/8;
985+ gChannels = ckfmt->wChannels;
986+ gUnit = gBytePerSample * gChannels;
987+
988+ pre_datlen = ftell(fp); /* get current file pointer */
989+ printf("Headers Len: %d\n", pre_datlen);
990+
991+ printf("---- Cut Info ----\n");
992+ printf("CutLevel: %d (%.1f%%)\n",
993+ ((1 << (ckfmt->wBitsPerSample - 1)) * th_val/1000),
994+ ((float)th_val)/10);
995+ printf("BlankSec: %.1fsec\n", ((float)bl_sec)/10);
996+
997+ outf = 0;
998+ curdsec = total/(ckfmt->dwAvgBytesPerSec/10);
999+ for (i = 0; i<ntment; i++) {
1000+ if (start_dsec[i] <= curdsec && curdsec < end_dsec[i]){
1001+ outf = 1;
1002+ }
1003+ }
1004+
1005+ if (sf || (ntment && outf)) {
1006+ /* ### Open Output File */
1007+ sprintf(fname, "%s_%03d.wav", in_fname, file_cnt++);
1008+ printf("## Writing %s ...\n", fname);
1009+ wfp = fopen(fname, "wb");
1010+ if (wfp == NULL) {
1011+ perror(fname);
1012+ exit(1);
1013+ }
1014+ /* ### WriteWavHeaders */
1015+ WriteWavHeaders(wfp,
1016+ &riffhdr, /* 01 riff header */
1017+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
1018+ ckfmt, /* 03 fmt data */
1019+ ckfact); /* 04: no write */
1020+ }
1021+
1022+ data_size = 0;
1023+
1024+ while ((rlen = fread(rbuf, 1, gUnit*50, fp)) > 0) { /* V0.21-C */
1025+ for (j = 0; j < rlen; j+=gUnit) { /* V0.21-A */
1026+ len = gUnit; /* V0.21-A */
1027+ buf = &rbuf[j]; /* V0.21-A */
1028+ buf16 = (short *)buf; /* V0.21-A */
1029+
1030+ if (wfp) {
1031+ fwrite(buf, 1, gUnit, wfp);
1032+ data_size += len; /* data chunk size for write */
1033+ }
1034+
1035+ if (df) {
1036+ printf("%08x: ", total);
1037+ DumpData(buf, len);
1038+ }
1039+
1040+ /* current time */
1041+ if (df) {
1042+ printf("%02d:%05.2f ", total/ckfmt->dwAvgBytesPerSec/60,
1043+ ((float)(total-(total/ckfmt->dwAvgBytesPerSec/60)*ckfmt->dwAvgBytesPerSec*60)/ckfmt->dwAvgBytesPerSec));
1044+ }
1045+
1046+ for (i = 0; i < gChannels; i++) {
1047+ if (gBytePerSample == 1) {
1048+ /* 1 byte */
1049+ val = buf[i * gBytePerSample] - 0x80;
1050+ } else {
1051+ /* 2 byte gBytePerSample == 2 */
1052+ /* val = buf16[i * gBytePerSample]; */
1053+ val = buf16[i];
1054+ }
1055+ if (df) printf("ch%d:%6d ", i+1, val);
1056+
1057+ if (maxval[i] < abs(val)) {
1058+ maxval[i] = abs(val); /* new max */
1059+ maxvalcnt[i] = 1; /* reset */
1060+ } else if (maxval[i] == abs(val)) {
1061+ ++maxvalcnt[i]; /* count up */
1062+ }
1063+ }
1064+ if (df) printf("\n");
1065+
1066+ /* sound blank check for -s */
1067+ if (abs(val) <
1068+ ((1 << (ckfmt->wBitsPerSample - 1)) * th_val/1000)) {
1069+ /* blank level */
1070+ //printf("%8d: th_val...%d\n", total,
1071+ // ((1 << (ckfmt->wBitsPerSample - 1)) * th_val/1000));
1072+ ++lowcont;
1073+ if (contf == 0 && lowcont > (ckfmt->dwSamplesPerSec*bl_sec)/10) {
1074+ /* 1sec continue... maybe blank area */
1075+ printf("Blank Time Start: %02d:%05.2f\n",
1076+ total/ckfmt->dwAvgBytesPerSec/60,
1077+ ((float)(total-
1078+ (total/ckfmt->dwAvgBytesPerSec/60)
1079+ *ckfmt->dwAvgBytesPerSec*60)
1080+ /ckfmt->dwAvgBytesPerSec));
1081+ contf = 1;
1082+
1083+ if (sf && wfp) {
1084+ /* ### Change Each Header Size */
1085+ ChangeWavHeaders(wfp,
1086+ &riffhdr, /* 01 riff header */
1087+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
1088+ ckfmt, /* 03 fmt data */
1089+ ckfact, /* 04: no write */
1090+ data_size); /* "data" block size */
1091+ printf("##4 %s (%02d:%05.2f)\n", fname,
1092+ data_size/ckfmt->dwAvgBytesPerSec/60,
1093+ ((float)(data_size-
1094+ (data_size/ckfmt->dwAvgBytesPerSec/60)
1095+ *ckfmt->dwAvgBytesPerSec*60)
1096+ /ckfmt->dwAvgBytesPerSec));
1097+ /* ### Close Wav File */
1098+ if (wfp) fclose(wfp);
1099+ wfp = NULL;
1100+ }
1101+ }
1102+
1103+ } else {
1104+ /* no blank level */
1105+ lowcont = 0;
1106+ if (contf) {
1107+ contf = 0;
1108+ printf("Blank Time End : %02d:%05.2f\n",
1109+ total/ckfmt->dwAvgBytesPerSec/60,
1110+ ((float)(total-
1111+ (total/ckfmt->dwAvgBytesPerSec/60)
1112+ *ckfmt->dwAvgBytesPerSec*60)
1113+ /ckfmt->dwAvgBytesPerSec));
1114+
1115+ data_size = 0; /* reset data chunk size */
1116+ if (sf) {
1117+ sprintf(fname, "%s_%03d.wav", in_fname, file_cnt++);
1118+ printf("## Writing %s ...\n", fname);
1119+ /* ### Open Next Wav File */
1120+ wfp = fopen(fname, "wb");
1121+ if (wfp == NULL) {
1122+ perror(fname);
1123+ exit(1);
1124+ }
1125+ /* ### WriteWavHeaders */
1126+ WriteWavHeaders(wfp,
1127+ &riffhdr, /* 01 riff header */
1128+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
1129+ ckfmt, /* 03 fmt data */
1130+ ckfact); /* 04: no write */
1131+ }
1132+ }
1133+ }
1134+
1135+ /* for -ex */
1136+ if (ntment) {
1137+ outf = 0;
1138+ reopen = 0;
1139+ curdsec = total/(ckfmt->dwAvgBytesPerSec/10);
1140+ for (i = 0; i<ntment; i++) {
1141+ if (start_dsec[i] <= curdsec && curdsec < end_dsec[i]){
1142+ outf = 1;
1143+ if (curdsec == end_dsec[i]) {
1144+ reopen = 1;
1145+ }
1146+ }
1147+ }
1148+ if (outf == 0 || reopen == 1) {
1149+ if (wfp) {
1150+ /* ### Change Each Header Size */
1151+ ChangeWavHeaders(wfp,
1152+ &riffhdr, /* 01 riff header */
1153+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
1154+ ckfmt, /* 03 fmt data */
1155+ ckfact, /* 04: no write */
1156+ data_size); /* "data" block size */
1157+ printf("##5 %s (%02d:%05.2f)\n", fname,
1158+ data_size/ckfmt->dwAvgBytesPerSec/60,
1159+ ((float)(data_size-
1160+ (data_size/ckfmt->dwAvgBytesPerSec/60)
1161+ *ckfmt->dwAvgBytesPerSec*60)
1162+ /ckfmt->dwAvgBytesPerSec));
1163+ /* ### Close Wav File */
1164+ if (wfp) fclose(wfp);
1165+ wfp = NULL;
1166+ data_size = 0; /* reset data chunk size */
1167+ }
1168+ }
1169+ if (outf) {
1170+ if (wfp == NULL) {
1171+ data_size = 0; /* reset data chunk size */
1172+ sprintf(fname, "%s_%03d.wav", in_fname, file_cnt++);
1173+ printf("## Writing %s ...\n", fname);
1174+ /* ### Open Wav File */
1175+ wfp = fopen(fname, "wb");
1176+ if (wfp == NULL) {
1177+ perror(fname);
1178+ exit(1);
1179+ }
1180+ /* ### WriteWavHeaders */
1181+ WriteWavHeaders(wfp,
1182+ &riffhdr, /* 01 riff header */
1183+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
1184+ ckfmt, /* 03 fmt data */
1185+ ckfact); /* 04: no write */
1186+ }
1187+ }
1188+ }
1189+
1190+ total += len; /* total read size */
1191+
1192+ if (total >= cklen) {
1193+ break;
1194+ }
1195+ } /* 1 bufferd data loop V0.21-A */
1196+ } /* data chunk loop */
1197+
1198+ if (contf) {
1199+ contf = 0;
1200+ printf("Blank Time End : %02d:%05.2f\n",
1201+ total/ckfmt->dwAvgBytesPerSec/60,
1202+ ((float)(total-
1203+ (total/ckfmt->dwAvgBytesPerSec/60)
1204+ *ckfmt->dwAvgBytesPerSec*60)
1205+ /ckfmt->dwAvgBytesPerSec));
1206+ }
1207+
1208+ if (wfp) {
1209+ /* ### Change Each Header Size */
1210+ ChangeWavHeaders(wfp,
1211+ &riffhdr, /* 01 riff header */
1212+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
1213+ ckfmt, /* 03 fmt data */
1214+ ckfact, /* 04: no write */
1215+ data_size); /* "data" block size */
1216+ printf("##6 %s (%02d:%05.2f)\n", fname,
1217+ data_size/ckfmt->dwAvgBytesPerSec/60,
1218+ ((float)(data_size-
1219+ (data_size/ckfmt->dwAvgBytesPerSec/60)
1220+ *ckfmt->dwAvgBytesPerSec*60)
1221+ /ckfmt->dwAvgBytesPerSec));
1222+ /* ### Close Wav File */
1223+ if (wfp) fclose(wfp);
1224+ wfp = NULL;
1225+ }
1226+
1227+ printf("---- Other Info ----\n");
1228+ /* ch0:Left ch1:Right */
1229+ printf("Max Power : ");
1230+ for (i = 0; i < gChannels; i++) {
1231+ printf("ch%d:%d/%d (%d times) ", i+1,
1232+ maxval[i], 1 << (ckfmt->wBitsPerSample - 1),
1233+ maxvalcnt[i]);
1234+ if (peak_level < maxval[i]) {
1235+ peak_level = maxval[i];
1236+ }
1237+ }
1238+ max_level = 1 << (ckfmt->wBitsPerSample - 1);
1239+ printf("\n");
1240+ //printf("Time : %.2f sec\n",
1241+ // ((float)cklen)/ckfmt->dwAvgBytesPerSec);
1242+ printf("Time : %02d:%05.2f\n", cklen/ckfmt->dwAvgBytesPerSec/60,
1243+ ((float)(cklen-(cklen/ckfmt->dwAvgBytesPerSec/60)*ckfmt->dwAvgBytesPerSec*60)/ckfmt->dwAvgBytesPerSec));
1244+ }
1245+ }
1246+ }
1247+#endif /* 作成中 */
1248+}
1249+/* V0.24-A start */
1250+
1251+/*
1252+ * TimeStr2Sec()
1253+ *
1254+ * IN str : mm:ss.n
1255+ * OUT ret : dsec (1/10sec)
1256+ * -1 : invalid time format
1257+ */
1258+int TimeStr2Sec(char *str)
1259+{
1260+ char *pt;
1261+ char wk[1024];
1262+ int mm, ss, ds;
1263+ int rval = 0;
1264+
1265+ mm = ss = ds = 0;
1266+
1267+ /* get mm */
1268+ pt = strchr(str, ':');
1269+ if (pt) {
1270+ mm = atoi(str);
1271+ ++pt;
1272+ } else {
1273+ pt = str;
1274+ }
1275+
1276+ /* get ss */
1277+ ss = atoi(pt);
1278+
1279+ /* get ds */
1280+ pt = strchr(str, '.');
1281+ if (pt) {
1282+ ++pt;
1283+ ds = *pt - '0';
1284+ if (ds < 0 || ds > 9) {
1285+ printf("invalid time value [%s]\n", str);
1286+ return -1;
1287+ }
1288+ }
1289+
1290+ rval = (mm*60+ss)*10 + ds;
1291+ dprintf2("dsec = %d\n", rval);
1292+
1293+ return rval;
1294+}
1295+
1296+/*
1297+ * GetTimes()
1298+ *
1299+ * IN time_exp : mm:ss.n-mm:ss.n[,mm:ss.n-mm:ss.n,...]
1300+ * OUT st_dsec[] : start dsec (1/10sec)
1301+ * OUT ed_dsec[] : end dsec (1/10sec)
1302+ * OUT ret : num of time (0 : format error)
1303+ *
1304+ */
1305+int GetTimes(char *time_exp, int **st_dsec, int **en_dsec)
1306+{
1307+ int n_time = 0;
1308+ int i;
1309+ int err = 0;
1310+ char buf[4096];
1311+ char *pt, *pt2;
1312+ char wkst[1024];
1313+ char wken[1024];
1314+
1315+ strncpy(buf, time_exp, sizeof(buf));
1316+ buf[sizeof(buf)-1] = '\0';
1317+
1318+ ++n_time;
1319+ for (i = 0; i<strlen(buf); i++) {
1320+ if (buf[i] == ',') {
1321+ ++n_time;
1322+ }
1323+ }
1324+ if (n_time) {
1325+ *st_dsec = malloc(sizeof(int)*n_time);
1326+ *en_dsec = malloc(sizeof(int)*n_time);
1327+ if (*st_dsec == NULL || *en_dsec == NULL) {
1328+ err = 1;
1329+ } else {
1330+ memset(*st_dsec, 0, sizeof(int)*n_time);
1331+ memset(*en_dsec, 0, sizeof(int)*n_time);
1332+ }
1333+ }
1334+
1335+ i = 0;
1336+ pt = strtok(buf, ",");
1337+ while (err == 0 && pt) {
1338+ pt2 = strchr(pt, '-');
1339+ if (pt2 == NULL) {
1340+ err = 1;
1341+ break;
1342+ }
1343+ *pt2 = '\0';
1344+ ++pt2;
1345+ strcpy(wkst, pt); /* copy start time */
1346+ strcpy(wken, pt2); /* copy end time */
1347+ (*st_dsec)[i] = TimeStr2Sec(wkst);
1348+ (*en_dsec)[i] = TimeStr2Sec(wken);
1349+ if ((*st_dsec)[i] < 0 || (*en_dsec)[i] < 0) {
1350+ err = 1;
1351+ break;
1352+ }
1353+ dprintf("## st = %d en = %d\n", (*st_dsec)[i], (*en_dsec)[i]);
1354+ ++i;
1355+ pt = strtok(NULL, ",");
1356+ }
1357+
1358+ if (err) {
1359+ n_time = 0;
1360+ }
1361+ return n_time;
1362+}
1363+
1364+void usage()
1365+{
1366+ printf("wavcut Ver %s\n", VER);
1367+ printf("usage: wavcut [-d]\n");
1368+ printf(" { [-s] [-lv <cut_level(%d)>] [-ln <blank_len>(%d)>]\n", th_val, bl_sec);
1369+ printf(" | -ex mm:ss-mm:ss[,mm:ss-ss,...]\n");
1370+ printf(" | {-no | -vol <%%>}\n");
1371+ printf(" | -rv }\n");
1372+ printf(" [<wav_file>]\n");
1373+ printf(" -d : display data\n");
1374+ printf(" -s : split wav data\n");
1375+ printf(" -lv : blank level. default:%d (x0.1%%)\n", th_val);
1376+ printf(" -ln : time to recognize blank. default:%d (x0.1sec)\n", bl_sec);
1377+ printf(" -ex : extract wav part\n");
1378+ printf(" -no : normalize wav data\n");
1379+ printf(" -vol: set volume\n");
1380+ printf(" -rv : reduce voice part\n");
1381+ printf("usage: wavcut -m <wav_file> <wav_file> ...\n"); /* V0.27-A */
1382+ printf(" -m : merge wav files\n"); /* V0.27-A */
1383+ exit(1);
1384+}
1385+
1386+int main(int a, char *b[])
1387+{
1388+ int i;
1389+ char buf[4096];
1390+ char *filename = NULL;
1391+ FILE *fp;
1392+ char **files; /* files for -m V0.27-A */
1393+ int fcnt = 0; /* file count V0.27-A */
1394+
1395+ files = (char **)malloc((a+1) * sizeof(char *)); /* V0.27-A */
1396+ memset(files, 0, (a+1) * sizeof(char *)); /* V0.27-A */
1397+
1398+ for (i = 1; i<a; i++) {
1399+ if (!strcmp(b[i],"-v")) {
1400+ ++vf;
1401+ continue;
1402+ }
1403+ if (!strncmp(b[i],"-d",2)) {
1404+ df = 1; /* Display Wav Data */
1405+ continue;
1406+ }
1407+ if (!strcmp(b[i],"-rv")) {
1408+ rvf = 1; /* Reduce Voice */
1409+ continue;
1410+ }
1411+ if (!strncmp(b[i],"-s",2)) {
1412+ if (ntment) {
1413+ usage();
1414+ }
1415+ sf = 1; /* Split Wav Data */
1416+ continue;
1417+ }
1418+ if (!strcmp(b[i],"-m")) {
1419+ mf = 1; /* Merge Wav Files */
1420+ continue;
1421+ }
1422+ if (i+1 < a && !strncmp(b[i],"-lv",3)) {
1423+ th_val = atoi(b[++i]); /* Blank Level */
1424+ continue;
1425+ }
1426+ if (i+1 < a && !strncmp(b[i],"-ln",3)) {
1427+ bl_sec = atoi(b[++i]); /* Blank Sec */
1428+ continue;
1429+ }
1430+ if (!strncmp(b[i],"-no",3)) {
1431+ /* nf = 1; /* normalize */
1432+ nf = 1 + atoi(&b[i][3]); /* -no[X] normalize +1X0% (secret opt) */
1433+ continue;
1434+ }
1435+
1436+ /* V0.25-A start */
1437+ if (i+1 < a && !strcmp(b[i],"-vol")) {
1438+ volf = atoi(b[++i]); /* set Volume */
1439+ continue;
1440+ }
1441+ /* V0.25-A end */
1442+
1443+ if (i+1 < a && !strncmp(b[i],"-ex",3)) {
1444+ if (sf) {
1445+ usage();
1446+ }
1447+ ntment = GetTimes(b[++i], &start_dsec, &end_dsec); /* Extract wav */
1448+ if (ntment <= 0) {
1449+ usage();
1450+ }
1451+
1452+ continue;
1453+ }
1454+ if (!strncmp(b[i],"-h",2)) {
1455+ usage();
1456+ }
1457+ filename = b[i];
1458+ files[fcnt++];
1459+ }
1460+
1461+ if (volf && nf) {
1462+ usage();
1463+ }
1464+
1465+ /* V0.27-A start */
1466+ if (mf && (volf || nf || sf || ntment || rvf)) {
1467+ usage();
1468+ }
1469+
1470+ if (mf) {
1471+ /* -m: merage wav files */
1472+ MergeWavs(files);
1473+ return 0;
1474+ }
1475+ /* V0.27-A end */
1476+
1477+ if (filename) {
1478+ if (!(fp = fopen(filename,"rb"))) {
1479+ perror(filename);
1480+ exit(1);
1481+ }
1482+ strcpy(in_fname, filename);
1483+ if (!strcasecmp(&in_fname[strlen(in_fname)-4], ".wav")) {
1484+ in_fname[strlen(in_fname)-4] = '\0'; /* delete .wav */
1485+ }
1486+ } else {
1487+ if (nf) {
1488+ printf("Error: -no option not support stdin data.\n");
1489+ exit(1);
1490+ }
1491+ fp = stdin;
1492+ strcpy(in_fname, "stdin");
1493+ }
1494+
1495+ WavAnalyze(fp);
1496+
1497+ if (nf) {
1498+ fseek(fp, 0, SEEK_SET); /* seek to top */
1499+ if (nf > 1) {
1500+ /* peak_level = (peak_level*10)/11; /* 110% V0.22 */
1501+
1502+ /* nf = 1 : 100% */
1503+ /* nf = 2 : 110% */
1504+ /* nf = 3 : 120% */
1505+ /* nf = 4 : 130% */
1506+ /* nf =10 : 190% */
1507+ peak_level = (peak_level*10)/(10+(nf-1)); /* 1[nf-1]0% V0.23 */
1508+ }
1509+ WavNormalize(fp, peak_level, max_level);
1510+ }
1511+ /* V0.25-A start */
1512+ else if (volf) {
1513+ fseek(fp, 0, SEEK_SET); /* seek to top */
1514+ WavNormalize(fp, 100, volf); /* volf/100 */
1515+ }
1516+ /* V0.25-A end */
1517+ /* V0.24-A start */
1518+ else if (rvf) {
1519+ fseek(fp, 0, SEEK_SET); /* seek to top */
1520+ ReduceVoice(fp);
1521+ }
1522+ /* V0.24-A end */
1523+
1524+ fclose(fp);
1525+
1526+ return 0;
1527+}
1528+
1529+/* vim:ts=8:sw=8:
1530+ */
--- /dev/null
+++ b/wavcut2.c
@@ -0,0 +1,1663 @@
1+/*
2+ * .WAV cutter
3+ *
4+ * 05/10/18 V0.10 support blank cut by oga.
5+ * 05/10/28 V0.11 support -ex
6+ * 05/11/05 V0.20 support -no (normalize)
7+ * 05/11/13 V0.21 perf up 29.51sec=>7.93sec (41.9MB wav, K6/175MHz)
8+ * 05/12/25 V0.22 normalize 110% (test)
9+ * 06/02/01 V0.23 support -noX normalize 1X0%
10+ * 07/03/11 V0.24 support -rv reduce voice part
11+ * 07/10/07 V0.25 support -vol volume
12+ * 07/11/18 V0.26 fix riff_len bug
13+ * 07/12/02 V0.27 support -m (merge wavs)
14+ * 10/11/06 V0.28 support -cs (change speed)
15+ *
16+ */
17+
18+#if 0
19+ typical wav format
20+ ---- RIFF Header ---- riff_hdr
21++00 riff_id : [RIFF]
22++04 riff_len : 0x0017d93c (1562940)
23++08 wave_id : [WAVE]
24+ ---- Chunk Header ---- chunk_hdr
25++0c chunk_id : [fmt ]
26++10 chunk_len : 0x00000010 (16)
27+ ---- fmt chunk (len=18) ---- ck_fmt
28++14 FormatTag : 0x0001 (1) MS PCM
29++16 Channels : 0x0002 (2) Stereo
30++18 SamplesPerSec : 0x0000ac44 (44100)
31++1c AvgBytesPerSec : 0x0002b110 (176400)
32++20 BlockAlign : 0x0004 (4)
33++22 BitsPerSample : 0x0010 (16 bits)
34++24 unknown : 0x0000 (0) (len=16の場合はなし)
35+ ---- Chunk Header ----
36+ chunk_id : [fact]
37+ chunk_len : 0x00000004 (4)
38+ ---- fact chunk (len=4) ---- ck_fact
39+ unknown : 0x00973cea (9911530)
40+ ---- Chunk Header ----
41+ chunk_id : [data]
42+ chunk_len : 0x0017d918 (1562904)
43+#endif
44+
45+#include <stdio.h>
46+#include <errno.h>
47+#include <stdlib.h>
48+#include <string.h>
49+
50+#ifdef _WIN32
51+#define strcasecmp stricmp
52+#define strncasecmp strnicmp
53+#endif /* _WIN32 */
54+
55+#define dprintf if (vf) printf
56+#define dprintf2 if (vf >= 2) printf
57+#define sgn(x) (x==0)?0:((x>0)?1:-1)
58+
59+int vf = 0; /* -v verbose */
60+int df = 0; /* -d disp all data value */
61+int sf = 0; /* -s split wav data */
62+int th_val = 60; /* -lv threshold value (blank level) default:6.0% */
63+int bl_sec = 10; /* -ln time to recognize blank default:1.0s */
64+char in_fname[1024]; /* in wav filename (without suffix) */
65+int *start_dsec; /* start dsecs */
66+int *end_dsec; /* end dsecs */
67+int ntment = 0; /* -ex num of time data */
68+int nf = 0; /* -no normalize */
69+int volf = 0; /* -vol volume V0.25-A */
70+int rvf = 0; /* -rv reduce voice V0.24-A */
71+int mf = 0; /* -m merge wavfiles V0.27-A */
72+int csf = 0; /* -cs change speed V0.28-A */
73+int peak_level = 0; /* peak level for -no */
74+int max_level = 0; /* max level for -no */
75+long pre_datlen = 0; /* heders total length to wav data */
76+
77+int gBytePerSample = 0; /* Byte / Sample */
78+int gChannels = 0; /* Num of Channel */
79+int gUnit = 0; /* Byte / Sample * nChannel */
80+
81+
82+/* data formats */
83+struct riff_hdr {
84+ char id[4]; /* RIFF id ("RIFF") */
85+ unsigned long len; /* length */
86+ char wave_id[4]; /* data type ("WAVE") */
87+};
88+
89+struct chunk_hdr {
90+ char id[4]; /* chunk id ("fmt "|"data"...) */
91+ unsigned long len; /* chunk length */
92+};
93+
94+/* chunk type fmt 1 */
95+struct ck_fmt {
96+ unsigned short wFormatTag; /* Format category */
97+#define WAVE_FORMAT_UNKNOWN 0x0000 /* unknown */
98+#define WAVE_FORMAT_PCM 0x0001 /* Microsoft PCM */
99+#define WAVE_FORMAT_ADPCM 0x0002 /* Microsoft ADPCM */
100+#define WAVE_FORMAT_ALAW 0x0006 /* A-Law */
101+#define WAVE_FORMAT_MULAW 0x0007 /* mu-Law */
102+#define WAVE_FORMAT_IDADPCM 0x0011 /* IMA/DVI ADPCM */
103+#define WAVE_FORMAT_TRUESPEECH 0x0022 /* TrueSpeech */
104+#define WAVE_FORMAT_GSM 0x0031 /* TrueSpeech */
105+#define IBM_FORMAT_MULAW 0x0101 /* IBM mu-law format */
106+#define IBM_FORMAT_ALAW 0x0102 /* IBM a-law format */
107+#define IBM_FORMAT_ADPCM 0x0103 /* IBM AVC Adaptive Diff PCM format */
108+ unsigned short wChannels; /* Number of channels */
109+ unsigned long dwSamplesPerSec; /* Sampling rate */
110+ unsigned long dwAvgBytesPerSec; /* For buffer estimation */
111+ unsigned short wBlockAlign; /* Data block size */
112+ unsigned short wBitsPerSample; /* Sample size (for WAVE_FORMAT_PCM */
113+ unsigned short unknown; /* Unknown data */
114+ char dummy[256]; /* dummy area for over run */
115+};
116+
117+/* chunk type fact 2 */
118+struct ck_fact {
119+ int unknown; /* unknown */
120+};
121+
122+/* chunk type data 3 */
123+/* any length data */
124+
125+/* wav headers V0.28-A start */
126+struct wav_header {
127+ struct riff_hdr rhd;
128+ struct chunk_hdr chd;
129+ struct ck_fmt ckf;
130+};
131+/* V0.28-A end */
132+
133+/*
134+ * Dump Data
135+ *
136+ * IN buf : dump buffer
137+ * len : dump length
138+ */
139+void DumpData(unsigned char *buf, int len)
140+{
141+ int i;
142+
143+ for (i=0; i<len; i++){
144+ printf(" %02x",buf[i]);
145+ }
146+ printf("\n");
147+}
148+
149+/*
150+ * Read fmt chunk header block
151+ *
152+ * IN fp
153+ * IN cklen : chunk data len
154+ * OUT ckfmt : fmt chunk data
155+ * OUT ret : 0 success
156+ * -1 error
157+ */
158+int ReadChunkFmt(FILE *fp, int len, struct ck_fmt *ckfmt)
159+{
160+ if (len > sizeof(struct ck_fmt)) {
161+ printf("Error: ReadChunkFmt: Length Too long. (%d)\n",len);
162+ return -1;
163+ }
164+
165+ /* read wav format chunk */
166+ if (vf) printf("ck_fmt size = %d\n", sizeof(struct ck_fmt));
167+ fread(ckfmt, 1, len, fp); /* get fmt data */
168+ printf("---- fmt chunk (len=%d) ----\n", len);
169+ printf("FormatTag : 0x%04x (%d) %s\n",ckfmt->wFormatTag, ckfmt->wFormatTag,
170+ (ckfmt->wFormatTag == WAVE_FORMAT_PCM)?"MS PCM":"Other PCM");
171+ printf("Channels : 0x%04x (%d) %s\n",ckfmt->wChannels, ckfmt->wChannels,
172+ (ckfmt->wChannels == 1)?"Mono":"Stereo");
173+ printf("SamplesPerSec : 0x%08x (%d)\n",ckfmt->dwSamplesPerSec, ckfmt->dwSamplesPerSec);
174+ printf("AvgBytesPerSec : 0x%08x (%d)\n",ckfmt->dwAvgBytesPerSec, ckfmt->dwAvgBytesPerSec);
175+ printf("BlockAlign : 0x%04x (%d)\n",ckfmt->wBlockAlign, ckfmt->wBlockAlign);
176+ printf("BitsPerSample : 0x%04x (%d bits)\n",ckfmt->wBitsPerSample, ckfmt->wBitsPerSample);
177+ if (len > 16) {
178+ printf("unknown : 0x%04x (%d)\n",ckfmt->unknown, ckfmt->unknown);
179+ }
180+ return 0;
181+}
182+
183+/*
184+ * Read fact chunk header block
185+ *
186+ * IN fp
187+ * IN cklen : chunk data len
188+ * OUT ckfact : fact chunk data
189+ * OUT ret : 0 success
190+ * -1 error
191+ */
192+int ReadChunkFact(FILE *fp, int len, struct ck_fact *ckfact)
193+{
194+ if (len > sizeof(struct ck_fact)) {
195+ printf("Error: ReadChunkFact: Length Too long. (%d)\n",len);
196+ return -1;
197+ }
198+
199+ /* read wav format chunk */
200+ if (vf) printf("ck_fact size = %d\n", sizeof(struct ck_fact));
201+ fread(ckfact, 1, len, fp); /* get fact data */
202+ printf("---- fact chunk (len=%d) ----\n", len);
203+ printf("unknown : 0x%08x (%d)\n",ckfact->unknown,
204+ ckfact->unknown);
205+ return 0;
206+}
207+
208+/*
209+ * Analyze chunk header block
210+ *
211+ * IN fp
212+ * OUT ckid : chunk id
213+ * OUT cklen : chunk data len
214+ * OUT ret : 0 success
215+ * -1 EOF or error
216+ */
217+int ReadChunkHeader(FILE *fp, char *ckid, int *cklen, struct chunk_hdr *chunkhdr)
218+{
219+ if (vf) printf("chunk_hdr size = %d\n", sizeof(struct chunk_hdr));
220+ if (fread(chunkhdr, 1, sizeof(struct chunk_hdr), fp) < sizeof(struct chunk_hdr)) {
221+ /* EOF or Error or Format Error */
222+ return -1;
223+ }
224+ printf("---- Chunk Header ----\n");
225+ strncpy(ckid, chunkhdr->id, 4);
226+ ckid[4] = '\0';
227+ *cklen = chunkhdr->len;
228+ printf("chunk_id : [%s]\n", ckid);
229+ printf("chunk_len : 0x%08x (%d)\n", *cklen, *cklen);
230+
231+ return 0;
232+}
233+
234+/*
235+ * Analyze WAV(RIFF) header block
236+ *
237+ * IN fp
238+ * OUT ret : 0 success
239+ * -1 error
240+ */
241+int ReadWavHeader(FILE *fp, struct riff_hdr *riffhdr)
242+{
243+ char wk[4096];
244+ int len;
245+
246+ /* read riff header */
247+ if (vf) printf("riffhdr size = %d\n", sizeof(struct riff_hdr));
248+ fread(riffhdr, sizeof(struct riff_hdr), 1, fp); /* get header */
249+ strncpy(wk, riffhdr->id, 4);
250+ wk[4] = '\0';
251+ if (strcmp(wk, "RIFF")) {
252+ /* not WAV file */
253+ printf("Error : Not RIFF [%s]\n",wk);
254+ return -1;
255+ }
256+
257+ printf("---- RIFF Header ----\n");
258+ printf("riff_id : [%s]\n", wk);
259+ printf("riff_len : 0x%08x (%d)\n", riffhdr->len, riffhdr->len);
260+
261+ return 0;
262+}
263+
264+/*
265+ * Analyze WAV header block
266+ *
267+ * IN fp
268+ * OUT ret : 0 success
269+ * -1 error
270+ */
271+int ReadWavData(FILE *fp)
272+{
273+ char wk[4096];
274+ int len;
275+ int i, c;
276+
277+ for (i=0; i<10; i++) {
278+ len = fread(wk, 1, 16, fp);
279+ DumpData(wk, len);
280+ }
281+ return 0;
282+}
283+
284+/*
285+ * Write wav headers
286+ *
287+ */
288+int WriteWavHeaders(FILE *wfp,
289+ struct riff_hdr *rhdr,
290+ struct chunk_hdr *cnkhdr, int cnkcnt,
291+ struct ck_fmt *cnkfmt,
292+ struct ck_fact *cnkfct)
293+{
294+ int i;
295+ char buf[16];
296+
297+ dprintf("## write RIFF header ...\n");
298+
299+ fwrite(rhdr, sizeof(struct riff_hdr), 1, wfp);
300+
301+ for (i = 0; i<cnkcnt; i++) {
302+ if (strncmp(cnkhdr[i].id, "fact", 4)) {
303+ /* excpt fact chunk (fmt, data...) */
304+ fwrite(&cnkhdr[i], sizeof(struct chunk_hdr), 1, wfp); /* chunk header */
305+ if (!strncmp(cnkhdr[i].id, "fmt ", 4)) {
306+ fwrite(cnkfmt, cnkhdr[i].len, 1, wfp); /* fmt body */
307+ }
308+
309+ /* verbose log */
310+ strncpy(buf, cnkhdr[i].id, 4);
311+ buf[4] = '\0';
312+ dprintf("## write %s header ...\n", buf);
313+ }
314+ }
315+ return 0;
316+}
317+
318+/*
319+ * Change wav headers
320+ *
321+ */
322+int ChangeWavHeaders(FILE *wfp,
323+ struct riff_hdr *rhdr,
324+ struct chunk_hdr *cnkhdr, int cnkcnt,
325+ struct ck_fmt *cnkfmt,
326+ struct ck_fact *cnkfct, /* no write */
327+ int data_size)
328+{
329+ int i;
330+ int fmt_len = 0;
331+ char buf[16];
332+
333+ printf("## change RIFF header ...\n");
334+
335+ /* Seek to head */
336+ fseek(wfp, 0, SEEK_SET);
337+
338+ /* get fmt length & set data size */
339+ for (i = 0; i<cnkcnt; i++) {
340+ if (!strncmp(cnkhdr[i].id, "fmt ", 4)) {
341+ fmt_len = cnkhdr[i].len;
342+ } else if (!strncmp(cnkhdr[i].id, "data", 4)) {
343+ cnkhdr[i].len = data_size;
344+ }
345+ }
346+
347+ /* set riffhdr length */
348+ rhdr->len = data_size /* data size */
349+ + sizeof(struct chunk_hdr) /* data chunk header */
350+ + fmt_len /* fmt size */
351+ + sizeof(struct chunk_hdr) /* fmt chunk header */
352+ + 4; /* riff_hdr."WAVE" size V0.26-A */
353+
354+ WriteWavHeaders(wfp, rhdr, cnkhdr, cnkcnt, cnkfmt, cnkfct);
355+
356+ return 0;
357+}
358+
359+/*
360+ * Wav Analyze
361+ *
362+ * IN fp : input file pointer
363+ *
364+ * [global]
365+ * OUT in_fname : input file name (without ".wav")
366+ * OUT pre_datlen : Header Length
367+ *
368+ */
369+
370+int WavAnalyze(FILE *fp)
371+{
372+ int i, j;
373+ int cklen = 0; /* chunk len */
374+ char ckid[256]; /* chunk id */
375+ unsigned char rbuf[4096]; /* buf for fread() V0.21-A */
376+ unsigned char *buf = rbuf; /* dummy buffer V0.21-C */
377+ char buf_fmt[4096];
378+ char buf_fact[4096];
379+ char fname[1024];
380+ int maxval[16]; /* Max Power 16ch */
381+ int maxvalcnt[16]; /* Max Power count 16ch */
382+ int lowcont = 0; /* low level continue count */
383+ int contf = 0; /* blank continue flag */
384+ int outf = 0; /* output flag for -ex */
385+ int reopen = 0; /* reopen flag for -ex (end=next start) */
386+ int curdsec = 0; /* current dsec */
387+
388+ struct riff_hdr riffhdr; /* 01 */
389+ struct chunk_hdr chunkhdr[10]; /* 02 */
390+ int chunk_cnt = 0;
391+ struct ck_fmt *ckfmt = (struct ck_fmt *)buf_fmt; /* 03 */
392+ struct ck_fact *ckfact = (struct ck_fact *)buf_fact; /* 04 */
393+
394+ /* initialize */
395+ for (i = 0; i<16; i++) {
396+ maxval[i] = 0;
397+ maxvalcnt[i] = 0;
398+ }
399+
400+ printf("\n# Analyze WAV file. by oga.\n");
401+
402+ if (ReadWavHeader(fp, &riffhdr)) {
403+ printf("This is not WAV(RIFF) format file.\n");
404+ exit(1);
405+ }
406+
407+ while (!ReadChunkHeader(fp, ckid, &cklen, &chunkhdr[chunk_cnt++])) {
408+ if (!strncmp(ckid, "fmt", 3)) {
409+ ReadChunkFmt(fp, cklen, (struct ck_fmt *)buf_fmt);
410+ } else if (!strncmp(ckid, "fact", 4)) {
411+ ReadChunkFact(fp, cklen, (struct ck_fact *)buf_fact);
412+ } else if (!strncmp(ckid, "LIST", 4)) {
413+ printf("---- LIST chunk (len=%d) ----\n", cklen);
414+ printf("LIST:[");
415+ for (i = 0; i<cklen; i++) {
416+ if (fread(buf, 1, 1, fp) <= 0) {
417+ break;
418+ }
419+ if (buf[0] < 0x20) {
420+ printf("<0x%02x>", buf[0]);
421+ } else {
422+ printf("%c", buf[0]);
423+ }
424+ }
425+ printf("]\n");
426+ } else if (!strncmp(ckid, "data", 4)) {
427+ /* PCM Data */
428+ int total = 0; /* total data chunk size */
429+ int rlen = 0; /* read len V0.21-A */
430+ int len = 0; /* dummy read len V0.21-C */
431+ int val;
432+ short *buf16 = (short *)buf;
433+
434+ int file_cnt = 0; /* split file counter */
435+ int data_size = 0; /* data chank size */
436+ FILE *wfp = NULL; /* write wav fp */
437+
438+ gBytePerSample = ckfmt->wBitsPerSample/8;
439+ gChannels = ckfmt->wChannels;
440+ gUnit = gBytePerSample * gChannels;
441+
442+ pre_datlen = ftell(fp); /* get current file pointer */
443+ printf("Headers Len: %d\n", pre_datlen);
444+
445+ printf("---- Cut Info ----\n");
446+ printf("CutLevel: %d (%.1f%%)\n",
447+ ((1 << (ckfmt->wBitsPerSample - 1)) * th_val/1000),
448+ ((float)th_val)/10);
449+ printf("BlankSec: %.1fsec\n", ((float)bl_sec)/10);
450+
451+ outf = 0;
452+ curdsec = total/(ckfmt->dwAvgBytesPerSec/10);
453+ for (i = 0; i<ntment; i++) {
454+ if (start_dsec[i] <= curdsec && curdsec < end_dsec[i]){
455+ outf = 1;
456+ }
457+ }
458+
459+ if (sf || (ntment && outf)) {
460+ /* ### Open Output File */
461+ sprintf(fname, "%s_%03d.wav", in_fname, file_cnt++);
462+ printf("## Writing %s ...\n", fname);
463+ wfp = fopen(fname, "wb");
464+ if (wfp == NULL) {
465+ perror(fname);
466+ exit(1);
467+ }
468+ /* ### WriteWavHeaders */
469+ WriteWavHeaders(wfp,
470+ &riffhdr, /* 01 riff header */
471+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
472+ ckfmt, /* 03 fmt data */
473+ ckfact); /* 04: no write */
474+ }
475+
476+ data_size = 0;
477+
478+ while ((rlen = fread(rbuf, 1, gUnit*50, fp)) > 0) { /* V0.21-C */
479+ for (j = 0; j < rlen; j+=gUnit) { /* V0.21-A */
480+ len = gUnit; /* V0.21-A */
481+ buf = &rbuf[j]; /* V0.21-A */
482+ buf16 = (short *)buf; /* V0.21-A */
483+
484+ if (wfp) {
485+ fwrite(buf, 1, gUnit, wfp);
486+ data_size += len; /* data chunk size for write */
487+ }
488+
489+ if (df) {
490+ printf("%08x: ", total);
491+ DumpData(buf, len);
492+ }
493+
494+ /* current time */
495+ if (df) {
496+ printf("%d:%04.2f ", total/ckfmt->dwAvgBytesPerSec/60,
497+ ((float)(total-(total/ckfmt->dwAvgBytesPerSec/60)*ckfmt->dwAvgBytesPerSec*60)/ckfmt->dwAvgBytesPerSec));
498+ }
499+
500+ for (i = 0; i < gChannels; i++) {
501+ if (gBytePerSample == 1) {
502+ /* 1 byte */
503+ val = buf[i * gBytePerSample] - 0x80;
504+ } else {
505+ /* 2 byte gBytePerSample == 2 */
506+ /* val = buf16[i * gBytePerSample]; */
507+ val = buf16[i];
508+ }
509+ if (df) printf("ch%d:%6d ", i+1, val);
510+
511+ if (maxval[i] < abs(val)) {
512+ maxval[i] = abs(val); /* new max */
513+ maxvalcnt[i] = 1; /* reset */
514+ } else if (maxval[i] == abs(val)) {
515+ ++maxvalcnt[i]; /* count up */
516+ }
517+ }
518+ if (df) printf("\n");
519+
520+ /* sound blank check for -s */
521+ if (abs(val) <
522+ ((1 << (ckfmt->wBitsPerSample - 1)) * th_val/1000)) {
523+ /* blank level */
524+ //printf("%8d: th_val...%d\n", total,
525+ // ((1 << (ckfmt->wBitsPerSample - 1)) * th_val/1000));
526+ ++lowcont;
527+ if (contf == 0 && lowcont > (ckfmt->dwSamplesPerSec*bl_sec)/10) {
528+ /* 1sec continue... maybe blank area */
529+ printf("Blank Time Start: %d:%04.2f\n",
530+ total/ckfmt->dwAvgBytesPerSec/60,
531+ ((float)(total-
532+ (total/ckfmt->dwAvgBytesPerSec/60)
533+ *ckfmt->dwAvgBytesPerSec*60)
534+ /ckfmt->dwAvgBytesPerSec));
535+ contf = 1;
536+
537+ if (sf && wfp) {
538+ /* ### Change Each Header Size */
539+ ChangeWavHeaders(wfp,
540+ &riffhdr, /* 01 riff header */
541+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
542+ ckfmt, /* 03 fmt data */
543+ ckfact, /* 04: no write */
544+ data_size); /* "data" block size */
545+ printf("## %s (%d:%04.2f)\n", fname,
546+ data_size/ckfmt->dwAvgBytesPerSec/60,
547+ ((float)(data_size-
548+ (data_size/ckfmt->dwAvgBytesPerSec/60)
549+ *ckfmt->dwAvgBytesPerSec*60)
550+ /ckfmt->dwAvgBytesPerSec));
551+ /* ### Close Wav File */
552+ if (wfp) fclose(wfp);
553+ wfp = NULL;
554+ }
555+ }
556+
557+ } else {
558+ /* no blank level */
559+ lowcont = 0;
560+ if (contf) {
561+ contf = 0;
562+ printf("Blank Time End : %d:%04.2f\n",
563+ total/ckfmt->dwAvgBytesPerSec/60,
564+ ((float)(total-
565+ (total/ckfmt->dwAvgBytesPerSec/60)
566+ *ckfmt->dwAvgBytesPerSec*60)
567+ /ckfmt->dwAvgBytesPerSec));
568+
569+ data_size = 0; /* reset data chunk size */
570+ if (sf) {
571+ sprintf(fname, "%s_%03d.wav", in_fname, file_cnt++);
572+ printf("## Writing %s ...\n", fname);
573+ /* ### Open Next Wav File */
574+ wfp = fopen(fname, "wb");
575+ if (wfp == NULL) {
576+ perror(fname);
577+ exit(1);
578+ }
579+ /* ### WriteWavHeaders */
580+ WriteWavHeaders(wfp,
581+ &riffhdr, /* 01 riff header */
582+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
583+ ckfmt, /* 03 fmt data */
584+ ckfact); /* 04: no write */
585+ }
586+ }
587+ }
588+
589+ /* for -ex */
590+ if (ntment) {
591+ outf = 0;
592+ reopen = 0;
593+ curdsec = total/(ckfmt->dwAvgBytesPerSec/10);
594+ for (i = 0; i<ntment; i++) {
595+ if (start_dsec[i] <= curdsec && curdsec < end_dsec[i]){
596+ outf = 1;
597+ if (curdsec == end_dsec[i]) {
598+ reopen = 1;
599+ }
600+ }
601+ }
602+ if (outf == 0 || reopen == 1) {
603+ if (wfp) {
604+ /* ### Change Each Header Size */
605+ ChangeWavHeaders(wfp,
606+ &riffhdr, /* 01 riff header */
607+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
608+ ckfmt, /* 03 fmt data */
609+ ckfact, /* 04: no write */
610+ data_size); /* "data" block size */
611+ printf("## %s (%d:%04.2f)\n", fname,
612+ data_size/ckfmt->dwAvgBytesPerSec/60,
613+ ((float)(data_size-
614+ (data_size/ckfmt->dwAvgBytesPerSec/60)
615+ *ckfmt->dwAvgBytesPerSec*60)
616+ /ckfmt->dwAvgBytesPerSec));
617+ /* ### Close Wav File */
618+ if (wfp) fclose(wfp);
619+ wfp = NULL;
620+ data_size = 0; /* reset data chunk size */
621+ }
622+ }
623+ if (outf) {
624+ if (wfp == NULL) {
625+ data_size = 0; /* reset data chunk size */
626+ sprintf(fname, "%s_%03d.wav", in_fname, file_cnt++);
627+ printf("## Writing %s ...\n", fname);
628+ /* ### Open Wav File */
629+ wfp = fopen(fname, "wb");
630+ if (wfp == NULL) {
631+ perror(fname);
632+ exit(1);
633+ }
634+ /* ### WriteWavHeaders */
635+ WriteWavHeaders(wfp,
636+ &riffhdr, /* 01 riff header */
637+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
638+ ckfmt, /* 03 fmt data */
639+ ckfact); /* 04: no write */
640+ }
641+ }
642+ }
643+
644+ total += len; /* total read size */
645+
646+ if (total >= cklen) {
647+ break;
648+ }
649+ } /* 1 bufferd data loop V0.21-A */
650+ } /* data chunk loop */
651+
652+ if (contf) {
653+ contf = 0;
654+ printf("Blank Time End : %d:%04.2f\n",
655+ total/ckfmt->dwAvgBytesPerSec/60,
656+ ((float)(total-
657+ (total/ckfmt->dwAvgBytesPerSec/60)
658+ *ckfmt->dwAvgBytesPerSec*60)
659+ /ckfmt->dwAvgBytesPerSec));
660+ }
661+
662+ if (wfp) {
663+ /* ### Change Each Header Size */
664+ ChangeWavHeaders(wfp,
665+ &riffhdr, /* 01 riff header */
666+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
667+ ckfmt, /* 03 fmt data */
668+ ckfact, /* 04: no write */
669+ data_size); /* "data" block size */
670+ printf("## %s (%d:%04.2f)\n", fname,
671+ data_size/ckfmt->dwAvgBytesPerSec/60,
672+ ((float)(data_size-
673+ (data_size/ckfmt->dwAvgBytesPerSec/60)
674+ *ckfmt->dwAvgBytesPerSec*60)
675+ /ckfmt->dwAvgBytesPerSec));
676+ /* ### Close Wav File */
677+ if (wfp) fclose(wfp);
678+ wfp = NULL;
679+ }
680+
681+ printf("---- Other Info ----\n");
682+ /* ch0:Left ch1:Right */
683+ printf("Max Power : ");
684+ for (i = 0; i < gChannels; i++) {
685+ printf("ch%d:%d/%d (%d times) ", i+1,
686+ maxval[i], 1 << (ckfmt->wBitsPerSample - 1),
687+ maxvalcnt[i]);
688+ if (peak_level < maxval[i]) {
689+ peak_level = maxval[i];
690+ }
691+ }
692+ max_level = 1 << (ckfmt->wBitsPerSample - 1);
693+ printf("\n");
694+ //printf("Time : %.2f sec\n",
695+ // ((float)cklen)/ckfmt->dwAvgBytesPerSec);
696+ printf("Time : %d:%04.2f\n", cklen/ckfmt->dwAvgBytesPerSec/60,
697+ ((float)(cklen-(cklen/ckfmt->dwAvgBytesPerSec/60)*ckfmt->dwAvgBytesPerSec*60)/ckfmt->dwAvgBytesPerSec));
698+ }
699+ }
700+
701+ printf("WAV file Analyze end.\n");
702+ return 0;
703+}
704+
705+
706+/*
707+ * WavNormalize
708+ *
709+ * IN infp : input wav file fp
710+ * IN peek_lv : peek level
711+ * IN max_lv : max level
712+ *
713+ * [global]
714+ * IN in_fname : input file name (without ".wav")
715+ * IN pre_datlen : headers length
716+ *
717+ * OUT "<in_fname>.normalize.wav"
718+ *
719+ */
720+void WavNormalize(FILE *infp, int peak_lv, int max_lv)
721+{
722+ char ofname[1024];
723+ char buf[1024];
724+ short *buf16 = (short *)buf;
725+ FILE *ofp;
726+ int size, rsize;
727+ int rtotal = 0;
728+ int val, newval;
729+ int len;
730+ int i;
731+
732+ printf("Normalize: Level x %.2f (%d%%)\n", ((float)max_lv)/peak_lv, 100+10*(nf-1));
733+ if (volf) {
734+ /* change volume */
735+ sprintf(ofname, "%s.%d%%.wav", in_fname, volf);
736+ } else {
737+ /* normalize */
738+ sprintf(ofname, "%s.normalize.wav", in_fname);
739+ }
740+
741+ if (pre_datlen > sizeof(buf)) {
742+ printf("Error: WavNormalize: headers size too big!\n");
743+ exit(1);
744+ }
745+
746+ ofp = fopen(ofname, "wb");
747+ if (ofp == NULL) {
748+ perror(ofname);
749+ return;
750+ }
751+
752+ /* copy headers */
753+ size = fread(buf, 1, pre_datlen, infp);
754+ if (pre_datlen != size) {
755+ printf("Error: WavNormalize: read size too short!\n");
756+ exit(1);
757+ }
758+ fwrite(buf, 1, size, ofp);
759+
760+ /* normalize */
761+ while ((len = fread(buf, 1, gUnit, infp)) > 0) {
762+
763+ for (i = 0; i < gChannels; i++) {
764+ if (gBytePerSample == 1) {
765+ /* 1 byte */
766+ /*val = buf[i * gBytePerSample] - 0x80; */
767+ val = buf[i * gBytePerSample];
768+ newval = (val * max_lv) / peak_lv;
769+
770+ /* check overflow V0.23 */
771+ if (nf > 1 && abs(newval) >= max_lv) {
772+ buf[i * gBytePerSample] = sgn(newval) * (max_lv-1); /* V0.23 */
773+ } else {
774+ buf[i * gBytePerSample] = newval;
775+ }
776+ if (vf) printf("%d => %d\n", val, buf[i * gBytePerSample]);
777+ } else {
778+ /* 2 byte gBytePerSample == 2 */
779+ /* val = buf16[i * gBytePerSample]; */
780+ val = buf16[i];
781+ newval = (val * max_lv) / peak_lv;
782+
783+ /* check overflow V0.23 */
784+ if (nf > 1 && abs(newval) >= max_lv) {
785+ buf16[i] = sgn(newval) * (max_lv-1); /* V0.23 */
786+ } else {
787+ buf16[i] = newval;
788+ }
789+ if (vf) printf("%d => %d\n", val, buf16[i]);
790+ }
791+ }
792+
793+ if (ofp) {
794+ fwrite(buf, 1, gUnit, ofp);
795+ }
796+ } /* data chunk loop */
797+
798+ fclose(ofp);
799+}
800+
801+/*
802+ * ChgSpeed
803+ *
804+ * IN infp : input wav file fp
805+ * IN speed : nn%
806+ *
807+ * [global]
808+ * IN in_fname : input file name (without ".wav")
809+ * IN pre_datlen : headers length
810+ *
811+ * OUT "<in_fname>.speedNN.wav"
812+ *
813+ */
814+void ChgSpeed(FILE *infp, int speed)
815+{
816+ char ofname[1024];
817+ char buf[1024];
818+ short *buf16 = (short *)buf;
819+ struct wav_header *wavh = (struct wav_header *)buf;
820+ FILE *ofp;
821+ int size, rsize;
822+ int rtotal = 0;
823+ int val, newval;
824+ int len;
825+ int i;
826+ int cnt = 0;
827+ int slow = 0;
828+ int speed_factor = 0;
829+
830+ printf("Change Speed: speed = %d%%\n", speed);
831+ sprintf(ofname, "%s.speed%d.wav", in_fname, speed);
832+
833+ if (pre_datlen > sizeof(buf)) {
834+ printf("Error: ChgSpeed: headers size too big!\n");
835+ exit(1);
836+ }
837+
838+ // 25%(400%) : slow4倍 1回に追加3回書き込み (400-100) = 300回追加で書く/100回
839+ // 50%(200%) : slow2倍 1回に追加1回書き込み (200-100) = 100回追加で書く/100回
840+ // 75%(133%) : slow25% 2回に追加1回書き込み (133-100) = 33回追加で書く/100回
841+ // 150% : fast1.5倍
842+ // 200% : fast2倍 2回に1回間引き
843+ // 400% : fast4倍 4回に3回間引き
844+ slow = 0;
845+ if (speed < 100) {
846+ slow = 1;
847+ speed_factor = 100 - speed;
848+ } else {
849+ speed_factor = speed - 200;
850+ }
851+
852+ ofp = fopen(ofname, "wb");
853+ if (ofp == NULL) {
854+ perror(ofname);
855+ return;
856+ }
857+
858+ /* copy headers */
859+ size = fread(buf, 1, pre_datlen, infp);
860+ if (pre_datlen != size) {
861+ printf("Error: ChgSpeed: read size too short!\n");
862+ exit(1);
863+ }
864+ wavh->ckf.dwSamplesPerSec = (wavh->ckf.dwSamplesPerSec*speed)/100;
865+ wavh->ckf.dwAvgBytesPerSec = (wavh->ckf.dwAvgBytesPerSec*speed)/100;
866+ fwrite(buf, 1, size, ofp);
867+
868+ /* normalize */
869+ cnt = 0;
870+ while ((len = fread(buf, 1, gUnit, infp)) > 0) {
871+
872+ for (i = 0; i < gChannels; i++) {
873+ if (gBytePerSample == 1) {
874+ /* 1 byte */
875+ /*val = buf[i * gBytePerSample] - 0x80; */
876+ val = buf[i * gBytePerSample];
877+ newval = val;
878+ buf[i * gBytePerSample] = newval;
879+ } else {
880+ /* 2 byte gBytePerSample == 2 */
881+ /* val = buf16[i * gBytePerSample]; */
882+ val = buf16[i];
883+ newval = val;
884+ buf16[i] = newval;
885+ }
886+ }
887+
888+ if (ofp) {
889+ if (speed < 100) {
890+ // slow
891+ fwrite(buf, 1, gUnit, ofp);
892+ if ((cnt % speed_factor) == 0) { /* 1.05倍slow (1回/n回データ補完) */
893+ fwrite(buf, 1, gUnit, ofp); /* 2回ずつ書き込んでみるテスト */
894+ }
895+ /* fwrite(buf, 1, gUnit, ofp); /* 2回ずつ書き込んでみるテスト */
896+ } else {
897+ // fast
898+ if ((cnt % speed_factor) != 0) { /* 1.05倍fast (1回/n回間引き) */
899+ fwrite(buf, 1, gUnit, ofp);
900+ }
901+ }
902+ }
903+ ++cnt;
904+ } /* data chunk loop */
905+
906+ fclose(ofp);
907+}
908+
909+/* V0.24-A start */
910+/*
911+ * ReduceVoice
912+ *
913+ * IN infp : input wav file fp
914+ *
915+ * [global]
916+ * IN in_fname : input file name (without ".wav")
917+ * IN pre_datlen : headers length
918+ *
919+ * OUT "<in_fname>.novoice.wav"
920+ *
921+ */
922+void ReduceVoice(FILE *infp)
923+{
924+ char ofname[1024];
925+ char buf[1024];
926+ short *buf16 = (short *)buf;
927+ FILE *ofp;
928+ int size, rsize;
929+ int rtotal = 0;
930+ int val, newval;
931+ int len;
932+ int i;
933+
934+ sprintf(ofname, "%s.novoice.wav", in_fname);
935+
936+ printf("reduce voice data output to %s ...\n", ofname);
937+
938+ if (pre_datlen > sizeof(buf)) {
939+ printf("Error: ReduceVoice: headers size too big!\n");
940+ exit(1);
941+ }
942+ if (gChannels < 2) {
943+ printf("Error: ReduceVoice: not support mono data\n");
944+ exit(1);
945+ }
946+
947+ ofp = fopen(ofname, "wb");
948+ if (ofp == NULL) {
949+ perror(ofname);
950+ return;
951+ }
952+
953+ /* copy headers */
954+ size = fread(buf, 1, pre_datlen, infp);
955+ if (pre_datlen != size) {
956+ printf("Error: ReduceVoice: read size too short!\n");
957+ exit(1);
958+ }
959+ fwrite(buf, 1, size, ofp);
960+
961+ /* reduce voice */
962+ while ((len = fread(buf, 1, gUnit, infp)) > 0) {
963+ if (gBytePerSample == 1) {
964+ /* 1 byte */
965+ /*val = buf[i * gBytePerSample] - 0x80; */
966+ printf("unsupport reduce voice for 1byte/sample.\n");
967+#if 0
968+ val = buf[i * gBytePerSample];
969+
970+ /* check overflow V0.23 */
971+ if (nf > 1 && abs(newval) >= max_lv) {
972+ buf[i * gBytePerSample] = sgn(newval) * (max_lv-1); /* V0.23 */
973+ } else {
974+ buf[i * gBytePerSample] = newval;
975+ }
976+ if (vf) printf("%d => %d\n", val, buf[i * gBytePerSample]);
977+#endif
978+ } else {
979+ /* 2 byte gBytePerSample == 2 */
980+ /* val = buf16[i * gBytePerSample]; */
981+ if (buf16[0] * buf16[1] > 0) {
982+ if (buf16[0] > 0) {
983+ /* plus */
984+ if (buf16[0] > buf16[1]) {
985+ buf16[0] = buf16[0] - buf16[1];
986+ buf16[1] = 0;
987+ } else {
988+ buf16[0] = 0;
989+ buf16[1] = buf16[1] - buf16[0];
990+ }
991+ } else {
992+ /* minus */
993+ if (buf16[0] > buf16[1]) {
994+ buf16[1] = buf16[1] - buf16[0];
995+ buf16[0] = 0;
996+ } else {
997+ buf16[1] = 0;
998+ buf16[0] = buf16[0] - buf16[1];
999+ }
1000+ }
1001+ }
1002+ }
1003+
1004+ if (ofp) {
1005+ fwrite(buf, 1, gUnit, ofp);
1006+ }
1007+ } /* data chunk loop */
1008+
1009+ fclose(ofp);
1010+}
1011+/* V0.24-A start */
1012+
1013+/* V0.27-A start */
1014+/*
1015+ * MergeWavs
1016+ *
1017+ * IN files : input wav files
1018+ *
1019+ * OUT "<in_file1>.merge.wav"
1020+ *
1021+ */
1022+void MergeWavs(char **files)
1023+{
1024+ char ofname[1024];
1025+ FILE *ofp, *fp;
1026+#if 0
1027+ char buf[1024];
1028+ short *buf16 = (short *)buf;
1029+ int size, rsize;
1030+ int rtotal = 0;
1031+ int val, newval;
1032+ int len;
1033+#endif
1034+ int i;
1035+ int first = 1;
1036+ int fcnt = 0;
1037+ char *pt;
1038+
1039+ int cklen = 0; /* chunk len */
1040+ char ckid[256]; /* chunk id */
1041+ char buf_fmt[4096];
1042+ char buf_fact[4096];
1043+ struct riff_hdr riffhdr; /* 01 */
1044+ struct chunk_hdr chunkhdr[10]; /* 02 */
1045+ int chunk_cnt = 0;
1046+ struct ck_fmt *ckfmt = (struct ck_fmt *)buf_fmt; /* 03 */
1047+ struct ck_fact *ckfact = (struct ck_fact *)buf_fact; /* 04 */
1048+
1049+#if 0 /* 作成中 */
1050+ strcpy(ofname, files[0]);
1051+ pt = strrchr(ofname, '.');
1052+ if (pt) {
1053+ *pt = '\0'; /* delete suffix */
1054+ }
1055+
1056+ strcat(ofname, ".merge.wav");
1057+ if (!(ofp = fopen(ofname, "wb"))) {
1058+ perror(ofname);
1059+ exit(1);
1060+ }
1061+
1062+ while (files[fcnt]) {
1063+ if (!(fp = fopen(files[fcnt], "rb"))) {
1064+ perror(files[fcnt]);
1065+ exit(1);
1066+ }
1067+
1068+ if (ReadWavHeader(fp, &riffhdr)) {
1069+ printf("This is not WAV(RIFF) format file.\n");
1070+ exit(1);
1071+ }
1072+
1073+ while (!ReadChunkHeader(fp, ckid, &cklen, &chunkhdr[chunk_cnt++])) {
1074+ if (!strncmp(ckid, "fmt", 3)) {
1075+ ReadChunkFmt(fp, cklen, (struct ck_fmt *)buf_fmt);
1076+ } else if (!strncmp(ckid, "fact", 4)) {
1077+ ReadChunkFact(fp, cklen, (struct ck_fact *)buf_fact);
1078+ } else if (!strncmp(ckid, "LIST", 4)) {
1079+ printf("---- LIST chunk (len=%d) ----\n", cklen);
1080+ printf("LIST:[");
1081+ for (i = 0; i<cklen; i++) {
1082+ if (fread(buf, 1, 1, fp) <= 0) {
1083+ break;
1084+ }
1085+ if (buf[0] < 0x20) {
1086+ printf("<0x%02x>", buf[0]);
1087+ } else {
1088+ printf("%c", buf[0]);
1089+ }
1090+ }
1091+ printf("]\n");
1092+ } else if (!strncmp(ckid, "data", 4)) {
1093+ /* PCM Data */
1094+ int total = 0; /* total data chunk size */
1095+ int rlen = 0; /* read len V0.21-A */
1096+ int len = 0; /* dummy read len V0.21-C */
1097+ int val;
1098+ short *buf16 = (short *)buf;
1099+
1100+ int file_cnt = 0; /* split file counter */
1101+ int data_size = 0; /* data chank size */
1102+ FILE *wfp = NULL; /* write wav fp */
1103+
1104+ gBytePerSample = ckfmt->wBitsPerSample/8;
1105+ gChannels = ckfmt->wChannels;
1106+ gUnit = gBytePerSample * gChannels;
1107+
1108+ pre_datlen = ftell(fp); /* get current file pointer */
1109+ printf("Headers Len: %d\n", pre_datlen);
1110+
1111+ printf("---- Cut Info ----\n");
1112+ printf("CutLevel: %d (%.1f%%)\n",
1113+ ((1 << (ckfmt->wBitsPerSample - 1)) * th_val/1000),
1114+ ((float)th_val)/10);
1115+ printf("BlankSec: %.1fsec\n", ((float)bl_sec)/10);
1116+
1117+ outf = 0;
1118+ curdsec = total/(ckfmt->dwAvgBytesPerSec/10);
1119+ for (i = 0; i<ntment; i++) {
1120+ if (start_dsec[i] <= curdsec && curdsec < end_dsec[i]){
1121+ outf = 1;
1122+ }
1123+ }
1124+
1125+ if (sf || (ntment && outf)) {
1126+ /* ### Open Output File */
1127+ sprintf(fname, "%s_%03d.wav", in_fname, file_cnt++);
1128+ printf("## Writing %s ...\n", fname);
1129+ wfp = fopen(fname, "wb");
1130+ if (wfp == NULL) {
1131+ perror(fname);
1132+ exit(1);
1133+ }
1134+ /* ### WriteWavHeaders */
1135+ WriteWavHeaders(wfp,
1136+ &riffhdr, /* 01 riff header */
1137+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
1138+ ckfmt, /* 03 fmt data */
1139+ ckfact); /* 04: no write */
1140+ }
1141+
1142+ data_size = 0;
1143+
1144+ while ((rlen = fread(rbuf, 1, gUnit*50, fp)) > 0) { /* V0.21-C */
1145+ for (j = 0; j < rlen; j+=gUnit) { /* V0.21-A */
1146+ len = gUnit; /* V0.21-A */
1147+ buf = &rbuf[j]; /* V0.21-A */
1148+ buf16 = (short *)buf; /* V0.21-A */
1149+
1150+ if (wfp) {
1151+ fwrite(buf, 1, gUnit, wfp);
1152+ data_size += len; /* data chunk size for write */
1153+ }
1154+
1155+ if (df) {
1156+ printf("%08x: ", total);
1157+ DumpData(buf, len);
1158+ }
1159+
1160+ /* current time */
1161+ if (df) {
1162+ printf("%d:%04.2f ", total/ckfmt->dwAvgBytesPerSec/60,
1163+ ((float)(total-(total/ckfmt->dwAvgBytesPerSec/60)*ckfmt->dwAvgBytesPerSec*60)/ckfmt->dwAvgBytesPerSec));
1164+ }
1165+
1166+ for (i = 0; i < gChannels; i++) {
1167+ if (gBytePerSample == 1) {
1168+ /* 1 byte */
1169+ val = buf[i * gBytePerSample] - 0x80;
1170+ } else {
1171+ /* 2 byte gBytePerSample == 2 */
1172+ /* val = buf16[i * gBytePerSample]; */
1173+ val = buf16[i];
1174+ }
1175+ if (df) printf("ch%d:%6d ", i+1, val);
1176+
1177+ if (maxval[i] < abs(val)) {
1178+ maxval[i] = abs(val); /* new max */
1179+ maxvalcnt[i] = 1; /* reset */
1180+ } else if (maxval[i] == abs(val)) {
1181+ ++maxvalcnt[i]; /* count up */
1182+ }
1183+ }
1184+ if (df) printf("\n");
1185+
1186+ /* sound blank check for -s */
1187+ if (abs(val) <
1188+ ((1 << (ckfmt->wBitsPerSample - 1)) * th_val/1000)) {
1189+ /* blank level */
1190+ //printf("%8d: th_val...%d\n", total,
1191+ // ((1 << (ckfmt->wBitsPerSample - 1)) * th_val/1000));
1192+ ++lowcont;
1193+ if (contf == 0 && lowcont > (ckfmt->dwSamplesPerSec*bl_sec)/10) {
1194+ /* 1sec continue... maybe blank area */
1195+ printf("Blank Time Start: %d:%04.2f\n",
1196+ total/ckfmt->dwAvgBytesPerSec/60,
1197+ ((float)(total-
1198+ (total/ckfmt->dwAvgBytesPerSec/60)
1199+ *ckfmt->dwAvgBytesPerSec*60)
1200+ /ckfmt->dwAvgBytesPerSec));
1201+ contf = 1;
1202+
1203+ if (sf && wfp) {
1204+ /* ### Change Each Header Size */
1205+ ChangeWavHeaders(wfp,
1206+ &riffhdr, /* 01 riff header */
1207+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
1208+ ckfmt, /* 03 fmt data */
1209+ ckfact, /* 04: no write */
1210+ data_size); /* "data" block size */
1211+ printf("## %s (%d:%04.2f)\n", fname,
1212+ data_size/ckfmt->dwAvgBytesPerSec/60,
1213+ ((float)(data_size-
1214+ (data_size/ckfmt->dwAvgBytesPerSec/60)
1215+ *ckfmt->dwAvgBytesPerSec*60)
1216+ /ckfmt->dwAvgBytesPerSec));
1217+ /* ### Close Wav File */
1218+ if (wfp) fclose(wfp);
1219+ wfp = NULL;
1220+ }
1221+ }
1222+
1223+ } else {
1224+ /* no blank level */
1225+ lowcont = 0;
1226+ if (contf) {
1227+ contf = 0;
1228+ printf("Blank Time End : %d:%04.2f\n",
1229+ total/ckfmt->dwAvgBytesPerSec/60,
1230+ ((float)(total-
1231+ (total/ckfmt->dwAvgBytesPerSec/60)
1232+ *ckfmt->dwAvgBytesPerSec*60)
1233+ /ckfmt->dwAvgBytesPerSec));
1234+
1235+ data_size = 0; /* reset data chunk size */
1236+ if (sf) {
1237+ sprintf(fname, "%s_%03d.wav", in_fname, file_cnt++);
1238+ printf("## Writing %s ...\n", fname);
1239+ /* ### Open Next Wav File */
1240+ wfp = fopen(fname, "wb");
1241+ if (wfp == NULL) {
1242+ perror(fname);
1243+ exit(1);
1244+ }
1245+ /* ### WriteWavHeaders */
1246+ WriteWavHeaders(wfp,
1247+ &riffhdr, /* 01 riff header */
1248+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
1249+ ckfmt, /* 03 fmt data */
1250+ ckfact); /* 04: no write */
1251+ }
1252+ }
1253+ }
1254+
1255+ /* for -ex */
1256+ if (ntment) {
1257+ outf = 0;
1258+ reopen = 0;
1259+ curdsec = total/(ckfmt->dwAvgBytesPerSec/10);
1260+ for (i = 0; i<ntment; i++) {
1261+ if (start_dsec[i] <= curdsec && curdsec < end_dsec[i]){
1262+ outf = 1;
1263+ if (curdsec == end_dsec[i]) {
1264+ reopen = 1;
1265+ }
1266+ }
1267+ }
1268+ if (outf == 0 || reopen == 1) {
1269+ if (wfp) {
1270+ /* ### Change Each Header Size */
1271+ ChangeWavHeaders(wfp,
1272+ &riffhdr, /* 01 riff header */
1273+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
1274+ ckfmt, /* 03 fmt data */
1275+ ckfact, /* 04: no write */
1276+ data_size); /* "data" block size */
1277+ printf("## %s (%d:%04.2f)\n", fname,
1278+ data_size/ckfmt->dwAvgBytesPerSec/60,
1279+ ((float)(data_size-
1280+ (data_size/ckfmt->dwAvgBytesPerSec/60)
1281+ *ckfmt->dwAvgBytesPerSec*60)
1282+ /ckfmt->dwAvgBytesPerSec));
1283+ /* ### Close Wav File */
1284+ if (wfp) fclose(wfp);
1285+ wfp = NULL;
1286+ data_size = 0; /* reset data chunk size */
1287+ }
1288+ }
1289+ if (outf) {
1290+ if (wfp == NULL) {
1291+ data_size = 0; /* reset data chunk size */
1292+ sprintf(fname, "%s_%03d.wav", in_fname, file_cnt++);
1293+ printf("## Writing %s ...\n", fname);
1294+ /* ### Open Wav File */
1295+ wfp = fopen(fname, "wb");
1296+ if (wfp == NULL) {
1297+ perror(fname);
1298+ exit(1);
1299+ }
1300+ /* ### WriteWavHeaders */
1301+ WriteWavHeaders(wfp,
1302+ &riffhdr, /* 01 riff header */
1303+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
1304+ ckfmt, /* 03 fmt data */
1305+ ckfact); /* 04: no write */
1306+ }
1307+ }
1308+ }
1309+
1310+ total += len; /* total read size */
1311+
1312+ if (total >= cklen) {
1313+ break;
1314+ }
1315+ } /* 1 bufferd data loop V0.21-A */
1316+ } /* data chunk loop */
1317+
1318+ if (contf) {
1319+ contf = 0;
1320+ printf("Blank Time End : %d:%04.2f\n",
1321+ total/ckfmt->dwAvgBytesPerSec/60,
1322+ ((float)(total-
1323+ (total/ckfmt->dwAvgBytesPerSec/60)
1324+ *ckfmt->dwAvgBytesPerSec*60)
1325+ /ckfmt->dwAvgBytesPerSec));
1326+ }
1327+
1328+ if (wfp) {
1329+ /* ### Change Each Header Size */
1330+ ChangeWavHeaders(wfp,
1331+ &riffhdr, /* 01 riff header */
1332+ chunkhdr, chunk_cnt, /* 02 each chunk headers */
1333+ ckfmt, /* 03 fmt data */
1334+ ckfact, /* 04: no write */
1335+ data_size); /* "data" block size */
1336+ printf("## %s (%d:%04.2f)\n", fname,
1337+ data_size/ckfmt->dwAvgBytesPerSec/60,
1338+ ((float)(data_size-
1339+ (data_size/ckfmt->dwAvgBytesPerSec/60)
1340+ *ckfmt->dwAvgBytesPerSec*60)
1341+ /ckfmt->dwAvgBytesPerSec));
1342+ /* ### Close Wav File */
1343+ if (wfp) fclose(wfp);
1344+ wfp = NULL;
1345+ }
1346+
1347+ printf("---- Other Info ----\n");
1348+ /* ch0:Left ch1:Right */
1349+ printf("Max Power : ");
1350+ for (i = 0; i < gChannels; i++) {
1351+ printf("ch%d:%d/%d (%d times) ", i+1,
1352+ maxval[i], 1 << (ckfmt->wBitsPerSample - 1),
1353+ maxvalcnt[i]);
1354+ if (peak_level < maxval[i]) {
1355+ peak_level = maxval[i];
1356+ }
1357+ }
1358+ max_level = 1 << (ckfmt->wBitsPerSample - 1);
1359+ printf("\n");
1360+ //printf("Time : %.2f sec\n",
1361+ // ((float)cklen)/ckfmt->dwAvgBytesPerSec);
1362+ printf("Time : %d:%04.2f\n", cklen/ckfmt->dwAvgBytesPerSec/60,
1363+ ((float)(cklen-(cklen/ckfmt->dwAvgBytesPerSec/60)*ckfmt->dwAvgBytesPerSec*60)/ckfmt->dwAvgBytesPerSec));
1364+ }
1365+ }
1366+ }
1367+#endif /* 作成中 */
1368+}
1369+/* V0.24-A start */
1370+
1371+/*
1372+ * TimeStr2Sec()
1373+ *
1374+ * IN str : mm:ss.n
1375+ * OUT ret : dsec (1/10sec)
1376+ * -1 : invalid time format
1377+ */
1378+int TimeStr2Sec(char *str)
1379+{
1380+ char *pt;
1381+ char wk[1024];
1382+ int mm, ss, ds;
1383+ int rval = 0;
1384+
1385+ mm = ss = ds = 0;
1386+
1387+ /* get mm */
1388+ pt = strchr(str, ':');
1389+ if (pt) {
1390+ mm = atoi(str);
1391+ ++pt;
1392+ } else {
1393+ pt = str;
1394+ }
1395+
1396+ /* get ss */
1397+ ss = atoi(pt);
1398+
1399+ /* get ds */
1400+ pt = strchr(str, '.');
1401+ if (pt) {
1402+ ++pt;
1403+ ds = *pt - '0';
1404+ if (ds < 0 || ds > 9) {
1405+ printf("invalid time value [%s]\n", str);
1406+ return -1;
1407+ }
1408+ }
1409+
1410+ rval = (mm*60+ss)*10 + ds;
1411+ dprintf2("dsec = %d\n", rval);
1412+
1413+ return rval;
1414+}
1415+
1416+/*
1417+ * GetTimes()
1418+ *
1419+ * IN time_exp : mm:ss.n-mm:ss.n[,mm:ss.n-mm:ss.n,...]
1420+ * OUT st_dsec[] : start dsec (1/10sec)
1421+ * OUT ed_dsec[] : end dsec (1/10sec)
1422+ * OUT ret : num of time (0 : format error)
1423+ *
1424+ */
1425+int GetTimes(char *time_exp, int **st_dsec, int **en_dsec)
1426+{
1427+ int n_time = 0;
1428+ int i;
1429+ int err = 0;
1430+ char buf[4096];
1431+ char *pt, *pt2;
1432+ char wkst[1024];
1433+ char wken[1024];
1434+
1435+ strncpy(buf, time_exp, sizeof(buf));
1436+ buf[sizeof(buf)-1] = '\0';
1437+
1438+ ++n_time;
1439+ for (i = 0; i<strlen(buf); i++) {
1440+ if (buf[i] == ',') {
1441+ ++n_time;
1442+ }
1443+ }
1444+ if (n_time) {
1445+ *st_dsec = malloc(sizeof(int)*n_time);
1446+ *en_dsec = malloc(sizeof(int)*n_time);
1447+ if (*st_dsec == NULL || *en_dsec == NULL) {
1448+ err = 1;
1449+ } else {
1450+ memset(*st_dsec, 0, sizeof(int)*n_time);
1451+ memset(*en_dsec, 0, sizeof(int)*n_time);
1452+ }
1453+ }
1454+
1455+ i = 0;
1456+ pt = strtok(buf, ",");
1457+ while (err == 0 && pt) {
1458+ pt2 = strchr(pt, '-');
1459+ if (pt2 == NULL) {
1460+ err = 1;
1461+ break;
1462+ }
1463+ *pt2 = '\0';
1464+ ++pt2;
1465+ strcpy(wkst, pt); /* copy start time */
1466+ strcpy(wken, pt2); /* copy end time */
1467+ (*st_dsec)[i] = TimeStr2Sec(wkst);
1468+ (*en_dsec)[i] = TimeStr2Sec(wken);
1469+ if ((*st_dsec)[i] < 0 || (*en_dsec)[i] < 0) {
1470+ err = 1;
1471+ break;
1472+ }
1473+ dprintf("## st = %d en = %d\n", (*st_dsec)[i], (*en_dsec)[i]);
1474+ ++i;
1475+ pt = strtok(NULL, ",");
1476+ }
1477+
1478+ if (err) {
1479+ n_time = 0;
1480+ }
1481+ return n_time;
1482+}
1483+
1484+void usage()
1485+{
1486+ printf("usage: wavcut [-d]\n");
1487+ printf(" { [-s] [-lv <cut_level(%d)>] [-ln <blank_len>(%d)>]\n", th_val, bl_sec);
1488+ printf(" | -ex mm:ss-mm:ss[,mm:ss-ss,...]\n");
1489+ printf(" | {-no | -vol <%%>}\n");
1490+ printf(" | -cs <speed(1-199)>\n");
1491+ printf(" | -rv }\n");
1492+ printf(" [<wav_file>]\n");
1493+ printf(" -d : display data\n");
1494+ printf(" -s : split wav data\n");
1495+ printf(" -lv : blank level. default:%d (x0.1%%)\n", th_val);
1496+ printf(" -ln : time to recognize blank. default:%d (x0.1sec)\n", bl_sec);
1497+ printf(" -ex : extract wav part\n");
1498+ printf(" -no : normalize wav data\n");
1499+ printf(" -vol: set volume\n");
1500+ printf(" -rv : reduce voice part\n");
1501+ printf(" -cs : change speed (%%)\n");
1502+ printf("usage: wavcut -m <wav_file> <wav_file> ...\n"); /* V0.27-A */
1503+ printf(" -m : merge wav files\n"); /* V0.27-A */
1504+ exit(1);
1505+}
1506+
1507+int main(int a, char *b[])
1508+{
1509+ int i;
1510+ char buf[4096];
1511+ char *filename = NULL;
1512+ FILE *fp;
1513+ char **files; /* files for -m V0.27-A */
1514+ int fcnt = 0; /* file count V0.27-A */
1515+
1516+ files = (char **)malloc((a+1) * sizeof(char *)); /* V0.27-A */
1517+ memset(files, 0, (a+1) * sizeof(char *)); /* V0.27-A */
1518+
1519+ for (i = 1; i<a; i++) {
1520+ if (!strcmp(b[i],"-v")) {
1521+ ++vf;
1522+ continue;
1523+ }
1524+ if (!strcmp(b[i],"-d")) {
1525+ df = 1; /* Display Wav Data */
1526+ continue;
1527+ }
1528+ if (!strcmp(b[i],"-rv")) {
1529+ rvf = 1; /* Reduce Voice */
1530+ continue;
1531+ }
1532+ if (!strcmp(b[i],"-s")) {
1533+ if (ntment) {
1534+ usage();
1535+ }
1536+ sf = 1; /* Split Wav Data */
1537+ continue;
1538+ }
1539+ if (!strcmp(b[i],"-m")) {
1540+ mf = 1; /* Merge Wav Files */
1541+ continue;
1542+ }
1543+ /* V0.28-A start */
1544+ if (i+1 < a && !strcmp(b[i],"-cs")) {
1545+ csf = atoi(b[++i]); /* Change Speed(%) */
1546+ if (csf < 1 || csf > 199) {
1547+ usage();
1548+ }
1549+ continue;
1550+ }
1551+ /* V0.28-A end */
1552+ if (i+1 < a && !strcmp(b[i],"-lv")) {
1553+ th_val = atoi(b[++i]); /* Blank Level */
1554+ continue;
1555+ }
1556+ if (i+1 < a && !strcmp(b[i],"-ln")) {
1557+ bl_sec = atoi(b[++i]); /* Blank Sec */
1558+ continue;
1559+ }
1560+ if (!strcmp(b[i],"-no")) {
1561+ /* nf = 1; /* normalize */
1562+ nf = 1 + atoi(&b[i][3]); /* -no[X] normalize +1X0% (secret opt) */
1563+ continue;
1564+ }
1565+
1566+ /* V0.25-A start */
1567+ if (i+1 < a && !strcmp(b[i],"-vol")) {
1568+ volf = atoi(b[++i]); /* set Volume */
1569+ continue;
1570+ }
1571+ /* V0.25-A end */
1572+
1573+ if (i+1 < a && !strcmp(b[i],"-ex")) {
1574+ if (sf) {
1575+ usage();
1576+ }
1577+ ntment = GetTimes(b[++i], &start_dsec, &end_dsec); /* Extract wav */
1578+ if (ntment <= 0) {
1579+ usage();
1580+ }
1581+
1582+ continue;
1583+ }
1584+ if (!strncmp(b[i],"-h",2)) {
1585+ usage();
1586+ }
1587+ filename = b[i];
1588+ files[fcnt++];
1589+ }
1590+
1591+ if (volf && nf) {
1592+ usage();
1593+ }
1594+
1595+ /* V0.27-A start */
1596+ if (mf && (volf || nf || sf || ntment || rvf)) {
1597+ usage();
1598+ }
1599+
1600+ if (mf) {
1601+ /* -m: merage wav files */
1602+ MergeWavs(files);
1603+ return 0;
1604+ }
1605+ /* V0.27-A end */
1606+
1607+ if (filename) {
1608+ if (!(fp = fopen(filename,"rb"))) {
1609+ perror(filename);
1610+ exit(1);
1611+ }
1612+ strcpy(in_fname, filename);
1613+ if (!strcasecmp(&in_fname[strlen(in_fname)-4], ".wav")) {
1614+ in_fname[strlen(in_fname)-4] = '\0'; /* delete .wav */
1615+ }
1616+ } else {
1617+ if (nf) {
1618+ printf("Error: -no option not support stdin data.\n");
1619+ exit(1);
1620+ }
1621+ fp = stdin;
1622+ strcpy(in_fname, "stdin");
1623+ }
1624+
1625+ WavAnalyze(fp);
1626+
1627+ if (nf) {
1628+ fseek(fp, 0, SEEK_SET); /* seek to top */
1629+ if (nf > 1) {
1630+ /* peak_level = (peak_level*10)/11; /* 110% V0.22 */
1631+
1632+ /* nf = 1 : 100% */
1633+ /* nf = 2 : 110% */
1634+ /* nf = 3 : 120% */
1635+ /* nf = 4 : 130% */
1636+ /* nf =10 : 190% */
1637+ peak_level = (peak_level*10)/(10+(nf-1)); /* 1[nf-1]0% V0.23 */
1638+ }
1639+ WavNormalize(fp, peak_level, max_level);
1640+ }
1641+ /* V0.25-A start */
1642+ else if (volf) {
1643+ fseek(fp, 0, SEEK_SET); /* seek to top */
1644+ WavNormalize(fp, 100, volf); /* volf/100 */
1645+ }
1646+ /* V0.25-A end */
1647+ /* V0.24-A start */
1648+ else if (rvf) {
1649+ fseek(fp, 0, SEEK_SET); /* seek to top */
1650+ ReduceVoice(fp);
1651+ }
1652+ /* V0.24-A end */
1653+ /* V0.28-A start */
1654+ else if (csf) {
1655+ fseek(fp, 0, SEEK_SET); /* seek to top */
1656+ ChgSpeed(fp, csf);
1657+ }
1658+ /* V0.28-A end */
1659+
1660+ fclose(fp);
1661+
1662+ return 0;
1663+}
--- /dev/null
+++ b/webget.c
@@ -0,0 +1,1145 @@
1+/*
2+ * webget.c
3+ *
4+ * Webファイル一括Getツール
5+ *
6+ * 指定したURL以下のディレクトリから、指定の拡張子のファイルを取り出す。
7+ *
8+ * usage : webget <url> [{-s <suffix> | -all}]
9+ *
10+ * 1998/01/17 V1.00 by oga.
11+ * 1998/01/25 V1.01 support 'frame src='
12+ * 1998/02/15 V1.02 bug fix on cross reference html
13+ * 1998/03/07 V1.03 Ignore mailto:
14+ * 1998/03/17 V1.04 Ignore suffix case
15+ * 1999/03/07 V1.05 recv error retry
16+ * 1999/09/03 V1.07 support ommitting "http://" and -na option
17+ * 2000/07/22 V1.071 bug fix upperdir check
18+ * 1999/11/09 V1.08 support link trace limit (-t)
19+ * 2000/03/23 V1.10 support proxy server (not available)
20+ * 2001/06/26 V1.11 support "xx%" progress disp/ support host:port
21+ * 2001/07/01 V1.12 delimiter "'" support
22+ * 2001/07/24 V1.13 support progress bar
23+ * 2001/10/14 V1.14 support -bd option and delete # in "xx.html#xxx"
24+ * 2001/10/15 V1.15 support -i option
25+ * 2001/11/15 V1.16 support Windows
26+ * 2003/04/07 V1.17 support progress bytes (KB)
27+ * 2003/05/12 V1.18 support "img.*src"
28+ * 2003/10/29 V1.19 support signal handler for debug
29+ * 2003/11/01 V1.20 support analyzed list (donelist)
30+ * 2003/11/04 V1.21 bug fix upperdir check
31+ * 2010/01/03 V1.22 trace level 1up for img/default get css
32+ * 2010/02/14 V1.23 support link trace level 2
33+ *
34+ * Varbose Level
35+ * 1: xx
36+ * 2: link trace over file
37+ * 3: all GetURL path
38+ *
39+ * 取得の仕様
40+ * (1)ファイルが存在する場合はコンテンツをサーバから取ってこない
41+ * 但し、-f 指定の場合ファイルが存在してもサーバから取ってくる
42+ * (2)既に解析したhtmlファイルは解析しない(V1.20より)
43+ * (-na指定の場合、存在するファイルの内部解析をしない (古いオブション))
44+ *
45+ */
46+#include <stdio.h>
47+#include <stdlib.h>
48+#include <sys/stat.h>
49+
50+#ifdef _WIN32
51+#include <windows.h>
52+#include <winsock.h>
53+#else
54+#include <unistd.h>
55+#include <string.h>
56+#include <sys/time.h>
57+#include <sys/types.h>
58+#include <sys/socket.h>
59+#include <sys/time.h>
60+#include <netinet/in.h>
61+#include <netdb.h>
62+#include <arpa/inet.h>
63+#include <fcntl.h>
64+#include <signal.h>
65+#endif
66+
67+#ifdef _WIN32
68+#define strncasecmp strnicmp
69+#define strcasecmp stricmp
70+/*
71+struct timeval {
72+ u_int tv_sec;
73+ u_int tv_usec;
74+};
75+*/
76+
77+struct timezone {
78+ int tz_minuteswest;
79+ int tz_dsttime;
80+};
81+
82+int gettimeofday(struct timeval *tv, struct timezone *tz);
83+#endif /* _WIN32 */
84+
85+/* types */
86+typedef struct filelist {
87+ struct filelist *next;
88+ char *fname;
89+} filen_t;
90+
91+/* define */
92+#define VER "1.23"
93+#define HOST "HOST:"
94+#define PORT "PORT:"
95+#define HTTP_PREFIX "http://"
96+#define FTP_PREFIX "ftp://"
97+#define dprintf if (vf >= 4) printf
98+#define PERSEC 1000
99+
100+
101+/* funcs */
102+void get_file_opt();
103+void GET_DATA(FILE *, int); /* no use */
104+int GetURLData(char *,int, char *);
105+char *GetHREF(FILE *, char *);
106+char *GetTag(FILE *, char *);
107+int mkdirp(char *);
108+void Url2HostPath(char *, char *, char *, int *);
109+int suffck(char *, char *);
110+int IsImgPath(char *);
111+void DelDot2(char *);
112+
113+/* list utility */
114+int AddList(filen_t **, char *);
115+void DelList(filen_t **, char *);
116+void FreeList(filen_t **);
117+
118+/* globals */
119+int vf = 0; /* verboseモード */
120+int ff = 0; /* forceフラグ */
121+int allf = 0; /* */
122+int lv = 0; /* 許可レベル */
123+int bdf = 0; /* -bd 指定フラグ */
124+int imf = 0; /* -i 指定フラグ V1.15 */
125+int na = 0; /* 1:ファイルが存在した場合、解析しない */
126+int trl = 0; /* リンクトレース制限 0:無制限 */
127+int trl_plus = 0; /* リンクトレース制限(画像1plus) */
128+int first = 1; /* 初取得フラグ */
129+int trace_level = 0; /* リンクトレース階層 */
130+int prox_port; /* proxy port 番号 V1.10 */
131+char suff[260]; /* suffix */
132+char startdir[1025] = ""; /* start dir */
133+char prox_host[256]=""; /* proxy host格納用 V1.10 */
134+filen_t *openlist = NULL; /* open file list */
135+filen_t *donelist = NULL; /* 解析済みlist */
136+char *bar = "################################################## ";
137+
138+void usage()
139+{
140+ printf("webget Ver %s\n", VER);
141+ printf("usage : webget <url> [{-s <suffix> | -all}]\n");
142+ printf(" [-l {<0>|1|2|3}]\n");
143+ printf(" [-t <link_trace_level(0)>[+]\n");
144+ printf(" [-p <port>] [-f] [-na] [-v ...]\n");
145+ printf(" [-i] [-bd <base_dir>]\n");
146+#if SUPPORT_PROXY
147+ printf(" [-proxy <host> <port>]\n");
148+#endif
149+ printf(" -s <suffix> : get only spcified suffix file(default .jpg)\n");
150+ printf(" -all : get all file\n");
151+ printf(" -l {<0>|1|2} : link allow level\n");
152+ printf(" 0: file under spcified URL only (default)\n");
153+ printf(" 1: allow same host\n");
154+ printf(" 2: allow all hosts (suffix only)\n");
155+ printf(" 3: allow all hosts\n");
156+ printf(" -t <level>[+] : link trace level. 0:no limit\n");
157+ printf(" +: if image, trace level 1 up (ex. -t 3+)\n");
158+ printf(" -bd : change base dir for -l option (no http://)\n");
159+ printf(" -p <port> : port number\n");
160+ printf(" -f : get duplicate file\n");
161+ printf(" -i : don't send http version (for i-mode site)\n");
162+ printf(" -na : no analize exist file\n");
163+ printf(" -v : verbose mode\n");
164+#if SUPPORT_PROXY
165+ printf(" -proxy <host> <port> : use proxy server\n");
166+#endif
167+}
168+
169+#ifndef _WIN32
170+void SigHup(int sig)
171+{
172+ ++vf;
173+ printf("### verbose level = %d\n", vf);
174+ signal(SIGHUP, SigHup);
175+}
176+#endif
177+
178+int main(a,b)
179+int a;
180+char *b[];
181+{
182+ int an = 0; /* 引数なし引数のカウンタ */
183+ int i;
184+ int waitsec = 1; /* send後のwait時間 */
185+ int port; /* port 番号 */
186+ char *recvfile = NULL;
187+ char *sendf = NULL;
188+ char *pt = NULL;
189+ char host[256]; /* host格納用 */
190+ char path[260]; /* URL パス部分 */
191+ char url[260]; /* URL */
192+ char basedir[260]; /* base dir */
193+
194+#ifdef _WIN32
195+ WSADATA WsaData;
196+#endif
197+
198+
199+ /* init */
200+ first = 1; /* first data */
201+ port = 80; /* default port */
202+ strcpy(host,"localhost"); /* default host */
203+ strcpy(path,"/"); /* suffix */
204+ strcpy(suff,".jpg"); /* suffix */
205+ strcpy(url, "");
206+
207+ /* arg */
208+ for (i = 1; i<a ; i++) {
209+ if (!strcmp(b[i],"-h")) { /* ヘルプ */
210+ usage();
211+ exit(1);
212+ }
213+ if (!strcmp(b[i],"-s") && i+1<a) { /* suffix */
214+ strcpy(suff,b[++i]);
215+ continue;
216+ }
217+ if (!strcmp(b[i],"-all")) { /* 全ファイル取り出し */
218+ allf = 1;
219+ continue;
220+ }
221+ if (!strcmp(b[i],"-l") && i+1<a) { /* allow level */
222+ lv = atoi(b[++i]);
223+ continue;
224+ }
225+ if (!strcmp(b[i],"-bd") && i+1<a) { /* base dir V1. */
226+ strcpy(startdir, b[++i]);
227+ continue;
228+ }
229+ if (!strcmp(b[i],"-p") && i+1<a) { /* port */
230+ port = atoi(b[++i]);
231+ continue;
232+ }
233+ if (!strcmp(b[i],"-f")) { /* force */
234+ ff = 1;
235+ continue;
236+ }
237+ if (!strcmp(b[i],"-i")) { /* -i option V1.15-A */
238+ imf = 1;
239+ continue;
240+ }
241+ if (!strcmp(b[i],"-na")) { /* no analize exist file V1.07 */
242+ /* クロスリンク無限ループ対策 */
243+ na = 1;
244+ continue;
245+ }
246+ if (!strcmp(b[i],"-t") && i+1<a) { /* link trace limit level V1.08 */
247+ /* リンクトレースレベル制限 0:制限なし */
248+ trl = atoi(b[++i]);
249+ /* V1.22-A start */
250+ if (b[i][strlen(b[i])-1] == '+') {
251+ trl_plus = 1;
252+ }
253+ /* V1.22-A end */
254+ continue;
255+ }
256+ if (!strcmp(b[i],"-proxy")) { /* proxy */
257+ if (i+2 < a) {
258+ usage();
259+ exit(1);
260+ }
261+ strcpy(prox_host,b[++i]);
262+ prox_port = atoi(b[++i]);
263+ continue;
264+ }
265+ if (!strcmp(b[i],"-v")) { /* verbose */
266+ ++vf;
267+ continue;
268+ }
269+ strcpy(url,b[i]); /* URL */
270+ }
271+
272+ if (strlen(url) == 0) { /* V1.13-A */
273+ usage();
274+ exit(1);
275+ }
276+
277+#ifdef _WIN32
278+ WSAStartup(0x0101, &WsaData);
279+ /* Win don't support scroll bar. */
280+ /* set i-mode flag (don't use HTTP/1.0) */
281+ /* imf = 1; */ /* V1.21-D */
282+#else /* UNIX */
283+ signal(SIGHUP, SigHup);
284+#endif
285+
286+#if 1
287+ Url2HostPath(url, host, path, &port);
288+#else
289+ /* Url2HostPath(url,host,path)にしよう */
290+ if (strstr(url,HTTP_PREFIX)) {
291+ /* ホスト名取り出し */
292+ strcpy(host,&url[strlen(HTTP_PREFIX)]);
293+ pt = (char *)strchr(host,'/'); /* pt=/aaa/bbb/test.html */
294+ if (pt) {
295+ strcpy(path,pt);
296+ *pt = '\0';
297+ }
298+ dprintf("# hostname is [%s]\n",host);
299+ dprintf("# path is [%s]\n",path);
300+ }
301+#endif
302+
303+ mkdir(host,0775);
304+ chdir(host);
305+
306+ GetURLData(host,port,path);
307+
308+ FreeList(&donelist);
309+
310+#ifdef _WIN32
311+ WSACleanup();
312+#endif
313+
314+ exit(0);
315+}
316+
317+/*
318+ * urlをhost名とpath部分に分解する
319+ * V1.11 support host:port
320+ *
321+ * http://host.domain[:port]/aaa/bbb/test.html
322+ *
323+ * => host ... host.domain
324+ * => path ... aaa/bbb/test.html
325+ * => port ... nnnn
326+ */
327+void Url2HostPath(char *url, char *host, char *path, int *port)
328+{
329+ char *pt;
330+ char urlwk[2048]; /* V1.07 */
331+
332+ if (!strncmp(url, HTTP_PREFIX, strlen(HTTP_PREFIX))) {
333+ strcpy(urlwk, url);
334+ } else {
335+ sprintf(urlwk, "%s%s",HTTP_PREFIX, url);
336+ }
337+
338+ if (strstr(urlwk,HTTP_PREFIX)) {
339+ /* ホスト名取り出し */
340+ strcpy(host,&urlwk[strlen(HTTP_PREFIX)]);
341+ pt = (char *)strchr(host,'/'); /* pt=/aaa/bbb/test.html */
342+ if (pt) {
343+ strcpy(path,pt);
344+ *pt = '\0';
345+ }
346+
347+ /* V1.11 get port */
348+ pt = (char *)strchr(host,':'); /* pt=:8080 */
349+ if (pt) {
350+ *port = atoi(pt+1);
351+ if (*port == 0) {
352+ *port = 80;
353+ }
354+ *pt = '\0';
355+ }
356+
357+ dprintf("# hostname is [%s]\n",host);
358+ dprintf("# port is [%d]\n",*port);
359+ dprintf("# path is [%s]\n",path);
360+ }
361+}
362+
363+/*
364+ * GetURLData()
365+ *
366+ * IN host : web hostname
367+ * port : port (80)
368+ * path : path without hostname (fullpath) (eg. /xxx/yyy.html)
369+ *
370+ */
371+int GetURLData(char *host,int port,char *path)
372+{
373+ FILE *ofp, *rfp;
374+ int sockfd; /* ソケットFD */
375+ int len, slen;
376+ int total,old;
377+ int start,end;
378+ int content_len; /* Content Length */
379+ int port2;
380+ int lvplus = 0; /* trace level up for img V1.22-A */
381+ struct sockaddr_in serv_addr;
382+ struct hostent *hep;
383+ char buf[4096];
384+ char wk[4096];
385+ char *pt;
386+ char wfile[260];
387+ char host2[256]; /* リンク先 host格納用 */
388+ char path2[260]; /* リンク先 URL パス部分 */
389+ char cwd[260]; /* 現在のディレクトリ */
390+ char strbar[100]; /* for progress bar V1.13 */
391+ struct stat stbuf;
392+
393+ if (vf >= 3) printf("# GetURLData[%s] trace_level=%d\n",path, trace_level+1);
394+ ++trace_level;
395+
396+ /* V1.22-A start */
397+ if (IsImgPath(path) && trl_plus) {
398+ lvplus = 1;
399+ }
400+ /* V1.22-A end */
401+
402+ if (trl && trace_level > trl+lvplus) { /* V1.08 V1.22-C */
403+ if (vf >= 2) printf("## Skip load %s (tracelevel %d)\n",path,trace_level);
404+ --trace_level;
405+ return 1;
406+ }
407+
408+ /* コマンドに指定されたpathのディレクトリ部分を保存 */
409+ if (startdir[0] == '\0') {
410+ strcpy(startdir,path);
411+ if (pt = (char *)strrchr(startdir,'/')) {
412+ if (&startdir[0] != pt) { /* V1.071-A */
413+ *pt = '\0';
414+ } else { /* V1.071-A */
415+ *(pt+1) = '\0';
416+ }
417+ }
418+ }
419+
420+ /* allow level 0の場合は、指定ディレクトリより上のディレクトリの
421+ * ファイルをGetしない
422+ */
423+ if (!first && lv == 0 && strncmp(path,startdir,strlen(startdir))) {
424+ if (vf) printf("## Skip load %s (upper dir)\n",path);
425+ --trace_level;
426+ return 1;
427+ }
428+ first = 0;
429+
430+ /* wk : 格納先パス用 path : 取得URL */
431+ if (pt = (char *)strchr(path,'#')) {
432+ /* a nameの#は取る */
433+ *pt = '\0';
434+ }
435+ strcpy(wk,path);
436+ if (pt = (char *)strchr(wk,'~')) {
437+ /* ~は@に変換 */
438+ *pt = '@';
439+ }
440+
441+ /* ファイル格納用ディレクトリ作成 */
442+ mkdirp(wk);
443+
444+ /* 格納用のファイル(wfile)は頭の/を削除 */
445+ if (wk[0] == '/') {
446+ strcpy(wfile,&wk[1]);
447+ } else {
448+ strcpy(wfile,wk);
449+ }
450+
451+ /* /で終っていたら、index.htmlを付ける */
452+ if (!strlen(wfile) || wfile[strlen(wfile)-1] == '/') {
453+ strcat(wfile,"index.html");
454+ }
455+
456+ /* .html/.css と 指定した拡張子以外のファイルは読み込まない V1.22-C */
457+ if (!allf && !suffck(wfile,".html") && !suffck(wfile,".htm")
458+ && !suffck(wfile,".css") && !suffck(wfile,suff) ) {
459+ /* 読む必要のないファイル */
460+ --trace_level;
461+ return 1;
462+
463+ }
464+
465+ /* cwd 設定 */
466+ strcpy(cwd,path);
467+ pt = (char *)strrchr(cwd,'/');
468+ if (pt) {
469+ *(pt+1) = '\0'; /* cwd = /dir1/dir2/ */
470+ }
471+
472+ /* 取得済みでない場合読み込む (-forceなら常に読む) */
473+ if (ff || stat(wfile,&stbuf)) {
474+ if (ff) {
475+ printf("## reload %s .\n");
476+ }
477+ /*
478+ * start URL Get
479+ */
480+ memset((char *)&serv_addr, 0, sizeof(serv_addr));
481+
482+ hep = gethostbyname(host);
483+ if (!hep) {
484+ printf("Error: gethostbyname(%s) error \n",host);
485+ --trace_level;
486+ return 1;
487+ }
488+
489+ serv_addr.sin_family = AF_INET;
490+ serv_addr.sin_addr.s_addr = *(int *)hep->h_addr;
491+ serv_addr.sin_port = htons(port);
492+
493+ if (vf >= 2) {
494+ pt = (char *)&serv_addr.sin_addr.s_addr;
495+ /*printf("# IP addr : %u.%u.%u.%u (%08x)\n", pt[0],pt[1],pt[2],pt[3],
496+ serv_addr.sin_addr.s_addr); */
497+ printf("# IP addr : %s\n", inet_ntoa(serv_addr.sin_addr));
498+ }
499+
500+ if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
501+ perror("socket");
502+ --trace_level;
503+ return 1;
504+ }
505+
506+ if(connect(sockfd, (struct sockaddr *)&serv_addr,
507+ sizeof(serv_addr)) < 0){
508+ perror("connect");
509+ --trace_level;
510+ return 1;
511+ }
512+
513+ /*
514+ * write file open
515+ */
516+ dprintf("# fopen(%s)\n",wfile);
517+ if (!(ofp = fopen(wfile,"wb"))) { /* V1.16-C */
518+ printf("Error: recv data file open error : \n");
519+ perror("fopen");
520+ --trace_level;
521+ return 1;
522+ }
523+
524+ if (imf) { /* V1.15-A */
525+ sprintf(buf, "GET %s\n",path); /* V1.11-D V1.15-A */
526+ } else {
527+ sprintf(buf, "GET %s HTTP/1.0\n\n",path); /* V1.11-A */
528+ }
529+ len = strlen(buf);
530+
531+ dprintf("# send request = %s",buf);
532+
533+ /* send data */
534+ slen = send(sockfd, buf, len, 0);
535+ if (slen != len) {
536+ printf("Warning: send incompleted len=%d send=%d\n",len,slen);
537+ }
538+
539+ /* V1.11-A start */
540+ content_len = 0;
541+ if (!imf) {
542+ /* for "GET xx HTTP/1.0" */
543+ /* Get HTTP Header */
544+ do {
545+ recv_oneline(sockfd, buf, sizeof(buf));
546+ if (!strncasecmp(buf, "Content-Length: ", 16)) {
547+ content_len = atoi(&buf[strlen("Content-Length: ")]);
548+ dprintf("content_len = %d\n", content_len);
549+ }
550+ } while(strlen(buf) != 0);
551+ }
552+ /* V1.11-A end */
553+
554+ total = 0;
555+ old = 0;
556+ printf("## LV:%d loading %s .",trace_level, wfile);
557+ if (content_len) printf("\n"); /* V1.11 */
558+ fflush(stdout);
559+ start = clock1000();
560+ do {
561+ /* recv data */
562+ len = recv(sockfd,buf,sizeof(buf),0);
563+ if (len > 0) {
564+ fwrite(buf,1,len,ofp);
565+ }
566+ if (len < 0) { /* V1.05 */
567+ printf("# recv error (%d). retry!!\n");
568+ continue;
569+ }
570+ /* printf("receive %d bytes\n", len); */
571+ total += len;
572+
573+ if (content_len) { /* V1.11-A */
574+ /* for disp by % V1.11-A */
575+ int pcent;
576+ if (content_len > 1024*1024) {
577+ pcent = total/(content_len/100);
578+ } else {
579+ pcent = (total*100)/content_len;
580+ }
581+ /* for disp progress bar V1.03-A */
582+ strncpy(strbar, &bar[50-pcent/2], 50);
583+ strbar[0] = strbar[10] = strbar[20] = strbar[30]
584+ = strbar[40] = strbar[50] = '|';
585+ strbar[51] = '\0';
586+ /* printf(" %3d%% %s\n\033M", pcent, strbar); */
587+#ifdef _WIN32
588+ printf(" %3d%% %s %d/%d KB\r", pcent, strbar, total/1024, content_len/1024); /* V1.17-C */
589+#else /* !_WIN32 */
590+ printf(" %3d%% %s %d/%d KB\n\033M", pcent, strbar, total/1024, content_len/1024); /* V1.17-C */
591+#endif /* !_WIN32 */
592+ fflush(stdout);
593+ } else {
594+ /* disp by dot */
595+ if (total > old+4096) {
596+ printf(".");
597+ fflush(stdout);
598+ old += 4096;
599+ }
600+ }
601+ } while (len > 0);
602+
603+ if (ofp != stdout) {
604+ dprintf("\n# fclose(%s)\n",wfile);
605+ fclose(ofp);
606+ }
607+ close(sockfd);
608+ end = clock1000();
609+
610+ {
611+ char wk2[256]; /* V1.17-A */
612+ sprintf(wk2, " (%d bytes %.2fKB/sec) ", /* V1.17-C */
613+ total,((float)total)/(end-start)/1.024);
614+ wk2[79] = '\0'; /* V1.17-A */
615+ printf("%s\n", wk2); /* V1.17-A */
616+ }
617+ } else {
618+ if (vf) printf("## %s is already loaded. skip load.\n",wfile);
619+ if (na) { /* V1.07 */
620+ /* 既にファイルが存在する場合は、ファイル内部を解析しない */
621+ if (vf) printf("## and skip analyze.\n",wfile);
622+ --trace_level;
623+ return 0; /* V1.07 */
624+ } /* V1.07 */
625+ }
626+
627+
628+ /*
629+ * 取り出したファイル(wfile) がHTMLなら 内容を解析して、
630+ * GetURLData()をリカーシブコール
631+ *
632+ * 既に解析済みのものは解析しない
633+ * (トレース階層がリミットレベルの場合は解析済みリストに追加しない)
634+ */
635+ if ((suffck(wfile,".html") || suffck(wfile,".htm"))
636+ && ((trace_level >= trl+lvplus) || AddList(&donelist, wfile))) { /* V1.22-C */
637+ /* html && 未解析 => 内容解析 */
638+ if (AddList(&openlist, wfile) && (rfp = fopen(wfile,"r"))) {
639+ while (GetHREF(rfp,buf)) {
640+ dprintf("# get link data %s\n",buf);
641+ if (strstr(buf,HTTP_PREFIX)) {
642+ /* http://xxxx 形式 */
643+ port2 = 80; /* V1.11 */
644+ Url2HostPath(buf, host2, path2, &port2); /* V1.11-C */
645+ if (!strlen(host2) || !strcmp(host2,host)) {
646+ /* 自サイトならリンク先を取りに行く */
647+ GetURLData(host,port,path2);
648+ } else if (lv == 2 && suffck(wfile, suff)) {
649+ /* 自サイトでなくてもallow level 2 で指定ファイルなら
650+ * リンク先を取りに行く
651+ */
652+ GetURLData(host2,port2,path2); /* V1.11-C */
653+ } else if (lv >= 3) {
654+ /* 自サイトでなくてもallow level 3 以上なら
655+ * リンク先を取りに行く
656+ */
657+ GetURLData(host2,port2,path2); /* V1.11-C */
658+ } else {
659+ /* ホストが違うのでロードしない */
660+ if (vf) printf("## Skip load %s (other host)\n",buf);
661+ }
662+ } else if (strstr(buf,FTP_PREFIX)) {
663+ continue; /* V1.071-A */
664+ } else {
665+ /* http://指定なし */
666+ if (buf[0] == '/') {
667+ /* 自ホスト絶対パス */
668+ GetURLData(host,port,buf);
669+ } else if (!strcasecmp(buf,"mailto:")){
670+ /* "mailto:<name@mail.adr>" は無視 V1.03 */
671+ ;
672+ }else {
673+ /* 自ホスト相対パス */
674+ strcpy(wk,cwd); /* Base Dir */
675+ strcat(wk,buf); /* absolute path */
676+ DelDot2(wk);
677+ GetURLData(host,port,wk);
678+ }
679+ }
680+ }
681+ fclose(rfp);
682+ DelList(&openlist, wfile);
683+ }
684+ }
685+
686+ --trace_level;
687+ return 0;
688+
689+}
690+
691+/*
692+ * suffix check
693+ *
694+ * bufの終りがsufixであるかチェックする(大文字小文字無視)
695+ *
696+ * IN buf : check path
697+ * sufix : suffix
698+ * OUT ret : 1 ... match suffix
699+ * 0 ... no match suffix
700+ */
701+int suffck(char *buf, char *sufix)
702+{
703+ int len = strlen(buf);
704+ int len2 = strlen(sufix);
705+
706+ if (len < len2) {
707+ return 0;
708+ }
709+
710+ return (!strcasecmp(&buf[len-len2],sufix));
711+}
712+
713+/*
714+ * <...>のタグを取り出す
715+ *
716+ * IN fp : fopen("r")済みHTMLファイルポインタ
717+ * OUT buf : タグ"<....>"を返す
718+ * ret : buf タグ格納
719+ * 0 EOF
720+ */
721+char *GetTag(FILE *fp, char *buf)
722+{
723+ int i=0;
724+ int c=0;
725+
726+ i = 0;
727+ while (c != EOF && c != '<') c = getc(fp);
728+ if (c == EOF) return 0;
729+ while (c != EOF && c != '>') {
730+ buf[i++] = c;
731+ c = getc(fp);
732+ }
733+ buf[i] = '\0';
734+ return buf;
735+}
736+
737+/*
738+ * bufから<link.*href="url"> を見つけたら"src"の先頭ポインタを返す V1.22
739+ *
740+ *
741+ */
742+char *GetCssSrc(char *buf)
743+{
744+ char *pt;
745+
746+ if (!strstr(buf, "link ")) {
747+ if (!strstr(buf, "LINK ")) {
748+ return NULL;
749+ }
750+ }
751+ if (pt = strstr(buf, "href")) {
752+ return pt;
753+ }
754+ if (pt = strstr(buf, "HREF")) {
755+ return pt;
756+ }
757+ return NULL;
758+}
759+
760+/*
761+ * bufから<img.*src="url"> を見つけたら"src"の先頭ポインタを返す V1.18
762+ *
763+ *
764+ */
765+char *GetImgSrc(char *buf)
766+{
767+ char *pt;
768+
769+ if (!strstr(buf, "img ")) {
770+ if (!strstr(buf, "IMG ")) {
771+ return NULL;
772+ }
773+ }
774+ if (pt = strstr(buf, "src")) {
775+ return pt;
776+ }
777+ if (pt = strstr(buf, "SRC")) {
778+ return pt;
779+ }
780+ return NULL;
781+}
782+
783+/*
784+ * a href= または、img src=のリンク先をbufに返す
785+ *
786+ * img src=があったら、GetURLDataを呼ぶ
787+ *
788+ * IN fp : fopen("r")済みHTMLファイルポインタ
789+ *
790+ * OUT ret : buf リンクあり
791+ * 0 EOF
792+ */
793+char *GetHREF(FILE *fp, char *buf)
794+{
795+ int i = 0;
796+ char *pt;
797+ char *status;
798+ char wk[4096];
799+
800+ while (status = GetTag(fp,wk)) {
801+ if ((pt = GetImgSrc(wk))
802+ || (pt = GetCssSrc(wk)) /* V1.22 */
803+ || (pt = (char *)strstr(wk,"frame src")) /* V1.01 */
804+ || (pt = (char *)strstr(wk,"FRAME SRC")) /* V1.01 */
805+ || (pt = (char *)strstr(wk,"a href"))
806+ || (pt = (char *)strstr(wk,"A href"))
807+ || (pt = (char *)strstr(wk,"A HREF"))) {
808+ while (*pt != '"' && *pt != '\'' && *pt != '\0') pt++;/*V1.12*/
809+ pt++;
810+ while (*pt != '"' && *pt != '\'' && *pt != '\0') { /*V1.12*/
811+ buf[i++] = *pt;
812+ ++pt;
813+ }
814+ buf[i] = '\0';
815+ break;
816+ }
817+ }
818+ if (status == NULL) {
819+ return (char *)0;
820+ }
821+ dprintf("# find Link [%s]\n",buf);
822+ return buf;
823+}
824+
825+/*
826+ * 指定されたパスのディレクトリ部分のディレクトリを作成する
827+ *
828+ * path = /aaa/bbb/test.html
829+ *
830+ * mkdir -p ./aaa/bbb
831+ */
832+int mkdirp(char *path)
833+{
834+ char *pt;
835+ char cwd[260];
836+ char wk[260];
837+
838+ dprintf("# mkdirp=[%s]\n",path);
839+
840+ getcwd(cwd,sizeof(cwd));
841+
842+ dprintf("# pwd=[%s]\n",cwd);
843+
844+ /* path = /aaa/bbb/test.html */
845+ if (path[0] == '/') {
846+ strcpy(wk,&path[1]);
847+ } else {
848+ strcpy(wk,path);
849+ }
850+ pt = (char *)strrchr(wk,'/');
851+ if (!pt) {
852+ /* ディレクトリ部分なし */
853+ return 0;
854+ }
855+ *pt = '\0';
856+ /* wk = aaa/bbb */
857+
858+ pt = (char *)strtok(wk,"/");
859+ while (pt) {
860+ dprintf("# mkdir %s\n",pt);
861+ mkdir(pt, 0775);
862+ chdir(pt);
863+ pt = (char *)strtok(NULL,"/");
864+ }
865+
866+ chdir(cwd);
867+ return 0;
868+
869+}
870+
871+
872+/*
873+ * send data ファイル内の埋め込みオプションを取り込む。
874+ * コマンドの引数に設定されている場合は取り込まない。
875+ *
876+ * IN sendf : send data file
877+ * OUT host : HOST:で指定されたホスト名
878+ * port : PORT:で指定されたポート番号(文字列)
879+ * (注) host,portとも呼出時に長さが0で渡された場合のみ設定される
880+ *
881+ */
882+void get_file_opt(sendf,host,port)
883+char *sendf, *host, *port;
884+{
885+ FILE *fp;
886+ char buf[2048];
887+ int len;
888+
889+ if (!(fp = fopen(sendf,"r"))) {
890+ return;
891+ }
892+ while (fgets(buf,sizeof(buf),fp)) {
893+ /* 改行削除 */
894+ len = strlen(buf);
895+ if (buf[len-1] == 0x0a) {
896+ buf[len-1] = '\0';
897+ }
898+ if (!strncmp(buf,HOST,strlen(HOST)) && !strlen(host)) {
899+ strcpy(host,&buf[strlen(HOST)]);
900+ }
901+ if (!strncmp(buf,PORT,strlen(PORT)) && !strlen(port)) {
902+ strcpy(port,&buf[strlen(PORT)]);
903+ }
904+ if (strlen(host) && strlen(port)) {
905+ /* 両方設定された時点で終了 */
906+ break;
907+ }
908+ }
909+ fclose(fp);
910+}
911+
912+/*
913+ * clock1000()
914+ *
915+ * 1/PERSEC sec 単位の値をリターンする
916+ */
917+int clock1000()
918+{
919+ int code = 0;
920+#ifdef AIX
921+ struct tms buf;
922+
923+ code = times(&buf)*PERSEC/HZ;
924+#else
925+ struct timeval tv;
926+ struct timezone tz;
927+ gettimeofday(&tv,&tz);
928+
929+ code = tv.tv_sec*PERSEC+(tv.tv_usec)/(1000000/PERSEC);
930+#endif /* AIX */
931+ return code;
932+}
933+
934+#define SIZE 4096
935+/*
936+ * sockfd : input fd (socket)
937+ * fd : output fp
938+ */
939+void GET_DATA(fp, sockfd)
940+FILE *fp;
941+int sockfd;
942+{
943+ char c[SIZE];
944+ int size, all=0;
945+ struct timeval tv, tv2;
946+ unsigned int wk,wk2,diff;
947+
948+ if (vf >= 3) {
949+ gettimeofday(&tv,0);
950+ wk = tv.tv_sec*1000000 + tv.tv_usec;
951+ printf("start usec : %u\n",wk);
952+ }
953+
954+ while((size = read(sockfd, c, SIZE)) != 0) {
955+ fwrite(c,1,size,fp);
956+ /* c[size] = '\0'; */
957+ /* printf("%s",c); */
958+ /* fflush(stdout); */
959+ all += size;
960+ }
961+
962+ if (vf >= 3) {
963+ gettimeofday(&tv,0);
964+ wk2 = tv.tv_sec*1000000 + tv.tv_usec;
965+ diff = wk2-wk;
966+ if (diff <0 ) diff = -diff;
967+ printf(" end usec : %u\n",wk2);
968+ printf(" diff usec : %u\n",diff);
969+ printf("size = %d time = %.6fsec perf = %dKB/sec\n",
970+ all,
971+ (float)diff/1000000,
972+ (all*1000)/diff);
973+ }
974+}
975+
976+/*
977+ * listにpathがあるかチェックする
978+ *
979+ * OUT ret 0:すでにpathはlistにある
980+ * 1:listにpathを追加した
981+ *
982+ */
983+int AddList(filen_t **listpp, char *path)
984+{
985+ filen_t *wk, *wkold;
986+ wk = *listpp;
987+ wkold = (filen_t *)listpp;
988+ while (wk) {
989+ if (!strcmp(wk->fname,path)) {
990+ /* already open */
991+ dprintf("# already opend [%s]\n",path);
992+ return 0;
993+ }
994+ wkold = wk;
995+ wk = wk->next;
996+ }
997+ wk = (filen_t *)malloc(sizeof(filen_t));
998+ memset(wk,0,sizeof(filen_t));
999+ wkold->next = wk;
1000+ wk->fname = (char *)strdup(path);
1001+ return 1;
1002+}
1003+
1004+/*
1005+ * listからpathのあるエントリを削除する
1006+ *
1007+ */
1008+void DelList(filen_t **listpp, char *path)
1009+{
1010+ filen_t *wk, *wkold;
1011+ wk = *listpp;
1012+ wkold = (filen_t *)listpp;
1013+ while (wk) {
1014+ if (!strcmp(wk->fname,path)) {
1015+ wkold->next = wk->next;
1016+ free(wk->fname);
1017+ free(wk);
1018+ return;
1019+ }
1020+ wkold = wk;
1021+ wk = wk->next;
1022+ }
1023+ printf("# path(%s) not found in openlist\n",path);
1024+}
1025+
1026+/*
1027+ * listをすべて開放する
1028+ *
1029+ */
1030+void FreeList(filen_t **listpp)
1031+{
1032+ filen_t *wk, *wknext;
1033+ int cnt = 1;
1034+
1035+ wk = *listpp;
1036+ while (wk) {
1037+ if (vf >= 3) printf("# FreeList(%d:%s)\n", cnt, wk->fname);
1038+ wknext = wk->next;
1039+ free(wk->fname);
1040+ free(wk);
1041+ wk = wknext;
1042+ ++cnt;
1043+ }
1044+ *listpp = NULL;
1045+}
1046+
1047+/*
1048+ * path から、/../ /./を除いてきれいなパスにする
1049+ *
1050+ */
1051+void DelDot2(char *path)
1052+{
1053+ char *pt,*pt2;
1054+ if (pt = (char *)strstr(path,"/../")) {
1055+ pt2 = pt + strlen("/../"); /* pt2 : aaa/bbb/../Ibbb */
1056+ *pt = '\0'; /* path: aaa/bbb ../bbb */
1057+ pt = (char *)strrchr(path,'/'); /* pt : aaaI/bbb ../bbb */
1058+ pt++; /* pt : aaa/Ibbb ../bbb */
1059+ strcpy(pt,pt2);
1060+ DelDot2(path);
1061+ }
1062+ if (pt = (char *)strstr(path,"/./")) {
1063+ pt2 = pt + strlen("/./"); /* pt2 : aaa/bbb/./Ibbb */
1064+ pt++; /* pt : aaa/bbb/I./bbb */
1065+ strcpy(pt,pt2);
1066+ DelDot2(path);
1067+ }
1068+}
1069+
1070+/*
1071+ * 1行recv V1.11
1072+ * IN sockfd socket fd
1073+ * sz bufのサイズ
1074+ * OUT buf 読み込んだ1行(改行除く)
1075+ * ret 読み込んだ文字数(改行除く)
1076+ *
1077+ */
1078+int recv_oneline(int sockfd, char *buf, int sz)
1079+{
1080+ int i = 0;
1081+ int ret = 0;
1082+
1083+ while (i < (sz-1) && (ret = recv(sockfd,&buf[i],1,0))) {
1084+ if (buf[i++] == 0x0a) {
1085+ break;
1086+ }
1087+ }
1088+ buf[i] = '\0';
1089+
1090+ /* del CRLF */
1091+ if (buf[i-1] == 0x0a) {
1092+ buf[i-1] = '\0';
1093+ i--;
1094+ }
1095+ if (buf[i-1] == 0x0d) {
1096+ buf[i-1] = '\0';
1097+ i--;
1098+ }
1099+
1100+ dprintf("buf=[%s]\n",buf);
1101+ return i;
1102+}
1103+
1104+
1105+#ifdef _WIN32
1106+int gettimeofday(struct timeval *tv, struct timezone *tz)
1107+{
1108+ SYSTEMTIME syst;
1109+
1110+ //GetSystemTime(&syst); // UTC
1111+ GetLocalTime(&syst);
1112+ tv->tv_sec = syst.wHour * 3600 +
1113+ syst.wMinute *60 +
1114+ syst.wSecond;
1115+ tv->tv_usec = syst.wMilliseconds * 1000;
1116+ return 0;
1117+}
1118+#endif /* _WIN32 */
1119+
1120+/*
1121+ * イメージ等のファイルかどうかのチェック
1122+ *
1123+ * IN path path(URL)
1124+ * OUT ret 0: no image file
1125+ * 1: image file path
1126+ */
1127+int IsImgPath(char *path)
1128+{
1129+ int pos;
1130+
1131+ pos = strlen(path) - 4;
1132+ /* とりあえずこれだけが対象 */
1133+ if (!strcasecmp(&path[pos], ".jpg") ||
1134+ !strcasecmp(&path[pos-1], ".jpeg") ||
1135+ !strcasecmp(&path[pos], ".gif") ||
1136+ !strcasecmp(&path[pos], ".bmp") ||
1137+ !strcasecmp(&path[pos], ".pdf") ||
1138+ !strcasecmp(&path[pos], ".png")) {
1139+ return 1;
1140+ }
1141+ return 0;
1142+}
1143+
1144+/* vim:ts=8:sw=8
1145+ */
--- /dev/null
+++ b/welcome.c
@@ -0,0 +1,359 @@
1+/*
2+ * welcome.c
3+ *
4+ * クライアントからポートに接続があったら
5+ * 音を鳴らす
6+ *
7+ * 04/04/03 V1.00 by oga. (based miscserver.c)
8+ */
9+#include <stdio.h>
10+#include <stdlib.h>
11+#include <string.h>
12+#include <sys/types.h>
13+#include <sys/socket.h>
14+#include <sys/time.h>
15+#include <time.h>
16+#include <netinet/in.h>
17+#include <arpa/inet.h>
18+#include <fcntl.h>
19+#include <signal.h>
20+#include <errno.h>
21+#include <netdb.h> /* gethostbyaddr() */
22+
23+void PUT_DATA(int, int);
24+void GET_DATA(int, int);
25+void reapchild();
26+void memdump(FILE *, unsigned char *, int);
27+void print_host(struct in_addr sin_addr);
28+
29+#define DEFAULT_CHIME "/home/oga/Media/wavs/SE/eu_info.mp3"
30+
31+/* MP3ファイルの再生 */
32+void PlayMp3(char *snd_file)
33+{
34+ char command[2048];
35+
36+ sprintf(command, "mpg123 %s", snd_file);
37+ system(command);
38+}
39+
40+/* WAVファイルの再生 */
41+void PlayWav(char *snd_file)
42+{
43+ char command[2048];
44+
45+ sprintf(command, "play %s", snd_file);
46+ system(command);
47+}
48+
49+/* サウンドファイルの再生 */
50+void Play(char *snd_file)
51+{
52+ if (strlen(snd_file) > 4 && !strcasecmp(&snd_file[strlen(snd_file)-4], ".mp3")) {
53+ PlayMp3(snd_file);
54+ } else {
55+ PlayWav(snd_file);
56+ }
57+}
58+
59+#define SIZE 4096
60+void PUT_DATA(fd, newsockfd)
61+int fd;
62+int newsockfd;
63+{
64+ char c[SIZE];
65+ int size;
66+ while((size = read(fd, c, SIZE)) != 0)
67+ write(newsockfd, c,size);
68+}
69+
70+/*
71+ * get socket data and write to file
72+ *
73+ * IN : fd : 出力ファイル
74+ * sockfd : 入力ソケットディスクリプタ
75+ */
76+void GET_DATA(fd, sockfd)
77+int fd;
78+int sockfd;
79+{
80+ char c[SIZE];
81+ int size, all=0;
82+ struct timeval tv, tv2;
83+ unsigned int wk,wk2,diff;
84+
85+ gettimeofday(&tv,0);
86+ wk = tv.tv_sec*1000000 + tv.tv_usec;
87+ printf("start usec : %u\n",wk);
88+
89+ while((size = read(sockfd, c, SIZE)) != 0) {
90+ write(fd, c,size);
91+ /* c[size] = '\0'; */
92+ /* printf("%s",c); */
93+ /* fflush(stdout); */
94+ all += size;
95+ }
96+ gettimeofday(&tv,0);
97+ wk2 = tv.tv_sec*1000000 + tv.tv_usec;
98+ diff = wk2-wk;
99+ if (diff <0 ) diff = -diff;
100+ printf(" end usec : %u\n",wk2);
101+ printf(" diff usec : %u\n",diff);
102+ printf("size = %d time = %.6fsec perf = %dKB/sec\n",
103+ all,
104+ (float)diff/1000000,
105+ (all*1000)/diff);
106+}
107+
108+
109+/*
110+ * get socket data and store to buffer
111+ *
112+ * IN : sockfd : 入力ソケットディスクリプタ
113+ * buf : 格納バッファ
114+ * size : 格納バッファサイズ
115+ */
116+int GET_DATA2BUF(sockfd,buf,size)
117+int sockfd,size;
118+char *buf;
119+{
120+ int sz, all=0;
121+
122+ printf("start GET_DATA2BUF\n");
123+ while((sz = read(sockfd, &buf[all], size-all)) > 0) {
124+ printf(" read %d byte\n",sz);
125+ all += sz;
126+ }
127+ if (sz < 0) {
128+ perror("read");
129+ }
130+ printf(" return with %d byte\n",all);
131+ return all;
132+}
133+
134+void print_host(struct in_addr sin_addr)
135+{
136+ struct hostent *hostp;
137+ int i;
138+
139+ hostp = gethostbyaddr((char *)&sin_addr.s_addr,
140+ sizeof(sin_addr.s_addr),
141+ AF_INET);
142+
143+ /* print all hostname/aliases */
144+ /* print hostname */
145+ printf("## hostname : %s\n",hostp->h_name);
146+
147+ /* print aliases */
148+ i = 0;
149+ while (hostp->h_aliases[i]) {
150+ printf("## alias%d : %s\n",i+1,hostp->h_aliases[i]);
151+ i++;
152+ }
153+}
154+
155+void reapchild()
156+{
157+ wait(0);
158+ signal(SIGCLD,reapchild);
159+}
160+
161+/*
162+ * void memdump(fp, buf, size)
163+ *
164+ * bufから、size分を fp にヘキサ形式で出力する
165+ *
166+ * <出力例>
167+ * Location: +0 +4 +8 +C /0123456789ABCDEF
168+ * 00000000: 2f2a0a20 2a205265 76697369 6f6e312e //#. # Revision1.
169+ * 00000010: 31203936 2e30372e 30312074 616b6173 /1 96.07.01 takas
170+ * 00000020: 6869206b 61696e75 6d610a20 2a2f0a2f /hi kainuma. #/./
171+ *
172+ * IN fp : 出力ファイルポインタ (標準出力の場合はstdoutを指定)
173+ * buf : ダンプメモリ先頭アドレス
174+ * size : ダンプサイズ
175+ *
176+ */
177+void memdump(fp, buf, size)
178+FILE *fp;
179+unsigned char *buf;
180+int size;
181+{
182+ int c, xx, addr = 0, i;
183+ int f=0, f2=0;
184+ int kflag = 0; /* 漢字出力 */
185+ int pos = 0;
186+ char asc[17];
187+
188+ /* ヘッダ出力 */
189+ fprintf(fp,
190+ "Location: +0 +4 +8 +C /0123456789ABCDEF\n");
191+
192+ c = buf[pos++]; /* c = getc(infp); */
193+ while(pos <= size) {
194+ xx = 0;
195+ strcpy(asc," ");
196+ fprintf(fp,"%08x: ",addr);
197+ f = 0;
198+ while(pos <= size && xx < 16) {
199+ fprintf(fp,"%02x",c);
200+ if (c < 32) {
201+ if (f) {
202+ asc[xx] = c;
203+ if (c == 10 || c == 13) {
204+ asc[xx] = '.'; /* 暫定 */
205+ }
206+ } else {
207+ asc[xx] = '.';
208+ }
209+ f = 0;
210+ } else if (c > 127 ) {
211+ if (kflag) {
212+ if (f) {
213+ asc[xx] = c;
214+ f = 0;
215+ } else {
216+ asc[xx] = c;
217+ f = 1;
218+ }
219+ } else {
220+ asc[xx] = '.';
221+ }
222+ } else {
223+ asc[xx] = c;
224+ f = 0;
225+ }
226+ if (xx == 0 && f2) {
227+ asc[xx] = '.';
228+ f = 0;
229+ f2 = 0;
230+ }
231+ if ((xx % 4) == 3) fprintf(fp," ");
232+ ++xx;
233+ ++addr;
234+ c = buf[pos++]; /* c = getc(infp); */
235+ if (f == 1 && xx >= 16) {
236+ asc[xx++] = c;
237+ f = 0;
238+ f2 = 1;
239+ }
240+ }
241+ while (xx <16) {
242+ fprintf(fp," ");
243+ if ((xx % 4) == 3) fprintf(fp," ");
244+ ++xx;
245+ }
246+ asc[xx]='\0';
247+ fprintf(fp,"/%16s \n",asc);
248+ }
249+ fflush(stdout);
250+}
251+
252+void usage()
253+{
254+ printf("usage : welcome <port_number(59000)> [<snd_file>] \n");
255+ exit(1);
256+}
257+
258+int main(int a, char *b[])
259+{
260+ int sockfd,newsockfd,clilen,childpid;
261+ struct sockaddr_in cli_addr,serv_addr;
262+ int fd;
263+ int con = 0;
264+ int port = -1;
265+ unsigned char buf[4096];
266+ int sz;
267+ int closef = 0; /* close after recv */
268+ int nodump = 0; /* no data dump flag */
269+ int i;
270+ char *snd_file = NULL;
271+
272+ for (i = 1; i < a; i++) {
273+ if (!strcmp(b[i],"-h")) {
274+ usage();
275+ }
276+ if (port < 0) {
277+ port = atoi(b[i]);
278+ continue;
279+ }
280+ if (!snd_file) {
281+ snd_file = b[i];
282+ continue;
283+ }
284+ }
285+
286+ if (port < 0) {
287+ port = 59000;
288+ }
289+ if (snd_file == NULL) {
290+ snd_file = DEFAULT_CHIME;
291+ }
292+
293+ printf("wait for port %d (chime:%s)\n",port, snd_file);
294+
295+ if( (sockfd=socket(AF_INET, SOCK_STREAM, 0)) < 0 ){
296+ perror("socket");
297+ exit(-1);
298+ }
299+
300+ bzero((char *)&serv_addr, sizeof(serv_addr));
301+ serv_addr.sin_family = AF_INET;
302+ serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
303+ serv_addr.sin_port = htons(port);
304+
305+ if(bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0){
306+ perror("bind");
307+ exit(-1);
308+ }
309+
310+ signal(SIGCLD, reapchild);
311+
312+ printf("listen...\n");
313+ if(listen(sockfd, 5) < 0){
314+ perror("listen");
315+ exit(-1);
316+ }
317+ fflush(stdout);
318+
319+ while (1) {
320+ clilen = sizeof(cli_addr);
321+ newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr,
322+ &clilen);
323+ if(newsockfd < 0){
324+ if (errno == EINTR) {
325+ printf("accept interrupted\n");
326+ continue;
327+ }
328+ perror("accept");
329+ exit(-1);
330+ }
331+
332+ if (fork() == 0) {
333+ /* child */
334+ time_t tt;
335+ char timebuf[64];
336+
337+ close(sockfd);
338+
339+ time(&tt); /* current time */
340+ strftime(timebuf, sizeof(timebuf),
341+ "%y/%m/%d %H:%M:%S", localtime(&tt));
342+
343+ printf("%s accept No.%d pid=%d\n",timebuf, con, getpid());
344+ printf("## client addr=%s, port=%d\n", inet_ntoa(cli_addr.sin_addr), cli_addr.sin_port);
345+ print_host(cli_addr.sin_addr);
346+ fflush(stdout);
347+
348+ /* サーバ処理 */
349+ Play(snd_file);
350+
351+ close(newsockfd);
352+ printf("child pid=%d exit!\n\n",getpid());
353+ exit(0);
354+ }
355+ close(newsockfd);
356+ con++;
357+ }
358+}
359+
--- /dev/null
+++ b/which.c
@@ -0,0 +1,186 @@
1+/*
2+ * which <command_name> : 実行されるコマンドの位置を求める
3+ *
4+ * 1995.02.02 V0.10 Initial Revision by oga.
5+ * 1995.02.05 V0.20 add .r
6+ * 1995.07.08 V0.30 -all support.
7+ * 1995.10.30 V0.40 porting to DOS.
8+ * 1999.02.02 V0.41 add verbose
9+ * 2009.12.31 V0.42 add .dll and change PATH env buf length
10+ * 2012.12.25 V0.43 merge soruce
11+ *
12+ * compile option
13+ * X680x0 : -DX68K
14+ * DOS : -DX68K -DDOS
15+ */
16+
17+#include <stdio.h>
18+#include <sys/stat.h>
19+#include <stdlib.h>
20+#include <string.h>
21+
22+int vf = 0; /* V0.41 verbose */
23+
24+usage()
25+{
26+ printf("usage : which <command_name> [-a]\n");
27+ exit(1);
28+}
29+
30+main(a,b)
31+int a;
32+char *b[];
33+{
34+ char path[2048]; /* stat path V0.41-C */
35+ char *pathenvp;
36+ char pathp[4096]; /* ENV path V0.41-C */
37+ char *filename = NULL; /* filename V0.41-A */
38+ int pathlen, comsize;
39+ int i, j;
40+ struct stat statb;
41+ int allf = 0;
42+ int found = 0;
43+ int vf = 0; /* 1:verbose V0.41-A */
44+
45+ /* V0.41-C start */
46+ for (i = 1; i<a; i++) {
47+ if (!strcmp(b[i],"-h")) {
48+ usage();
49+ }
50+ if (!strcmp(b[i],"-a")) {
51+ allf = 1;
52+ continue;
53+ }
54+ if (!strcmp(b[i],"-v")) {
55+ ++vf;
56+ continue;
57+ }
58+ filename = b[i];
59+ }
60+
61+ if (filename == NULL) {
62+ usage();
63+ }
64+ /* V0.41-C end */
65+
66+#ifdef X68K
67+ strcpy(pathp,".;");
68+#ifdef DOS
69+ pathenvp="";
70+ pathenvp = (char *)getenv("PATH");
71+#else /* DOS */
72+ pathenvp = (char *)getenv("path");
73+#endif /* DOS */
74+
75+ if (vf) printf("PATH=%s\n",pathenvp);
76+
77+#else /* H3050 */
78+ pathp[0]='\0';
79+ pathenvp = (char *)getenv("PATH");
80+#endif
81+ if (pathenvp) strcat(pathp,pathenvp);
82+ pathlen = strlen(pathp);
83+
84+ if (vf) printf("path=%s\n",pathp);
85+
86+ i = 0;
87+
88+ while (i < pathlen) {
89+ j = 0;
90+#ifdef X68K
91+ while (pathp[i] != ';' && i < pathlen) /* path[] = "/usr/bin" */
92+#else
93+ while (pathp[i] != ':' && i < pathlen) /* path[] = "/usr/bin" */
94+#endif
95+ {
96+ path[j] = pathp[i];
97+ if (path[j] == '\\')
98+ path[j] = '/';
99+ ++i;
100+ ++j;
101+ }
102+ i++;
103+ path[j] = '\0';
104+
105+ if (vf) printf("path=[%s]\n",path);
106+
107+ strcat(path,"/"); /* path[] = "/usr/bin/" */
108+ strcat(path,filename); /* path[] = "/usr/bin/com" */
109+
110+ if (vf) printf("check path=%s\n",path);
111+#ifndef X68K
112+ if (stat(path,&statb) == 0) { /* path[] = "/usr/bin/com" */
113+ find(path);
114+ if (allf) found = 1;
115+ else exit(0);
116+ }
117+#else /* X68K */
118+ comsize = strlen(path);
119+#ifndef DOS
120+ strcpy(&path[comsize],".x"); /* path[] = "/usr/bin/com.x" */
121+ if (stat(path,&statb) == 0) {
122+ find(path);
123+ if (allf) found = 1;
124+ else exit(0);
125+ }
126+ strcpy(&path[comsize],".r"); /* path[] = "/usr/bin/com.r" */
127+ if (stat(path,&statb) == 0) {
128+ find(path);
129+ if (allf) found = 1;
130+ else exit(0);
131+ }
132+ strcpy(&path[comsize],".sh"); /* path[] = "/usr/bin/com.sh" */
133+ if (stat(path,&statb) == 0) {
134+ find(path);
135+ if (allf) found = 1;
136+ else exit(0);
137+ }
138+#endif /* !DOS */
139+ strcpy(&path[comsize],".bat"); /* path[] = "/usr/bin/com.bat"*/
140+ if (stat(path,&statb) == 0) {
141+ find(path);
142+ if (allf) found = 1;
143+ else exit(0);
144+ }
145+#ifdef DOS
146+ strcpy(&path[comsize],".exe"); /* path[] = "/usr/bin/com.exe"*/
147+ if (vf) printf("find [%s]\n",path);
148+ if (stat(path,&statb) == 0) {
149+ find(path);
150+ if (allf) found = 1;
151+ else exit(0);
152+ }
153+ strcpy(&path[comsize],".com"); /* path[] = "/usr/bin/com.com"*/
154+ if (stat(path,&statb) == 0) {
155+ find(path);
156+ if (allf) found = 1;
157+ else exit(0);
158+ }
159+
160+ /* V0.42-A start */
161+ strcpy(&path[comsize],".dll"); /* path[] = "/usr/bin/dllname.dll" */
162+ if (stat(path,&statb) == 0) {
163+ find(path);
164+ if (allf) found = 1;
165+ else exit(0);
166+ }
167+ /* V0.42-A end */
168+#endif /* DOS */
169+#endif /* X68K */
170+ }
171+ if (!found) {
172+ printf("command %s not found.\n",filename);
173+ exit(1);
174+ }
175+ exit(0);
176+}
177+
178+find(path)
179+char *path;
180+{
181+ printf("%s\n",path);
182+ if (vf) printf("### found [%s]\n",path);
183+ return 0;
184+}
185+
186+
--- /dev/null
+++ b/wwstat.c
@@ -0,0 +1,341 @@
1+/*
2+ * wwstat : httpd-logの統計情報をとり、結果をHTMLで出力する。
3+ *
4+ * 95/10/17 V0.10 by Hyper Halx.oga
5+ * 96/06/17 V0.11 add href
6+ * 96/07/08 V0.12 add hosts href
7+ * 96/07/12 V0.13 expand freq area
8+ * 01/09/19 V0.14 support Linux
9+ *
10+ */
11+
12+#include <stdio.h>
13+#include <stdlib.h>
14+#include <string.h>
15+
16+#define VER "0.14"
17+/* #define HTTPD_LOG "/usr/local/etc/httpd/httpd-log" */
18+#define HTTPD_LOG "/var/log/httpd/access_log"
19+#define MAX_HOST 5000
20+#define MAX_URL 10000
21+
22+#define dprintf if (vbf) printf
23+
24+struct name_t {
25+ int refc;
26+ char *namep;
27+};
28+
29+int nh=0,nu=0; /* host, urlの数 */
30+int vf = 0, hlf = 0, ulf = 0, vbf = 0;
31+char *vhost = (char *)0;
32+
33+void usage()
34+{
35+ printf("wwstat Ver %s by oga.\n",VER);
36+ printf("usage : wwstat [-v <hostname>] [-hl] [-ul] [log_file]\n");
37+ printf(" -v : 指定したホストを統計から除く\n");
38+ printf(" -hl : HOSTをリンクする\n");
39+ printf(" -ul : URLをリンクする\n");
40+ exit(1);
41+}
42+
43+main(a,b)
44+int a;
45+char *b[];
46+{
47+ int i, c;
48+ char *filename = HTTPD_LOG;
49+ char *hostp,*urlp;
50+ char buf[4096]; /* V1.04-C */
51+ char wk[128];
52+ FILE *fp;
53+ struct name_t *host;
54+ struct name_t *url;
55+
56+ for (i = 1; i< a ; i++) {
57+ if (!strcmp(b[i],"-h")) {
58+ usage();
59+ }
60+ if (!strcmp(b[i],"-v")) {
61+ if (i+1 >= a) {
62+ printf("-v require hostname\n");
63+ usage();
64+ }
65+ vhost = b[++i];
66+ vf = 1;
67+ continue;
68+ }
69+ if (!strcmp(b[i],"-hl")) {
70+ hlf = 1;
71+ continue;
72+ }
73+ if (!strcmp(b[i],"-ul")) {
74+ ulf = 1;
75+ continue;
76+ }
77+ if (!strcmp(b[i],"-vb")) {
78+ vbf = 1; /* verbose */
79+ continue;
80+ }
81+ filename = b[i]; /* - : stdin */
82+ }
83+
84+ host = (struct name_t *) malloc(sizeof(struct name_t)*MAX_HOST);
85+ url = (struct name_t *) malloc(sizeof(struct name_t)*MAX_URL);
86+ bzero(host,sizeof(struct name_t)*MAX_HOST);
87+ bzero(url,sizeof(struct name_t)*MAX_URL);
88+
89+ dprintf("fopen\n");
90+ if (!strcmp(filename, "-")) {
91+ fp = stdin;
92+ } else {
93+ if (!(fp = fopen(filename,"r"))) {
94+ printf("log_file=%s\n",filename);
95+ perror("wwstat");
96+ exit(1);
97+ }
98+ }
99+
100+ dprintf("readline\n");
101+ while((c = readline(fp,buf)) != EOF) {
102+ add_host_url(buf,host,url);
103+ }
104+
105+ dprintf("fclose\n");
106+ if (strcmp(filename, "-")) {
107+ fclose(fp);
108+ }
109+
110+ /* xsort_byname(host,nh); */
111+ xsort_byref(host,nh);
112+ xsort_byref(url,nu);
113+
114+ printf("<TITLE>Access frequency</TITLE>\n");
115+ printf("<H1>ホスト別 アクセス頻度</H1>\n");
116+ printf("<PRE>\n");
117+#ifdef LINEAR
118+ printf("---------------+-----+----+----+----+----+----+----+----+----+---\n");
119+ printf("Hostname/IPaddr| freq| 10 20 30 40 50 60 70 80回\n");
120+ printf("---------------+-----+----+----+----+----+----+----+----+----+---\n");
121+#else
122+ printf("---------------+-----+----+----+---+----+---+----+---+----+---\n");
123+ printf("Hostname/IPaddr| freq| 10 100 1000 10000 回\n");
124+ printf("---------------+-----+----+----+---+----+---+----+---+----+---\n");
125+#endif
126+ i=0;
127+ while(host[i].refc != 0) {
128+ if (hlf) {
129+ printf("<a href=%chttp://%s/%c>%-15s</a>|%5d|",'"',host[i].namep,'"',host[i].namep,host[i].refc);
130+ } else {
131+ printf("%-15s|%5d|",host[i].namep,host[i].refc);
132+ }
133+#ifdef LINEAR
134+ bzero(wk,sizeof(wk));
135+ strncpy(wk,"****|****|****|****|****|****|****|****|>>",host[i].refc/2);
136+ wk[(host[i].refc/2)+1]='\0';
137+ printf("%s\n",wk);
138+ printf("---------------+-----+----+----+----+----+----+----+----+----+---\n");
139+#else
140+ disp_bar(host[i].refc);
141+ printf("---------------+-----+----+----+---+----+---+----+---+----+---\n");
142+#endif
143+ ++i;
144+ }
145+ printf("<ADDRESS>Copyright (C) 1995, 2001, M.Ogasawara, All Rights Reserved.<ADDRESS>\n");
146+ printf("</PRE>\n");
147+ printf("<HR>\n");
148+ printf("<HR>\n");
149+ printf("<H1>URL別 アクセス頻度</H1>\n");
150+ printf("<PRE>\n");
151+ i=0;
152+ while(url[i].refc != 0) {
153+ if (ulf) {
154+ printf("%5d <a href=%c%s%c>%s</a>\n",url[i].refc,
155+ 34,url[i].namep,34,url[i].namep);
156+ } else {
157+ printf("%5d %s\n",url[i].refc,url[i].namep);
158+ }
159+ ++i;
160+ }
161+ printf("</PRE>\n");
162+
163+}
164+int readline(fp,buf)
165+FILE *fp;
166+char *buf;
167+{
168+ int c; /* V1.04-C */
169+ int i = 0;
170+ int first = 1;
171+
172+ dprintf("readline start\n");
173+ c = getc(fp);
174+ while (c != '\n' && c != EOF) {
175+ if (vf) {
176+ putchar(c);
177+ fflush(stdout);
178+ }
179+ if (i < 128) {
180+ buf[i++] = c;
181+ }
182+ c = getc(fp);
183+ }
184+ buf[i] = '\0';
185+#ifdef DEBUG
186+ printf("LINE = %s\n",buf);
187+#endif
188+ dprintf("readline end\n");
189+ return c;
190+}
191+
192+/*
193+ * n個の配列fileにポイントされている文字列を並べ変える。
194+ *
195+ * V1.00 by oga.
196+ */
197+xsort_byname(file,n)
198+struct name_t *file;
199+int n;
200+{
201+ char *wk;
202+ int wk2;
203+ int i,j;
204+
205+ for (i=1; i<n; i++) {
206+ for (j=0;j<n-i;j++) {
207+ if (strcmp(file[j].namep,file[j+1].namep) > 0 ) {
208+ wk = file[j].namep;
209+ file[j].namep = file[j+1].namep;
210+ file[j+1].namep = wk;
211+ wk2 = file[j].refc;
212+ file[j].refc = file[j+1].refc;
213+ file[j+1].refc = wk2;
214+ }
215+ }
216+ }
217+}
218+xsort_byref(file,n)
219+struct name_t *file;
220+int n;
221+{
222+ char *wk;
223+ int wk2;
224+ int i,j;
225+
226+ for (i=1; i<n; i++) {
227+ for (j=0;j<n-i;j++) {
228+ if (file[j].refc < file[j+1].refc ) {
229+ wk = file[j].namep;
230+ file[j].namep = file[j+1].namep;
231+ file[j+1].namep = wk;
232+ wk2 = file[j].refc;
233+ file[j].refc = file[j+1].refc;
234+ file[j+1].refc = wk2;
235+ }
236+ }
237+ }
238+}
239+
240+int add_host_url(buf,host,url)
241+char *buf;
242+struct name_t *host,*url;
243+{
244+ char buf2[4096];
245+
246+ dprintf("add_host_url start\n");
247+ if (getword(buf,1,buf2)) {
248+ printf("host entry not found!\n");
249+ } else {
250+ nh += add_ent(host,buf2);
251+ }
252+
253+ if (getword(buf,7,buf2)) {
254+ printf("url entry not found!\n");
255+ } else {
256+ nu += add_ent(url,buf2);
257+ }
258+ dprintf("add_host_url end\n");
259+}
260+
261+/*
262+ *
263+ * out : 0:新エントリ追加無し 1:新エントリ追加
264+ */
265+int add_ent(host,name)
266+struct name_t *host;
267+char *name;
268+{
269+ int i=0;
270+ int hit=0;
271+
272+ dprintf("add_ent start\n");
273+ while (host[i].refc != 0) {
274+ if (!strcmp(host[i].namep,name)) {
275+ host[i].refc++;
276+ return 0;
277+ }
278+ i++;
279+ }
280+
281+ dprintf("add_ent 2 %s/%s\n", name, vhost);
282+ /* -v host? */
283+ if (vf && !strcmp(name,vhost)) return 0;
284+
285+ dprintf("add_ent 3\n");
286+ /* new entry */
287+ host[i].refc++ ;
288+ host[i].namep=(char *)malloc(strlen(name)+1);
289+ strcpy(host[i].namep,name);
290+
291+ dprintf("add_ent end\n");
292+ return 1;
293+}
294+
295+int getword(inbuf,n,outbuf)
296+char *inbuf,*outbuf;
297+int n;
298+{
299+ int i = 0, ii = 0;
300+ int ret = 1;
301+ int j;
302+
303+ dprintf("getword start\n");
304+ for (j=1 ; j<=n; j++) {
305+ while (inbuf[i] == ' ' || inbuf[i] == '\t') ++i;
306+ if (j != n) {
307+ while (inbuf[i] != 0 && inbuf[i] != ' ' && inbuf[i] != '\t') ++i;
308+ } else {
309+ while (inbuf[i] != 0 && inbuf[i] != ' ' && inbuf[i] != '\t') {
310+ outbuf[ii++]=inbuf[i++];
311+ outbuf[ii]='\0';
312+ ret = 0;
313+ }
314+ }
315+ if (!inbuf[i]) break;
316+ }
317+
318+ dprintf("getword end\n");
319+ return ret;
320+}
321+
322+disp_bar(val)
323+int val;
324+{
325+ int i, j=0;
326+ int ff=0;
327+
328+ while (val > 10) {
329+ j += 9;
330+ val /= 10;
331+ }
332+ j += val;
333+ for (i = 1; i <= j; i++)
334+ if (ff && (i % 9) == 1) {
335+ printf("|");
336+ } else {
337+ ff = 1;
338+ printf("*");
339+ }
340+ printf("\n");
341+}
--- /dev/null
+++ b/xalloc.c
@@ -0,0 +1,70 @@
1+/*
2+ * xalloc [delta<100> KB] : 確保出来る最大のメモリを確保し、アクセスする。
3+ *
4+ * delta : mallocリトライ時の減少サイズ
5+ *
6+ * 1995.03.28 V1.00 by hyper halx.oga
7+ */
8+#include <stdio.h>
9+#include <stdlib.h>
10+#include <string.h>
11+#include <signal.h>
12+#include "cur.h"
13+
14+#define DELTA 1000
15+#define MAX_MEM 700000*1024
16+
17+void SigProc(int sig)
18+{
19+ printf("signal = %d\n", sig);
20+ if (sig == SIGINT) exit(1);
21+}
22+
23+main(a,b)
24+int a;
25+char *b[];
26+{
27+ int delta, size = MAX_MEM, i;
28+ char *adr,buf[100];
29+
30+ for (i = 0; i<=NSIG; i++) {
31+ signal(i, SigProc);
32+ }
33+
34+ if (a > 1) {
35+ if (strcmp(b[1],"-h") == 0) {
36+ printf("usage : xalloc [delta<100> KB]\n");
37+ return 1;
38+ }
39+ delta = atoi(b[1]) * 1024;
40+ } else {
41+ delta = DELTA * 1024;
42+ }
43+ cls();
44+ while ((adr = malloc(size)) == 0) {
45+ size -= delta;
46+ locate(1,1);
47+ printf("alloc size =%6d KB\n",size/1024);
48+ }
49+ while (1) {
50+ locate(1,2);
51+ printf(" ");
52+ locate(1,2);
53+ printf("Access allocated memory! Enter 'y' => ");
54+ scanf("%s",buf);
55+ if (strcmp(buf,"y") == 0) {
56+ locate(1,3);
57+ printf("in access... \n");
58+ for (i=0; i<size; i+=4)
59+ adr[i] = 1;
60+ locate(1,3);
61+ printf(" \n");
62+ } else {
63+ break;
64+ }
65+ }
66+
67+ printf("free allocated memory (size = %d KB)\n",size/1024);
68+ free(adr);
69+ return 0;
70+}
--- /dev/null
+++ b/xmem.c
@@ -0,0 +1,650 @@
1+/*
2+ * xmem : メモリの使用状況を表示
3+ *
4+ * V0.10 96.08.31 by Hyper Halx.f oga.
5+ * V0.20 97.02.14 Support Linux2.0.X "cached:"
6+ * V0.21 97.05.16 Support HI-UX/WE2 flag is HIUX
7+ * V0.30 97.06.07 change out lokking
8+ * V0.31 99.05.07 delete MB when over 64MB
9+ * V0.32 01.02.12 support every 20M,50M scale
10+ * V0.33 01.10.11 support -title option
11+ * V0.34 05.09.11 support Linux2.6.X
12+ *
13+ */
14+
15+#include <X11/Xlib.h>
16+#include <X11/Xutil.h>
17+#include <stdio.h>
18+#include <string.h>
19+#include <math.h>
20+#include <unistd.h>
21+#include <errno.h>
22+
23+#define VER "Ver 0.34"
24+#define S_MEM "Memory"
25+#define S_SWAP "Swap"
26+
27+/* constants */
28+#define RM 10 /* right margine */
29+#define TM 5 /* top margine */
30+#define OFFS 45 /* string area */
31+
32+unsigned long MyColor();
33+void get_memdata();
34+
35+#ifdef HIUX
36+typedef struct _MEMORYSTATUS {
37+ unsigned int dwLength; /* not used on UNIX */
38+ unsigned int dwMemoryLoad; /* not used on UNIX */
39+ unsigned int dwTotalPhys; /* 全 物理メモリ */
40+ unsigned int dwAvailPhys; /* 空き物理メモリ */
41+ unsigned int dwTotalPageFile; /* 全 スワップ容量 */
42+ unsigned int dwAvailPageFile; /* 空きスワップ容量 */
43+ unsigned int dwTotalVirtual; /* not used on UNIX */
44+ unsigned int dwAvailVirtual; /* not used on UNIX */
45+} MEMORYSTATUS; /* for GlobalMemoryStatus */
46+
47+void GlobalMemoryStatus(MEMORYSTATUS *);
48+int ExecOpenStdout(char *, int *);
49+int ReadLine(char *, int , int );
50+char *get_item(char *, char *, int, char *);
51+#endif /* HIUX */
52+
53+typedef struct mem {
54+ int total; /* total memory size <KB> */
55+ int used; /* used memory size <KB> */
56+ int free; /* free memory size <KB> */
57+ int shared; /* shared memory size <KB> */
58+ int buf; /* filesystem used cache size <KB> */
59+ int cache; /* cache size(V0.20 for Linux 2.0.X)*/
60+ int swap_total; /* total swap size <KB> */
61+ int swap_used; /* used swap size <KB> */
62+ int swap_free; /* free swap size <KB> */
63+} mem_t;
64+
65+/*
66+union {
67+ XEvent report;
68+ XKeyEvent key;
69+} report;
70+*/
71+XEvent report;
72+
73+main(a,b)
74+int a;
75+char *b[];
76+{
77+ Display *d;
78+ Window w;
79+ GC gc_use, gc_buf, gc_free,gc_black, gc_scale, gc_cache, gc_str;
80+ XSetWindowAttributes att;
81+ unsigned long black, cuse, cbuf, cfree, cscale, ccache, cstr;
82+ int i;
83+ int x_size = 0, y_size = 0; /* current window size */
84+ int x_home = 10, y_home = 10;
85+ int x0, y0;
86+ int xbuf, xused, xfree, xcache;
87+ int xsused, xsfree;
88+#ifdef HIUX
89+ int wait = 1; /* 5sec */
90+#else /* HIUX */
91+ int wait = 1; /* 1sec */
92+#endif /* HIUX */
93+ int width;
94+ char name[128],wk[128];
95+ char title[512]; /* -title V0.33 */
96+ char *pt;
97+ mem_t mem;
98+ int vf = 0; /* verbose flag */
99+ int UNIT = 0; /* 1 scale */
100+
101+ strcpy(title, ""); /* V0.33-A */
102+
103+ d = XOpenDisplay(NULL);
104+
105+ for (i = 1; i<a ; i++) {
106+ if (!strncmp(b[i],"-h",2)) {
107+ printf("usage : xmem [-update <time>] [-geometry <X>x<Y>+<X>+<Y>]\n");
108+ printf(" [-scale <scale_width>]\n");
109+ printf(" [-title <title>\n");
110+ exit(1);
111+ }
112+ if (!strncmp(b[i],"-g",2) && a > i) {
113+ strcpy(name,b[++i]);
114+ if (pt = strtok(name,"x")) x_size = atoi(pt);
115+ if (pt = strtok(NULL,"+")) y_size = atoi(pt);
116+ if (pt = strtok(NULL,"+")) x_home = atoi(pt);
117+ if (pt = strtok(NULL,"+")) y_home = atoi(pt);
118+ }
119+ if (!strncmp(b[i],"-u",2) && a > i) {
120+ wait = atoi(b[++i]); /* update time */
121+ }
122+ if (!strncmp(b[i],"-s",2) && a > i) {
123+ UNIT = atoi(b[++i]); /* scale width */
124+ }
125+ if (!strncmp(b[i],"-title",6) && a > i) {
126+ strcpy(title, b[++i]); /* title V0.33-A */
127+ }
128+ if (!strncmp(b[i],"-v",2) && a > i) {
129+ vf = 1; /* verbose */
130+ }
131+ }
132+
133+ get_memdata(&mem);
134+ /* mem.total = 8*1024; */
135+ if (!UNIT) {
136+ UNIT = (250 - OFFS - RM)/((mem.total-1)/10240 + 1) ;
137+ if (UNIT > 100) UNIT=100;
138+ }
139+ if (!x_size) {
140+ i = (mem.total-1)/10240 + 1;
141+ if (i < 2) i = 2;
142+ x_size = OFFS + i * UNIT + RM;
143+ }
144+ if (!y_size) {
145+ y_size = 55+TM;
146+ }
147+ if (vf) printf("mem.total=%d, x_size=%d, UNIT=%d\n",mem.total,x_size,UNIT);
148+
149+ cuse = MyColor(d,"red");
150+ cbuf = MyColor(d,"green");
151+ cfree = MyColor(d,"blue");
152+ cscale = MyColor(d,"white");
153+ ccache = MyColor(d,"yellow");
154+ cstr = MyColor(d,"yellow");
155+ black = MyColor(d,"Black");
156+
157+ w = XCreateSimpleWindow(d, RootWindow (d,0),
158+ x_home,y_home, /* home x,y */
159+ x_size,y_size, /* window size x,y */
160+ 1, /* border_width */
161+ 1, /* border */
162+ 0 ); /* background */
163+
164+ att.override_redirect = 0; /* Window Manager 介入あり ... 0 */
165+ /* なし ... 1 */
166+
167+ XChangeWindowAttributes(d,w,CWOverrideRedirect,&att);
168+ XMapWindow(d,w);
169+
170+ gc_use = XCreateGC(d,w,0,0); /* create gc */
171+ gc_buf = XCreateGC(d,w,0,0); /* create gc */
172+ gc_free = XCreateGC(d,w,0,0); /* create gc */
173+ gc_scale = XCreateGC(d,w,0,0); /* create gc */
174+ gc_cache = XCreateGC(d,w,0,0); /* create gc */
175+ gc_str = XCreateGC(d,w,0,0); /* create gc */
176+ gc_black = XCreateGC(d,w,0,0); /* create gc */
177+
178+ XSetForeground(d,gc_use ,cuse); /* set color to gc */
179+ XSetForeground(d,gc_buf ,cbuf); /* set color to gc */
180+ XSetBackground(d,gc_buf ,black); /* set back color to gc */
181+ XSetForeground(d,gc_free ,cfree); /* set color to gc */
182+ XSetForeground(d,gc_scale,cscale); /* set color to gc */
183+ XSetForeground(d,gc_cache,ccache); /* set color to gc */
184+ XSetBackground(d,gc_scale,black); /* set back color to gc */
185+ XSetForeground(d,gc_str ,cstr); /* set color to gc */
186+ XSetBackground(d,gc_str ,black); /* set back color to gc */
187+ XSetForeground(d,gc_black,black); /* set color to gc */
188+
189+ if (strlen(title)) {
190+ sprintf(name,"%s - xmem %s",title, VER);
191+ } else {
192+ sprintf(name,"xmem %s",VER);
193+ }
194+ XStoreName(d,w,name);
195+ XSelectInput(d,w, ButtonPressMask|ExposureMask);
196+
197+ while (1){
198+ get_memdata(&mem);
199+
200+ y0 = (y_size-TM)/7;
201+ width = (y_size-TM)*2/7;
202+
203+ xbuf = (UNIT * mem.buf)/10240;
204+ xcache = (UNIT * mem.cache)/10240;
205+ xused = (UNIT * mem.used)/10240 - xbuf - xcache;
206+ xfree = (UNIT * mem.free)/10240;
207+
208+ xsused = (UNIT * mem.swap_used)/10240;
209+ xsfree = (UNIT * mem.swap_free)/10240;
210+
211+ /* disp mem data */
212+ XFillRectangle(d,w,gc_use, OFFS, y0+TM,xused,width);
213+ XFillRectangle(d,w,gc_cache,OFFS+xused, y0+TM,xcache,width);
214+ XFillRectangle(d,w,gc_buf, OFFS+xused+xcache, y0+TM,xbuf, width);
215+ XFillRectangle(d,w,gc_free, OFFS+xused+xcache+xbuf,y0+TM,xfree,width);
216+ if (mem.cache) {
217+ /* Linux 2.0.X format */
218+ sprintf(wk,"Memory (%.1fM/%.1fM/%.1fM/%.1fM) ",
219+ (float)(mem.used-mem.buf-mem.cache)/1024,
220+ (float)mem.cache/1024,
221+ (float)mem.buf /1024,
222+ (float)mem.free /1024);
223+ } else {
224+#ifdef HIUX
225+ /* HIUX format */
226+ sprintf(wk,"Memory (%.1fM/%.1fM) ",
227+ (float)mem.used /1024,
228+ (float)mem.free /1024);
229+#else /* HIUX */
230+ /* Linux 1.2.13 format */
231+ sprintf(wk,"Memory (%.1fM/%.1fM/%.1fM) ",
232+ (float)(mem.used-mem.buf-mem.cache)/1024,
233+ (float)mem.buf /1024,
234+ (float)mem.free /1024);
235+#endif /* HIUX */
236+ }
237+#ifdef V020
238+ XDrawImageString(d, w, gc_scale,
239+ OFFS+xused+xcache+xbuf+xfree+5, y0*3-3, wk, strlen(wk));
240+#else /* V030 */
241+ XDrawImageString(d, w, gc_str,
242+ 5, y0*3-3+TM, S_MEM, strlen(S_MEM));
243+#endif /* V020 */
244+
245+ /* disp swap data */
246+ XFillRectangle(d,w,gc_use,OFFS,y0*4+TM,xsused,width);
247+ XFillRectangle(d,w,gc_free,OFFS+xsused,y0*4+TM,xsfree,width);
248+ sprintf(wk,"Swap (%.1fM/%.1fM)",
249+ (float)mem.swap_used/1024,
250+ (float)mem.swap_total/1024);
251+#ifdef V020
252+ XDrawImageString(d,w,gc_scale,OFFS+xsused+xsfree+5,y0*6,
253+ wk,strlen(wk));
254+#else /* V030 */
255+ XDrawImageString(d, w, gc_str,
256+ 5, y0*6+TM, S_SWAP, strlen(S_SWAP));
257+#endif /* V020 */
258+
259+ /* 目盛 */
260+ for (i = 0; i<100; ++i) {
261+#ifdef V020
262+ XFillRectangle(d,w,gc_scale,
263+ OFFS+UNIT*i,
264+ y0*3+y0/4+1,
265+ 2,
266+ y0/2);
267+#else /* V030 */
268+ XFillRectangle(d,w,gc_black,
269+ OFFS+UNIT*(i+1),
270+ y0+TM,
271+ 1,
272+ y0*6+TM);
273+
274+ if (mem.total/1024 <= 64) { /* V0.31 */
275+ sprintf(wk,"%dM",(i+1)*10); /* V0.33 */
276+ } else {
277+ sprintf(wk,"%d",(i+1)*10);
278+ }
279+
280+ /* V0.32-A start */
281+ if (UNIT < 10) {
282+ if (((i+1) % 5) != 0) continue;
283+ } else if (UNIT < 20) {
284+ if (((i+1) % 2) != 0) continue;
285+ }
286+ /* V0.32-A end */
287+
288+ XDrawImageString(d, w, gc_scale,
289+ OFFS+UNIT*(i+1)-8, 10, wk, strlen(wk));
290+
291+#endif /* V020 */
292+ }
293+
294+ XFlush(d);
295+
296+ /* 画面をクリックされたら */
297+ if (XCheckMaskEvent(d,ButtonPressMask,&report) == True) {
298+ printf("xmem %s by Moritaka Ogasawara.\n",VER);
299+ }
300+
301+ /* リサイズ */
302+ if (XCheckMaskEvent(d,ExposureMask,&report) == True) {
303+ Window root;
304+ int x,y;
305+ unsigned int width,height, border, depth;
306+
307+ XGetGeometry(d,w,&root,&x,&y,&width,&height,&border,&depth);
308+ if (x_size != width || y_size != height) {
309+ x_size = width;
310+ y_size = height;
311+ XClearWindow(d,w);
312+ }
313+ }
314+
315+ sleep(wait);
316+ }
317+}
318+
319+unsigned long MyColor(display,color)
320+Display *display;
321+char *color;
322+{
323+ Colormap cmap;
324+ XColor c0,c1;
325+ int code;
326+
327+ cmap = DefaultColormap(display,0);
328+
329+ code = XAllocNamedColor(display,cmap,color,&c1,&c0);
330+ if (code)
331+ return(c1.pixel);
332+ else
333+ return(-1);
334+}
335+
336+#ifdef HIUX
337+/*
338+ * get memory information from /etc/sysinfo command for HIUX
339+ *
340+ */
341+void get_memdata(mem)
342+mem_t *mem;
343+{
344+ int *fd;
345+ char buf[1024];
346+ char *pt;
347+ FILE *fp;
348+ MEMORYSTATUS memst;
349+
350+ GlobalMemoryStatus(&memst);
351+ mem->total = memst.dwTotalPhys/1024;
352+ mem->free = memst.dwAvailPhys/1024;
353+ mem->used = (mem->total - mem->free);
354+ mem->shared = 0;
355+ mem->buf = 0;
356+ mem->swap_total = memst.dwTotalPageFile/1024;
357+ mem->swap_free = memst.dwAvailPageFile/1024;
358+ mem->swap_used = mem->swap_total - mem->swap_free;
359+
360+#ifdef DEBUG
361+ printf("Memory : %d %d %d %d %d %d\n",mem->total,mem->used,
362+ mem->free,mem->shared,mem->buf,mem->cache);
363+ printf("Swap : %d %d %d\n",mem->swap_total,mem->swap_used,mem->swap_free);
364+#endif
365+}
366+
367+#else /* Linux */
368+/*
369+ * get memory information from /proc/meminfo for Linux
370+ *
371+ * unit is KB
372+ */
373+void get_memdata(mem)
374+mem_t *mem;
375+{
376+ FILE *fp;
377+ char buf[1024];
378+ char *pt;
379+
380+ if (!(fp = fopen("/proc/meminfo","r"))) {
381+ perror("fopen /proc/meminfo");
382+ exit(1);
383+ }
384+ fgets(buf,sizeof(buf),fp); /* skip header */
385+
386+ if (strstr(buf, "total:")) {
387+ /* Linux 2.0〜2.4 */
388+ fgets(buf,sizeof(buf),fp); /* read memdata */
389+ strtok(buf," "); /* skip Mem: */
390+ mem->total = atoi(strtok(NULL," "))/1024;
391+ mem->used = atoi(strtok(NULL," "))/1024;
392+ mem->free = atoi(strtok(NULL," "))/1024;
393+ mem->shared = atoi(strtok(NULL," "))/1024;
394+ mem->buf = atoi(strtok(NULL," "))/1024;
395+ if (pt = strtok(NULL," ")) { /* V0.20 */
396+ mem->cache = atoi(pt)/1024;
397+ } else {
398+ mem->cache = 0;
399+ }
400+
401+ fgets(buf,sizeof(buf),fp); /* read swapdata */
402+ strtok(buf," "); /* skip Mem: */
403+ mem->swap_total = atoi(strtok(NULL," "))/1024;
404+ mem->swap_used = atoi(strtok(NULL," "))/1024;
405+ mem->swap_free = atoi(strtok(NULL," "))/1024;
406+ } else {
407+ /* Linux 2.6〜 */
408+ mem->shared = 0;
409+ do {
410+ if (!strncmp(buf, "MemTotal:", strlen("MemTotal:"))) {
411+ mem->total = atoi(&buf[strlen("MemTotal:")]); /* KB */
412+ continue;
413+ } else if (!strncmp(buf, "MemFree:", strlen("MemFree:"))) {
414+ mem->free = atoi(&buf[strlen("MemFree:")]); /* KB */
415+ continue;
416+ } else if (!strncmp(buf, "Buffers:", strlen("Buffers:"))) {
417+ mem->buf = atoi(&buf[strlen("Buffers:")]); /* KB */
418+ continue;
419+ } else if (!strncmp(buf, "Cached:", strlen("Cached:"))) {
420+ mem->cache = atoi(&buf[strlen("Cached:")]); /* KB */
421+ continue;
422+ } else if (!strncmp(buf, "SwapTotal:", strlen("SwapTotal:"))) {
423+ mem->swap_total = atoi(&buf[strlen("SwapTotal:")]); /* KB */
424+ continue;
425+ } else if (!strncmp(buf, "SwapFree:", strlen("SwapFree:"))) {
426+ mem->swap_free = atoi(&buf[strlen("SwapFree:")]); /* KB */
427+ continue;
428+ }
429+ } while (fgets(buf, sizeof(buf), fp));
430+
431+ mem->used = mem->total - mem->free;
432+ mem->swap_used = mem->swap_total - mem->swap_free;
433+ }
434+
435+ fclose(fp);
436+
437+#ifdef DEBUG
438+ printf("%d %d %d %d %d %d\n",mem->total,mem->used,
439+ mem->free,mem->shared,mem->buf,mem->cache);
440+ printf("%d %d %d\n",mem->swap_total,mem->swap_used,mem->swap_free);
441+#endif
442+}
443+#endif /* Linux */
444+
445+#ifdef HIUX
446+/*
447+ * GlobalMemoryStatus(mem) ... Win32 GlobalMemoryStatus Emulation A3UAD001
448+ *
449+ * IN mem : MEMORYSTATUS *
450+ */
451+void GlobalMemoryStatus(MEMORYSTATUS *mem)
452+{
453+ int sysfd; /* file descriptor */
454+ int st; /* err code */
455+ char *phys = "physical memory is"; /* 物理メモリ */
456+ char *freem = "free memory"; /* 空きメモリ */
457+ char buf[2048];
458+ char wk[2048];
459+
460+ memset(mem,0,sizeof(MEMORYSTATUS));
461+
462+ /*
463+ * メモリ情報取得 (/etc/sysdef)
464+ */
465+ if ((sysfd = ExecOpenStdout("/etc/sysdef" , &st)) < 0) {
466+ /* /etc/sysdef 起動失敗 */
467+ printf("/etc/sysdef execute error. code=%d",st);
468+ } else {
469+ /* /etc/sysdef 起動成功 */
470+ while(ReadLine(buf,sizeof(buf),sysfd) >= 0) {
471+ if (strstr(buf,phys)) {
472+ if (get_item(buf," ",4,wk)) {
473+ mem->dwTotalPhys = ((unsigned int)atoi(wk)) * 1024;
474+ }
475+ } else if (strstr(buf,freem)) {
476+ if (get_item(buf," ",10,wk)) {
477+ mem->dwAvailPhys = ((unsigned int)atoi(wk)) * 1024;
478+ }
479+ }
480+ }
481+ if (st = close(sysfd)) {
482+ printf("/etc/sysdef stdout close error. code=%d",st);
483+ }
484+ }
485+
486+ /*
487+ * スワップ情報取得 (/etc/swapinfo)
488+ */
489+ if ((sysfd = ExecOpenStdout("/etc/swapinfo" , &st)) < 0) {
490+ /* /etc/swapinfo 起動失敗 */
491+ printf("/etc/swapinfo execute error. code=%d",st);
492+ return;
493+ } else {
494+ /* /etc/swapinfo 起動成功 */
495+ while(ReadLine(buf,sizeof(buf),sysfd) >= 0) {
496+ if (!strncmp(buf,"dev", strlen("dev")) ||
497+ !strncmp(buf,"fs", strlen("fs")) ||
498+ !strncmp(buf,"localfs",strlen("localfs")) ||
499+ !strncmp(buf,"network",strlen("network")) ) {
500+ if (get_item(buf," ",2,wk)) {
501+ /* AVAIL */
502+ mem->dwTotalPageFile += ((unsigned int)atoi(wk)) * 1024;
503+ }
504+ if (get_item(buf," ",4,wk)) {
505+ /* FREE */
506+ mem->dwAvailPageFile += ((unsigned int)atoi(wk)) * 1024;
507+ }
508+ }
509+ }
510+ if (st = close(sysfd)) {
511+ printf("/etc/swapinfo stdout close error. code=%d", st);
512+ }
513+ }
514+
515+ return;
516+}
517+/*
518+ * ExecOpenStdout(path) A3UAD001
519+ *
520+ * pathで指定されたコマンドを実行し、そのコマンドの標準出力の
521+ * ファイルディスクリプタを返す。
522+ *
523+ * IN path : 実行するコマンドのフルパス
524+ * OUT ret : 成功 : 実行したコマンドの標準出力のファイルディスクリプタ。
525+ * 失敗 : -1
526+ * err : 失敗時、errnoが設定される
527+ *
528+ * (注) ExecOpenStdout()が成功した場合、呼び出し側で返された
529+ * ファイルディスクリプタをclose()すること。
530+ */
531+int ExecOpenStdout(char *path , int *err)
532+{
533+ int pfd1[2]; /* [0]:for read [1]:for write */
534+ int pid;
535+
536+ /* パイプ作成 */
537+ if (pipe(pfd1) < 0) {
538+ *err = errno;
539+ return -1; /* pipe create error */
540+ }
541+
542+ if (!(pid = fork())) {
543+ /* 子プロセス(実行コマンド側) */
544+ close(1); /* stdout を閉じる */
545+ dup(pfd1[1]); /* コマンドのstdoutを pfd1[1]に割り当てる */
546+ close(pfd1[0]); /* 読み込み用のpfd1[0]を閉じる */
547+ execlp(path, path,(char *)0); /* コマンド実行(引数なし) */
548+ /* not reached */
549+ } else if (pid < (pid_t)0) {
550+ *err = errno;
551+ return -1; /* fork error */
552+ }
553+
554+ /* 親プロセス(呼び出し側) */
555+ close(pfd1[1]); /* 書き込み用のpfd1[0]を閉じる */
556+
557+ return pfd1[0]; /* ファイルディスクリプタを返す */
558+}
559+
560+/*
561+ * ReadLine(buf, size, fd) A3UAD001
562+ *
563+ * ファイルディスクリプタfdから一行分の文字列を取出す。
564+ * fgets()のファイルディスクリプタ版
565+ * 最大size-1だけ読み込む
566+ *
567+ * IN size : 文字列格納領域の最大サイズ
568+ * fd : 読み込み対象ファイルディスクリプタ
569+ * OUT buf : 一行分の文字列
570+ * ret : 読み込んだサイズ
571+ * 失敗(EOF) : -1
572+ *
573+ * (注) ExecOpenStdout()が成功した場合、呼び出し側で返された
574+ * ファイルディスクリプタをclose()すること。
575+ */
576+int ReadLine(char *buf, int size, int fd)
577+{
578+ int cnt = 0;
579+ int len = 0;
580+
581+ while (len = read(fd,&buf[cnt],1)) { /* 1バイトづつ読む */
582+ if (buf[cnt] == '\n') {
583+ break;
584+ }
585+ ++cnt;
586+ if (cnt >= size-1) {
587+ break;
588+ }
589+ }
590+ buf[cnt] = '\0';
591+#ifdef XDEBUG
592+ printf( "OUTPUT:[%s] cnt=%d len=%d\n",buf,cnt,len);
593+#endif
594+ if (len < 0) {
595+ printf("command output read error. code=%d",errno);
596+ return -1;
597+ }
598+ if (len == 0) return -1; /* EOF */
599+ return cnt;
600+}
601+
602+/*
603+ * char *get_item(buf,sep,pos,outbuf)
604+ *
605+ * buf内のsepで区切られたpos番目の項目をoutbufにコピーして返します。
606+ * 項目中の前後のスペース文字は削除されます
607+ * bufは1024文字までです
608+ * sepに","を指定すると、",,"は一つの区切り文字として認識されます
609+ *
610+ * IN buf : 切り出し元の文字列(項目がsepで区切られている)
611+ * pos : 1以上の値 (1が最初の項目)
612+ * sep : 項目の区切り文字です " ", ","など
613+ * OUT outbuf : 指定項目の文字列(項目中の後のスペース/改行は削除)
614+ * ret : 成功時 outbuf
615+ * 失敗時 (char *)0
616+ */
617+char *get_item(char *buf, char *sep, int pos, char *outbuf)
618+{
619+ int i;
620+ char *pt;
621+ char *p;
622+ char wk[1024];
623+
624+ strcpy(wk,buf); /* strtok()はbufを破壊するためコピーして利用する */
625+
626+ for (i = 0; i<pos; i++) {
627+ if (i == 0) {
628+ pt = strtok(wk,sep);
629+ } else {
630+ pt = strtok(NULL,sep);
631+ }
632+ if (pt == NULL) break;
633+ }
634+ if (pt == NULL) {
635+ printf("Out of item(%s) pos(%d).",buf,pos);
636+ /* 結果領域クリア */
637+ strcpy(outbuf,"");
638+ return (char *)0;
639+ }
640+
641+ strcpy(outbuf, pt);
642+
643+ /* cut tail space */
644+ p = &outbuf[strlen(outbuf)-1]; /* last char */
645+ while (*p == ' ' || *p == 0x0a) --p;
646+ *(p+1) = '\0';
647+
648+ return outbuf;
649+} /* get_item */
650+#endif /* HIUX */
--- /dev/null
+++ b/xpkt.c
@@ -0,0 +1,707 @@
1+/*
2+ * xpkt : パケットの流量表示
3+ *
4+ * V1.00 1998.05.30 by Hyper Halx.f oga.
5+ * V1.01 1998.11.01 fix 1000000 packet bug
6+ * V1.02 2000.01.05 support -title
7+ * V1.03 2000.12.22 support value display
8+ * V1.04 2001.02.03 fix invalid value when if add/delete
9+ * V1.05 2001.05.02 support Linux 2.2.x
10+ * V1.06 2003.05.12 fix ibyte,obyte overflow
11+ */
12+
13+#include <X11/Xlib.h>
14+#include <X11/Xutil.h>
15+#include <stdio.h>
16+#include <string.h>
17+#include <math.h>
18+#include <unistd.h>
19+#include <errno.h>
20+#include <net/if.h>
21+#include <netinet/in.h>
22+#include <sys/ioctl.h>
23+
24+#define VER "Ver 1.06"
25+#define S_IN "IN"
26+#define S_OUT "OUT"
27+
28+/* #define DEBUG 1 */
29+
30+#ifdef DEBUG
31+#define dprintf printf
32+#else
33+#define dprintf if (vf) printf
34+#endif
35+
36+/* constants */
37+#define NCOLOR 8 /* num of color */
38+#define RM 10 /* right margine */
39+#define TM 0 /* top margine */
40+#define LH 14 /* Label height */
41+#define OFFS 40 /* string area */
42+#define NDAT 20 /* string area */
43+
44+typedef struct _if_t {
45+ char name[32]; /* Interface name */
46+ int mtu; /* MTU size */
47+ int active; /* active flag V1.04*/
48+ int ipkt; /* Input packet (or bytes) */
49+ int opkt; /* Output packet (or bytes) */
50+} if_t;
51+
52+/* globals */
53+if_t pktdat[NDAT];
54+if_t pktold[NDAT];
55+
56+GC gc[NCOLOR];
57+XEvent report;
58+
59+int vf = 0; /* verbose flag */
60+
61+unsigned long MyColor(Display *, char *);
62+int get_pktdata();
63+int get_bar(int);
64+char *get_item(char *, char *, int, char *);
65+
66+#ifdef HIUX
67+void GlobalMemoryStatus(MEMORYSTATUS *);
68+int ExecOpenStdout(char *, int *);
69+int ReadLine(char *, int , int );
70+#endif /* HIUX */
71+
72+main(a,b)
73+int a;
74+char *b[];
75+{
76+ Display *d;
77+ Window w;
78+ XSetWindowAttributes att;
79+ Font font;
80+ int i;
81+ int x_size = 0, y_size = 0; /* current window size */
82+ int x_home = 10, y_home = 10;
83+ int x0, y0;
84+ int xbuf, xused, xfree, xcache;
85+ int wait = 1; /* 5sec */
86+ int width;
87+ char name[128],wk[128];
88+ char value[1024]; /* V1.03 */
89+ char *pt;
90+ char *title = NULL; /* V1.02 */
91+ int UNIT = 50; /* 1 scale */
92+ int nonumf = 0; /* V1.03 -nonum */
93+ int ifnum; /* num of network interface */
94+ int ibyte,obyte,ilen,olen;
95+
96+ char *unit[8] = {
97+ "10K", /* 0 */
98+ "100K", /* 1 */
99+ "1M", /* 2 */
100+ "10M", /* 3 */
101+ "100M", /* 4 */
102+ "1G", /* 5 */
103+ "10G" /* 6 */
104+ "100G" /* 7 */
105+ };
106+
107+ u_long color[NCOLOR];
108+ char *cname[NCOLOR] = {
109+ "black", /* 0 */
110+ "red", /* 1 */
111+ "blue", /* 2 */
112+ "magenta", /* 3 */
113+ "green", /* 4 */
114+ "cyan", /* 5 */
115+ "yellow", /* 6 */
116+ "white" /* 7 */
117+ };
118+ enum col {BLACK, RED, BLUE, MAGENTA, GREEN, CYAN, YELLOW, WHITE};
119+
120+ d = XOpenDisplay(NULL);
121+
122+ for (i = 1; i<a ; i++) {
123+ if (!strncmp(b[i],"-h",2)) {
124+ /*printf("usage : xpkt [-update <time>] [-geometry <X>x<Y>+<X>+<Y>]\n"); */
125+ printf("usage : xpkt [-update <time(1)>]\n");
126+ printf(" [-scale <scale_width>]\n");
127+ printf(" [-title <title>]\n");
128+ printf(" [-nonum]\n");
129+ exit(1);
130+ }
131+ if (!strncmp(b[i],"-g",2) && a > i) {
132+ strcpy(name,b[++i]);
133+ if (pt = strtok(name,"x")) x_size = atoi(pt);
134+ if (pt = strtok(NULL,"+")) y_size = atoi(pt);
135+ if (pt = strtok(NULL,"+")) x_home = atoi(pt);
136+ if (pt = strtok(NULL,"+")) y_home = atoi(pt);
137+ continue;
138+ }
139+ if (!strncmp(b[i],"-u",2) && a > i) {
140+ wait = atoi(b[++i]); /* update time */
141+ continue;
142+ }
143+ if (!strncmp(b[i],"-s",2) && a > i) {
144+ UNIT = atoi(b[++i]); /* scale width */
145+ continue;
146+ }
147+ if (!strncmp(b[i],"-v",2)) {
148+ vf = 1; /* verbose */
149+ continue;
150+ }
151+ if (!strcmp(b[i],"-title") && a > i) {
152+ title = b[++i]; /* title V1.02 */
153+ continue;
154+ }
155+ if (!strcmp(b[i],"-nonum")) {
156+ nonumf = 1; /* nonum V1.03 */
157+ continue;
158+ }
159+ }
160+
161+ memset(pktdat, 0, sizeof(pktdat));
162+ memset(pktold, 0, sizeof(pktold));
163+
164+ ifnum = get_pktdata(pktdat);
165+
166+ if (!x_size) {
167+ x_size = OFFS + 4*UNIT + RM; /* 1MB/secまでOK */
168+ }
169+ if (!y_size) {
170+ y_size = 20*ifnum +LH;
171+ }
172+
173+ for (i = 0; i<NCOLOR; i++) {
174+ color[i] = MyColor(d,cname[i]); /* create color id */
175+ }
176+
177+ if (vf) {
178+ printf("x=%d, y=%d, width=%d, height=%d\n",
179+ x_home,y_home,x_size,y_size);
180+ }
181+
182+ w = XCreateSimpleWindow(d, RootWindow (d,0),
183+ x_home,y_home, /* home x,y */
184+ x_size,y_size, /* window size x,y */
185+ 1, /* border_width */
186+ 1, /* border */
187+ 0 ); /* background */
188+
189+ att.override_redirect = 0; /* Window Manager 介入あり ... 0 */
190+ /* なし ... 1 */
191+
192+ XChangeWindowAttributes(d,w,CWOverrideRedirect,&att);
193+ XMapWindow(d,w);
194+
195+ for (i = 0; i<NCOLOR; i++) {
196+ gc[i] = XCreateGC(d,w,0,0); /* create gc */
197+ XSetForeground(d,gc[i], color[i]); /* set fg color to gc */
198+ XSetBackground(d,gc[i], color[BLACK]); /* set bg color to gc(black)*/
199+ if (i == RED) {
200+ /* load font and set */
201+ /* font = XLoadFont(d, "5x10"); */
202+ font = XLoadFont(d, "7x13");
203+ XSetFont(d,gc[i],font);
204+ }
205+ }
206+
207+ /* Title Name */
208+ if (title) {
209+ sprintf(name,"%s - xpkt %s",title,VER); /* V1.02 */
210+ } else {
211+ sprintf(name,"xpkt %s",VER);
212+ }
213+ XStoreName(d,w,name);
214+ XSelectInput(d,w, ButtonPressMask|ExposureMask);
215+
216+ while (1){
217+ memcpy(pktold, pktdat, sizeof(pktold)); /* pktold <= pktdat */
218+ ifnum = get_pktdata(pktdat);
219+
220+ y0 = LH;
221+ width = (y_size-TM-LH)/(ifnum*2);
222+
223+ XFillRectangle(d,w,gc[BLACK],0,0,x_size,y_size);
224+
225+ for (i = 0; i<ifnum; i++) {
226+ /* グラフ描画 */
227+ if (pktdat[i].mtu > 0) { /* V1.05-A */
228+ /* Linux -2.0.x (packets) */
229+ ibyte = pktdat[i].mtu * (pktdat[i].ipkt - pktold[i].ipkt);
230+ obyte = pktdat[i].mtu * (pktdat[i].opkt - pktold[i].opkt);
231+ } else { /* V1.05-A */
232+ /* Linux 2.2.x- (bytes) V1.05-A */
233+ ibyte = (pktdat[i].ipkt - pktold[i].ipkt);
234+ obyte = (pktdat[i].opkt - pktold[i].opkt);
235+ } /* V1.05-A */
236+ ilen = get_bar(ibyte)*UNIT/10;
237+ olen = get_bar(obyte)*UNIT/10;
238+ dprintf("### ibyte=%d ilen=%d obyte=%d olen=%d\n",ibyte,ilen,obyte,olen);
239+
240+ /* interface name */
241+ /* pktdat[i].name[strlen(pktdat[i].name)-1] = '\0'; V1.04-D */
242+ XDrawImageString(d, w, gc[WHITE], 5, y0+TM+LH+(i*width*2)-4,
243+ pktdat[i].name, strlen(pktdat[i].name));
244+
245+ /* receive packet bar */
246+ XFillRectangle(d,w,gc[GREEN], OFFS, y0+TM+(i*width*2),
247+ ilen,width-2);
248+
249+ /* transmit packet bar */
250+ XFillRectangle(d,w,gc[YELLOW],OFFS, y0+TM+(i*width*2)+width,
251+ olen,width-2);
252+
253+ if (!nonumf) {
254+ /* receive packet value V1.03 */
255+ if (ibyte) {
256+ sprintf(value, "%d", ibyte/1024);
257+ XDrawImageString(d, w, gc[RED], OFFS+2,
258+ y0+TM+LH+(i*width*2)-7,
259+ value, strlen(value));
260+ }
261+
262+ /* transmit packet value V1.03 */
263+ if (obyte) {
264+ sprintf(value, "%d", obyte/1024);
265+ XDrawImageString(d, w, gc[RED], OFFS+2,
266+ y0+TM+LH+(i*width*2)-7+width,
267+ value, strlen(value));
268+ }
269+ }
270+
271+ }
272+
273+ /* 目盛 */
274+ for (i = 0; i<7; ++i) {
275+ XFillRectangle(d,w,gc[BLACK],
276+ OFFS+UNIT*(i+1),
277+ y0+TM,
278+ 1,
279+ y0*6+TM);
280+
281+ XDrawImageString(d, w, gc[WHITE],
282+ OFFS+UNIT*(i+1)-8, 10, unit[i], strlen(unit[i]));
283+ }
284+
285+ XFlush(d);
286+
287+ /* 画面をクリックされたら */
288+ if (XCheckMaskEvent(d,ButtonPressMask,&report) == True) {
289+ printf("xpkt %s by Moritaka Ogasawara.\n",VER);
290+ }
291+
292+ /* リサイズ */
293+ if (XCheckMaskEvent(d,ExposureMask,&report) == True) {
294+ Window root;
295+ int x,y;
296+ unsigned int width,height, border, depth;
297+
298+ XGetGeometry(d,w,&root,&x,&y,&width,&height,&border,&depth);
299+ if (x_size != width || y_size != height) {
300+ x_size = width;
301+ y_size = height;
302+ XClearWindow(d,w);
303+ }
304+ }
305+
306+ sleep(wait);
307+ }
308+}
309+
310+unsigned long MyColor(display,color)
311+Display *display;
312+char *color;
313+{
314+ Colormap cmap;
315+ XColor c0,c1;
316+ int code;
317+
318+ cmap = DefaultColormap(display,0);
319+
320+ code = XAllocNamedColor(display,cmap,color,&c1,&c0);
321+ if (code)
322+ return(c1.pixel);
323+ else
324+ return(-1);
325+}
326+
327+#ifdef HIUX
328+/*
329+ * get memory information from /etc/sysinfo command for HIUX
330+ *
331+ */
332+void get_memdata(mem)
333+mem_t *mem;
334+{
335+ int *fd;
336+ char buf[1024];
337+ char *pt;
338+ FILE *fp;
339+ MEMORYSTATUS memst;
340+
341+ GlobalMemoryStatus(&memst);
342+ mem->total = memst.dwTotalPhys/1024;
343+ mem->free = memst.dwAvailPhys/1024;
344+ mem->used = (mem->total - mem->free);
345+ mem->shared = 0;
346+ mem->buf = 0;
347+ mem->swap_total = memst.dwTotalPageFile/1024;
348+ mem->swap_free = memst.dwAvailPageFile/1024;
349+ mem->swap_used = mem->swap_total - mem->swap_free;
350+
351+#ifdef DEBUG
352+ printf("Memory : %d %d %d %d %d %d\n",mem->total,mem->used,
353+ mem->free,mem->shared,mem->buf,mem->cache);
354+ printf("Swap : %d %d %d\n",mem->swap_total,mem->swap_used,mem->swap_free);
355+#endif
356+}
357+
358+#else /* Linux */
359+
360+/* V1.05-A start (not available) */
361+/*
362+ * get mtu for Linux 2.2.x
363+ *
364+ * IN ifname : interface name
365+ * OUT omtu : mtu
366+ *
367+ */
368+int get_mtu(char *ifname, int *omtu)
369+{
370+ struct ifreq ifr;
371+ static int sfd = -1;
372+
373+ strcpy(ifr.ifr_name, ifname);
374+
375+ if (sfd < 0) {
376+ /* open one time */
377+ sfd = socket(PF_INET, SOCK_STREAM, 0);
378+ if (sfd < 0) {
379+ perror("socket");
380+ }
381+ }
382+ if (ioctl(sfd, SIOCGIFMTU, &ifr) < 0) {
383+ /* failed */
384+ *omtu = -1;
385+ } else {
386+ /* success */
387+ *omtu = ifr.ifr_mtu;
388+ dprintf("MTU=%d\n", *omtu);
389+ }
390+ /* close(sfd); no close */
391+}
392+/* V1.05-A end */
393+
394+/*
395+ * 10桁以上の場合下9桁のみに変更する
396+ *
397+ */
398+void to9digit(char *strnum)
399+{
400+ char buf[64];
401+
402+ if (strlen(strnum) < 10) return;
403+ strcpy(buf, &strnum[strlen(strnum)-9]);
404+ strcpy(strnum, buf);
405+}
406+
407+/*
408+ * get packet information from /proc/net/route,dev for Linux
409+ *
410+ * IN if_t *pkt : if_t *pkt[n]
411+ * OUT ret : 見つかったインタフェーステーブル数を格納する。
412+ */
413+int get_pktdata(if_t pkt[])
414+{
415+ FILE *fp;
416+ char buf[1024],wk[1024];
417+ char *pt;
418+ int i,j,found;
419+
420+ dprintf("## get_pktdata start\n");
421+
422+ /* memset(pkt, 0, sizeof(if_t)*NDAT); V1.04-D */
423+ for (i = 0; i<NDAT; i++) { /* V1.04-A */
424+ pkt[i].active = 0; /* V1.04-A */
425+ } /* V1.04-A */
426+
427+ /* get MTU,Ifname */
428+ if (!(fp = fopen("/proc/net/route","r"))) {
429+ perror("fopen /proc/net/route");
430+ exit(1);
431+ }
432+ fgets(buf,sizeof(buf),fp); /* skip header */
433+
434+ /* get Interface MTU */
435+ while (fgets(buf,sizeof(buf),fp)) {
436+ if (get_item(buf,"\t",1,wk)) {
437+ /* strcat(wk,":"); /* "eth0:" V1.04-D */
438+ i = 0;
439+ found = 0;
440+ while(pkt[i].mtu) {
441+ if (!strcmp(pkt[i].name, wk)) {
442+ found = 1;
443+ pkt[i].active = 1; /* V1.04-A */
444+ break;
445+ }
446+ i++;
447+ }
448+ if (!found) {
449+ /* まだ未登録なら登録 */
450+ strcpy(pkt[i].name, wk);
451+ if (get_item(buf,"\t",9,wk)) pkt[i].mtu = atoi(wk);
452+ /* V1.05-A start */
453+ if (pkt[i].mtu == 0) {
454+ pkt[i].mtu = -1;
455+ }
456+#if 0
457+ if (pkt[i].mtu == 0) {
458+ dprintf("NAME[%s] MTU[%d]\n", pkt[i].name, pkt[i].mtu);
459+ get_mtu(pkt[i].name, &pkt[i].mtu);
460+ }
461+ dprintf("NAME[%s] MTU[%d]\n", pkt[i].name, pkt[i].mtu);
462+#endif
463+ /* V1.05-A end */
464+ pkt[i].active = 1; /* V1.04-A */
465+ }
466+ }
467+ }
468+ fclose(fp);
469+
470+ /* get Packet data */
471+ if (!(fp = fopen("/proc/net/dev","r"))) {
472+ perror("fopen /proc/net/dev");
473+ exit(1);
474+ }
475+ fgets(buf,sizeof(buf),fp); /* skip header1 */
476+ fgets(buf,sizeof(buf),fp); /* skip header2 */
477+
478+ while (fgets(buf,sizeof(buf),fp)) {
479+ if (get_item(buf," ",1,wk)) {
480+ i = 0;
481+ while (pkt[i].mtu && i < NDAT) {
482+ /* /proc/net/routeにあるifのみ設定 */
483+ if (strstr(wk,pkt[i].name)) {
484+ pt = strchr(buf, ':'); /* V1.01 */
485+ if (pt) *pt = ' '; /* V1.01 */
486+ if (pkt[i].mtu > 0) { /* V1.05-A */
487+ /* Linux -2.0.x (packets) */
488+ if (get_item(buf," ",2,wk)) pkt[i].ipkt = atoi(wk);
489+ if (get_item(buf," ",7,wk)) pkt[i].opkt = atoi(wk);
490+ } else { /* V1.05-A */
491+ /* Linux 2.2.x- (bytes) V1.05-A */
492+ /* V1.06-C start */
493+ /* if (get_item(buf," ",2,wk)) pkt[i].ipkt = atoi(wk); */
494+ /* if (get_item(buf," ",10,wk)) pkt[i].opkt = atoi(wk); */
495+ if (get_item(buf," ",2,wk)) {
496+ to9digit(wk);
497+ pkt[i].ipkt = atoi(wk);
498+ }
499+ if (get_item(buf," ",10,wk)) {
500+ to9digit(wk);
501+ pkt[i].opkt = atoi(wk);
502+ }
503+ /* V1.06-C end */
504+ } /* V1.05-A */
505+ break;
506+ }
507+ i++;
508+ }
509+ }
510+ }
511+ fclose(fp);
512+
513+ /* count num of interfaces */
514+ i = 0;
515+ while (pkt[i].mtu && i < NDAT) {
516+ if (vf) {
517+ printf("IF:[%s] ACTIVE[%d] MTU[%d] IN[%d] OUT[%d]\n",
518+ pkt[i].name,
519+ pkt[i].active, /* V1.04-A */
520+ pkt[i].mtu,
521+ pkt[i].ipkt,
522+ pkt[i].opkt);
523+ }
524+ i++;
525+ }
526+ dprintf("## get_pktdata end\n");
527+ return i;
528+}
529+#endif /* Linux */
530+
531+#ifdef HIUX
532+/*
533+ * ExecOpenStdout(path) A3UAD001
534+ *
535+ * pathで指定されたコマンドを実行し、そのコマンドの標準出力の
536+ * ファイルディスクリプタを返す。
537+ *
538+ * IN path : 実行するコマンドのフルパス
539+ * OUT ret : 成功 : 実行したコマンドの標準出力のファイルディスクリプタ。
540+ * 失敗 : -1
541+ * err : 失敗時、errnoが設定される
542+ *
543+ * (注) ExecOpenStdout()が成功した場合、呼び出し側で返された
544+ * ファイルディスクリプタをclose()すること。
545+ */
546+int ExecOpenStdout(char *path , int *err)
547+{
548+ int pfd1[2]; /* [0]:for read [1]:for write */
549+ int pid;
550+
551+ /* パイプ作成 */
552+ if (pipe(pfd1) < 0) {
553+ *err = errno;
554+ return -1; /* pipe create error */
555+ }
556+
557+ if (!(pid = fork())) {
558+ /* 子プロセス(実行コマンド側) */
559+ close(1); /* stdout を閉じる */
560+ dup(pfd1[1]); /* コマンドのstdoutを pfd1[1]に割り当てる */
561+ close(pfd1[0]); /* 読み込み用のpfd1[0]を閉じる */
562+ execlp(path, path,(char *)0); /* コマンド実行(引数なし) */
563+ /* not reached */
564+ } else if (pid < (pid_t)0) {
565+ *err = errno;
566+ return -1; /* fork error */
567+ }
568+
569+ /* 親プロセス(呼び出し側) */
570+ close(pfd1[1]); /* 書き込み用のpfd1[0]を閉じる */
571+
572+ return pfd1[0]; /* ファイルディスクリプタを返す */
573+}
574+
575+/*
576+ * ReadLine(buf, size, fd) A3UAD001
577+ *
578+ * ファイルディスクリプタfdから一行分の文字列を取出す。
579+ * fgets()のファイルディスクリプタ版
580+ * 最大size-1だけ読み込む
581+ *
582+ * IN size : 文字列格納領域の最大サイズ
583+ * fd : 読み込み対象ファイルディスクリプタ
584+ * OUT buf : 一行分の文字列
585+ * ret : 読み込んだサイズ
586+ * 失敗(EOF) : -1
587+ *
588+ * (注) ExecOpenStdout()が成功した場合、呼び出し側で返された
589+ * ファイルディスクリプタをclose()すること。
590+ */
591+int ReadLine(char *buf, int size, int fd)
592+{
593+ int cnt = 0;
594+ int len = 0;
595+
596+ while (len = read(fd,&buf[cnt],1)) { /* 1バイトづつ読む */
597+ if (buf[cnt] == '\n') {
598+ break;
599+ }
600+ ++cnt;
601+ if (cnt >= size-1) {
602+ break;
603+ }
604+ }
605+ buf[cnt] = '\0';
606+#ifdef XDEBUG
607+ printf( "OUTPUT:[%s] cnt=%d len=%d\n",buf,cnt,len);
608+#endif
609+ if (len < 0) {
610+ printf("command output read error. code=%d",errno);
611+ return -1;
612+ }
613+ if (len == 0) return -1; /* EOF */
614+ return cnt;
615+}
616+#endif /* HIUX */
617+
618+/*
619+ * char *get_item(buf,sep,pos,outbuf)
620+ *
621+ * buf内のsepで区切られたpos番目の項目をoutbufにコピーして返します。
622+ * 項目中の前後のスペース文字は削除されます
623+ * bufは1024文字までです
624+ * sepに","を指定すると、",,"は一つの区切り文字として認識されます
625+ *
626+ * IN buf : 切り出し元の文字列(項目がsepで区切られている)
627+ * pos : 1以上の値 (1が最初の項目)
628+ * sep : 項目の区切り文字です " ", ","など
629+ * OUT outbuf : 指定項目の文字列(項目中の後のスペース/改行は削除)
630+ * ret : 成功時 outbuf
631+ * 失敗時 (char *)0
632+ */
633+char *get_item(char *buf, char *sep, int pos, char *outbuf)
634+{
635+ int i;
636+ char *pt = NULL;
637+ char *p;
638+ char wk[1024];
639+
640+ strcpy(wk,buf); /* strtok()はbufを破壊するためコピーして利用する */
641+
642+ for (i = 0; i<pos; i++) {
643+ if (i == 0) {
644+ pt = strtok(wk,sep);
645+ } else {
646+ pt = strtok(NULL,sep);
647+ }
648+ if (pt == NULL) break;
649+ }
650+ if (pt == NULL) {
651+ printf("Out of item(%s) pos(%d).",buf,pos);
652+ /* 結果領域クリア */
653+ strcpy(outbuf,"");
654+ return (char *)0;
655+ }
656+
657+ strcpy(outbuf, pt);
658+
659+ /* cut tail space */
660+ p = &outbuf[strlen(outbuf)-1]; /* last char */
661+ while (*p == ' ' || *p == 0x0a) --p;
662+ *(p+1) = '\0';
663+
664+ return outbuf;
665+} /* get_item */
666+
667+/*
668+ * 対数っぽい長さを求める
669+ *
670+ * val ret
671+ * 1 ... 1
672+ * 10 ... 1
673+ * 100 ... 1
674+ * 1K ... 1
675+ * 10K ... 10
676+ * 100K ... 20
677+ * 1M ... 30
678+ * 10M ... 40
679+ * 100M ... 50
680+ *
681+ */
682+int get_bar(int val)
683+{
684+ int j=0;
685+ int valsv = val;
686+
687+ if (valsv == 0) {
688+ return 0;
689+ }
690+
691+ dprintf("get_bar : val = %d ",val);
692+
693+ while (val > 10) {
694+ j += 10;
695+ val /= 10;
696+ }
697+ j += val;
698+
699+ j -= 30; /* 10KBを10とする */
700+
701+ if (j <= 0) {
702+ j = 1;
703+ }
704+ dprintf("ret = %d\n",j);
705+
706+ return j;
707+}
--- /dev/null
+++ b/xpstat.c
@@ -0,0 +1,545 @@
1+/*
2+ * xpstat : デーモン起動状態監視ツール
3+ *
4+ * defailt : for Linux
5+ * -DH3050R : for HI-UX/WE2 and HP-UX
6+ *
7+ * V1.00 96/10/30 by oga.
8+ * V1.01 96/10/30 -fn support and wait time adjust
9+ * V1.02 96/10/31 -fs, -n support
10+ * V1.03 96/11/06 .xpstat comment, -x, -y, -l support
11+ *
12+ */
13+#include <stdio.h>
14+#include <errno.h>
15+#include <sys/types.h>
16+#include <sys/stat.h>
17+#include <sys/time.h>
18+#include <signal.h>
19+#include <fcntl.h>
20+#include <X11/Xlib.h>
21+#include <X11/Xutil.h>
22+
23+#define VER "1.03"
24+#define MAXPRC 64
25+#define BARLEN 12
26+#define MAXBARLEN 30
27+#define LOADTITLE "Load ave."
28+#define AVEKEY "average: "
29+
30+/* process info */
31+typedef struct pst {
32+ char procname[256]; /* process name */
33+ char name[256]; /* display process name */
34+ char active; /* 0:inactive 1:active */
35+ char cnt; /* bar length */
36+} ps_t;
37+
38+/* globals */
39+Display *d;
40+Window w;
41+GC ggreen,gwhite,gblack,gred,gskblue,gyellow;
42+int xx, yy;
43+int refresh = 0; /* -r spcify flag (black refresh option) */
44+int kaif = 0; /* -k spcify flag (kainuma option) */
45+int vuef = 0; /* -vue spcify flag (for VUE option) */
46+int lf = 0; /* -l spcify flag (load average) */
47+int nf = 0; /* -n spcify flag (number of procs) */
48+int loadave = 0; /* load average */
49+char fontn[256]; /* font name */
50+char tmpf[256]; /* tmp filename */
51+
52+int BX = 10; /* mini : 8 */
53+int BY = 15; /* mini : 12 */
54+
55+void usage()
56+{
57+ printf("\n");
58+ printf(" xpstat Ver %s\n",VER);
59+ printf("\n");
60+ printf(" usage : xpstat [{ -f <proc_file> | procname1 procname2 ...}]\n");
61+ printf("\n");
62+ printf(" # <proc_file> is following format.\n");
63+ printf(" procname1[:name1]\n");
64+ printf(" procname2[:name2]\n");
65+ printf(" : : \n\n");
66+ printf(" # null line is a separator\n");
67+ printf(" # default <proc_file> is $HOME/.xpstat\n");
68+ printf(" -n : level meter is number of processes\n");
69+ printf(" -x : level meter block width\n");
70+ printf(" -y : level meter block height\n");
71+ printf(" -l : display load average\n");
72+ printf(" -fn : set font name<%s>\n",fontn);
73+ printf(" -fs : set font size<7>\n");
74+#if 0
75+ printf(" -vue : string color blue\n");
76+ printf(" -k : kainuma option (display only one block)\n");
77+ printf(" -r : refresh/always fill black\n");
78+#endif
79+ printf("\n Copyright(C)1996, Moritaka Ogasawara. All Rights Reserved.\n\n");
80+}
81+
82+/*
83+ * 監視するプロセス名ファイル(.xpstat)を読み込む
84+ */
85+void getprocs(prc,num,filen,maxlen)
86+ps_t *prc;
87+int *num, *maxlen;
88+char *filen;
89+{
90+ FILE *fp;
91+ int i,j;
92+ char buf[1024];
93+
94+ if (!(fp = fopen(filen,"r"))) {
95+ sprintf(buf,"read %s",filen);
96+ perror(buf);
97+ usage();
98+ exit(1);
99+ }
100+ while (fgets(buf,sizeof(buf),fp)) {
101+ if (buf[0] == '#') {
102+ /* skip comment line */
103+ continue;
104+ }
105+ if (buf[strlen(buf)-1] == 0xa) {
106+ buf[strlen(buf)-1] = '\0';
107+ }
108+ i=0;
109+ while (buf[i] != ':' && buf[i] != '\0') {
110+ prc[*num].procname[i] = buf[i];
111+ i++;
112+ }
113+ j=0;
114+ if (buf[i] == ':') {
115+ i++;
116+ while (buf[i] != ':' && buf[i] != '\0') {
117+ prc[*num].name[j] = buf[i];
118+ i++;
119+ j++;
120+ }
121+ } else {
122+ strcpy(prc[*num].name, prc[*num].procname);
123+ }
124+ if (*maxlen < strlen(prc[*num].name)) {
125+ *maxlen = strlen(prc[*num].name);
126+ }
127+#ifdef DEBUG
128+ fprintf(stderr,"procname=[%s]\t/ name=[%s]\n",
129+ prc[*num].procname,prc[*num].name);
130+#endif
131+ ++(*num);
132+ }
133+ fclose(fp);
134+}
135+
136+/*
137+ * レベルメータを表示する。
138+ */
139+void dispbar(x,y,len)
140+int x,y,len;
141+{
142+ int i, barlen;
143+
144+ if (nf) {
145+ barlen = MAXBARLEN;
146+ } else {
147+ barlen = BARLEN;
148+ }
149+
150+ for (i = 0; i<barlen; i++) {
151+ if (i < len) {
152+ if (i < 9) {
153+ /* green level */
154+ XFillRectangle(d,w,ggreen,x+i*BX, y, BX-2, BY-2);
155+ if (kaif) break; /* 1個だけ表示 */
156+ } else {
157+ /* red zone */
158+ XFillRectangle(d,w,gred,x+i*BX, y, BX-2, BY-2);
159+ }
160+ } else {
161+ XFillRectangle(d,w,gblack,x+i*BX, y, BX-2, BY-2);
162+ if (kaif) break; /* 1個だけ表示 */
163+ }
164+ }
165+}
166+
167+/*
168+ * 監視プロセス情報を表示する
169+ */
170+void dispall(prc,num,strarea)
171+ps_t *prc;
172+int num,strarea;
173+{
174+ int i, nfbk;
175+
176+ if (refresh) {
177+ /* fill black for VUE */
178+ XFillRectangle(d,w,gblack,0,0,xx,yy);
179+ }
180+
181+ if (lf) {
182+ /* display load average line */
183+ XDrawString(d, w, gyellow, 3, BY, LOADTITLE, strlen(LOADTITLE));
184+ nfbk = nf;
185+ nf = 1; /* MAXBARLEN 使用 */
186+ dispbar(strarea,2,(loadave*3)/100 +1);
187+ nf = nfbk;
188+ }
189+ for(i = 0; i<num; i++) {
190+ if (strlen(prc[i].procname)) {
191+ /* draw process name */
192+ XDrawString(d, w, gwhite, 3, (i+lf)*BY+BY,
193+ prc[i].name,strlen(prc[i].name));
194+ if (nf) {
195+ /* length is number of procs */
196+ dispbar(strarea,(i+lf)*BY+2,prc[i].active);/* disp meter */
197+ } else {
198+ dispbar(strarea,(i+lf)*BY+2,prc[i].cnt); /* disp meter */
199+ }
200+ } else {
201+ /* draw separate line */
202+ XFillRectangle(d, w, gskblue, 3, (i+lf)*BY+BY/2+2,
203+ strarea+BX*MAXBARLEN-6,1);
204+ }
205+ }
206+ XFlush(d);
207+}
208+
209+unsigned long MyColor(display,color)
210+Display *display;
211+char *color;
212+{
213+ Colormap cmap;
214+ XColor c0,c1;
215+ int code;
216+
217+ cmap = DefaultColormap(display,0);
218+
219+ code = XAllocNamedColor(display,cmap,color,&c1,&c0);
220+ if (code)
221+ return(c1.pixel);
222+ else
223+ return((unsigned long)-1);
224+}
225+
226+/*
227+ * get load average
228+ *
229+ * IN : buf ... uptime output
230+ * OUT : ret ... load average x 100
231+ */
232+int get_loadave(buf)
233+char *buf;
234+{
235+ char *pt;
236+ char wkbuf[16];
237+ int i=0;
238+
239+ pt = (char *)strstr(buf,AVEKEY);/* search "average: " */
240+
241+ pt += strlen(AVEKEY); /* move pointer to X.XX */
242+ while (*pt != ' ') {
243+ if (*pt != '.') { /* skip . */
244+ wkbuf[i] = *pt;
245+ i++;
246+ }
247+ pt++;
248+ }
249+ wkbuf[i] = '\0';
250+
251+#ifdef DEBUG
252+ fprintf(stderr,"load ave = %s\n",wkbuf);
253+#endif
254+ return(atoi(wkbuf));
255+}
256+
257+void sigcatch()
258+{
259+ unlink(tmpf);
260+ exit(1);
261+}
262+
263+/*
264+ * MAIN routine
265+ */
266+void main(a,b)
267+int a;
268+char *b[];
269+{
270+ FILE *fp;
271+ int fd;
272+ int num= 0, i, j, strarea = 0;
273+ int ff = 0; /* -f spcify flag */
274+ int fnsize = 7; /* font width */
275+ int x_home=0,y_home=0;
276+ char buf[1024], filen[256];
277+ char *pt;
278+ ps_t prc[MAXPRC];
279+ struct timeval tv, tv2, tv3;
280+ struct timezone tz;
281+
282+ /* for Window */
283+ Font font;
284+ XSetWindowAttributes att;
285+ unsigned long green,red,skblue,yellow,white,black;
286+
287+ memset(prc,0,sizeof(ps_t)*MAXPRC);
288+ gettimeofday(&tv2,&tz); /* init */
289+
290+ /* default font name */
291+#ifdef H3050R
292+ strcpy(fontn,"7x13bold");
293+#else /* Linux */
294+ strcpy(fontn,"7x14bold");
295+#endif
296+
297+ /* get args */
298+ for (i=1; i<a; i++) {
299+ if (!strncmp(b[i],"-h",2)) {
300+ usage();
301+ exit(1);
302+ }
303+ if (!strcmp(b[i],"-f")) {
304+ ff = 1;
305+ i++;
306+ strcpy(filen,b[i]);
307+ continue;
308+ }
309+ if (!strncmp(b[i],"-g",2) && a > i) {
310+ strcpy(buf,b[++i]);
311+ if (pt =(char *) strtok(buf,"+")) x_home = atoi(pt);
312+ if (pt =(char *) strtok(NULL,"+")) y_home = atoi(pt);
313+ /* printf("x=%d / y=%d\n",x_home,y_home); */
314+ continue;
315+ }
316+ if (!strncmp(b[i],"-r",2)) {
317+ refresh = 1; /* VUE用にいちいち黒く塗る(注)ちかちかする*/
318+ continue;
319+ }
320+ if (!strncmp(b[i],"-k",2)) {
321+ kaif = 1; /* 1 個のみ表示 海沼の好み */
322+ continue;
323+ }
324+ if (!strncmp(b[i],"-v",2)) {
325+ vuef = 1; /* 文字の色を青にする for VUE */
326+ continue;
327+ }
328+ if (!strcmp(b[i],"-fn")) {
329+ if (++i < a) {
330+ strcpy(fontn,b[i]);
331+ } else {
332+ printf("specify font name!\n");
333+ }
334+ continue;
335+ }
336+ if (!strcmp(b[i],"-fs")) {
337+ if (++i < a) {
338+ fnsize = atoi(b[i]);
339+ } else {
340+ printf("specify font size!\n");
341+ }
342+ continue;
343+ }
344+ if (!strcmp(b[i],"-l")) {
345+ lf = 1; /* load average 表示 */
346+ continue;
347+ }
348+ if (!strcmp(b[i],"-n")) {
349+ nf = 1; /* レベルメータはプロセス数 */
350+ continue;
351+ }
352+ if (!strcmp(b[i],"-x")) {
353+ if (++i < a) {
354+ BX = atoi(b[i]);
355+ } else {
356+ printf("specify block width!\n");
357+ }
358+ continue;
359+ }
360+ if (!strcmp(b[i],"-y")) {
361+ if (++i < a) {
362+ BY = atoi(b[i]);
363+ } else {
364+ printf("specify block height!\n");
365+ }
366+ continue;
367+ }
368+ strcpy(prc[num].procname,b[i]);
369+ strcpy(prc[num].name,b[i]);
370+ if (strarea < strlen(prc[num].name)) {
371+ strarea = strlen(prc[num].name);
372+ }
373+ num++;
374+ /* clear arg area */
375+ memset(b[i],0,strlen(b[i]));
376+ }
377+
378+ /* read proc name */
379+ if (!ff) {
380+ sprintf(filen,"%s/.xpstat",getenv("HOME"));
381+ }
382+ if (!num) {
383+ getprocs(prc,&num,filen,&strarea);
384+ }
385+ if (lf) {
386+ if (strarea < strlen(LOADTITLE)) {
387+ strarea = strlen(LOADTITLE);
388+ }
389+ }
390+ strarea = strarea*fnsize+7; /* proc name area length */
391+
392+ d = XOpenDisplay(NULL);
393+
394+ green = MyColor(d,"green");
395+ red = MyColor(d,"red");
396+ skblue = MyColor(d,"orange");
397+ yellow = MyColor(d,"yellow");
398+
399+ if (vuef) {
400+ white = MyColor(d,"blue");
401+ } else {
402+ white = MyColor(d,"white");
403+ }
404+ black = MyColor(d,"Black");
405+
406+ xx = strarea+BX*BARLEN+3;
407+ yy = num*BY+5;
408+
409+ w = XCreateSimpleWindow(d, RootWindow (d,0),
410+ x_home,y_home, /* home x,y */
411+ strarea+BX*BARLEN+3, (num+lf)*BY+5,/* window size x,y */
412+ 1, /* border_width */
413+ 1, /* border */
414+ 0 ); /* background */
415+
416+ att.override_redirect = 0; /* Window Manager 介入あり ... 0 */
417+ /* なし ... 1 */
418+
419+ sprintf(buf,"xpstat %s",VER);
420+ XStoreName(d,w,buf);
421+
422+ XChangeWindowAttributes(d,w,CWOverrideRedirect,&att);
423+ XMapWindow(d,w);
424+
425+ ggreen = XCreateGC(d,w,0,0); /* create gc */
426+ gred = XCreateGC(d,w,0,0); /* create gc */
427+ gwhite = XCreateGC(d,w,0,0); /* create gc */
428+ gblack = XCreateGC(d,w,0,0); /* create gc */
429+ gskblue = XCreateGC(d,w,0,0); /* create gc */
430+ gyellow = XCreateGC(d,w,0,0); /* create gc */
431+
432+ XSetForeground(d,ggreen ,green); /* set color to gc */
433+ XSetForeground(d,gred ,red); /* set color to gc */
434+ XSetForeground(d,gwhite ,white); /* set color to gc */
435+ XSetBackground(d,gwhite ,black); /* set back color to gc */
436+ XSetForeground(d,gblack ,black); /* set color to gc */
437+ XSetForeground(d,gskblue ,skblue); /* set color to gc */
438+ XSetForeground(d,gyellow ,yellow); /* set color to gc */
439+
440+ /* load font and set */
441+ font = XLoadFont(d, fontn);
442+ XSetFont(d,gwhite,font);
443+ XSetFont(d,gyellow,font);
444+
445+ XSelectInput(d,w, ButtonPressMask|ExposureMask);
446+
447+ /* set tmp filename */
448+ sprintf(tmpf,"/tmp/pstmp%d",tv2.tv_usec);
449+
450+ /* set signal handler */
451+ signal(SIGINT, sigcatch);
452+ signal(SIGQUIT,sigcatch);
453+ signal(SIGTRAP,sigcatch);
454+ signal(SIGABRT,sigcatch);
455+ signal(SIGTERM,sigcatch);
456+ signal(SIGPIPE,sigcatch); /* close button */
457+
458+ while(1) {
459+ /* ブロセスデータ採取 */
460+ if ((fd = open(tmpf,O_CREAT|O_RDWR|O_TRUNC)) < 0) {
461+ perror("open pstmp");
462+ exit(1);
463+ }
464+ close(1); /* close stdout(1) */
465+ dup(fd); /* stdout(1) redirect to tmpfile */
466+
467+ if (lf) {
468+ /* get load average */
469+ system("uptime");
470+ }
471+#ifdef H3050R
472+ system("ps -ef");
473+#else /* linux */
474+ system("ps ax");
475+#endif
476+ fchmod(fd,0666); /* mode set to rw-rw-rw- */
477+ close(fd); /* close tmpfile */
478+
479+ /* プロセス起動状態チェック */
480+ if (!(fp = fopen(tmpf,"r"))) {
481+ perror("fopen pstmp");
482+ exit(1);
483+ }
484+
485+ for (i=0; i<num; i++) {
486+ prc[i].active = 0;
487+ }
488+ if (lf) {
489+ /* get load average */
490+ fgets(buf,sizeof(buf),fp);
491+ loadave = get_loadave(buf);
492+ }
493+ while (fgets(buf,sizeof(buf),fp)) {
494+ for (i=0; i<num; i++) {
495+ if (strstr(buf,"xpstat")) {
496+ continue; /* H3050R cannot clear args */
497+ }
498+ if (pt =(char *) strstr(buf,prc[i].procname)) {
499+ int c1,c2;
500+
501+ /* 前後が区切り文字であることのチェック */
502+ c1 = pt[strlen(prc[i].procname)];
503+ c2 = *(--pt);
504+ if ((c1 == ' ' || c1 == 0xa || c1 == '\0') &&
505+ (c2 == '/' || c2 == ' ')) {
506+ ++prc[i].active; /* process is active */
507+ }
508+ }
509+ }
510+ }
511+ fclose(fp);
512+
513+ /* 起動/停止状態によりBARの長さを変更 */
514+ for (j=0; j<3; j++) {
515+ for (i=0; i<num; i++) {
516+ if (prc[i].active) {
517+ (prc[i].cnt < BARLEN)? prc[i].cnt++ : 0 ;
518+ } else {
519+ (prc[i].cnt > 0)? prc[i].cnt-- : 0 ;
520+ }
521+ }
522+
523+ /* ちょっと待ってみよう */
524+ gettimeofday(&tv3,&tz);
525+ tv.tv_sec = 0;
526+ /* tv.tv_usec = 300000; /* 0.3sec */
527+
528+ /* 待ち時間調整 */
529+ if (tv2.tv_usec < tv3.tv_usec) {
530+ tv.tv_usec = 300000 - (tv3.tv_usec-tv2.tv_usec);
531+ } else {
532+ tv.tv_usec = 300000 - (1000000+tv3.tv_usec-tv2.tv_usec);
533+ }
534+ if (tv.tv_usec < 0) {
535+ tv.tv_usec = 1;
536+ }
537+
538+ select(0,0,0,0,&tv); /* wait a little */
539+ gettimeofday(&tv2,&tz);
540+
541+ /* BAR 表示 */
542+ dispall(prc,num,strarea);
543+ }
544+ }
545+}
--- /dev/null
+++ b/zusa.c
@@ -0,0 +1,43 @@
1+/*
2+ * zusa.c
3+ * 2ch zusaaaa...
4+ *
5+ * 2002/04/21 by oga.
6+ */
7+#include <stdio.h>
8+#include <string.h>
9+#include <sys/types.h>
10+#include <unistd.h>
11+
12+int main(int a, char *b[])
13+{
14+
15+ int i, j;
16+ char buf[256];
17+ char work[256];
18+ char *get[6] = {
19+ "今だ!%d番ゲットォォォォ!!",
20+ " ̄ ̄ ̄ ̄ ̄∨ ̄ ̄ ̄       (´´",
21+ "    ∧ ∧          (´⌒(´",
22+ "  ⊂(゚Д゚⊂⌒`つ≡≡≡(´⌒;;;≡≡≡",
23+ "        ̄ ̄  (´⌒(´⌒;;",
24+ "      ズザーーーーーッ"
25+ };
26+
27+ printf("\n\n\n\n\n\n\n");
28+ for (j = 10; j>=0; j--) {
29+ printf("%cM%cM%cM%cM%cM%cM", 27,27,27,27,27,27);
30+ for (i = 0; i<6; i++) {
31+ memset(buf, 0x20, sizeof(buf));
32+ strcpy(&buf[j], get[i]);
33+ strcat(buf, " ");
34+ if (i == 0) {
35+ sprintf(work, buf, getpid());
36+ printf("%s\n", work);
37+ } else {
38+ printf("%s\n", buf);
39+ }
40+ }
41+ usleep(100000);
42+ }
43+}