oga's tools
修訂 | aefa1f5106cfe7c5747dce12926e539983d9a56a (tree) |
---|---|
時間 | 2013-12-31 10:56:32 |
作者 | oga <oga@mxg....> |
Commiter | oga |
add tools
@@ -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 | +} |
@@ -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 | + |
@@ -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> > < &) | |
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 | + |
@@ -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[]="[32m <H> [1B [35mH H H [1B HHHHH [1B H H H \n"; | |
94 | +#else /* X68000 */ | |
95 | +char ship[]="[37m <H> [1B [35mH H H [1B HHHHH [1B H H H \n"; | |
96 | +#endif /* X68000 */ | |
97 | +char space[]=" [1B "; | |
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]="[33mV v[1B[36mXooX\n"; | |
128 | + alien[1]="[33mv V[1B[36mXOOX\n"; | |
129 | +#else /* X68000 */ | |
130 | + alien[0]="[37mV v[1B[36mXooX\n"; | |
131 | + alien[1]="[37mv V[1B[36mXOOX\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("[2J[0;0H\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,"☆☆[1B☆☆",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("[35mA"); | |
509 | + } | |
510 | + sprintf(buf, "SCORE [37m%08d\n",sc); | |
511 | + sprintf(bufhi,"HI-SCORE [37m%08d [35m%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," ☆☆[1B ☆☆☆[1B ☆☆☆[1B ☆☆☆\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 | +} |
@@ -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 | +} |
@@ -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 | + |
@@ -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 | + */ |
@@ -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 | + */ |
@@ -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 | + |
@@ -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 | + |
@@ -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 | +} |
@@ -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 | + |
@@ -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 | +} |
@@ -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 | + |
@@ -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 | + |
@@ -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 | + |
@@ -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 | +} |
@@ -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 | +} |
@@ -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 | + |
@@ -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 | +} |
@@ -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 | +} |
@@ -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 | + |
@@ -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 | +} |
@@ -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 | +} |
@@ -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 | + |
@@ -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 | +} |
@@ -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 | + */ |
@@ -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 | +} |
@@ -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 | + */ |
@@ -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 | + |
@@ -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 | + |
@@ -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 | +} |
@@ -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 | +} |
@@ -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 */ |
@@ -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 | +} |
@@ -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 | +} |
@@ -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 | +} |