1 #include <sys/types.h> 2 #include <sys/socket.h> 3 #include <netinet/in.h> 4 #include <arpa/inet.h> 5 #include <sys/un.h> 6 #include <netdb.h> 7 #include <signal.h> 8 #include <string.h> 9 #include <stdio.h> 10 #include <unistd.h> 11 #include <stdlib.h> 12 13 #define LINELEN 2048 14 static char Buffer[LINELEN], Command[LINELEN]; 15 16 static int Usage() 17 { 18 fprintf(stderr, "Usage: pppctl [-v] [ -t n ] [ -p passwd ] Port|LocalSock command[;command]...\n"); 19 fprintf(stderr, " -v tells pppctl to output all conversation\n"); 20 fprintf(stderr, " -t n specifies a timeout of n seconds (default 2)\n"); 21 fprintf(stderr, " -p passwd specifies your password\n"); 22 return 1; 23 } 24 25 static int TimedOut = 0; 26 void Timeout(int Sig) 27 { 28 TimedOut = 1; 29 } 30 31 #define REC_PASSWD (1) 32 #define REC_SHOW (2) 33 #define REC_VERBOSE (4) 34 35 static char *passwd; 36 37 int Receive(int fd, unsigned TimeoutVal, int display) 38 { 39 int Result; 40 struct sigaction act, oact; 41 int len; 42 char *last; 43 44 TimedOut = 0; 45 if (TimeoutVal) { 46 act.sa_handler = Timeout; 47 sigemptyset(&act.sa_mask); 48 act.sa_flags = 0; 49 sigaction(SIGALRM, &act, &oact); 50 alarm(TimeoutVal); 51 } 52 53 len = 0; 54 while (Result = read(fd, Buffer+len, sizeof(Buffer)-len-1), Result != -1) { 55 len += Result; 56 Buffer[len] = '\0'; 57 if (TimedOut) { 58 if (display & REC_VERBOSE) 59 write(1,Buffer,len); 60 Result = -1; 61 break; 62 } else if (len > 2 && !strcmp(Buffer+len-2, "> ")) { 63 if (display & (REC_SHOW|REC_VERBOSE)) { 64 if (display & REC_VERBOSE) 65 last = Buffer+len-1; 66 else 67 last = rindex(Buffer, '\n'); 68 if (last) { 69 *++last = '\0'; 70 write(1, Buffer, last-Buffer); 71 } 72 } 73 for (last = Buffer+len-2; last > Buffer && *last != ' '; last--) 74 ; 75 if (last > Buffer+3 && !strncmp(last-3, " on", 3)) { 76 /* a password is required ! */ 77 if (display & REC_PASSWD) { 78 if (TimeoutVal) { 79 alarm(0); 80 sigaction(SIGALRM, &oact, 0); 81 } 82 /* password time */ 83 if (!passwd) 84 passwd = getpass("Password: "); 85 sprintf(Buffer, "passwd %s\n", passwd); 86 bzero(passwd, strlen(passwd)); 87 if (display & REC_VERBOSE) 88 write(1, Buffer, strlen(Buffer)); 89 write(fd, Buffer, strlen(Buffer)); 90 bzero(Buffer, strlen(Buffer)); 91 return Receive(fd, TimeoutVal, display & ~REC_PASSWD); 92 } 93 Result = 1; 94 } else 95 Result = 0; 96 break; 97 } 98 } 99 100 if (TimedOut) 101 Result = -1; 102 103 if (TimeoutVal) { 104 alarm(0); 105 sigaction(SIGALRM, &oact, 0); 106 } 107 return Result; 108 } 109 110 int 111 main(int argc, char **argv) 112 { 113 struct servent *s; 114 struct hostent *h; 115 struct sockaddr *sock; 116 struct sockaddr_in ifsin; 117 struct sockaddr_un ifsun; 118 int socksz, arg, fd, len, verbose; 119 unsigned TimeoutVal; 120 char *DoneWord = "x", *next, *start; 121 struct sigaction act, oact; 122 123 verbose = 0; 124 TimeoutVal = 2; 125 126 for (arg = 1; arg < argc; arg++) 127 if (*argv[arg] == '-') { 128 for (start = argv[arg] + 1; *start; start++) 129 switch (*start) { 130 case 't': 131 TimeoutVal = (unsigned)atoi 132 (start[1] ? start + 1 : argv[++arg]); 133 start = DoneWord; 134 break; 135 136 case 'v': 137 verbose = REC_VERBOSE; 138 break; 139 140 case 'p': 141 passwd = (start[1] ? start + 1 : argv[++arg]); 142 start = DoneWord; 143 break; 144 145 default: 146 return Usage(); 147 } 148 } 149 else 150 break; 151 152 153 if (argc < arg + 2) 154 return Usage(); 155 156 if (*argv[arg] == '/') { 157 sock = (struct sockaddr *)&ifsun; 158 socksz = sizeof ifsun; 159 160 ifsun.sun_len = strlen(argv[arg]); 161 if (ifsun.sun_len > sizeof ifsun.sun_path - 1) { 162 fprintf(stderr, "%s: Path too long\n", argv[arg]); 163 return 1; 164 } 165 ifsun.sun_family = AF_LOCAL; 166 strcpy(ifsun.sun_path, argv[arg]); 167 168 if (fd = socket(AF_LOCAL, SOCK_STREAM, 0), fd < 0) { 169 fprintf(stderr, "Cannot create local domain socket\n"); 170 return 2; 171 } 172 } else { 173 char *port, *host, *colon; 174 int hlen; 175 176 colon = strchr(argv[arg], ':'); 177 if (colon) { 178 port = colon + 1; 179 *colon = '\0'; 180 host = argv[arg]; 181 } else { 182 port = argv[arg]; 183 host = "127.0.0.1"; 184 } 185 sock = (struct sockaddr *)&ifsin; 186 socksz = sizeof ifsin; 187 hlen = strlen(host); 188 189 if (strspn(host, "0123456789.") == hlen) { 190 if (!inet_aton(host, (struct in_addr *)&ifsin.sin_addr.s_addr)) { 191 fprintf(stderr, "Cannot translate %s\n", host); 192 return 1; 193 } 194 } else if ((h = gethostbyname(host)) == 0) { 195 fprintf(stderr, "Cannot resolve %s\n", host); 196 return 1; 197 } 198 else 199 ifsin.sin_addr.s_addr = *(u_long *)h->h_addr_list[0]; 200 201 if (colon) 202 *colon = ':'; 203 204 if (strspn(port, "0123456789") == strlen(port)) 205 ifsin.sin_port = htons(atoi(port)); 206 else if (s = getservbyname(port, "tcp"), !s) { 207 fprintf(stderr, "%s isn't a valid port or service!\n", port); 208 return Usage(); 209 } 210 else 211 ifsin.sin_port = s->s_port; 212 213 ifsin.sin_len = sizeof(ifsin); 214 ifsin.sin_family = AF_INET; 215 216 if (fd = socket(AF_INET, SOCK_STREAM, 0), fd < 0) { 217 fprintf(stderr, "Cannot create internet socket\n"); 218 return 2; 219 } 220 } 221 222 TimedOut = 0; 223 if (TimeoutVal) { 224 act.sa_handler = Timeout; 225 sigemptyset(&act.sa_mask); 226 act.sa_flags = 0; 227 sigaction(SIGALRM, &act, &oact); 228 alarm(TimeoutVal); 229 } 230 231 if (connect(fd, sock, socksz) < 0) { 232 if (TimeoutVal) { 233 alarm(0); 234 sigaction(SIGALRM, &oact, 0); 235 } 236 if (TimedOut) 237 fputs("Timeout: ", stderr); 238 fprintf(stderr, "Cannot connect to socket %s\n", argv[arg]); 239 close(fd); 240 return 3; 241 } 242 243 if (TimeoutVal) { 244 alarm(0); 245 sigaction(SIGALRM, &oact, 0); 246 } 247 248 len = 0; 249 Command[sizeof(Command)-1] = '\0'; 250 for (arg++; arg < argc; arg++) { 251 if (len && len < sizeof(Command)-1) 252 strcpy(Command+len++, " "); 253 strncpy(Command+len, argv[arg], sizeof(Command)-len-1); 254 len += strlen(Command+len); 255 } 256 257 switch (Receive(fd, TimeoutVal, verbose | REC_PASSWD)) 258 { 259 case 1: 260 fprintf(stderr, "Password incorrect\n"); 261 break; 262 263 case 0: 264 start = Command; 265 do { 266 next = index(start, ';'); 267 while (*start == ' ' || *start == '\t') 268 start++; 269 if (next) 270 *next = '\0'; 271 strcpy(Buffer, start); 272 Buffer[sizeof(Buffer)-2] = '\0'; 273 strcat(Buffer, "\n"); 274 if (verbose) 275 write(1, Buffer, strlen(Buffer)); 276 write(fd, Buffer, strlen(Buffer)); 277 if (Receive(fd, TimeoutVal, verbose | REC_SHOW) != 0) { 278 fprintf(stderr, "No reply from ppp\n"); 279 break; 280 } 281 if (next) 282 start = ++next; 283 } while (next && *next); 284 if (verbose) 285 puts(""); 286 break; 287 288 default: 289 fprintf(stderr, "ppp is not responding\n"); 290 break; 291 } 292 293 close(fd); 294 295 return 0; 296 } 297