diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/dial/at.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/dial/at.c')
-rwxr-xr-x | sys/src/cmd/dial/at.c | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/sys/src/cmd/dial/at.c b/sys/src/cmd/dial/at.c new file mode 100755 index 000000000..a680511ab --- /dev/null +++ b/sys/src/cmd/dial/at.c @@ -0,0 +1,144 @@ +#include <u.h> +#include <libc.h> + +void +usage(void) +{ + fprint(2, "usage: %s [-q] [-t seconds] command\n", argv0); + exits("usage"); +} + +struct { + char *resp; + int ok; +} tab[] = +{ + { "ok", 1 }, + { "connect", 1 }, + { "no carrier", 0 }, + { "no dialtone", 0 }, + { "error", 0 }, + { "busy", 0 }, + { "no answer", 0 }, + { "delayed", 0 }, + { "blacklisted", 0 }, +}; + +int +writewithoutcr(int fd, char *p, int i) +{ + char *q, *e; + + /* dump cr's */ + for(e = p+i; p < e; ){ + q = memchr(p, '\r', e-p); + if(q == nil) + break; + if(q > p) + if(write(fd, p, q-p) < 0) + return -1; + p = q+1; + } + if(p < e) + if(write(fd, p, e-p) < 0) + return -1; + return i; +} + +int +readln(int fd, char *buf, int n) +{ + int c, i, sofar; + + sofar = 0; + buf[sofar] = 0; + while(sofar < n-1){ + i = read(fd, buf+sofar, 1); + if(i <= 0) + return i; + c = buf[sofar]; + if(c == '\r') + continue; + sofar++; + if(c == '\n') + break; + } + buf[sofar] = 0; + return sofar; +} + +void +docmd(char *cmd, int timeout, int quiet, int consfd) +{ + char buf[4096]; + int i; + char *p, *cp; + + if(timeout == 0){ + if(*cmd == 'd' || *cmd == 'D') + timeout = 2*60; + else + timeout = 5; + } + + p = smprint("at%s\r", cmd); + for(cp = p; *cp; cp++){ + write(1, cp, 1); + sleep(100); + } + free(p); + + alarm(timeout*1000); + for(;;){ + i = readln(0, buf, sizeof(buf)); + if(i <= 0){ + rerrstr(buf, sizeof buf); + exits(buf); + } + if(!quiet) + writewithoutcr(consfd, buf, i); + for(i = 0; i < nelem(tab); i++) + if(cistrstr(buf, tab[i].resp)){ + if(tab[i].ok) + goto out; + else + exits(buf); + } + } +out: + alarm(0); +} + +void +main(int argc, char **argv) +{ + int timeout; + int quiet; + int i; + int consfd; + + timeout = 0; + quiet = 0; + ARGBEGIN { + case 't': + timeout = atoi(EARGF(usage())); + break; + case 'q': + quiet = 1; + break; + default: + usage(); + } ARGEND; + + if(argc < 1) + usage(); + + consfd = open("/dev/cons", ORDWR); + if(consfd < 0) + sysfatal("opening /dev/cons: %r"); + + for(i = 0; i < argc; i++) + docmd(argv[i], timeout, quiet, consfd); + + exits(0); +} |