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