listen1.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <auth.h>
  12. int verbose;
  13. int trusted;
  14. void
  15. usage(void)
  16. {
  17. fprint(2, "usage: listen1 [-tv] address cmd args...\n");
  18. exits("usage");
  19. }
  20. void
  21. becomenone(void)
  22. {
  23. int fd;
  24. fd = open("#c/user", OWRITE);
  25. if(fd < 0 || write(fd, "none", strlen("none")) < 0)
  26. sysfatal("can't become none: %r");
  27. close(fd);
  28. if(newns("none", nil) < 0)
  29. sysfatal("can't build namespace: %r");
  30. }
  31. char*
  32. remoteaddr(char *dir)
  33. {
  34. static char buf[128];
  35. char *p;
  36. int n, fd;
  37. snprint(buf, sizeof buf, "%s/remote", dir);
  38. fd = open(buf, OREAD);
  39. if(fd < 0)
  40. return "";
  41. n = read(fd, buf, sizeof(buf));
  42. close(fd);
  43. if(n > 0){
  44. buf[n] = 0;
  45. p = strchr(buf, '!');
  46. if(p)
  47. *p = 0;
  48. return buf;
  49. }
  50. return "";
  51. }
  52. void
  53. main(int argc, char **argv)
  54. {
  55. char data[60], dir[40], ndir[40];
  56. int ctl, nctl, fd;
  57. ARGBEGIN{
  58. default:
  59. usage();
  60. case 't':
  61. trusted = 1;
  62. break;
  63. case 'v':
  64. verbose = 1;
  65. break;
  66. }ARGEND
  67. if(argc < 2)
  68. usage();
  69. if(!verbose){
  70. close(1);
  71. fd = open("/dev/null", OWRITE);
  72. if(fd != 1){
  73. dup(fd, 1);
  74. close(fd);
  75. }
  76. }
  77. if(!trusted)
  78. becomenone();
  79. print("listen started\n");
  80. ctl = announce(argv[0], dir);
  81. if(ctl < 0)
  82. sysfatal("announce %s: %r", argv[0]);
  83. for(;;){
  84. nctl = listen(dir, ndir);
  85. if(nctl < 0)
  86. sysfatal("listen %s: %r", argv[0]);
  87. switch(rfork(RFFDG|RFPROC|RFNOWAIT|RFENVG|RFNAMEG|RFNOTEG)){
  88. case -1:
  89. reject(nctl, ndir, "host overloaded");
  90. close(nctl);
  91. continue;
  92. case 0:
  93. fd = accept(nctl, ndir);
  94. if(fd < 0){
  95. fprint(2, "accept %s: can't open %s/data: %r\n",
  96. argv[0], ndir);
  97. _exits(0);
  98. }
  99. print("incoming call for %s from %s in %s\n", argv[0],
  100. remoteaddr(ndir), ndir);
  101. fprint(nctl, "keepalive");
  102. close(ctl);
  103. close(nctl);
  104. putenv("net", ndir);
  105. snprint(data, sizeof data, "%s/data", ndir);
  106. bind(data, "/dev/cons", MREPL);
  107. dup(fd, 0);
  108. dup(fd, 1);
  109. dup(fd, 2);
  110. close(fd);
  111. exec(argv[1], argv+1);
  112. if(argv[1][0] != '/')
  113. exec(smprint("/bin/%s", argv[1]), argv+1);
  114. fprint(2, "%s: exec: %r\n", argv0);
  115. exits(nil);
  116. default:
  117. close(nctl);
  118. break;
  119. }
  120. }
  121. }