]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/dial/at.c
abaco: cleanup, handle image/x-icon, don't use backspace as a hotkey, and remove...
[plan9front.git] / sys / src / cmd / dial / at.c
1 #include <u.h>
2 #include <libc.h>
3
4 void
5 usage(void)
6 {
7         fprint(2, "usage: %s [-q] [-t seconds] command\n", argv0);
8         exits("usage");
9 }
10
11 struct {
12         char    *resp;
13         int     ok;
14 } tab[] =
15 {
16         { "ok",                 1 },
17         { "connect",            1 },
18         { "no carrier",         0 },
19         { "no dialtone",        0 },
20         { "error",              0 },
21         { "busy",               0 },
22         { "no answer",          0 },
23         { "delayed",            0 },
24         { "blacklisted",        0 },
25 };
26
27 int
28 writewithoutcr(int fd, char *p, int i)
29 {
30         char *q, *e;
31
32         /* dump cr's */
33         for(e = p+i; p < e; ){
34                 q = memchr(p, '\r', e-p);
35                 if(q == nil)
36                         break;
37                 if(q > p)
38                         if(write(fd, p, q-p) < 0)
39                                 return -1;
40                 p = q+1;
41         }
42         if(p < e)
43                 if(write(fd, p, e-p) < 0)
44                         return -1;
45         return i;
46 }
47
48 int
49 readln(int fd, char *buf, int n)
50 {
51         int c, i, sofar;
52
53         sofar = 0;
54         buf[sofar] = 0;
55         while(sofar < n-1){
56                 i = read(fd, buf+sofar, 1);
57                 if(i <= 0)
58                         return i;
59                 c = buf[sofar];
60                 if(c == '\r')
61                         continue;
62                 sofar++;
63                 if(c == '\n')
64                         break;
65         }
66         buf[sofar] = 0;
67         return sofar;
68 }
69
70 void
71 docmd(char *cmd, int timeout, int quiet, int consfd)
72 {
73         char buf[4096];
74         int i;
75         char *p, *cp;
76
77         if(timeout == 0){
78                 if(*cmd == 'd' || *cmd == 'D')
79                         timeout = 2*60;
80                 else
81                         timeout = 5;
82         }
83
84         p = smprint("at%s\r", cmd);
85         for(cp = p; *cp; cp++){
86                 write(1, cp, 1);
87                 sleep(100);
88         }
89         free(p);
90
91         alarm(timeout*1000);
92         for(;;){
93                 i = readln(0, buf, sizeof(buf));
94                 if(i <= 0){
95                         rerrstr(buf, sizeof buf);
96                         exits(buf);
97                 }
98                 if(!quiet)
99                         writewithoutcr(consfd, buf, i);
100                 for(i = 0; i < nelem(tab); i++)
101                         if(cistrstr(buf, tab[i].resp)){
102                                 if(tab[i].ok)
103                                         goto out;
104                                 else
105                                         exits(buf);
106                         }
107         }
108 out:
109         alarm(0);
110 }
111
112 void
113 main(int argc, char **argv)
114 {
115         int timeout;
116         int quiet;
117         int i;
118         int consfd;
119
120         timeout = 0;
121         quiet = 0;
122         ARGBEGIN {
123         case 't':
124                 timeout = atoi(EARGF(usage()));
125                 break;
126         case 'q':
127                 quiet = 1;
128                 break;
129         default:
130                 usage();
131         } ARGEND;
132
133         if(argc < 1)
134                 usage();
135
136         consfd = open("/dev/cons", ORDWR);
137         if(consfd < 0)
138                 sysfatal("opening /dev/cons: %r");
139
140         for(i = 0; i < argc; i++)
141                 docmd(argv[i], timeout, quiet, consfd);
142
143         exits(0);
144 }