#include <u.h>#include <libc.h> voidusage(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 },}; intwritewithoutcr(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;} intreadln(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;} voiddocmd(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);} voidmain(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);}
#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);
}