pdial: la trasformazione di aswvdial - la potenza della GPL
Pubblicato da syscalo il 27/12/2002
Livello base
Introduzione
Da qualche tempo sono passato da Suse a Debian e tra i vari cambiamenti
c'è anche quello riguardante la connessione a internet. Con la Suse
utilizzavo wvdial mentre con la Debian sono passato a pon, poff & Co.
Per wvdial è disponibile una dockapp (io uso window maker) per
"controllarlo" e che mostra quando effettivamente è stato "tirato su"
ppp0 e la durata della connessione.
"Purtroppo" mi sono affezionato a aswvdial ma volendo usare pon e poff
l'unica soluzione è modificare adeguatamente aswvdial (di cui sono
disponibili i sorgenti ed è anche distribuito con licenza GPL) per
trasformarlo in pdial.
Programmi usati
Iniziamo
Analizzando il codice sorgente di aswvdial ho ricavato che funziona nel seguente modo:
Per quanto riguarda la configurazione ho deciso di mettere nel file /etc/pdial.conf i nomi dei vari account uno per riga. Questo perchè il comando pon accetta il nome dell'account come parametro. La funzione di lettura della configurazione si occupa solo di leggere ogni riga di questo file e di aggiungerla all'array già utilizzato da aswvdial per gestire i vari account.
Il comando di attivazione della connessione diventa ora "pon %s" in modo da
passare il nome dell'account selezionato a pon.
Il comando di disconnessione diventa ora "poff".
Sostituiti i 2 comandi nelle system e ripulite le parti inutili il lavoro
è fatto.
Dopo aver apportato le modifiche ho dato una ripulita ai sorgenti eliminando le variabili non più utilizzate; ho eliminato anche la gestione dei parametri dalla linea di comando e quindi la funzione che visualizza l'help in quanto il programma a mio modo di vedere va usato direttamente come dockapp avviata all'avvio di window maker.
Il nuovo programma pdial è disponibile, ovviamente con licenza GPL.
Di seguito c'è il listato del file pdial.c derivato da aswvdial.c:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <X11/Xlib.h>
#include <X11/xpm.h>
#include <X11/extensions/shape.h>
#include "./wmgeneral/wmgeneral.h"
#include "./wmgeneral/misc.h"
#include "master.xpm"
#include "mask.xbm"
#define TRUE 1
#define FALSE 0
#define VERSION "1.1"
char wvdial_opt[30][30];
int maxentrys;
int connection=FALSE;
int entry=0;
time_t start_t=0;
double elapsed_t=0.0;
/*prototypes*/
void pressEvent(XButtonEvent *xbe);
int readproc(void);
int readconfig(void);
void timing(char *cmd);
void drawCHAR(char what[]);
void drawNUMBER(int x, int y, double what);
int main(int argc, char **argv)
{
XEvent Event;
if(!readconfig()) return 1;
openXwindow(argc, argv, master_xpm, mask_bits, mask_width, mask_height);
while(1)
{
while(XPending(display))
{
XNextEvent(display, &Event);
switch(Event.type)
{
case Expose:
RedrawWindow();
break;
case ButtonPress:
pressEvent(&Event.xbutton);
break;
case DestroyNotify:
XCloseDisplay(display);
exit(0);
break;
default:
break;
}
} /*end of while XPending*/
drawCHAR(wvdial_opt[entry]);
if(readproc()==1)
{
copyXPMArea(8,96,7,7,2,42);
timing("start");
}
else
{
copyXPMArea(1,96,7,7,2,42);
timing("stop");
}
RedrawWindow();
usleep(50000L);
} /*end of while*/
return 0;
}
void pressEvent(XButtonEvent *xbe)
{
int x=xbe->x;
int y=xbe->y;
char temp[50];
if(xbe->button==Button1)
{
if(y>=50 && y<=64)
/*mouse click on buttons*/
{
if(x>=1 && x<=20 && !connection)
/*mouse click on left button*/
{
if(entry==0) entry=maxentrys;
else entry--;
}
if(x>=22 && x<=43)
/*mouse click on middle button*/
{
if(!connection)
{
copyXPMArea( 1,66,20,15,1,50);
copyXPMArea(22,66,22,15,22,50);
copyXPMArea(45,66,20,15,45,50);
connection=TRUE;
/*
sprintf(temp,"netup %s",wvdial_opt[entry]);
if(system(temp)==-1) printf("\nError: Cannot execute wvdial\n");
*/
sprintf(temp,"pon %s",wvdial_opt[entry]);
if(system(temp)==-1) printf("\nError: Cannot execute pon\n");
}
else
{
copyXPMArea( 1,81,20,15,1,50);
copyXPMArea(22,81,22,15,22,50);
copyXPMArea(45,81,20,15,45,50);
/*
if(system("netdown")==-1) printf("\nError: Cannot close connection\n");
*/
if(system("poff")==-1) printf("\nError: Cannot close connection\n");
connection=FALSE;
}
}
if(x>=45 && x<=64 && !connection)
/*mouse click on right button*/
{
if(entry==maxentrys) entry=0;
else entry++;
}
}
}
}
int readconfig(void)
{
FILE *config=NULL;
char line[256];
maxentrys=0;
config=fopen("/etc/pdial.conf","r");
if(config != 0)
{
while(fgets(line,256,config) != NULL)
{
if(maxentrys<=29)
{
strcpy(wvdial_opt[maxentrys++],line);
}
}
if(maxentrys!=0) maxentrys--;
fclose(config);
}
else
{
printf("\nError: cannot open /etc/pdial.conf\n");
return 0;
}
return 1;
}
int readproc(void)
{
FILE *fp=NULL;
char line[256];
int temp=0;
fp=fopen("/proc/net/route","r");
if(fp)
{
while(fgets(line,256,fp))
{
if(strstr(line,"ppp0")) temp=1;
}
}
else
{
printf("\nError: cannot open /proc/net/route\n");
}
fclose(fp);
return temp;
}
void timing(char *cmd)
{
double hours,minutes,seconds;
static int starttimer=TRUE;
if(cmd=="start")
{
if(starttimer)
{
starttimer=FALSE;
start_t=time(0);
}
elapsed_t=difftime(time(0),start_t);
}
else
{
if(!starttimer)
{
starttimer=TRUE;
elapsed_t=difftime(time(0),start_t);
}
}
minutes=modf(elapsed_t/3600,&hours);
minutes=minutes*60;
seconds=modf(minutes,&minutes);
seconds=seconds*60;
drawNUMBER( 1,23,hours);
drawNUMBER(17,23,minutes);
drawNUMBER(33,23,seconds);
}
void drawCHAR(char what[])
{
int i,x,y;
x=y=1;
for(i=0;i<18;i++,x=x+7)
{
if(i==9)
{
x=1;
y=11;
}
switch(toupper(what[i]))
{
case 'A':
copyXPMArea(15,111,7,9,x,y);
break;
case 'B':
copyXPMArea(22,111,7,9,x,y);
break;
case 'C':
copyXPMArea(29,111,7,9,x,y);
break;
case 'D':
copyXPMArea(36,111,7,9,x,y);
break;
case 'E':
copyXPMArea(43,111,7,9,x,y);
break;
case 'F':
copyXPMArea(50,111,7,9,x,y);
break;
case 'G':
copyXPMArea(57,111,7,9,x,y);
break;
case 'H':
copyXPMArea(1,120 ,7,9,x,y);
break;
case 'I':
copyXPMArea(8,120,7,9,x,y);
break;
case 'J':
copyXPMArea(15,120,7,9,x,y);
break;
case 'K':
copyXPMArea(22,120,7,9,x,y);
break;
case 'L':
copyXPMArea(29,120,7,9,x,y);
break;
case 'M':
copyXPMArea(36,120,7,9,x,y);
break;
case 'N':
copyXPMArea(43,120,7,9,x,y);
break;
case 'O':
copyXPMArea(50,120,7,9,x,y);
break;
case 'P':
copyXPMArea(57,120,7,9,x,y);
break;
case 'Q':
copyXPMArea(1,129,7,9,x,y);
break;
case 'R':
copyXPMArea(8,129 ,7,9,x,y);
break;
case 'S':
copyXPMArea(15,129,7,9,x,y);
break;
case 'T':
copyXPMArea(22,129,7,9,x,y);
break;
case 'U':
copyXPMArea(29,129,7,9,x,y);
break;
case 'V':
copyXPMArea(36,129,7,9,x,y);
break;
case 'W':
copyXPMArea(43,129,7,9,x,y);
break;
case 'X':
copyXPMArea(50,129,7,9,x,y);
break;
case 'Y':
copyXPMArea(57,129,7,9,x,y);
break;
case 'Z':
copyXPMArea(1,138,7,9,x,y);
break;
case '0':
copyXPMArea(1,102,7,9,x,y);
break;
case '1':
copyXPMArea(8,102,7,9,x,y);
break;
case '2':
copyXPMArea(15,102,7,9,x,y);
break;
case '3':
copyXPMArea(22,102,7,9,x,y);
break;
case '4':
copyXPMArea(29,102,7,9,x,y);
break;
case '5':
copyXPMArea(36,102,7,9,x,y);
break;
case '6':
copyXPMArea(43,102,7,9,x,y);
break;
case '7':
copyXPMArea(50,102,7,9,x,y);
break;
case '8':
copyXPMArea(57,102,7,9,x,y);
break;
case '9':
copyXPMArea(1,111,7,9,x,y);
break;
default:
copyXPMArea(8,111,7,9,x,y);
break;
} /*end of switch*/
} /*end of for*/
}
void drawNUMBER(int x, int y, double what)
{
int i;
double a,b;
a=modf(what/10,&b);
for(i=0;i<2;i++,x=x+7,a=modf(a*10,&b))
{
switch((int) b)
{
case 0:
copyXPMArea(1,102,7,9,x,y);
break;
case 1:
copyXPMArea(8,102,7,9,x,y);
break;
case 2:
copyXPMArea(15,102,7,9,x,y);
break;
case 3:
copyXPMArea(22,102,7,9,x,y);
break;
case 4:
copyXPMArea(29,102,7,9,x,y);
break;
case 5:
copyXPMArea(36,102,7,9,x,y);
break;
case 6:
copyXPMArea(43,102,7,9,x,y);
break;
case 7:
copyXPMArea(50,102,7,9,x,y);
break;
case 8:
copyXPMArea(57,102,7,9,x,y);
break;
case 9:
copyXPMArea(1,111,7,9,x,y);
break;
default:
copyXPMArea(8,111,7,9,x,y);
break;
} /*end of switch*/
} /*end of for*/
}
Conclusioni
Come avrete capito le modifiche apportate al programma originale sono molto
semplici, ma spero anche che avrete capito che lo scopo del tutorial è di
mostrare come con un po' di reversing dei sorgenti sia possibile far
nascere nuovi programmi risparmiando un sacco di tempo: per dare un'idea,
per ottenere pdial nella sua versione finale sono bastati 10 minuti, se avessi
dovuto scrivere l'applicazione da zero tra la raccolta delle informazioni
(su come si crea e gestisce una dockapp) e la realizzazione ci sarebbero volute
almeno due giornate.
Per concludere, sfruttate il codice altrui il più possibile!!
bye syscalo