at.c 2.0 KB

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