#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAXLINE 1024
static int alarm_flag = 0;
static struct sigaction act1, oact1;
int input_timeout(int, unsigned int);
int readline(int, char *, size_t);
int mkconnectsock(char *, int, int);
void alarm_function(int);
void isip4addr(char *);
int main(int argc, char *argv[]) {
FILE *fpout = {0};
char line[MAXLINE];
char c;
char *ptr = NULL;
char *ipaddr = "10.0.0.138";
char *comtab[2] = { "adsl info", "exit" };
int comtabsize = 2;
int ipport = 23;
int conntimeout = 10;
int sockid, bread;
int i, state;
i = state = 0;
/* this is a quick hack.. Not a program...! */
if(argc == 1)
error(1, 0, "Usage: %s ip4address", "adslinfo");
else {
isip4addr(argv[1]);
ipaddr = argv[1];
}
/* connect & setup write descrip. */
sockid = mkconnectsock(ipaddr, ipport, conntimeout);
if((fpout = fdopen(sockid, "w")) == NULL)
error(1, 0, "Error - fdopen()");
/* skipping the first [telnet] connection block.. */
/* SOH ETX SOH ETX */
/* 377 373 001 377 373 003 377 373 001 377 373 003 */
for(i = 0; i < 12; i++)
if((bread = recv(sockid, &c, 1, 0)) == -1)
error(1, 0, "Error - recv(): first 12 bytes");
/* w're not event driven.. */
fprintf(fpout, "%s", "\r\f"), fflush(fpout);
fprintf(fpout, "%s", "\r\f"), fflush(fpout);
/* issue commands */
for(i = 0; i < comtabsize; i++) {
fprintf(fpout, "%s\r\f", comtab[i]), fflush(fpout);
while(readline(sockid, line, sizeof(line)) > 0) {
if(line[0] == '=' && line[1] == '>')
break;
if(line[0] == 'M' && line[1] == 'o')
state = 1;
if(state == 1)
for(ptr = line; *ptr; ptr++)
if(*ptr != '\r')
printf("%c", *ptr);
}
}
return 0;
}
int mkconnectsock(char *ipstr, int port, int tmout) {
int sockid = -1;
struct sockaddr_in pin;
struct hostent *nlp_host;
if((nlp_host = gethostbyname(ipstr)) == 0)
error(1, 0, "Error - resolving host: %s", ipstr);
memset(&pin, '\0', sizeof(pin));
pin.sin_family = AF_INET;
pin.sin_addr.s_addr = htonl(INADDR_ANY);
pin.sin_addr.s_addr = ((struct in_addr *)(nlp_host->h_addr))->s_addr;
pin.sin_port = htons(port);
if((sockid = socket(AF_INET, SOCK_STREAM, 0)) < 0)
error(1, 0, "Error - socket(%d)", sockid);
/* set up alarm */
act1.sa_handler = alarm_function;
sigemptyset(&act1.sa_mask);
act1.sa_flags = 0;
#ifdef SA_INTERRUPT
act1.sa_flags |= SA_INTERRUPT;
#endif
if(sigaction(SIGALRM, &act1, &oact1) < 0)
error(1, 0, "Error - sigaction()");
/* connect .... */
alarm(tmout);
if(connect(sockid, (void *)&pin, sizeof(pin)) != 0)
error(1, 0, "Error - connect()");
alarm(0);
/* interrupted connect */
if(alarm_flag == 1)
error(1, 0, "Error - connect(): timeout");
return sockid;
}
int input_timeout(int filedes, unsigned int seconds) {
fd_set set;
struct timeval timeout;
FD_ZERO(&set);
FD_SET(filedes, &set);
timeout.tv_sec = seconds;
timeout.tv_usec = 0;
/* `0' on: timeout, `1' on: input available, `-1' on: error */
return select(FD_SETSIZE, &set, NULL, NULL, &timeout);
}
void alarm_function(int signo) {
alarm_flag = 1;
}
void isip4addr(char *str) {
char ipexpr[] = "^([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})$";
regex_t re = {0};
setlocale(LC_ALL, "");
if(regcomp(&re, ipexpr, REG_EXTENDED) != 0)
error(1, 0, "Error - Unable to compile regex:\n%s\n", ipexpr);
if(regexec(&re, str, 0, NULL, 0) != 0)
error(1, 0, "Error - Invalid ip4 address: %s", str);
regfree(&re);
return;
}
int readline(int fd, char *bufptr, size_t len) {
char *bufx = bufptr;
static char *bp;
static int cnt = 0;
static char b[1500];
char c;
while(--len > 0) {
if(--cnt <= 0) {
cnt = recv(fd, b, sizeof(b), 0);
if(cnt < 0) {
if(errno == EINTR) {
len++;
continue;
}
return -1;
}
if(cnt == 0)
return 0;
bp = b;
}
c = *bp++;
*bufptr++ = c;
if(c == '\n') {
*bufptr = '\0';
return bufptr - bufx;
}
}
return -1;
}