pppctl.c revision 31006
189580Smsmith#include <sys/types.h> 289580Smsmith#include <sys/socket.h> 389580Smsmith#include <netinet/in.h> 489580Smsmith#include <arpa/inet.h> 589580Smsmith#include <sys/un.h> 689580Smsmith#include <netdb.h> 789580Smsmith#include <signal.h> 889580Smsmith#include <string.h> 989580Smsmith#include <stdio.h> 1089580Smsmith#include <unistd.h> 1189580Smsmith#include <stdlib.h> 1289580Smsmith 1389580Smsmith#define LINELEN 2048 1489580Smsmithstatic char Buffer[LINELEN], Command[LINELEN]; 1589580Smsmith 1689580Smsmithstatic int Usage() 1789580Smsmith{ 1889580Smsmith fprintf(stderr, "Usage: pppctl [-v] [ -t n ] [ -p passwd ] Port|LocalSock [command[;command]...]\n"); 1989580Smsmith fprintf(stderr, " -v tells pppctl to output all conversation\n"); 2089580Smsmith fprintf(stderr, " -t n specifies a timeout of n seconds (default 2)\n"); 2189580Smsmith fprintf(stderr, " -p passwd specifies your password\n"); 2289580Smsmith return 1; 2389580Smsmith} 2489580Smsmith 2589580Smsmithstatic int TimedOut = 0; 2689580Smsmithvoid Timeout(int Sig) 2789580Smsmith{ 2889580Smsmith TimedOut = 1; 2989580Smsmith} 3089580Smsmith 3189580Smsmith#define REC_PASSWD (1) 3289580Smsmith#define REC_SHOW (2) 3389580Smsmith#define REC_VERBOSE (4) 3489580Smsmith 3589580Smsmithstatic char *passwd; 3689580Smsmith 3789580Smsmithint Receive(int fd, unsigned TimeoutVal, int display) 3889580Smsmith{ 3989580Smsmith int Result; 4089580Smsmith struct sigaction act, oact; 4189580Smsmith int len; 4289580Smsmith char *last; 4389580Smsmith 4495533Smike TimedOut = 0; 4589580Smsmith if (TimeoutVal) { 4689580Smsmith act.sa_handler = Timeout; 4789580Smsmith sigemptyset(&act.sa_mask); 4889580Smsmith act.sa_flags = 0; 4989580Smsmith sigaction(SIGALRM, &act, &oact); 5089580Smsmith alarm(TimeoutVal); 5189580Smsmith } 5289580Smsmith 5389580Smsmith len = 0; 5489580Smsmith while (Result = read(fd, Buffer+len, sizeof(Buffer)-len-1), Result != -1) { 5589580Smsmith len += Result; 5689580Smsmith Buffer[len] = '\0'; 5789580Smsmith if (TimedOut) { 5889580Smsmith if (display & REC_VERBOSE) 5989580Smsmith write(1,Buffer,len); 6089580Smsmith Result = -1; 6189580Smsmith break; 6289580Smsmith } else if (len > 2 && !strcmp(Buffer+len-2, "> ")) { 6389580Smsmith if (display & (REC_SHOW|REC_VERBOSE)) { 6489580Smsmith if (display & REC_VERBOSE) 6589580Smsmith last = Buffer+len-1; 6689580Smsmith else 6789580Smsmith last = rindex(Buffer, '\n'); 6889580Smsmith if (last) { 6989580Smsmith *++last = '\0'; 7089580Smsmith write(1, Buffer, last-Buffer); 7189580Smsmith } 7289580Smsmith } 7389580Smsmith for (last = Buffer+len-2; last > Buffer && *last != ' '; last--) 7489580Smsmith ; 7589580Smsmith if (last > Buffer+3 && !strncmp(last-3, " on", 3)) { 7689580Smsmith /* a password is required ! */ 7789580Smsmith if (display & REC_PASSWD) { 7889580Smsmith if (TimeoutVal) { 7989580Smsmith alarm(0); 8089580Smsmith sigaction(SIGALRM, &oact, 0); 8189580Smsmith } 8289580Smsmith /* password time */ 8389580Smsmith if (!passwd) 8489580Smsmith passwd = getpass("Password: "); 8589580Smsmith sprintf(Buffer, "passwd %s\n", passwd); 8689580Smsmith bzero(passwd, strlen(passwd)); 8789580Smsmith if (display & REC_VERBOSE) 8889580Smsmith write(1, Buffer, strlen(Buffer)); 8989580Smsmith write(fd, Buffer, strlen(Buffer)); 9089580Smsmith bzero(Buffer, strlen(Buffer)); 9189580Smsmith return Receive(fd, TimeoutVal, display & ~REC_PASSWD); 9289580Smsmith } 9389580Smsmith Result = 1; 9489580Smsmith } else 9589580Smsmith Result = 0; 9689580Smsmith break; 9789580Smsmith } 9889580Smsmith } 9989580Smsmith 10089580Smsmith if (TimedOut) 10189580Smsmith Result = -1; 10289580Smsmith 10389580Smsmith if (TimeoutVal) { 10489580Smsmith alarm(0); 10589580Smsmith sigaction(SIGALRM, &oact, 0); 10689580Smsmith } 10789580Smsmith return Result; 10889580Smsmith} 10989580Smsmith 11089580Smsmithint 11189580Smsmithmain(int argc, char **argv) 11289580Smsmith{ 11389580Smsmith struct servent *s; 11489580Smsmith struct hostent *h; 11589580Smsmith struct sockaddr *sock; 11689580Smsmith struct sockaddr_in ifsin; 11789580Smsmith struct sockaddr_un ifsun; 11889580Smsmith int socksz, arg, fd, len, verbose; 11989580Smsmith unsigned TimeoutVal; 12089580Smsmith char *DoneWord = "x", *next, *start; 12189580Smsmith struct sigaction act, oact; 12289580Smsmith 12389580Smsmith verbose = 0; 12489580Smsmith TimeoutVal = 2; 12589580Smsmith 12689580Smsmith for (arg = 1; arg < argc; arg++) 12789580Smsmith if (*argv[arg] == '-') { 12889580Smsmith for (start = argv[arg] + 1; *start; start++) 12989580Smsmith switch (*start) { 13089580Smsmith case 't': 13189580Smsmith TimeoutVal = (unsigned)atoi 13289580Smsmith (start[1] ? start + 1 : argv[++arg]); 13389580Smsmith start = DoneWord; 13489580Smsmith break; 13589580Smsmith 13689580Smsmith case 'v': 13789580Smsmith verbose = REC_VERBOSE; 13889580Smsmith break; 13989580Smsmith 14089580Smsmith case 'p': 14189580Smsmith passwd = (start[1] ? start + 1 : argv[++arg]); 14289580Smsmith start = DoneWord; 14389580Smsmith break; 14489580Smsmith 14589580Smsmith default: 14689580Smsmith return Usage(); 14789580Smsmith } 14889580Smsmith } 14989580Smsmith else 15089580Smsmith break; 15189580Smsmith 15289580Smsmith 15389580Smsmith if (argc < arg + 1) 15489580Smsmith return Usage(); 15589580Smsmith 15689580Smsmith if (*argv[arg] == '/') { 15789580Smsmith sock = (struct sockaddr *)&ifsun; 15889580Smsmith socksz = sizeof ifsun; 15989580Smsmith 16089580Smsmith ifsun.sun_len = strlen(argv[arg]); 16189580Smsmith if (ifsun.sun_len > sizeof ifsun.sun_path - 1) { 16289580Smsmith fprintf(stderr, "%s: Path too long\n", argv[arg]); 16389580Smsmith return 1; 16489580Smsmith } 16589580Smsmith ifsun.sun_family = AF_LOCAL; 16689580Smsmith strcpy(ifsun.sun_path, argv[arg]); 16789580Smsmith 16889580Smsmith if (fd = socket(AF_LOCAL, SOCK_STREAM, 0), fd < 0) { 16989580Smsmith fprintf(stderr, "Cannot create local domain socket\n"); 17089580Smsmith return 2; 17189580Smsmith } 17289580Smsmith } else { 17389580Smsmith char *port, *host, *colon; 17489580Smsmith int hlen; 17589580Smsmith 17689580Smsmith colon = strchr(argv[arg], ':'); 17789580Smsmith if (colon) { 17889580Smsmith port = colon + 1; 17989580Smsmith *colon = '\0'; 18089580Smsmith host = argv[arg]; 18189580Smsmith } else { 18289580Smsmith port = argv[arg]; 18389580Smsmith host = "127.0.0.1"; 18489580Smsmith } 18589580Smsmith sock = (struct sockaddr *)&ifsin; 18689580Smsmith socksz = sizeof ifsin; 18789580Smsmith hlen = strlen(host); 18889580Smsmith 18989580Smsmith if (strspn(host, "0123456789.") == hlen) { 19089580Smsmith if (!inet_aton(host, (struct in_addr *)&ifsin.sin_addr.s_addr)) { 19189580Smsmith fprintf(stderr, "Cannot translate %s\n", host); 19289580Smsmith return 1; 19389580Smsmith } 19489580Smsmith } else if ((h = gethostbyname(host)) == 0) { 19589580Smsmith fprintf(stderr, "Cannot resolve %s\n", host); 19689580Smsmith return 1; 19789580Smsmith } 19889580Smsmith else 19989580Smsmith ifsin.sin_addr.s_addr = *(u_long *)h->h_addr_list[0]; 20089580Smsmith 20189580Smsmith if (colon) 20289580Smsmith *colon = ':'; 20389580Smsmith 20489580Smsmith if (strspn(port, "0123456789") == strlen(port)) 20589580Smsmith ifsin.sin_port = htons(atoi(port)); 20689580Smsmith else if (s = getservbyname(port, "tcp"), !s) { 20789580Smsmith fprintf(stderr, "%s isn't a valid port or service!\n", port); 20889580Smsmith return Usage(); 20989580Smsmith } 21089580Smsmith else 21189580Smsmith ifsin.sin_port = s->s_port; 21289580Smsmith 21389580Smsmith ifsin.sin_len = sizeof(ifsin); 21489580Smsmith ifsin.sin_family = AF_INET; 21589580Smsmith 21689580Smsmith if (fd = socket(AF_INET, SOCK_STREAM, 0), fd < 0) { 21789580Smsmith fprintf(stderr, "Cannot create internet socket\n"); 21889580Smsmith return 2; 21989580Smsmith } 22089580Smsmith } 22189580Smsmith 22289580Smsmith TimedOut = 0; 22389580Smsmith if (TimeoutVal) { 22489580Smsmith act.sa_handler = Timeout; 22589580Smsmith sigemptyset(&act.sa_mask); 22689580Smsmith act.sa_flags = 0; 22789580Smsmith sigaction(SIGALRM, &act, &oact); 22889580Smsmith alarm(TimeoutVal); 22989580Smsmith } 23089580Smsmith 23189580Smsmith if (connect(fd, sock, socksz) < 0) { 23289580Smsmith if (TimeoutVal) { 23389580Smsmith alarm(0); 23489580Smsmith sigaction(SIGALRM, &oact, 0); 23589580Smsmith } 23689580Smsmith if (TimedOut) 23789580Smsmith fputs("Timeout: ", stderr); 23889580Smsmith fprintf(stderr, "Cannot connect to socket %s\n", argv[arg]); 23989580Smsmith close(fd); 24089580Smsmith return 3; 24189580Smsmith } 24289580Smsmith 24389580Smsmith if (TimeoutVal) { 24489580Smsmith alarm(0); 24589580Smsmith sigaction(SIGALRM, &oact, 0); 24689580Smsmith } 24789580Smsmith 24889580Smsmith len = 0; 24989580Smsmith Command[sizeof(Command)-1] = '\0'; 25089580Smsmith for (arg++; arg < argc; arg++) { 25189580Smsmith if (len && len < sizeof(Command)-1) 25289580Smsmith strcpy(Command+len++, " "); 25389580Smsmith strncpy(Command+len, argv[arg], sizeof(Command)-len-1); 25489580Smsmith len += strlen(Command+len); 25589580Smsmith } 25689580Smsmith 25789580Smsmith switch (Receive(fd, TimeoutVal, verbose | REC_PASSWD)) 25889580Smsmith { 25989580Smsmith case 1: 26089580Smsmith fprintf(stderr, "Password incorrect\n"); 26189580Smsmith break; 26289580Smsmith 26389580Smsmith case 0: 26489580Smsmith if (len == 0) { 26589580Smsmith if (!verbose) { 26689580Smsmith /* Give a \n to ppp for a prompt */ 26789580Smsmith write(fd, "\n", 1); 26889580Smsmith if (Receive(fd, TimeoutVal, REC_VERBOSE | REC_SHOW) != 0) { 26989580Smsmith fprintf(stderr, "Connection closed\n"); 27089580Smsmith break; 27189580Smsmith } 27289580Smsmith } 27389580Smsmith while (fgets(Buffer, sizeof(Buffer)-1, stdin)) { 27489580Smsmith write(fd, Buffer, strlen(Buffer)); 27589580Smsmith if (Receive(fd, TimeoutVal, REC_VERBOSE | REC_SHOW) != 0) { 27689580Smsmith fprintf(stderr, "Connection closed\n"); 27789580Smsmith break; 27889580Smsmith } 27989580Smsmith } 28089580Smsmith } else { 28189580Smsmith start = Command; 28289580Smsmith do { 28389580Smsmith next = index(start, ';'); 28489580Smsmith while (*start == ' ' || *start == '\t') 28589580Smsmith start++; 28689580Smsmith if (next) 28789580Smsmith *next = '\0'; 28889580Smsmith strcpy(Buffer, start); 28989580Smsmith Buffer[sizeof(Buffer)-2] = '\0'; 29089580Smsmith strcat(Buffer, "\n"); 29189580Smsmith if (verbose) 29289580Smsmith write(1, Buffer, strlen(Buffer)); 29389580Smsmith write(fd, Buffer, strlen(Buffer)); 29489580Smsmith if (Receive(fd, TimeoutVal, verbose | REC_SHOW) != 0) { 29589580Smsmith fprintf(stderr, "No reply from ppp\n"); 29689580Smsmith break; 29789580Smsmith } 29889580Smsmith if (next) 29989580Smsmith start = ++next; 30089580Smsmith } while (next && *next); 30189580Smsmith if (verbose) 30289580Smsmith puts(""); 30389580Smsmith } 30489580Smsmith break; 30589580Smsmith 30689580Smsmith default: 30789580Smsmith fprintf(stderr, "ppp is not responding\n"); 30889580Smsmith break; 30989580Smsmith } 31089580Smsmith 31189580Smsmith close(fd); 31289580Smsmith 31389580Smsmith return 0; 31489580Smsmith} 31589580Smsmith