wmdots: Fix typo in Makefile - use correct name for binary.
[dockapps.git] / wmdonkeymon / wmdonkeymon / wmdonkeymon.c
blob6eeeda19690a3bf1438246519d59eabbe76fdb06
2 /*
4 * wmdonkeymon 0.9 (C) 2002 Marcelo Burgos Morgade Cortizo (marcelomorgade@ig.com.br)
6 * - Show status of edonkey downloads based on '*.part.met' files
16 #include <stdio.h>
17 #include <dirent.h>
18 #include <unistd.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <X11/X.h>
22 #include <X11/xpm.h>
23 #include "../wmgeneral/wmgeneral.h"
24 #include "wmdonkeymon_master.xpm"
25 #include "wmdonkeymon_mask.xbm"
28 #define SLOT_SIZE 52
29 #define REF_RATE 5
30 #define VERSION "0.9"
33 int xpos[] = { 66, 71, 76, 81, 86, 91, /* A B C D E F */
34 66, 71, 76, 81, 86, 91, /* G H I J K L */
35 66, 71, 76, 81, 86, 91, /* M N O P Q R */
36 66, 71, 76, 81, 86, 91, /* S T U V W X */
37 66, 71, 76, 81, 86, 91, /* Y Z / _ - . */
38 96, 101, /* 0 1 */
39 96, 101, /* 2 3 */
40 96, 101, /* 4 5 */
41 96, 101, /* 6 7 */
42 96, 101
43 }; /* 8 9 */
45 int ypos[] = { 4, 4, 4, 4, 4, 4,
46 9, 9, 9, 9, 9, 9,
47 14, 14, 14, 14, 14, 14,
48 19, 19, 19, 19, 19, 19,
49 24, 24, 24, 24, 24, 24,
50 4, 4,
51 9, 9,
52 14, 14,
53 19, 19,
54 24, 24
58 int but_stat;
59 XEvent Event;
62 struct downlinfo {
63 char metname[30];
64 char name[516];
65 long int lastsize;
66 long int size;
67 char type[30];
68 long int copied;
69 int gappos[50][2];
70 int firstgap;
71 int t_miss;
72 unsigned char gapnum;
73 unsigned char status;
74 } files[4];
76 void usage();
77 void printversion();
78 void showString(char * buf, int row);
79 void pressEvent(XButtonEvent * xev);
80 void getStatus(int i,char * st);
81 void loadConfig(char * dir);
82 void splash();
84 int main(int argc, char *argv[])
86 int i=0,debug=0,r,j=0,x=0,selected=-1;
87 long int gi=0,gf=0;
88 int colord=66,colorg=71;
89 struct dirent **namelist;
90 int ls=0,metnum=0;
91 unsigned char buf[516] ;
92 char * tmpdir = NULL;
93 for (i=1; i<argc; i++) {
94 char *arg = argv[i];
95 if (*arg=='-') {
96 switch (arg[1]) {
97 case 't' :
98 tmpdir = argv[i+1];
99 printf("Using temp dir %s\n",tmpdir);
100 break;
101 case 'w' :
102 if (argc>i+1){
103 if (!strcasecmp(argv[i+1],"red")) colord=71;
104 else if (!strcasecmp(argv[i+1],"blue")) colord=76;
105 else if (!strcasecmp(argv[i+1],"yellow")) colord=81;
106 else if (!strcasecmp(argv[i+1],"white")) colord=86;
107 else if (!strcasecmp(argv[i+1],"cyan")) colord=91;
108 else if (!strcasecmp(argv[i+1],"black")) colord=96;
109 else if (!strcasecmp(argv[i+1],"blank")) colord=101;
110 else printf("Invalid color %s\n",argv[i+1]);
111 }else {usage();exit(-1);}
112 break;
113 case 'g' :
114 if (argc>i+1){
115 if (!strcasecmp(argv[i+1],"green")) colorg=66;
116 else if (!strcasecmp(argv[i+1],"blue")) colorg=76;
117 else if (!strcasecmp(argv[i+1],"yellow")) colorg=81;
118 else if (!strcasecmp(argv[i+1],"white")) colorg=86;
119 else if (!strcasecmp(argv[i+1],"cyan")) colorg=91;
120 else if (!strcasecmp(argv[i+1],"black")) colorg=96;
121 else if (!strcasecmp(argv[i+1],"blank")) colorg=101;
122 else printf("Invalid color %s\n",argv[i+1]);
123 }else {usage();exit(-1);}
124 break;
125 case 'v' :
126 printversion();
127 exit(0);
128 break;
129 case 'd' :
130 debug=1;
131 printf("Debuggin mode: \n");
132 break;
133 default:
134 usage();
135 exit(0);
136 break;
140 if (!tmpdir) { usage(); exit(-1);}
142 openXwindow(argc, argv, wmdonkeymon_master_xpm, wmdonkeymon_mask_bits, wmdonkeymon_mask_width, wmdonkeymon_mask_height);
143 copyXPMArea(5,60,52,54,5,3);
144 RedrawWindow();
145 splash();
148 r = 0;
149 while (1) {
150 if (!r) {
151 FILE * met;
152 unsigned char type;
153 short int len=0,vlen=0;
154 int gaps=0, firstgap = 0x7fffffff, miss=0, fsize=0,metcount=0;
155 long int fileSize=0, num =0;
156 char nvalue[516],value[516];
157 j =0;
158 metnum=0;
159 // Search for files in temp directory
160 ls = scandir(tmpdir, &namelist, 0, alphasort);
161 if (ls < 0){
162 printf("Can't find files in %s",tmpdir);
163 exit(-1);
165 else {
166 while(ls-- && (metcount<4)) {
167 char * pt;
168 pt = strstr(namelist[ls]->d_name,".part.met");
169 if (pt && !strcmp(pt,".part.met")) {
170 if(debug)printf("File: %s\n",namelist[ls]->d_name);
171 strcpy(files[metcount].metname,namelist[ls]->d_name);
172 metcount++;
174 free(namelist[ls]);
176 free(namelist);
178 for (metnum=0; metnum < metcount; metnum++) {
179 i=0;
180 sprintf(buf,"%s%s",tmpdir,files[metnum].metname);
181 files[metnum].t_miss=0;
182 if(debug)printf("opening %s\n",buf);
183 if ( (met = fopen(buf,"rb")) != NULL) {}
184 else {printf("Nada\n");};
186 // Version
187 i += fread(buf,1,1,met);
188 if(debug){ printf("Version: %x\n",buf[0]); }
190 // Date ??
191 i += fread(buf,1,4,met);
192 if(debug) { printf("Date: %x %x %x %x \n",buf[0],buf[1],buf[2],buf[3]); }
194 // Hash
195 i += fread(buf,1,16,met);
196 if(debug){ printf("Hash: "); for (j=0;j<16;j++) printf("%x ",buf[j]); printf("\n"); }
199 // Partial Hashes
200 i += fread(buf,1,2,met);
201 memcpy(&j,buf,2);
202 if(debug) printf("Num of Hashes: %d\n",j);
204 // Hashes
205 for (i=0;i<j;i++){
206 fread(buf,1,16,met);
207 if(debug){printf("Hash %d: ",i+1); for (x=0;x<16;x++) printf("%x ",buf[x]); printf("\n");}
210 // Num of Meta Tags
211 i = fread(buf,1,4,met);
212 memcpy(&num,buf,4);
213 if(debug){printf("Num of Meta Tags: %ld\n",num);}
214 x = 0;
216 // Meta Tags
217 for (i=0;i<num;i++){
218 fread(&type,1,1,met);
219 fread(&len,2,1,met);
220 fread(nvalue,1,len,met);
221 if (type==2){
222 // String Tag
223 fread(&vlen,1,2,met);
224 fread(value,1,vlen,met);
225 value[vlen] = '\0';
226 if (len==1){
227 // Special Tag
228 switch (nvalue[0]){
229 case 1:
230 strcpy(files[metnum].name,value);
231 if(debug){printf("File Name: %s\n",value);}
232 break;
233 case 3:
234 if(debug){printf("File Type: %s\n",value);}
235 strcpy(files[metnum].type,value);
236 break;
237 case 4:
238 if(debug){printf("File Format: %s\n",value);}
239 break;
240 case 18:
241 if(debug){printf("Temp file: %s\n",value);}
242 break;
246 } else if (debug)printf("Unknow String Tag %d: %s",nvalue[0],value);
247 }else if (type==3){
248 fread(&fsize,1,4,met);
249 if (len==1){
250 // Special Tag
251 switch (nvalue[0]){
252 case 2:
253 if(debug)printf("File Size: %d KB\n",fsize/(1024));
254 fileSize = fsize;
255 break;
256 case 8:
257 if(debug)printf("Copied so Far: %d KB\n",fsize/(1024));
258 files[metnum].copied=fsize;
259 break;
260 case 19:
261 if(debug) printf("Priority: %d\n",fsize);
262 break;
263 case 20:
264 if(debug)printf("Status: %d\n",fsize);
265 files[metnum].status = fsize;
266 break;
267 default:
268 if(debug)printf("Unknow Tag %d: %d\n",nvalue[0],fsize);
269 break;
271 } else {
272 if (nvalue[0]==9){
273 nvalue[len]='\0';
274 if(debug)printf("gap %3s from %10d", &nvalue[1], fsize);
275 gaps = fsize;
276 if (gaps < firstgap) firstgap = gaps;
277 }else if (nvalue[0]==10){
278 miss = fsize - gaps;
279 gi = (long int)((SLOT_SIZE * (gaps/1024)) / (fileSize/1024));
280 gf = (long int)((SLOT_SIZE * (fsize/1024)) / (fileSize/1024));
281 if (gf>=gi){
282 files[metnum].gappos[x][0] = gi;
283 files[metnum].gappos[x][1] = gf;
284 x++;
286 files[metnum].t_miss += miss;
287 if(debug)printf(" to %10d = %10d Size(%d) Gaprel: %d-%d\n",fsize,miss,9728000,files[metnum].gappos[x][0],files[metnum].gappos[x][1]);
294 files[metnum].gapnum = x;
295 files[metnum].firstgap = firstgap;
296 files[metnum].lastsize = files[metnum].copied;
297 files[metnum].size = fileSize;
299 // sort gaps
300 /* don'n needed
301 * for (i=0; i<x; i++)
302 for (j=0; j<x; j++) {
303 if (files[0].gappos[i][0]<files[0].gappos[j][0]) {
304 z = files[0].gappos[i][0];
305 files[0].gappos[i][0] = files[0].gappos[j][0];
306 files[0].gappos[j][0] = z;
307 z = files[0].gappos[i][1];
308 files[0].gappos[i][1] = files[0].gappos[j][1];
309 files[0].gappos[j][1] = z;
312 if(debug)for (i=0; i<x; i++){ printf("[%d-%d]",files[0].gappos[i][0],files[0].gappos[i][1]); }
315 if(debug)printf("%d bytes = %.2f mb missing\n", files[metnum].t_miss, (double)files[metnum].t_miss/(1024*1024));
316 if(debug)if (firstgap < 0x7fffffff) printf("first gap starts at %d (%d blocks are complete)\n", firstgap, firstgap/(9500*1024));
319 fclose(met);
325 while (XPending(display)) {
326 XNextEvent(display, &Event);
327 switch (Event.type) {
328 case Expose:
329 RedrawWindow();
330 break;
331 case ButtonPress:
332 but_stat = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
333 break;
334 case ButtonRelease:
335 i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
336 if (but_stat == i && but_stat >= 0) {
337 if (selected>-1) selected=-1;
338 else selected=i;
340 break;
344 for (j=0;j<15;j++) DelMouseRegion(j);
346 if (metnum==0){
347 splash();
348 showString("NO FILES",8);
349 showString("FOUND IN",9);
350 showString("TEMP DIR",10);
351 }else if (selected>-1){
352 char out[30];
353 char unit[4] = " KMG";
354 long int s,c;
355 int sk=0,ck=0;
356 copyXPMArea(5,60,52,54,5,3);
357 AddMouseRegion(0,5,5,54,54);
358 showString(files[selected].name,1);
360 s=files[selected].size;
361 while (s>1024){s/=1024;sk++;}
362 c=files[selected].copied;
363 while (c>1024){c/=1024;ck++;}
365 sprintf(out,"%ld%c/%ld%c",c,unit[ck],s,unit[sk]);
366 showString(out,4);
368 sprintf(out,"%s",files[selected].type);
369 showString(out,5);
371 // **************
372 // Donwload Rate
373 // Don't work unless edonkey update met files more frequently
375 // s = (files[selected].copied) - (files[selected].lastsize);
376 // sprintf(out,"%ld B/S",(s/REF_RATE));
377 // showString(out,8);
379 //************************
380 //STATUS
381 //status tag is always "Looking..." :(
383 //getStatus(files[selected].status,out);
384 //showString(out,9);
385 sprintf(out,"%.3f%%", (( 1.0 * files[selected].copied / files[selected].size))*100);
386 showString(out,8);
388 copyXPMArea(66,colord,52,5,5,11);
389 for (i=0; i < files[selected].gapnum ; i++) {
390 copyXPMArea(66,colorg,files[selected].gappos[i][1]-files[selected].gappos[i][0],5,files[selected].gappos[i][0]+5 ,11);
392 }else{
393 copyXPMArea(5,60,52,54,5,3);
394 for (j=0; j<metnum; j++){
395 showString(files[j].name,(j*2)+1+j);
396 copyXPMArea(66,colord,52,5,5,(j+1)*10+(j*5) );
397 // printf("top: %d\n",((j+1)*10+(j*5)));
398 for (i=0; i < files[j].gapnum ; i++) {
399 copyXPMArea(66,colorg,files[j].gappos[i][1]-files[j].gappos[i][0],5,files[j].gappos[i][0]+5 ,(j+1)*10+(j*5));
401 AddMouseRegion(j,5,(j+1)*5,52,(j+1)*10+(j*5)+5);
404 RedrawWindow();
406 sleep(1);
407 r++;
408 if (r==REF_RATE) r=0;
415 void
416 usage()
419 printf("\nwmdonkeymon %s: \n",VERSION);
420 printf("\nusage: wmdonkeymon -t tmpdir [-w color] [-g color]\n");
421 printf("\t-t\t\tPath to edonkey temp dir.\n");
422 printf("\t-w\t\tColor for downloaded parts\n");
423 printf("\t-g\t\tColor for gaps\n");
424 printf("\t-d\t\tDump a lot of debug messages\n");
425 printf("\t-h\t\tDisplay help screen.\n");
426 printf("\t\tColors: green,red,blue,yellow,white,cyan,black,blank\n");
429 void printversion(){
430 printf("\nwmfsm version: \n");
433 void pressEvent(XButtonEvent * xev)
435 return;
438 void strcaseup(char * str){
439 int i=0;
440 while(str[i]){
441 if (str[i]>='a' && str[i]<='z') { str[i]-=32;}
442 i++;
446 void showString(char * buf, int row){
447 int i;
448 strcaseup(buf);
449 for (i=0; buf[i] && i<10;i++){
450 if (buf[i]>='0' && buf[i]<='9') copyXPMArea(xpos[buf[i]-18],ypos[buf[i]-18],5,5,(i+1)*5,(row*5));
451 else if((buf[i]>='A' && buf[i]<='Z')) copyXPMArea(xpos[buf[i]-65],ypos[buf[i]-65],5,5,(i+1)*5,(row*5));
452 else if((buf[i]==' ')) copyXPMArea(66,44,5,5,(i+1)*5,(row*5));
453 else if((buf[i]=='/')) copyXPMArea(76,24,5,5,(i+1)*5,(row*5));
454 else if((buf[i]=='.')) copyXPMArea(91,24,5,5,(i+1)*5,(row*5));
455 else if((buf[i]=='%')) copyXPMArea(106,24,5,5,(i+1)*5,(row*5));
456 else copyXPMArea(xpos[28],ypos[28],5,5,(i+1)*5,(row*5));
460 void getStatus(int i,char * st){
461 if (i==0) strcpy(st,"Looking...");
462 else if(i==1) strcpy(st,"Paused");
463 else strcpy(st," ");
466 void splash(){
467 // Splash
468 int i=0;
469 char * s= ".WMDONKEY.";
470 while (i<4){
471 RedrawWindow();
472 showString(s,1);
473 copyXPMArea(70,47,47,19,9,20);
474 RedrawWindow();
475 sleep(1);
476 i++;