11cea1571SDavid du Colombier #include <u.h>
21cea1571SDavid du Colombier #include <libc.h>
31cea1571SDavid du Colombier
41cea1571SDavid du Colombier void
usage(void)51cea1571SDavid du Colombier usage(void)
61cea1571SDavid du Colombier {
71cea1571SDavid du Colombier fprint(2, "usage: %s [-q] [-t seconds] command\n", argv0);
81cea1571SDavid du Colombier exits("usage");
91cea1571SDavid du Colombier }
101cea1571SDavid du Colombier
111cea1571SDavid du Colombier struct {
121cea1571SDavid du Colombier char *resp;
131cea1571SDavid du Colombier int ok;
141cea1571SDavid du Colombier } tab[] =
151cea1571SDavid du Colombier {
16*853458f3SDavid du Colombier { "ok\n", 1 },
17*853458f3SDavid du Colombier { "connect\n", 1 },
18*853458f3SDavid du Colombier { "no carrier\n", 0 },
19*853458f3SDavid du Colombier { "no dialtone\n", 0 },
20*853458f3SDavid du Colombier { "error\n", 0 },
21*853458f3SDavid du Colombier { "busy\n", 0 },
22*853458f3SDavid du Colombier { "no answer\n", 0 },
23*853458f3SDavid du Colombier { "delayed\n", 0 },
24*853458f3SDavid du Colombier { "blacklisted\n", 0 },
251cea1571SDavid du Colombier };
261cea1571SDavid du Colombier
271cea1571SDavid du Colombier int
writewithoutcr(int fd,char * p,int i)281cea1571SDavid du Colombier writewithoutcr(int fd, char *p, int i)
291cea1571SDavid du Colombier {
301cea1571SDavid du Colombier char *q, *e;
311cea1571SDavid du Colombier
321cea1571SDavid du Colombier /* dump cr's */
331cea1571SDavid du Colombier for(e = p+i; p < e; ){
341cea1571SDavid du Colombier q = memchr(p, '\r', e-p);
351cea1571SDavid du Colombier if(q == nil)
361cea1571SDavid du Colombier break;
371cea1571SDavid du Colombier if(q > p)
381cea1571SDavid du Colombier if(write(fd, p, q-p) < 0)
391cea1571SDavid du Colombier return -1;
401cea1571SDavid du Colombier p = q+1;
411cea1571SDavid du Colombier }
421cea1571SDavid du Colombier if(p < e)
431cea1571SDavid du Colombier if(write(fd, p, e-p) < 0)
441cea1571SDavid du Colombier return -1;
451cea1571SDavid du Colombier return i;
461cea1571SDavid du Colombier }
471cea1571SDavid du Colombier
481cea1571SDavid du Colombier int
readln(int fd,char * buf,int n)491cea1571SDavid du Colombier readln(int fd, char *buf, int n)
501cea1571SDavid du Colombier {
511cea1571SDavid du Colombier int c, i, sofar;
521cea1571SDavid du Colombier
531cea1571SDavid du Colombier sofar = 0;
541cea1571SDavid du Colombier buf[sofar] = 0;
551cea1571SDavid du Colombier while(sofar < n-1){
561cea1571SDavid du Colombier i = read(fd, buf+sofar, 1);
571cea1571SDavid du Colombier if(i <= 0)
581cea1571SDavid du Colombier return i;
591cea1571SDavid du Colombier c = buf[sofar];
601cea1571SDavid du Colombier if(c == '\r')
611cea1571SDavid du Colombier continue;
621cea1571SDavid du Colombier sofar++;
631cea1571SDavid du Colombier if(c == '\n')
641cea1571SDavid du Colombier break;
651cea1571SDavid du Colombier }
661cea1571SDavid du Colombier buf[sofar] = 0;
671cea1571SDavid du Colombier return sofar;
681cea1571SDavid du Colombier }
691cea1571SDavid du Colombier
701cea1571SDavid du Colombier void
docmd(char * cmd,int timeout,int quiet,int consfd)711cea1571SDavid du Colombier docmd(char *cmd, int timeout, int quiet, int consfd)
721cea1571SDavid du Colombier {
731cea1571SDavid du Colombier char buf[4096];
741cea1571SDavid du Colombier int i;
751cea1571SDavid du Colombier char *p, *cp;
761cea1571SDavid du Colombier
771cea1571SDavid du Colombier if(timeout == 0){
781cea1571SDavid du Colombier if(*cmd == 'd' || *cmd == 'D')
791cea1571SDavid du Colombier timeout = 2*60;
801cea1571SDavid du Colombier else
811cea1571SDavid du Colombier timeout = 5;
821cea1571SDavid du Colombier }
831cea1571SDavid du Colombier
841cea1571SDavid du Colombier p = smprint("at%s\r", cmd);
851cea1571SDavid du Colombier for(cp = p; *cp; cp++){
861cea1571SDavid du Colombier write(1, cp, 1);
871cea1571SDavid du Colombier sleep(100);
881cea1571SDavid du Colombier }
891cea1571SDavid du Colombier free(p);
901cea1571SDavid du Colombier
911cea1571SDavid du Colombier alarm(timeout*1000);
921cea1571SDavid du Colombier for(;;){
931cea1571SDavid du Colombier i = readln(0, buf, sizeof(buf));
941cea1571SDavid du Colombier if(i <= 0){
951cea1571SDavid du Colombier rerrstr(buf, sizeof buf);
961cea1571SDavid du Colombier exits(buf);
971cea1571SDavid du Colombier }
981cea1571SDavid du Colombier if(!quiet)
991cea1571SDavid du Colombier writewithoutcr(consfd, buf, i);
1001cea1571SDavid du Colombier for(i = 0; i < nelem(tab); i++)
101*853458f3SDavid du Colombier if(cistrcmp(buf, tab[i].resp) == 0){
1021cea1571SDavid du Colombier if(tab[i].ok)
1031cea1571SDavid du Colombier goto out;
1041cea1571SDavid du Colombier else
1051cea1571SDavid du Colombier exits(buf);
1061cea1571SDavid du Colombier }
1071cea1571SDavid du Colombier }
1081cea1571SDavid du Colombier out:
1091cea1571SDavid du Colombier alarm(0);
1101cea1571SDavid du Colombier }
1111cea1571SDavid du Colombier
1121cea1571SDavid du Colombier void
main(int argc,char ** argv)1131cea1571SDavid du Colombier main(int argc, char **argv)
1141cea1571SDavid du Colombier {
1151cea1571SDavid du Colombier int timeout;
1161cea1571SDavid du Colombier int quiet;
1171cea1571SDavid du Colombier int i;
1181cea1571SDavid du Colombier int consfd;
1191cea1571SDavid du Colombier
1201cea1571SDavid du Colombier timeout = 0;
1211cea1571SDavid du Colombier quiet = 0;
1221cea1571SDavid du Colombier ARGBEGIN {
1231cea1571SDavid du Colombier case 't':
1241cea1571SDavid du Colombier timeout = atoi(EARGF(usage()));
1251cea1571SDavid du Colombier break;
1261cea1571SDavid du Colombier case 'q':
1271cea1571SDavid du Colombier quiet = 1;
1281cea1571SDavid du Colombier break;
1291cea1571SDavid du Colombier default:
1301cea1571SDavid du Colombier usage();
1311cea1571SDavid du Colombier } ARGEND;
1321cea1571SDavid du Colombier
1331cea1571SDavid du Colombier if(argc < 1)
1341cea1571SDavid du Colombier usage();
1351cea1571SDavid du Colombier
1361cea1571SDavid du Colombier consfd = open("/dev/cons", ORDWR);
1371cea1571SDavid du Colombier if(consfd < 0)
1381cea1571SDavid du Colombier sysfatal("opening /dev/cons: %r");
1391cea1571SDavid du Colombier
1401cea1571SDavid du Colombier for(i = 0; i < argc; i++)
1411cea1571SDavid du Colombier docmd(argv[i], timeout, quiet, consfd);
1421cea1571SDavid du Colombier
1431cea1571SDavid du Colombier exits(0);
1441cea1571SDavid du Colombier }
145