479 lines
13 KiB
C
479 lines
13 KiB
C
|
|
/*
|
|
*
|
|
* wmdonkeymon 0.9 (C) 2002 Marcelo Burgos Morgade Cortizo (marcelomorgade@ig.com.br)
|
|
*
|
|
* - Show status of edonkey downloads based on '*.part.met' files
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <dirent.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <X11/X.h>
|
|
#include <X11/xpm.h>
|
|
#include "../wmgeneral/wmgeneral.h"
|
|
#include "wmdonkeymon_master.xpm"
|
|
#include "wmdonkeymon_mask.xbm"
|
|
|
|
|
|
#define SLOT_SIZE 52
|
|
#define REF_RATE 5
|
|
#define VERSION "0.9"
|
|
|
|
|
|
int xpos[] = { 66, 71, 76, 81, 86, 91, /* A B C D E F */
|
|
66, 71, 76, 81, 86, 91, /* G H I J K L */
|
|
66, 71, 76, 81, 86, 91, /* M N O P Q R */
|
|
66, 71, 76, 81, 86, 91, /* S T U V W X */
|
|
66, 71, 76, 81, 86, 91, /* Y Z / _ - . */
|
|
96, 101, /* 0 1 */
|
|
96, 101, /* 2 3 */
|
|
96, 101, /* 4 5 */
|
|
96, 101, /* 6 7 */
|
|
96, 101
|
|
}; /* 8 9 */
|
|
|
|
int ypos[] = { 4, 4, 4, 4, 4, 4,
|
|
9, 9, 9, 9, 9, 9,
|
|
14, 14, 14, 14, 14, 14,
|
|
19, 19, 19, 19, 19, 19,
|
|
24, 24, 24, 24, 24, 24,
|
|
4, 4,
|
|
9, 9,
|
|
14, 14,
|
|
19, 19,
|
|
24, 24
|
|
};
|
|
|
|
|
|
int but_stat;
|
|
XEvent Event;
|
|
|
|
|
|
struct downlinfo {
|
|
char metname[30];
|
|
char name[516];
|
|
long int lastsize;
|
|
long int size;
|
|
char type[30];
|
|
long int copied;
|
|
int gappos[50][2];
|
|
int firstgap;
|
|
int t_miss;
|
|
unsigned char gapnum;
|
|
unsigned char status;
|
|
} files[4];
|
|
|
|
void usage();
|
|
void printversion();
|
|
void showString(char * buf, int row);
|
|
void pressEvent(XButtonEvent * xev);
|
|
void getStatus(int i,char * st);
|
|
void loadConfig(char * dir);
|
|
void splash();
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
int i=0,debug=0,r,j=0,x=0,selected=-1;
|
|
long int gi=0,gf=0;
|
|
int colord=66,colorg=71;
|
|
struct dirent **namelist;
|
|
int ls=0,metnum=0;
|
|
unsigned char buf[516] ;
|
|
char * tmpdir = NULL;
|
|
for (i=1; i<argc; i++) {
|
|
char *arg = argv[i];
|
|
if (*arg=='-') {
|
|
switch (arg[1]) {
|
|
case 't' :
|
|
tmpdir = argv[i+1];
|
|
printf("Using temp dir %s\n",tmpdir);
|
|
break;
|
|
case 'w' :
|
|
if (argc>i+1){
|
|
if (!strcasecmp(argv[i+1],"red")) colord=71;
|
|
else if (!strcasecmp(argv[i+1],"blue")) colord=76;
|
|
else if (!strcasecmp(argv[i+1],"yellow")) colord=81;
|
|
else if (!strcasecmp(argv[i+1],"white")) colord=86;
|
|
else if (!strcasecmp(argv[i+1],"cyan")) colord=91;
|
|
else if (!strcasecmp(argv[i+1],"black")) colord=96;
|
|
else if (!strcasecmp(argv[i+1],"blank")) colord=101;
|
|
else printf("Invalid color %s\n",argv[i+1]);
|
|
}else {usage();exit(-1);}
|
|
break;
|
|
case 'g' :
|
|
if (argc>i+1){
|
|
if (!strcasecmp(argv[i+1],"green")) colorg=66;
|
|
else if (!strcasecmp(argv[i+1],"blue")) colorg=76;
|
|
else if (!strcasecmp(argv[i+1],"yellow")) colorg=81;
|
|
else if (!strcasecmp(argv[i+1],"white")) colorg=86;
|
|
else if (!strcasecmp(argv[i+1],"cyan")) colorg=91;
|
|
else if (!strcasecmp(argv[i+1],"black")) colorg=96;
|
|
else if (!strcasecmp(argv[i+1],"blank")) colorg=101;
|
|
else printf("Invalid color %s\n",argv[i+1]);
|
|
}else {usage();exit(-1);}
|
|
break;
|
|
case 'v' :
|
|
printversion();
|
|
exit(0);
|
|
break;
|
|
case 'd' :
|
|
debug=1;
|
|
printf("Debuggin mode: \n");
|
|
break;
|
|
default:
|
|
usage();
|
|
exit(0);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!tmpdir) { usage(); exit(-1);}
|
|
|
|
openXwindow(argc, argv, wmdonkeymon_master_xpm, wmdonkeymon_mask_bits, wmdonkeymon_mask_width, wmdonkeymon_mask_height);
|
|
copyXPMArea(5,60,52,54,5,3);
|
|
RedrawWindow();
|
|
splash();
|
|
|
|
|
|
r = 0;
|
|
while (1) {
|
|
if (!r) {
|
|
FILE * met;
|
|
unsigned char type;
|
|
short int len=0,vlen=0;
|
|
int gaps=0, firstgap = 0x7fffffff, miss=0, fsize=0,metcount=0;
|
|
long int fileSize=0, num =0;
|
|
char nvalue[516],value[516];
|
|
j =0;
|
|
metnum=0;
|
|
// Search for files in temp directory
|
|
ls = scandir(tmpdir, &namelist, 0, alphasort);
|
|
if (ls < 0){
|
|
printf("Can't find files in %s",tmpdir);
|
|
exit(-1);
|
|
}
|
|
else {
|
|
while(ls-- && (metcount<4)) {
|
|
char * pt;
|
|
pt = strstr(namelist[ls]->d_name,".part.met");
|
|
if (pt && !strcmp(pt,".part.met")) {
|
|
if(debug)printf("File: %s\n",namelist[ls]->d_name);
|
|
strcpy(files[metcount].metname,namelist[ls]->d_name);
|
|
metcount++;
|
|
}
|
|
free(namelist[ls]);
|
|
}
|
|
free(namelist);
|
|
}
|
|
for (metnum=0; metnum < metcount; metnum++) {
|
|
i=0;
|
|
sprintf(buf,"%s%s",tmpdir,files[metnum].metname);
|
|
files[metnum].t_miss=0;
|
|
if(debug)printf("opening %s\n",buf);
|
|
if ( (met = fopen(buf,"rb")) != NULL) {}
|
|
else {printf("Nada\n");};
|
|
|
|
// Version
|
|
i += fread(buf,1,1,met);
|
|
if(debug){ printf("Version: %x\n",buf[0]); }
|
|
|
|
// Date ??
|
|
i += fread(buf,1,4,met);
|
|
if(debug) { printf("Date: %x %x %x %x \n",buf[0],buf[1],buf[2],buf[3]); }
|
|
|
|
// Hash
|
|
i += fread(buf,1,16,met);
|
|
if(debug){ printf("Hash: "); for (j=0;j<16;j++) printf("%x ",buf[j]); printf("\n"); }
|
|
|
|
|
|
// Partial Hashes
|
|
i += fread(buf,1,2,met);
|
|
memcpy(&j,buf,2);
|
|
if(debug) printf("Num of Hashes: %d\n",j);
|
|
|
|
// Hashes
|
|
for (i=0;i<j;i++){
|
|
fread(buf,1,16,met);
|
|
if(debug){printf("Hash %d: ",i+1); for (x=0;x<16;x++) printf("%x ",buf[x]); printf("\n");}
|
|
}
|
|
|
|
// Num of Meta Tags
|
|
i = fread(buf,1,4,met);
|
|
memcpy(&num,buf,4);
|
|
if(debug){printf("Num of Meta Tags: %ld\n",num);}
|
|
x = 0;
|
|
|
|
// Meta Tags
|
|
for (i=0;i<num;i++){
|
|
fread(&type,1,1,met);
|
|
fread(&len,2,1,met);
|
|
fread(nvalue,1,len,met);
|
|
if (type==2){
|
|
// String Tag
|
|
fread(&vlen,1,2,met);
|
|
fread(value,1,vlen,met);
|
|
value[vlen] = '\0';
|
|
if (len==1){
|
|
// Special Tag
|
|
switch (nvalue[0]){
|
|
case 1:
|
|
strcpy(files[metnum].name,value);
|
|
if(debug){printf("File Name: %s\n",value);}
|
|
break;
|
|
case 3:
|
|
if(debug){printf("File Type: %s\n",value);}
|
|
strcpy(files[metnum].type,value);
|
|
break;
|
|
case 4:
|
|
if(debug){printf("File Format: %s\n",value);}
|
|
break;
|
|
case 18:
|
|
if(debug){printf("Temp file: %s\n",value);}
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (debug)printf("Unknow String Tag %d: %s",nvalue[0],value);
|
|
}else if (type==3){
|
|
fread(&fsize,1,4,met);
|
|
if (len==1){
|
|
// Special Tag
|
|
switch (nvalue[0]){
|
|
case 2:
|
|
if(debug)printf("File Size: %d KB\n",fsize/(1024));
|
|
fileSize = fsize;
|
|
break;
|
|
case 8:
|
|
if(debug)printf("Copied so Far: %d KB\n",fsize/(1024));
|
|
files[metnum].copied=fsize;
|
|
break;
|
|
case 19:
|
|
if(debug) printf("Priority: %d\n",fsize);
|
|
break;
|
|
case 20:
|
|
if(debug)printf("Status: %d\n",fsize);
|
|
files[metnum].status = fsize;
|
|
break;
|
|
default:
|
|
if(debug)printf("Unknow Tag %d: %d\n",nvalue[0],fsize);
|
|
break;
|
|
}
|
|
} else {
|
|
if (nvalue[0]==9){
|
|
nvalue[len]='\0';
|
|
if(debug)printf("gap %3s from %10d", &nvalue[1], fsize);
|
|
gaps = fsize;
|
|
if (gaps < firstgap) firstgap = gaps;
|
|
}else if (nvalue[0]==10){
|
|
miss = fsize - gaps;
|
|
gi = (long int)((SLOT_SIZE * (gaps/1024)) / (fileSize/1024));
|
|
gf = (long int)((SLOT_SIZE * (fsize/1024)) / (fileSize/1024));
|
|
if (gf>=gi){
|
|
files[metnum].gappos[x][0] = gi;
|
|
files[metnum].gappos[x][1] = gf;
|
|
x++;
|
|
}
|
|
files[metnum].t_miss += miss;
|
|
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]);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
files[metnum].gapnum = x;
|
|
files[metnum].firstgap = firstgap;
|
|
files[metnum].lastsize = files[metnum].copied;
|
|
files[metnum].size = fileSize;
|
|
|
|
// sort gaps
|
|
/* don'n needed
|
|
* for (i=0; i<x; i++)
|
|
for (j=0; j<x; j++) {
|
|
if (files[0].gappos[i][0]<files[0].gappos[j][0]) {
|
|
z = files[0].gappos[i][0];
|
|
files[0].gappos[i][0] = files[0].gappos[j][0];
|
|
files[0].gappos[j][0] = z;
|
|
z = files[0].gappos[i][1];
|
|
files[0].gappos[i][1] = files[0].gappos[j][1];
|
|
files[0].gappos[j][1] = z;
|
|
}
|
|
}
|
|
if(debug)for (i=0; i<x; i++){ printf("[%d-%d]",files[0].gappos[i][0],files[0].gappos[i][1]); }
|
|
*/
|
|
|
|
if(debug)printf("%d bytes = %.2f mb missing\n", files[metnum].t_miss, (double)files[metnum].t_miss/(1024*1024));
|
|
if(debug)if (firstgap < 0x7fffffff) printf("first gap starts at %d (%d blocks are complete)\n", firstgap, firstgap/(9500*1024));
|
|
|
|
|
|
fclose(met);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
while (XPending(display)) {
|
|
XNextEvent(display, &Event);
|
|
switch (Event.type) {
|
|
case Expose:
|
|
RedrawWindow();
|
|
break;
|
|
case ButtonPress:
|
|
but_stat = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
|
|
break;
|
|
case ButtonRelease:
|
|
i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
|
|
if (but_stat == i && but_stat >= 0) {
|
|
if (selected>-1) selected=-1;
|
|
else selected=i;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (j=0;j<15;j++) DelMouseRegion(j);
|
|
|
|
if (metnum==0){
|
|
splash();
|
|
showString("NO FILES",8);
|
|
showString("FOUND IN",9);
|
|
showString("TEMP DIR",10);
|
|
}else if (selected>-1){
|
|
char out[30];
|
|
char unit[4] = " KMG";
|
|
long int s,c;
|
|
int sk=0,ck=0;
|
|
copyXPMArea(5,60,52,54,5,3);
|
|
AddMouseRegion(0,5,5,54,54);
|
|
showString(files[selected].name,1);
|
|
|
|
s=files[selected].size;
|
|
while (s>1024){s/=1024;sk++;}
|
|
c=files[selected].copied;
|
|
while (c>1024){c/=1024;ck++;}
|
|
|
|
sprintf(out,"%ld%c/%ld%c",c,unit[ck],s,unit[sk]);
|
|
showString(out,4);
|
|
|
|
sprintf(out,"%s",files[selected].type);
|
|
showString(out,5);
|
|
|
|
// **************
|
|
// Donwload Rate
|
|
// Don't work unless edonkey update met files more frequently
|
|
//
|
|
// s = (files[selected].copied) - (files[selected].lastsize);
|
|
// sprintf(out,"%ld B/S",(s/REF_RATE));
|
|
// showString(out,8);
|
|
|
|
//************************
|
|
//STATUS
|
|
//status tag is always "Looking..." :(
|
|
//
|
|
//getStatus(files[selected].status,out);
|
|
//showString(out,9);
|
|
sprintf(out,"%.3f%%", (( 1.0 * files[selected].copied / files[selected].size))*100);
|
|
showString(out,8);
|
|
|
|
copyXPMArea(66,colord,52,5,5,11);
|
|
for (i=0; i < files[selected].gapnum ; i++) {
|
|
copyXPMArea(66,colorg,files[selected].gappos[i][1]-files[selected].gappos[i][0],5,files[selected].gappos[i][0]+5 ,11);
|
|
}
|
|
}else{
|
|
copyXPMArea(5,60,52,54,5,3);
|
|
for (j=0; j<metnum; j++){
|
|
showString(files[j].name,(j*2)+1+j);
|
|
copyXPMArea(66,colord,52,5,5,(j+1)*10+(j*5) );
|
|
// printf("top: %d\n",((j+1)*10+(j*5)));
|
|
for (i=0; i < files[j].gapnum ; i++) {
|
|
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));
|
|
}
|
|
AddMouseRegion(j,5,(j+1)*5,52,(j+1)*10+(j*5)+5);
|
|
}
|
|
}
|
|
RedrawWindow();
|
|
|
|
sleep(1);
|
|
r++;
|
|
if (r==REF_RATE) r=0;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void
|
|
usage()
|
|
{
|
|
|
|
printf("\nwmdonkeymon %s: \n",VERSION);
|
|
printf("\nusage: wmdonkeymon -t tmpdir [-w color] [-g color]\n");
|
|
printf("\t-t\t\tPath to edonkey temp dir.\n");
|
|
printf("\t-w\t\tColor for downloaded parts\n");
|
|
printf("\t-g\t\tColor for gaps\n");
|
|
printf("\t-d\t\tDump a lot of debug messages\n");
|
|
printf("\t-h\t\tDisplay help screen.\n");
|
|
printf("\t\tColors: green,red,blue,yellow,white,cyan,black,blank\n");
|
|
}
|
|
|
|
void printversion(){
|
|
printf("\nwmfsm version: \n");
|
|
|
|
}
|
|
void pressEvent(XButtonEvent * xev)
|
|
{
|
|
return;
|
|
}
|
|
|
|
void strcaseup(char * str){
|
|
int i=0;
|
|
while(str[i]){
|
|
if (str[i]>='a' && str[i]<='z') { str[i]-=32;}
|
|
i++;
|
|
}
|
|
}
|
|
|
|
void showString(char * buf, int row){
|
|
int i;
|
|
strcaseup(buf);
|
|
for (i=0; buf[i] && i<10;i++){
|
|
if (buf[i]>='0' && buf[i]<='9') copyXPMArea(xpos[buf[i]-18],ypos[buf[i]-18],5,5,(i+1)*5,(row*5));
|
|
else if((buf[i]>='A' && buf[i]<='Z')) copyXPMArea(xpos[buf[i]-65],ypos[buf[i]-65],5,5,(i+1)*5,(row*5));
|
|
else if((buf[i]==' ')) copyXPMArea(66,44,5,5,(i+1)*5,(row*5));
|
|
else if((buf[i]=='/')) copyXPMArea(76,24,5,5,(i+1)*5,(row*5));
|
|
else if((buf[i]=='.')) copyXPMArea(91,24,5,5,(i+1)*5,(row*5));
|
|
else if((buf[i]=='%')) copyXPMArea(106,24,5,5,(i+1)*5,(row*5));
|
|
else copyXPMArea(xpos[28],ypos[28],5,5,(i+1)*5,(row*5));
|
|
}
|
|
}
|
|
|
|
void getStatus(int i,char * st){
|
|
if (i==0) strcpy(st,"Looking...");
|
|
else if(i==1) strcpy(st,"Paused");
|
|
else strcpy(st," ");
|
|
}
|
|
|
|
void splash(){
|
|
// Splash
|
|
int i=0;
|
|
char * s= ".WMDONKEY.";
|
|
while (i<4){
|
|
RedrawWindow();
|
|
showString(s,1);
|
|
copyXPMArea(70,47,47,19,9,20);
|
|
RedrawWindow();
|
|
sleep(1);
|
|
i++;
|
|
}
|
|
|
|
}
|