dockapps/wmdonkeymon/wmdonkeymon/wmdonkeymon.c
2017-02-21 11:15:02 +00:00

480 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++;
}
}