xref: /plan9/sys/src/cmd/dial/at.c (revision 853458f38e7eb3a48cfa3a36aefdb799375e398a)
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